///
struct AllocInfo {
unsigned Instruction;
- unsigned Operand;
+ int Operand; // (-1 if Instruction, or 0...n-1 for an operand.)
enum AllocStateTy { NotAllocated = 0, Allocated, Spilled };
AllocStateTy AllocState;
int Placement;
static StructType *getConstantType () {
std::vector<const Type *> TV;
TV.push_back (Type::UIntTy);
- TV.push_back (Type::UIntTy);
+ TV.push_back (Type::IntTy);
TV.push_back (Type::UIntTy);
TV.push_back (Type::IntTy);
return StructType::get (TV);
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 (ConstantSInt::get (Type::IntTy, Operand));
CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState));
CV.push_back (ConstantSInt::get (Type::IntTy, Placement));
return ConstantStruct::get (ST, CV);
}
+void PhyRegAlloc::saveStateForValue (std::vector<AllocInfo> &state,
+ const Value *V, unsigned Insn, int Opnd) {
+ LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap ()->find (V);
+ LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end ();
+ AllocInfo::AllocStateTy AllocState = AllocInfo::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 = AllocInfo::Allocated;
+ Placement = MRI.getUnifiedRegNum (L->getRegClassID (),
+ L->getColor ());
+ } else if (L->isMarkedForSpill ()) {
+ AllocState = AllocInfo::Spilled;
+ assert (L->hasSpillOffset ()
+ && "Live range marked for spill but has no spill offset");
+ Placement = L->getSpillOffFromFP ();
+ }
+ }
+ state.push_back (AllocInfo (Insn, Opnd, AllocState, Placement));
+}
+
+
/// Save the global register allocation decisions made by the register
/// allocator so that they can be accessed later (sort of like "poor man's
/// debug info").
void PhyRegAlloc::saveState () {
std::vector<AllocInfo> &state = FnAllocState[Fn];
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){
+ saveStateForValue (state, (*II), Insn, -1);
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);
- AllocInfo::AllocStateTy AllocState = AllocInfo::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 = AllocInfo::Allocated;
- Placement = MRI.getUnifiedRegNum (L->getRegClassID (),
- L->getColor ());
- } else if (L->isMarkedForSpill ()) {
- AllocState = AllocInfo::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));
+ // Don't worry about it unless it's something whose reg. we'll need.
+ if (!isa<Argument> (V) && !isa<Instruction> (V))
+ continue;
+ saveStateForValue (state, V, Insn, i);
}
++Insn;
}
/// Finish the job of saveState(), by collapsing FnAllocState into an LLVM
/// Constant and stuffing it inside the Module. (NOTE: Soon, there will be
/// other, better ways of storing the saved state; this one is cumbersome and
-/// will never work with the JIT.)
+/// does not work well with the JIT.)
///
bool PhyRegAlloc::doFinalization (Module &M) {
if (!SaveRegAllocState)
GlobalValue::InternalLinkage, S,
F->getName () + ".regAllocState", &M);
- // Have: { uint, [Size x { uint, uint, uint, int }] } *
- // Cast it to: { uint, [0 x { uint, uint, uint, int }] } *
+ // Have: { uint, [Size x { uint, int, uint, int }] } *
+ // Cast it to: { uint, [0 x { uint, int, 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 }] } *] }
+ // { uint, [Size x { uint, [0 x { uint, int, uint, int }] } *] }
std::vector<const Type *> TV2;
TV2.push_back (Type::UIntTy);
ArrayType *AT2 = ArrayType::get (PT, Size);
void addInterferencesForArgs();
void createIGNodeListsAndIGs();
void buildInterferenceGraphs();
+
+ void saveStateForValue (std::vector<AllocInfo> &state,
+ const Value *V, unsigned Insn, int Opnd);
void saveState();
void verifySavedState();
///
struct AllocInfo {
unsigned Instruction;
- unsigned Operand;
+ int Operand; // (-1 if Instruction, or 0...n-1 for an operand.)
enum AllocStateTy { NotAllocated = 0, Allocated, Spilled };
AllocStateTy AllocState;
int Placement;
static StructType *getConstantType () {
std::vector<const Type *> TV;
TV.push_back (Type::UIntTy);
- TV.push_back (Type::UIntTy);
+ TV.push_back (Type::IntTy);
TV.push_back (Type::UIntTy);
TV.push_back (Type::IntTy);
return StructType::get (TV);
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 (ConstantSInt::get (Type::IntTy, Operand));
CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState));
CV.push_back (ConstantSInt::get (Type::IntTy, Placement));
return ConstantStruct::get (ST, CV);
}
+void PhyRegAlloc::saveStateForValue (std::vector<AllocInfo> &state,
+ const Value *V, unsigned Insn, int Opnd) {
+ LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap ()->find (V);
+ LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end ();
+ AllocInfo::AllocStateTy AllocState = AllocInfo::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 = AllocInfo::Allocated;
+ Placement = MRI.getUnifiedRegNum (L->getRegClassID (),
+ L->getColor ());
+ } else if (L->isMarkedForSpill ()) {
+ AllocState = AllocInfo::Spilled;
+ assert (L->hasSpillOffset ()
+ && "Live range marked for spill but has no spill offset");
+ Placement = L->getSpillOffFromFP ();
+ }
+ }
+ state.push_back (AllocInfo (Insn, Opnd, AllocState, Placement));
+}
+
+
/// Save the global register allocation decisions made by the register
/// allocator so that they can be accessed later (sort of like "poor man's
/// debug info").
void PhyRegAlloc::saveState () {
std::vector<AllocInfo> &state = FnAllocState[Fn];
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){
+ saveStateForValue (state, (*II), Insn, -1);
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);
- AllocInfo::AllocStateTy AllocState = AllocInfo::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 = AllocInfo::Allocated;
- Placement = MRI.getUnifiedRegNum (L->getRegClassID (),
- L->getColor ());
- } else if (L->isMarkedForSpill ()) {
- AllocState = AllocInfo::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));
+ // Don't worry about it unless it's something whose reg. we'll need.
+ if (!isa<Argument> (V) && !isa<Instruction> (V))
+ continue;
+ saveStateForValue (state, V, Insn, i);
}
++Insn;
}
/// Finish the job of saveState(), by collapsing FnAllocState into an LLVM
/// Constant and stuffing it inside the Module. (NOTE: Soon, there will be
/// other, better ways of storing the saved state; this one is cumbersome and
-/// will never work with the JIT.)
+/// does not work well with the JIT.)
///
bool PhyRegAlloc::doFinalization (Module &M) {
if (!SaveRegAllocState)
GlobalValue::InternalLinkage, S,
F->getName () + ".regAllocState", &M);
- // Have: { uint, [Size x { uint, uint, uint, int }] } *
- // Cast it to: { uint, [0 x { uint, uint, uint, int }] } *
+ // Have: { uint, [Size x { uint, int, uint, int }] } *
+ // Cast it to: { uint, [0 x { uint, int, 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 }] } *] }
+ // { uint, [Size x { uint, [0 x { uint, int, uint, int }] } *] }
std::vector<const Type *> TV2;
TV2.push_back (Type::UIntTy);
ArrayType *AT2 = ArrayType::get (PT, Size);
void addInterferencesForArgs();
void createIGNodeListsAndIGs();
void buildInterferenceGraphs();
+
+ void saveStateForValue (std::vector<AllocInfo> &state,
+ const Value *V, unsigned Insn, int Opnd);
void saveState();
void verifySavedState();