C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

briggs_reg_alloc.h

Go to the documentation of this file.
00001 // $Id: briggs_reg_alloc.h,v 1.11 2003/08/11 17:38:51 abrown Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2002 University of Texas at Austin
00008 // 
00009 //  Paul Arthur Navratil
00010 //  Charles Nevill
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
00035 //
00036 // ----------------------------------------------------------------------
00037 
00038 #ifndef _BRIGGS_REG_ALLOC_H
00039 #define _BRIGGS_REG_ALLOC_H
00040 
00041 #include <list>
00042 #include <map>
00043 #include <set>
00044 #include <vector>
00045 
00046 #include <limits.h>
00047 #include <string.h>
00048 #include <stdlib.h>
00049 
00050 #include "reg_alloc.h"
00051 
00052 // def-use chain is a list of pointers to each LIR node for the id
00053 // LIR translator should assign temp registers for each instruction
00054 // assuming infinite registers. 
00055 // Unifying registers will occur when webs are formed.
00056 
00057 // symbol to identify web.      
00058 // can be var id, register, or const val
00059 struct Symbol
00060 {
00061 
00062   // ctors
00063   Symbol ()
00064   {
00065     _type = sym_unknown;
00066     _id = NULL;
00067   }
00068   Symbol (declNode * id)
00069   {
00070     _type = sym_id;
00071     _id = id;
00072   }
00073   Symbol (const Register & reg)
00074   {
00075     _type = sym_reg;
00076     _id = NULL;
00077     _reg = reg;
00078   }
00079   Symbol (const constant & con)
00080   {
00081     _type = sym_const;
00082     _id = NULL;
00083     _const = con;
00084   }
00085 
00086   // can be decl, register, or constant
00087   declNode *_id;
00088   Register _reg;
00089   constant _const;
00090 
00091   // what is it?
00092   enum
00093   {
00094     sym_unknown,
00095     sym_id,
00096     sym_reg,
00097     sym_const
00098   }
00099   _type;
00100 
00101   // compare two of these
00102   bool operator == (const Symbol & rhs) const;
00103 
00104   // get our type
00105   typeNode * getLirVt () const;
00106 };
00107 
00108 // the type we're going to use for our defuse chain
00109 typedef LirInst *DUChainDef;
00110 typedef list < DUChainDef > DUChainDefs;
00111 typedef
00112   DUChainDefs::iterator
00113   DUChainDefs_p;
00114 
00115 // list of LIR instruction pointers that form a def-use chain
00116 typedef LirInst *
00117   DuChainUse;
00118 typedef
00119   list <
00120   DuChainUse >
00121   DUChainUses;
00122 typedef
00123   DUChainUses::iterator
00124   DUChainUses_p;
00125 
00126 class
00127   sdu
00128 {
00129   Symbol
00130     sym;
00131   DUChainDef
00132     def;
00133   DUChainUses
00134     uses;
00135 
00136 public:
00137   sdu (Symbol sym, DUChainDef def):
00138   sym (sym),
00139   def (def)
00140   {
00141   }
00142 
00143   Symbol &
00144   getSymbol ()
00145   {
00146     return sym;
00147   }
00148   DUChainDef & getDef ()
00149   {
00150     return def;
00151   }
00152   DUChainUses & getUses ()
00153   {
00154     return uses;
00155   }
00156 };
00157 
00158 typedef
00159   list <
00160 sdu * >
00161   sduList;
00162 typedef
00163   sduList::iterator
00164   sduList_p;
00165 
00166 class
00167   WebRecord
00168 {
00169   Symbol
00170     sym;
00171   DUChainDefs
00172     defs;
00173   DUChainUses
00174     uses;
00175   bool
00176     spill;
00177   Register
00178     reg;
00179   int
00180     disp;
00181 
00182 public:
00183   WebRecord (Symbol sym, Register reg, bool spill = false, int disp = -1):
00184   sym (sym),
00185   spill (spill),
00186   reg (reg),
00187   disp (disp)
00188   {
00189   }
00190 
00191   bool
00192   intersectUses (DUChainUses & u);
00193   void
00194   unionDefs (DUChainDefs & d);
00195   void
00196   unionUses (DUChainUses & u);
00197 
00198   Symbol & getSym ()
00199   {
00200     return sym;
00201   }
00202   DUChainDefs & getDefs ()
00203   {
00204     return defs;
00205   }
00206   DUChainUses & getUses ()
00207   {
00208     return uses;
00209   }
00210   Register & getReg ()
00211   {
00212     return reg;
00213   }
00214   bool & getSpill ()
00215   {
00216     return spill;
00217   }
00218 };
00219 
00220 typedef
00221   set <
00222 WebRecord * >
00223   WRSet;
00224 typedef
00225   WRSet::iterator
00226   WRSet_p;
00227 
00228 typedef
00229   vector <
00230 WebRecord * >
00231   WRVector;
00232 typedef
00233   WRVector::iterator
00234   WRVector_p;
00235 
00236 typedef
00237 set < int >
00238   int_set;
00239 typedef
00240   int_set::iterator
00241   int_set_p;
00242 
00243 class
00244   ListRecord
00245 {
00246   int
00247     webNum;
00248   int
00249     num_ints,
00250     color,
00251     disp;
00252   float
00253     spillCost;
00254   int_set
00255     adjNodes,
00256     removeAdj;
00257 
00258 public:
00259   static const int
00260     color_none;
00261 
00262   ListRecord (int web, float spc):
00263   webNum (web),
00264   num_ints (0),
00265   color (color_none),
00266   disp (INT_MIN),
00267   spillCost (spc),
00268   adjNodes (),
00269   removeAdj ()
00270   {
00271   }
00272 
00273   void
00274   addAdjacentNode (int reg);
00275   void
00276   removeAdjacentNode (int reg);
00277   void
00278   removeAllAdjacencies ();
00279   void
00280   incCost (float f)
00281   {
00282     spillCost += f;
00283   }
00284   void
00285   decCost (float f)
00286   {
00287     spillCost -= f;
00288   }
00289 
00290   int
00291   getWeb ()
00292   {
00293     return webNum;
00294   }
00295   int
00296   numInts ()
00297   {
00298     return num_ints;
00299   }
00300   float
00301   getSpillCost ()
00302   {
00303     return spillCost;
00304   }
00305   const
00306     int_set &
00307   getAdjNodes ()
00308   {
00309     return adjNodes;
00310   }
00311   const
00312     int_set &
00313   getRmAdjNodes ()
00314   {
00315     return removeAdj;
00316   }
00317   int &
00318   getColor ()
00319   {
00320     return color;
00321   }
00322 };
00323 
00324 typedef
00325   vector <
00326 ListRecord * >
00327   LRVector;
00328 typedef
00329   LRVector::iterator
00330   LRVector_p;
00331 
00332 typedef
00333 hash_set_ex < int >
00334   color_set;
00335 
00336 class
00337   briggs_reg_alloc:
00338   public
00339   reg_alloc
00340 {
00341   // number of registers available to the algorithm
00342   int
00343     num_regs,
00344     usable_regs;
00345   int
00346     regs_reserved;
00347   int
00348     num_webs;
00349   WRVector
00350     Symreg;
00351 
00352   // stack of nodes built in pruneGraph
00353   list < int >
00354     nodeStack;
00355 
00356   // color of each real register - indexed by color, maps to register
00357   vector < int >
00358     colorToRealReg;
00359 
00360   // liveness information
00361   inst_to_reg_id_map
00362     liveRegs;
00363 
00364   // adjacency information
00365   vector <
00366     vector <
00367   bool > >
00368     adjMatrix;
00369   LRVector
00370     adjLists;
00371 
00372   // current procedure of interest
00373   procNode *
00374     proc;
00375 
00376   // spill cost weights
00377   static const float
00378     useWt;
00379   static const float
00380     copyWt;
00381   static const float
00382     defWt;
00383 
00384 protected:
00385   // helpers
00386   template <
00387     class
00388     T >
00389     set <
00390   T > *
00391   copySet (set < T > *s);
00392   bool
00393   interfere (WebRecord * wr, int reg);
00394   bool
00395   liveAt (WebRecord * wr, DUChainDef def);
00396   bool
00397   nonStore (int reg_k, int reg_l, instruction_list_p instr);
00398   void
00399   deleteInstr (instruction_list_p instr);
00400   int
00401   depth (instruction_list_p instr);
00402   void
00403   makeDuChains (sduList & DuChains);
00404   bool
00405   isSymReg (const Register & reg);
00406   void
00407   loadSymReg (Register & reg, declNode * contents,
00408               instruction_list_p currentInstruction,
00409               instruction_list & insts);
00410   void
00411   removeUnavailableColors (ListRecord * node, color_set & colors);
00412   void
00413   changeWebRegister (WebRecord * web, const Register & newReg);
00414 
00415   // Briggs Algorithm functions
00416   // Taken from Muchnick 1997, Chapter 16 
00417   void
00418   makeWebs (sduList & DuChains);
00419   void
00420   buildAdjMatrix ();
00421   bool
00422   coalesceRegisters ();
00423   void
00424   buildAdjLists ();
00425   void
00426   computeSpillCosts ();
00427   void
00428   pruneGraph ();
00429   void
00430   adjustNeighbors (int reg);
00431   bool
00432   assignRegisters ();
00433   void
00434   modifyCode ();
00435   void
00436   genSpillCode ();
00437 
00438 public:
00439   // allocate registers for a procedure
00440   void
00441   allocate (procNode * proc);
00442 
00443 };
00444 
00445 class
00446   RegAllocWalker:
00447   public
00448   Walker
00449 {
00450 public:
00451   // ctor
00452   RegAllocWalker ();
00453 
00454   // handle various things
00455 // acb - 6 May 2003
00456 // is this necessary?
00457 //   void at_unit(unitNode *the_unit, Order ord);
00458   void at_proc (procNode * the_proc, Order ord);
00459 
00460 };
00461 
00462 #endif

Generated on August 27, 2003
Back to the C-Breeze home page