diff options
| author | Brian Gaeke <gaeke@uiuc.edu> | 2003-09-24 18:08:54 +0000 | 
|---|---|---|
| committer | Brian Gaeke <gaeke@uiuc.edu> | 2003-09-24 18:08:54 +0000 | 
| commit | 1542a8b8206709aa0389916309c370579cfdf30c (patch) | |
| tree | ed8717d17abcfced6ce5c36247de6fc149693042 /llvm/lib/CodeGen/RegAlloc | |
| parent | 82585e030c1d95fb379997685497d0702ba1fbd3 (diff) | |
| download | bcm5719-llvm-1542a8b8206709aa0389916309c370579cfdf30c.tar.gz bcm5719-llvm-1542a8b8206709aa0389916309c370579cfdf30c.zip  | |
Untabify tabs in stuff I've recently added.
Check in my register allocator state-saving code.
llvm-svn: 8698
Diffstat (limited to 'llvm/lib/CodeGen/RegAlloc')
| -rw-r--r-- | llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp | 153 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h | 6 | 
2 files changed, 156 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp b/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp index 32a86047c52..53949a7acfe 100644 --- a/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp +++ b/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp @@ -20,6 +20,10 @@  #include "llvm/Function.h"  #include "llvm/Type.h"  #include "llvm/iOther.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Constants.h" +#include "llvm/Support/InstIterator.h" +#include "llvm/Module.h"  #include "Support/STLExtras.h"  #include "Support/SetOperations.h"  #include "Support/CommandLine.h" @@ -1137,9 +1141,9 @@ void PhyRegAlloc::markUnusableSugColors()      if (HMI->first) {         LiveRange *L = HMI->second;      // get the LiveRange        if (L && L->hasSuggestedColor ()) -	L->setSuggestedColorUsable -	  (!(MRI.isRegVolatile (L->getRegClassID (), L->getSuggestedColor ()) -	     && L->isCallInterference ())); +        L->setSuggestedColorUsable +          (!(MRI.isRegVolatile (L->getRegClassID (), L->getSuggestedColor ()) +             && L->isCallInterference ()));      }    } // for all LR's in hash map  } @@ -1173,6 +1177,145 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs() {  } +namespace { +  /// AllocInfo - Structure representing one instruction's +  /// operand's-worth of register allocation state. We create tables +  /// made out of these data structures to generate mapping information +  /// for this register allocator. (FIXME: This might move to a header +  /// file at some point.) +  /// +  struct AllocInfo { +    unsigned Instruction; +    unsigned Operand; +    unsigned AllocState; +    int Placement; +    AllocInfo (unsigned Instruction_, unsigned Operand_, +               unsigned AllocState_, int Placement_) : +      Instruction (Instruction_), Operand (Operand_), +      AllocState (AllocState_), Placement (Placement_) { } +    /// getConstantType - Return a StructType representing an AllocInfo +    /// object. +    /// +    static StructType *getConstantType () { +      std::vector<const Type *> TV; +      TV.push_back (Type::UIntTy); +      TV.push_back (Type::UIntTy); +      TV.push_back (Type::UIntTy); +      TV.push_back (Type::IntTy); +      return StructType::get (TV); +    } +    /// toConstant - Convert this AllocInfo into an LLVM Constant of type +    /// getConstantType(), and return the Constant. +    /// +    Constant *toConstant () const { +      StructType *ST = getConstantType (); +      std::vector<Constant *> CV; +      CV.push_back (ConstantUInt::get (Type::UIntTy, Instruction)); +      CV.push_back (ConstantUInt::get (Type::UIntTy, Operand)); +      CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState)); +      CV.push_back (ConstantSInt::get (Type::IntTy, Placement)); +      return ConstantStruct::get (ST, CV); +    } +  }; +} + +void PhyRegAlloc::saveState () +{ +  std::vector<Constant *> state; +  unsigned Insn = 0; +  LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end ();    +  for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II != IE; ++II) +    for (unsigned i = 0; i < (*II)->getNumOperands (); ++i) { +      const Value *V = (*II)->getOperand (i); +      // Don't worry about it unless it's something whose reg. we'll need. +      if (!isa<Argument> (V) && !isa<Instruction> (V)) +        continue; +      LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap ()->find (V); +      static const unsigned NotAllocated = 0, Allocated = 1, Spilled = 2; +      unsigned AllocState = NotAllocated; +      int Placement = -1; +      if ((HMI != HMIEnd) && HMI->second) { +        LiveRange *L = HMI->second; +        assert ((L->hasColor () || L->isMarkedForSpill ()) +                && "Live range exists but not colored or spilled"); +        if (L->hasColor()) { +          AllocState = Allocated; +          Placement = MRI.getUnifiedRegNum (L->getRegClassID (), +                                            L->getColor ()); +        } else if (L->isMarkedForSpill ()) { +          AllocState = Spilled; +          assert (L->hasSpillOffset () +                  && "Live range marked for spill but has no spill offset"); +          Placement = L->getSpillOffFromFP (); +        } +      } +      state.push_back (AllocInfo (Insn, i, AllocState, +                                  Placement).toConstant ()); +    } +  // Convert state into an LLVM ConstantArray, and put it in a +  // ConstantStruct (named S) along with its size. +  unsigned Size = state.size (); +  ArrayType *AT = ArrayType::get (AllocInfo::getConstantType (), Size); +  std::vector<const Type *> TV; +  TV.push_back (Type::UIntTy); +  TV.push_back (AT); +  StructType *ST = StructType::get (TV); +  std::vector<Constant *> CV; +  CV.push_back (ConstantUInt::get (Type::UIntTy, Size)); +  CV.push_back (ConstantArray::get (AT, state)); +  Constant *S = ConstantStruct::get (ST, CV); +  // Save S in the map containing register allocator state for this module. +  FnAllocState[Fn] = S; +} + + +bool PhyRegAlloc::doFinalization (Module &M) {  +  if (!SaveRegAllocState) +    return false; // Nothing to do here, unless we're saving state. + +  // Convert FnAllocState to a single Constant array and add it +  // to the Module. +  ArrayType *AT = ArrayType::get (AllocInfo::getConstantType (), 0); +  std::vector<const Type *> TV; +  TV.push_back (Type::UIntTy); +  TV.push_back (AT); +  PointerType *PT = PointerType::get (StructType::get (TV)); + +  std::vector<Constant *> allstate; +  for (Module::iterator I = M.begin (), E = M.end (); I != E; ++I) { +    Function *F = I; +    if (FnAllocState.find (F) == FnAllocState.end ()) { +      allstate.push_back (ConstantPointerNull::get (PT)); +    } else { +      GlobalVariable *GV = +        new GlobalVariable (FnAllocState[F]->getType (), true, +                            GlobalValue::InternalLinkage, FnAllocState[F], +                            F->getName () + ".regAllocState", &M); +      // Have: { uint, [Size x { uint, uint, uint, int }] } * +      // Cast it to: { uint, [0 x { uint, uint, uint, int }] } * +      Constant *CE = ConstantExpr::getCast (ConstantPointerRef::get (GV), PT); +      allstate.push_back (CE); +    } +  } + +  unsigned Size = allstate.size (); +  // Final structure type is: +  // { uint, [Size x { uint, [0 x { uint, uint, uint, int }] } *] } +  std::vector<const Type *> TV2; +  TV2.push_back (Type::UIntTy); +  ArrayType *AT2 = ArrayType::get (PT, Size); +  TV2.push_back (AT2); +  StructType *ST2 = StructType::get (TV2); +  std::vector<Constant *> CV2; +  CV2.push_back (ConstantUInt::get (Type::UIntTy, Size)); +  CV2.push_back (ConstantArray::get (AT2, allstate)); +  new GlobalVariable (ST2, true, GlobalValue::InternalLinkage, +                      ConstantStruct::get (ST2, CV2), "_llvm_regAllocState", +                      &M); +  return false; // No error. +} + +  //----------------------------------------------------------------------------  // The entry point to Register Allocation  //---------------------------------------------------------------------------- @@ -1244,6 +1387,10 @@ bool PhyRegAlloc::runOnFunction (Function &F) {    // insert code to copy to the correct register    colorIncomingArgs(); +  // Save register allocation state for this function in a Constant. +  if (SaveRegAllocState) +    saveState(); +    // Now update the machine code with register names and add any     // additional code inserted by the register allocator to the instruction    // stream diff --git a/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h b/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h index 438f2c56a91..6dcfa1feff5 100644 --- a/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h +++ b/llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h @@ -29,6 +29,7 @@ class FunctionLiveVarInfo;  class MachineInstr;  class LoopInfo;  class RegClass; +class Constant;  //----------------------------------------------------------------------------  // Class AddedInstrns: @@ -77,6 +78,8 @@ class PhyRegAlloc : public FunctionPass {    AddedInstrns AddedInstrAtEntry;       // to store instrns added at entry    const LoopInfo *LoopDepthCalc;        // to calculate loop depths  +  std::map<const Function *, Constant *> FnAllocState; +    PhyRegAlloc(const PhyRegAlloc&);     // DO NOT IMPLEMENT    void operator=(const PhyRegAlloc&);  // DO NOT IMPLEMENT  public: @@ -89,6 +92,8 @@ public:    ///    virtual bool runOnFunction (Function &F); +  virtual bool doFinalization (Module &M); +    virtual void getAnalysisUsage (AnalysisUsage &AU) const;    const char *getPassName () const { @@ -108,6 +113,7 @@ private:    void addInterferencesForArgs();    void createIGNodeListsAndIGs();    void buildInterferenceGraphs(); +  void saveState();    void setCallInterferences(const MachineInstr *MI,   			    const ValueSet *LVSetAft);  | 

