[llvm-commits] CVS: reopt/lib/Mapping/ValueAllocState.cpp

Brian Gaeke gaeke at cs.uiuc.edu
Tue Jul 13 23:12:05 PDT 2004



Changes in directory reopt/lib/Mapping:

ValueAllocState.cpp added (r1.1)

---
Log message:

ValueAllocState is just another piece of mapping info, although it does depend
on the existence of a TraceFunction.  So move it to the Mapping library.


---
Diffs of the changes:  (+203 -0)

Index: reopt/lib/Mapping/ValueAllocState.cpp
diff -c /dev/null reopt/lib/Mapping/ValueAllocState.cpp:1.1
*** /dev/null	Wed Jul 14 01:12:05 2004
--- reopt/lib/Mapping/ValueAllocState.cpp	Wed Jul 14 01:11:55 2004
***************
*** 0 ****
--- 1,203 ----
+ //===- ValueAllocState.cpp - Access saved state of PhyRegAlloc ----*- C++ -*-=//
+ // 
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ //
+ // Routines for accessing the global mapping between registers and LLVM Values
+ // created by the traditional SparcV9 graph-coloring register allocator. The
+ // main entry point for this code is the GetValueAllocState() global function.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "reopt/TraceToFunction.h"
+ #include "reopt/MappingInfo.h"
+ #include "llvm/Module.h"
+ #include "llvm/Argument.h"
+ #include "llvm/iPHINode.h"
+ #include "llvm/Support/InstIterator.h"
+ #include "Support/Debug.h"
+ #include "../../../../lib/Target/SparcV9/RegAlloc/AllocInfo.h"
+ #include "../../../../lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h"
+ #include <iostream>
+ 
+ namespace llvm {
+ 
+ /// Data structures describing the register allocator state
+ /// that gets saved by -save-ra-state.
+ ///
+ extern "C" { 
+   struct OperandAllocState {
+     int Instruction;
+     int Operand;
+     unsigned AllocState;
+     int Placement;
+   };
+   struct FunctionAllocState {
+     unsigned numTuples;
+     struct OperandAllocState tuples[0]; // variable length
+   };
+   struct ModuleAllocState {
+     unsigned numFunctions;
+     struct FunctionAllocState *functions[0]; // variable length
+   };
+   /// This global is filled in by PhyRegAlloc's -save-ra-state option
+   /// in LLC output:
+   ///
+   extern struct ModuleAllocState _llvm_regAllocState;
+ };
+ 
+ /// This global is filled in by PhyRegAlloc's -save-ra-state option in JIT
+ /// output:
+ ///
+ extern PhyRegAlloc::SavedStateMapTy ExportedFnAllocState;
+ 
+ /// Returns the index of the given Instruction in the given Function.
+ ///
+ static int getSavedStateIndexOfInstruction (const Function *F,
+                                                  const Instruction *I) {
+   unsigned Key = 0;
+   for (const_inst_iterator II=inst_begin (F), IE=inst_end (F); II!=IE; ++II) {
+     if (&*II == I)
+       return Key;
+     ++Key;
+   }
+   DEBUG (std::cerr << "getSavedStateIndexOfInstruction: Warning: Cannot find "
+     << "index of value " << I->getName() << " in its parent function "
+     << F->getName () << "()\n");
+   return -1;
+ }
+ 
+ /// Returns the index of the given Argument in the given Function's
+ /// argument list.
+ ///
+ static int getNumberOfFunctionArg (const Function *F, const Argument *Arg)
+ {
+   int ArgNum = 0;
+   for (Function::const_aiterator i = F->abegin (), e = F->aend (); i != e; ++i){
+     if (Arg == &*i) return ArgNum;
+     ++ArgNum;
+   }
+   std::cerr << "ERROR: getNumberOfFunctionArg couldn't find arg\n";
+   abort ();
+ }
+ 
+ static std::set<BasicBlock *> TraceBoundaryBlocks;
+ static TraceFunction *lastTraceFunction;
+ 
+ static void findTraceBoundaryBlocks (TraceFunction *TF) {
+   TraceBoundaryBlocks.clear ();
+   TraceBoundaryBlocks.insert (TF->T.getEntryBasicBlock ());
+   for (ReturnBlockMap::iterator i = TF->ReturnBlockForTraceExit.begin (),
+        e = TF->ReturnBlockForTraceExit.end (); i != e; ++i) {
+     TraceBoundaryBlocks.insert (i->second);
+   }
+ }
+ 
+ /// getValueAllocStateKeys - Fill in InstructionKey and OperandKey with the
+ /// indices used to look up saved register allocation state for V in F.
+ ///
+ static void getValueAllocStateKeys (Function *F, Value *V, int &InstructionKey,
+                                     int &OperandKey, bool preferLiveIn) {
+   InstructionKey = -1; OperandKey = -1;
+   if (Argument *Arg = dyn_cast<Argument> (V)) {
+     OperandKey = getNumberOfFunctionArg (F, Arg);
+   } else if (Instruction *Inst = dyn_cast<Instruction> (V)) {
+     InstructionKey = getSavedStateIndexOfInstruction (F, Inst);
+     if (isa<PHINode> (Inst) && preferLiveIn
+         && TraceBoundaryBlocks.find (Inst->getParent ())
+            != TraceBoundaryBlocks.end ())
+       OperandKey = -2; // look for PhiCpRes instead.
+   } else {
+     DEBUG (std::cerr << "getValueAllocStateKeys: keys not known for "
+            << F->getName () << ":" << *V << "\n");
+   }
+ }
+ 
+ /// Returns the register number or stack position where V can be found in the
+ /// machine code for the function F, which it finds by searching the global
+ /// variable _llvm_regAllocState written out by PhyRegAlloc.cpp during a
+ /// previous invocation of llc.
+ ///
+ static AllocInfo getValueAllocStateFromModule (Function *F, Value *V,
+                                                bool preferLiveIn) {
+   int InstructionKey = -1, OperandKey = -1;
+   getValueAllocStateKeys (F, V, InstructionKey, OperandKey, preferLiveIn);
+   if (InstructionKey == -1 && OperandKey == -1)
+     return AllocInfo();
+ 
+   unsigned FI = getLLVMFunctionPositionInfo (F);
+   FunctionAllocState *FAllocState = _llvm_regAllocState.functions[FI];
+   assert (FAllocState->numTuples > 0
+           && "Reg. alloc state for function is empty");
+   // Reconstruct the AllocInfo for V by searching
+   // _llvm_regAllocState.functions[FI] for a tuple that starts with
+   // (InstructionKey, OperandKey, ...):
+   for (unsigned i = 0; i < FAllocState->numTuples; ++i) {
+     OperandAllocState &T = FAllocState->tuples[i];
+     if (T.Instruction == InstructionKey && T.Operand == OperandKey) {
+       AllocInfo AI (T.Instruction, T.Operand,
+                     (AllocInfo::AllocStateTy) T.AllocState, T.Placement);
+       DEBUG (std::cerr << "Alloc state saved in module for " << F->getName ()
+              << ":" << V->getName () << " (key = " << InstructionKey << ","
+              << OperandKey << ") is " << AI << "\n");
+       return AI;
+     }
+   }
+   DEBUG (std::cerr << "Alloc state saved in module for " << F->getName ()
+          << ":" << V->getName () << " (key = " << InstructionKey << ","
+          << OperandKey << ") NOT FOUND\n");
+   return AllocInfo();
+ }
+ 
+ /// Returns the register number or stack position where V can be found in the
+ /// machine code for the function F, which it finds by searching the global
+ /// variable ExportedFnAllocState exported by PhyRegAlloc.cpp.
+ ///
+ static AllocInfo getValueAllocStateFromGlobal (Function *F, Value *V,
+                                                bool preferLiveIn) {
+   int InstructionKey = -1, OperandKey = -1;
+   getValueAllocStateKeys (F, V, InstructionKey, OperandKey, preferLiveIn);
+   if (InstructionKey == -1 && OperandKey == -1)
+     return AllocInfo();
+ 
+   // Get the saved PhyRegAlloc state for F out of ExportedFnAllocState:
+   std::vector<AllocInfo> &FState = ExportedFnAllocState[F];
+   assert (FState.size () > 0 && "Reg. alloc state for function is empty");
+   // Reconstruct the AllocInfo for V by searching
+   // FState for a tuple that starts with (InstructionKey, OperandKey, ...):
+   for (unsigned i = 0, s = FState.size (); i < s; ++i) {
+     AllocInfo &T = FState[i];
+     if (T.Instruction == InstructionKey && T.Operand == OperandKey) {
+       DEBUG (std::cerr << "Alloc state saved in global for " << F->getName ()
+              << ":" << V->getName () << " (key = " << InstructionKey << ","
+              << OperandKey << ") is " << T << "\n");
+       return T;
+     }
+   }
+   DEBUG (std::cerr << "Alloc state saved in global for " << F->getName ()
+          << ":" << V->getName () << " (key = " << InstructionKey << ","
+          << OperandKey << ") NOT FOUND\n");
+   return AllocInfo();
+ }
+ 
+ /// GetValueAllocState - Returns a pair <MatrixState,TraceState> containing the
+ /// saved register allocator state for a value.
+ ///
+ std::pair<AllocInfo, AllocInfo>
+ GetValueAllocState (TraceFunction *TF, Value *V, bool preferLiveIn) {
+   if (lastTraceFunction != TF) {
+     findTraceBoundaryBlocks (TF);
+     lastTraceFunction = TF;
+   }
+   return std::make_pair
+    (getValueAllocStateFromModule (TF->MatrixFn, V, preferLiveIn),
+     getValueAllocStateFromGlobal (TF->TraceFn,
+                                   TF->getCorrespondingValue (V, preferLiveIn),
+                                   preferLiveIn));
+ }
+ 
+ } // end namespace llvm





More information about the llvm-commits mailing list