preg.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies L.L.C. $Revision: 1.47 $ */
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 // All intermediate language (IL) operations work on pseudo registers (PRegs).
00027 // In contrast to real registers, the number of available pseudo registers is
00028 // unlimited.
00029 
00030 // PRegs are standard pseudo regs; the different kinds of PRegs differ
00031 // mainly in their purpose and in their live ranges
00032 // PReg: locals etc., multiply assigned, live range is the entire scope
00033 // SAPReg: single source-level assignment, live range = arbitrary subrange
00034 // SplitPReg: used for splitting
00035 // BlockPRegs: for blocks, live range = creating bci .. end
00036 // TempPRegs: local to one BB, used for certain hard-coded idioms (e.g.
00037 // loading an uplevel-accessed value)
00038 
00039 class PReg: public PrintableResourceObj {
00040  protected:
00041   int16 _id;                            // unique id
00042   int16 _nuses, _ndefs;                 // number of defs & uses (including soft uses)
00043                                         // (negative means incorrect/unknown values,
00044                                         // e.g. hardwired regs)
00045   int16 _nsoftUses;                     // number of "soft" uses
00046   LogicalAddress* _logicalAddress;      // for new backend only: logical address if created or NULL
00047   static const int AvgBBIndexLen;       // estimated # of BBs in which I appear
00048  public:
00049   static int currentNo;                 // id of next PReg created
00050   GrowableArray<PRegBBIndex*> dus;      // defs and uses
00051   InlinedScope* _scope;                 // scope to which I belong
00052   Location loc;                         // real location assigned to this preg
00053   CPInfo* cpInfo;                       // to follow effects of copy propagation
00054   GrowableArray<PReg*>* cpRegs;         // regs cp-ed away by me
00055   int regClass;                         // register equivalence class number
00056   PReg* regClassLink;                   // next element in class
00057   int weight;                           // weight (importance) for reg. allocation
00058                                         // (-1 if targeted register)
00059   GrowableArray<BlockPReg*>* _uplevelR; // list of blocks that uplevel-read me (or NULL)
00060   GrowableArray<BlockPReg*>* _uplevelW; // list of blocks that uplevel-write me (or NULL)
00061   bool debug;                           // value/loc needed for debugging info?
00062   int _map_index_cash;                  // cashes old map index - used to improve PregMapping access speed - must be >= 0
00063 
00064  protected:
00065   void initialize() {
00066     _id = currentNo++; 
00067     _uplevelR = _uplevelW = NULL; debug = false;
00068     _nuses = _ndefs = _nsoftUses = weight = 0;
00069     _logicalAddress = NULL;
00070     cpInfo = NULL; regClass = 0;
00071     regClassLink = 0; cpRegs = NULL;
00072     _map_index_cash = 0;
00073   }
00074   static const int VeryNegative;
00075     
00076  public:
00077   PReg(InlinedScope* s) : dus(AvgBBIndexLen) {
00078     assert(s, "must have a scope");
00079     initialize(); _scope = s; loc = unAllocated;
00080   }
00081 
00082   PReg(InlinedScope* s, Location l, bool incU, bool incD) : dus(AvgBBIndexLen){
00083     assert(s, "must have a scope");
00084     assert(!l.equals(illegalLocation), "illegal location");
00085     initialize(); _scope = s; loc = l;
00086     if (incU) _nuses = VeryNegative;
00087     if (incD) _ndefs = VeryNegative;
00088   }
00089 
00090   int id() const                        { return _id; }
00091   InlinedScope* scope() const           { return _scope; }
00092   virtual bool isSAPReg() const         { return false; }
00093   virtual bool isArgSAPReg() const      { return false; }
00094   virtual bool isSplitPReg() const      { return false; }
00095   virtual bool isTempPReg() const       { return false; }
00096   virtual bool isNoPReg() const         { return false; }
00097   virtual bool isBlockPReg() const      { return false; }
00098   virtual bool isConstPReg() const      { return false; }
00099   virtual bool isMemoized() const       { return false; }
00100 
00101   bool uplevelR() const                 { return _uplevelR != NULL; }  
00102   bool uplevelW() const                 { return _uplevelW != NULL; }
00103   void addUplevelAccessor(BlockPReg* blk, bool read, bool write);
00104   void removeUplevelAccessor(BlockPReg* blk);
00105   void removeAllUplevelAccessors();
00106 
00107   virtual int begBCI() const            { return PrologueBCI; }
00108   virtual int endBCI() const            { return EpilogueBCI; }
00109 
00110   virtual bool canCopyPropagate() const;
00111   bool incorrectDU() const              { return _nuses < 0 || _ndefs < 0; }
00112   bool incorrectD() const               { return               _ndefs < 0; } 
00113   bool incorrectU() const               { return _nuses < 0; }
00114   void makeIncorrectDU(bool incU, bool incD);
00115 
00116  protected:
00117   // don't use nuses() et al, use isUsed() instead
00118   // they are protected to avoid bugs; it's only safe to call them if uses are correct
00119   // (otherwise, nuses() et al can return negative values)
00120   int nuses() const                     { return _nuses; }
00121   int hardUses() const                  { return _nuses - _nsoftUses; }
00122   int ndefs() const                     { return _ndefs; }
00123   friend class RegisterAllocator;
00124  public:
00125   int nsoftUses() const                 { return _nsoftUses; }
00126   bool isUsed() const                   { return _ndefs || _nuses; }
00127   bool isUnused() const                 { return !isUsed(); }
00128   bool hasNoUses() const                { return _nuses == 0; }
00129         // NB: be careful with isUnused() vs. hasNoUses() -- they're different if a PReg has
00130         // no (hard) uses but has definitions
00131   virtual bool isSinglyAssigned() const { return _ndefs == 1; }
00132   bool isSinglyUsed() const             { return _nuses == 1; }
00133   bool isOnlySoftUsed() const           { return hardUses() == 0; }
00134 
00135   void incUses(Use* use); 
00136   void decUses(Use* use); 
00137   void incDefs(Def* def); 
00138   void decDefs(Def* def); 
00139 
00140   // incremental update of def-use info
00141   Use* addUse(DUInfo* info, NonTrivialNode* n);
00142   Use* addUse(BB* bb, NonTrivialNode* n);
00143   void removeUse(DUInfo* info, Use* u);
00144   void removeUse(BB* bb, Use* u);
00145   Def* addDef(DUInfo* info, NonTrivialNode* n);
00146   Def* addDef(BB* bb, NonTrivialNode* n);
00147   void removeDef(DUInfo* info, Def* d);
00148   void removeDef(BB* bb, Def* d);
00149   virtual bool extendLiveRange(Node* n);
00150   virtual bool extendLiveRange(InlinedScope* s, int bci);
00151   void forAllDefsDo(Closure<Def*>* c);
00152   void forAllUsesDo(Closure<Use*>* c);
00153     
00154   bool isLocalTo(BB* bb) const;
00155   void makeSameRegClass(PReg* other, GrowableArray<RegisterEqClass*>* classes);
00156   virtual void allocateTo(Location r);
00157     
00158   virtual bool canBeEliminated(bool withUses = false) const;
00159   virtual void eliminate(bool withUses = false);
00160   bool isCPEquivalent(PReg* r) const;
00161   bool checkEquivalentDefs() const;
00162   bool slow_isLiveAt(Node* n) const;
00163   virtual bool isLiveAt(Node* n) const;
00164  protected:
00165   void addDUHelper(Node* n, SList<DefUse*>* l, DefUse* el);
00166   virtual NameNode* locNameNode(bool mustBeLegal) const;
00167   void eliminateUses(DUInfo* info, BB* bb);
00168   void eliminateDefs(DUInfo* info, BB* bb, bool removing);
00169   void updateCPInfo(NonTrivialNode* n);
00170 
00171  public:
00172   virtual void print();
00173   virtual void print_short()                    { lprintf("%s\n", name()); }
00174   virtual char* name() const;                   // string representing the preg name
00175   char* safeName() const;                       // same as name() but handles NULL receiver
00176   virtual char* prefix() const                  { return "P"; }
00177   virtual bool verify() const;
00178   virtual NameNode* nameNode(bool mustBeLegal = true) const; // for debugging info
00179   LogicalAddress* createLogicalAddress();
00180   LogicalAddress* logicalAddress() const        { return _logicalAddress; }
00181   PReg* cpReg() const;                          // return "cp-equivalent" PReg
00182 
00183   friend InlinedScope* findAncestor(InlinedScope* s1, int& bci1,
00184                                  InlinedScope* s2, int& bci2);
00185       // find closest common ancestor of s1 and s2, and the
00186       // respective sender bcis in that scope
00187 
00188   // Initialization (before every compile)
00189   static void initPRegs();
00190 };
00191 
00192 // A temp preg is exactly like a PReg except that it is live for only
00193 // a very short (hard-wired) code sequence such as loading a frame ptr etc.
00194 class TempPReg : public PReg {
00195  public:
00196   TempPReg(InlinedScope* s) : PReg(s) {}
00197   TempPReg(InlinedScope* s, Location l, bool incU, bool incD): PReg(s, l, incU, incD) {}
00198   bool isTempPReg() const               { return true; }
00199   bool isLiveAt(Node* n) const          { Unused(n);  return false; }
00200   bool canCopyPropagate() const         { return false; }
00201   char* prefix() const                  { return "TempP"; }
00202 };
00203   
00204 // singly-assigned PReg (in source-level terms, e.g. expr. stack entry, arg;
00205 // may have several defs because of splitting etc.
00206 // makes copy propagation simpler
00207 class SAPReg : public PReg {
00208  protected:
00209   InlinedScope* _creationScope;         // source scope to which receiver belongs
00210   int creationStartBCI;                 // startBCI in creationScope 
00211   int _begBCI, _endBCI;                 // live range = [_begBCI, _endBCI] in scope
00212                                         // (for reg. alloc. purposes)
00213   const bool _isInContext;              // is this SAPReg a context location?
00214  public:
00215   SAPReg(InlinedScope* s, int st = IllegalBCI, int en = IllegalBCI, bool inContext = false);
00216   SAPReg(InlinedScope* s, Location l, bool incU, bool incD,
00217          int st, int en) : PReg((InlinedScope*)s, l, incU, incD), _isInContext(false) {
00218     _begBCI = creationStartBCI = st; _endBCI = en; _creationScope = s;
00219   }
00220 
00221   int  begBCI() const                   { return _begBCI; }
00222   int  endBCI() const                   { return _endBCI; }
00223   bool isInContext() const              { return _isInContext; }
00224   InlinedScope* creationScope() const   { return _creationScope; }
00225 
00226   bool isSinglyAssigned() const         { return true; }
00227   bool extendLiveRange(Node* n);
00228   bool extendLiveRange(InlinedScope* s, int bci);
00229   bool isLiveAt(Node* n) const;
00230   bool isSAPReg() const                 { return true; }
00231   char* prefix() const                  { return "SAP"; }
00232   bool verify() const;
00233  protected:
00234   bool basic_isLiveAt(InlinedScope* s, int bci) const;
00235   friend class ExprStack;
00236 };
00237 
00238 
00239 class BlockPReg : public SAPReg {
00240  protected:
00241   CompileTimeClosure*   _closure;                       // the compile-time closure representation
00242   bool                  _memoized;                      // is this a memoized block?
00243   bool                  _escapes;                       // does the block escape?
00244   GrowableArray<Node*>* _escapeNodes;                   // list of all nodes where the block escapes (or NULL)
00245   GrowableArray<PReg*>* _uplevelRead;                   // list of PRegs uplevel-read by block method (or NULL)
00246   GrowableArray<PReg*>* _uplevelWritten;                // list of PRegs uplevel-written by block method (or NULL)
00247   GrowableArray<Location*>* _contextCopies;             // list of context location containing a copy of the receiver (or NULL)
00248   static int            _numBlocks;
00249 
00250  public:
00251   BlockPReg(InlinedScope* scope, CompileTimeClosure* closure, int beg, int end);
00252 
00253   bool                  isBlockPReg() const             { return true; }
00254   virtual NameNode*     locNameNode(bool mustBeLegal) const;
00255   InlinedScope*         scope() const                   { return (InlinedScope*)_scope; }
00256   InlinedScope*         parent() const;
00257   CompileTimeClosure*   closure() const                 { return _closure; }
00258   methodOop             method() const                  { return _closure->method(); }
00259   static int            numBlocks()                     { return _numBlocks; }
00260   void                  memoize();                      // memoize this block if possible/desirable
00261   void                  markEscaped(Node* n);           // mark this block as escaping at node n
00262   void                  markEscaped();                  // ditto; receiver escapes because of uplevel access from escaping block
00263   bool                  isMemoized() const              { return _memoized; }
00264   bool                  escapes() const                 { return _escapes; }
00265   bool                  canBeEliminated(bool withUses = false) const;
00266   void                  eliminate(bool withUses = false);
00267   void                  computeUplevelAccesses();
00268   GrowableArray<PReg*>* uplevelRead() const             { return _uplevelRead; }
00269   GrowableArray<PReg*>* uplevelWritten() const          { return _uplevelWritten; }
00270   GrowableArray<Location*>* contextCopies() const       { return _contextCopies; }
00271   void                  addContextCopy(Location* l);
00272   char*                 prefix() const                  { return "BlkP"; }
00273   char*                 name() const;
00274   bool                  verify() const;
00275   void                  print();
00276 
00277   friend InlinedScope*  scopeFromBlockKlass(klassOop blockKlass);
00278   friend class PReg;
00279 };
00280 
00281 
00282 class NoPReg : public PReg {    // "no result" register (should have no uses)
00283  public:
00284   NoPReg(InlinedScope* scope) : PReg(scope)     { loc = noRegister; initialize(); }
00285   virtual bool isNoPReg() const                 { return true; }
00286   bool canCopyPropagate() const                 { return false; }
00287   NameNode* nameNode(bool mustBeLegal) const;
00288   char* name() const                            { return "nil"; }
00289   bool verify() const;
00290 };
00291 
00292 
00293 class ConstPReg : public PReg {
00294   // ConstPRegs are used to CSE constants; at register allocation time,
00295   // they can either get a register (if one is available), or they're
00296   // treated as literals by code generation, i.e. loaded into a temp reg
00297   // before each use.
00298  public:
00299   oop constant;
00300   protected:
00301   ConstPReg(InlinedScope* s, oop c) : PReg(s) { 
00302     constant = c; 
00303     assert(!c->is_mem() || c->is_old(), "constant must be tenured");
00304   }
00305  public:
00306   friend ConstPReg* new_ConstPReg(InlinedScope* s, oop c);
00307   friend ConstPReg* findConstPReg(Node* n, oop c);
00308   bool isConstPReg() const                      { return true; }
00309   void allocateTo(Location r);
00310   void extendLiveRange(InlinedScope* s);
00311   bool extendLiveRange(Node* n);
00312   bool covers(Node* n) const;
00313   bool needsRegister() const;
00314   NameNode* nameNode(bool mustBeLegal = true) const;
00315   char* prefix() const                          { return "ConstP"; }
00316   char* name() const;
00317   bool verify() const;
00318 };
00319 
00320 
00321 
00322 #ifdef not_yet_used
00323 // SplitPRegs hold the receiver of a split message send; their main
00324 // purpose is to make register allocation/live range computation simple
00325 // and efficient without implementing general live range analysis
00326 class SplitPReg : public SAPReg {
00327  public:
00328   SplitSig* sig;
00329   
00330   SplitPReg(InlinedScope* s, int st, int en, SplitSig* signature) : SAPReg(s, st, en) {
00331     sig = signature;
00332   }
00333 
00334   bool  isSinglyAssigned() const                { return true; }
00335   bool  extendLiveRange(Node* n);
00336   bool  isLiveAt(Node* n) const;
00337   bool  isSplitPReg() const                     { return true; }
00338   char* prefix() const                          { return "SplitP"; }
00339   char* name() const;
00340 };
00341 #endif
00342 
00343 
00344 # endif
00345   

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