pregMapping.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.24 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 #ifdef DELTA_COMPILER
00025 
00026 // A PRegClosure is used when iterating over a PRegMapping.
00027 
00028 class PRegClosure: public PrintableResourceObj {
00029  public:
00030   virtual void preg_do(PReg* preg) {}           // called for each PReg in the mapping
00031 };
00032 
00033 
00034 // A PRegMapping holds the mapping of life PRegs to (register and/or stack) locations.
00035 // Within one PRegMapping, at any time a particular PReg is mapped to at most one register
00036 // and one stack location, but different PRegs may be mapped to the same location. Because
00037 // of register moving/spilling, PReg locations may change automatically.
00038 //
00039 // Note: The _NLRinProgress flag indicates that the current mapping also reserves the
00040 //       3 special registers used during NLRs. This is needed because these registers
00041 //       are not explicitly visible in the intermediate data structure (no PRegs) but
00042 //       have to be preserved anyway (e.g. code generation for conformance mappings).
00043 
00044 class PRegMapping: public PrintableResourceObj {
00045  private:
00046   MacroAssembler*       _assm;                  // the low_level assembler (for spill code generation, etc.)
00047   bool                  _NLRinProgress;         // indicates that a NLR is in progress (see also Note above)
00048   Locations*            _locs;                  // the locations freelist
00049   GrowableArray<PReg*>* _pregs;                 // the pregs, a NULL entry means the slot is not used
00050   GrowableArray<int>*   _regLocs;               // the register to which a preg is mapped or -1
00051   GrowableArray<int>*   _stkLocs;               // the stack location to which a preg is mapped or -1
00052   GrowableArray<int>*   _tmpLocs;               // a list of temporary locations used by instances of Temporary
00053                                                 // (these locations will be freed when the mapping is copied)
00054 
00055   // Helper routines
00056   int  size() const                             { return _pregs->length(); }
00057   bool used(int i) const                        { return _pregs->at(i) != NULL; }
00058   int  regLoc(int i) const                      { return _regLocs->at(i); }
00059   int  stkLoc(int i) const                      { return _stkLocs->at(i); }
00060   bool hasRegLoc(int i) const                   { return _locs->isLocation(regLoc(i)); }
00061   bool hasStkLoc(int i) const                   { return _locs->isLocation(stkLoc(i)); }
00062   int  location(int i) const                    { int rloc = regLoc(i); return rloc >= 0 ? rloc : stkLoc(i); }
00063   void set_entry(int i, PReg* preg, int rloc, int sloc);
00064   int  index(PReg* preg);
00065   int  freeSlot();
00066   void print(int i);
00067   void destroy();                               // destroys mapping to make sure it is not accidentally used afterwards
00068 
00069   // Register allocation/spilling
00070   int  spillablePRegIndex();                    // returns the _pregs/_mappings index of a PReg mapped to a non-locked register
00071   void ensureOneFreeRegister();                 // ensures at least one free register in locations - spill a register if necessary
00072   void spillRegister(int loc);                  // spills register loc to a free stack location
00073   void saveRegister(int loc);
00074   
00075   // Helpers for class Temporary
00076   int  allocateTemporary(Register hint = noreg);
00077   void releaseTemporary(int regLoc);
00078   void releaseAllTemporaries();
00079 
00080   // make conformant implementations
00081   void old_makeConformant(PRegMapping* with);
00082   void new_makeConformant(PRegMapping* with);
00083 
00084  public:
00085   // Creation
00086   PRegMapping(MacroAssembler* assm, int nofArgs, int nofRegs, int nofTemps);
00087   PRegMapping(PRegMapping* m);
00088 
00089   MacroAssembler* assembler() const             { return _assm; }
00090 
00091   // Testers
00092   bool isInjective();
00093   bool isConformant(PRegMapping* with);
00094   bool isDefined(PReg* preg)                    { return index(preg) >= 0; }
00095   bool inRegister(PReg* preg)                   { int i = index(preg); return used(i) && hasRegLoc(i); }
00096   bool onStack(PReg* preg)                      { int i = index(preg); return used(i) && hasStkLoc(i); }
00097   
00098   // Definition
00099   void mapToArgument(PReg* preg, int argNo);
00100   void mapToRegister(PReg* preg, Register reg);
00101   void mapToTemporary(PReg* preg, int tempNo);
00102 
00103   void kill(PReg* preg);
00104   void killDeadsAt(Node* node, PReg* exception = NULL);
00105   void killAll(PReg* exception = NULL);
00106   void cleanupContextReferences();
00107 
00108   // Expressions
00109   Register def(PReg* preg, Register hint = noreg);      // defines a new value for preg (uses hint if given)
00110   Register use(PReg* preg, Register hint);              // uses the value of preg (uses hint if given)
00111   Register use(PReg* preg);                             // deals also with constants (code originally in CodeGenerator)
00112 
00113   // Assignments
00114   void move(PReg* dst, PReg* src);
00115 
00116   // Calls
00117   void saveRegisters(PReg* exception = NULL);
00118   void killRegisters(PReg* exception = NULL);
00119   void killRegister (PReg* preg);
00120 
00121   // Non-local returns
00122   bool NLRinProgress() const                    { return _NLRinProgress; }
00123   void acquireNLRRegisters();
00124   void releaseNLRRegisters();
00125 
00126   // Labels
00127   void makeInjective();
00128   void makeConformant(PRegMapping* with);
00129 
00130   // Iteration/Debug info
00131   void iterate(PRegClosure* closure);
00132   Location locationFor(PReg* preg);
00133 
00134   // Space usage
00135   int  nofPRegs();
00136   int  maxNofStackTmps();
00137 
00138   // Debugging
00139   void my_print();
00140   void print();
00141   void verify();
00142 
00143   friend class Temporary;
00144 };
00145 
00146 
00147 // A PRegLocker is used to lock certain PRegs for the existence of the scope of
00148 // a C++ function activation. A PReg that is locked in a PRegLocker is kept in
00149 // the same register once it has been mapped to a register location by a PRegMapping.
00150 // NOTE: PRegLockers MUST only be created/destructed in a stack-fashioned manner.
00151 
00152 class PRegLocker: StackObj {
00153  private:
00154   static PRegLocker*    _top;                   // the topmost PRegLocker
00155   PRegLocker*           _prev;                  // the previous PRegLocker
00156   PReg*                 _pregs[3];              // the locked PRregs
00157 
00158   void lock(PReg* r0, PReg* r1, PReg* r2)       { _prev = _top; _top = this; _pregs[0] = r0; _pregs[1] = r1; _pregs[2] = r2; }
00159   bool holds(PReg* preg) const;                 // returns true if preg belongs to the locked PRegs
00160 
00161  public:
00162   PRegLocker(PReg* r0);
00163   PRegLocker(PReg* r0, PReg* r1);
00164   PRegLocker(PReg* r0, PReg* r1, PReg* r2);
00165   ~PRegLocker()                                 { _top = _prev; }
00166 
00167   
00168   static bool locks(PReg* preg);                // returns true if preg is locked in any PRegLocker instance
00169   static void initialize()                      { _top = NULL; }
00170   friend class PRegMapping;
00171 };
00172 
00173 
00174 // A Temporary is a freely usable register allocated for the time the Temporary
00175 // is alive. Temporaries must be created/destructed in a stack-fashioned manner.
00176 
00177 class Temporary: StackObj {
00178  private:
00179   PRegMapping*  _mapping;
00180   int           _regLoc;
00181 
00182  public:
00183   Temporary(PRegMapping* mapping, Register hint = noreg);
00184   Temporary(PRegMapping* mapping, PReg* preg);  // keep a (modifiable) copy of the preg value in temporary register
00185   ~Temporary();
00186 
00187   Register reg() const                          { return _mapping->_locs->locationAsRegister(_regLoc); }
00188 };
00189 
00190 
00191 #endif

Generated on Mon Oct 9 13:37:22 2006 for Strongtalk VM by  doxygen 1.4.7