Use an enumeration to eliminate data relocations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29249 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Laskey 2006-07-21 20:57:35 +00:00
parent 6412f72b09
commit 60f09928a0
6 changed files with 55 additions and 27 deletions

View File

@ -49,6 +49,7 @@ public:
typedef const MVT::ValueType* vt_iterator;
typedef const TargetRegisterClass* const * sc_iterator;
private:
unsigned ID;
bool isSubClass;
const vt_iterator VTs;
const sc_iterator SubClasses;
@ -56,14 +57,18 @@ private:
const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
const iterator RegsBegin, RegsEnd;
public:
TargetRegisterClass(const MVT::ValueType *vts,
TargetRegisterClass(unsigned id,
const MVT::ValueType *vts,
const TargetRegisterClass * const *subcs,
const TargetRegisterClass * const *supcs,
unsigned RS, unsigned Al, iterator RB, iterator RE)
: VTs(vts), SubClasses(subcs), SuperClasses(supcs),
: ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs),
RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
virtual ~TargetRegisterClass() {} // Allow subclasses
// getID() - Return the register class ID number.
unsigned getID() const { return ID; }
// begin/end - Return all of the registers in this class.
iterator begin() const { return RegsBegin; }
iterator end() const { return RegsEnd; }
@ -301,6 +306,13 @@ public:
return regclass_end()-regclass_begin();
}
/// getRegClass - Returns the register class associated with the enumeration
/// value. See class TargetOperandInfo.
const TargetRegisterClass *getRegClass(unsigned i) const {
assert(i <= getNumRegClasses() && "Register Class ID out of range");
return i ? RegClassBegin[i - 1] : NULL;
}
//===--------------------------------------------------------------------===//
// Interfaces used by the register allocator and stack frame
// manipulation passes to move data around between registers,

View File

@ -90,10 +90,10 @@ const unsigned M_LOOK_UP_PTR_REG_CLASS = 1 << 0;
///
class TargetOperandInfo {
public:
/// RegClass - This specifies the register class of the operand if the
/// operand is a register. If not, this contains null.
const TargetRegisterClass *RegClass;
unsigned Flags;
/// RegClass - This specifies the register class enumeration of the operand
/// if the operand is a register. If not, this contains 0.
unsigned short RegClass;
unsigned short Flags;
/// Currently no other information.
};
@ -146,17 +146,6 @@ public:
return get(Opcode).Name;
}
const TargetRegisterClass
*getInstrOperandRegClass(const TargetInstrDescriptor *II, unsigned Op) const {
if (Op >= II->numOperands) {
assert((II->Flags & M_VARIABLE_OPS)&& "Invalid operand # of instruction");
return NULL;
}
const TargetOperandInfo &toi = II->OpInfo[Op];
return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS)
? getPointerRegClass() : toi.RegClass;
}
int getNumOperands(MachineOpCode Opcode) const {
return get(Opcode).numOperands;
}

View File

@ -226,7 +226,22 @@ static unsigned CountOperands(SDNode *Node) {
return N;
}
static unsigned CreateVirtualRegisters(MachineInstr *MI,
static const TargetRegisterClass *getInstrOperandRegClass(
const MRegisterInfo *MRI,
const TargetInstrInfo *TII,
const TargetInstrDescriptor *II,
unsigned Op) {
if (Op >= II->numOperands) {
assert((II->Flags & M_VARIABLE_OPS)&& "Invalid operand # of instruction");
return NULL;
}
const TargetOperandInfo &toi = II->OpInfo[Op];
return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS)
? TII->getPointerRegClass() : MRI->getRegClass(toi.RegClass);
}
static unsigned CreateVirtualRegisters(const MRegisterInfo *MRI,
MachineInstr *MI,
unsigned NumResults,
SSARegMap *RegMap,
const TargetInstrInfo *TII,
@ -234,10 +249,10 @@ static unsigned CreateVirtualRegisters(MachineInstr *MI,
// Create the result registers for this node and add the result regs to
// the machine instruction.
unsigned ResultReg =
RegMap->createVirtualRegister(TII->getInstrOperandRegClass(&II, 0));
RegMap->createVirtualRegister(getInstrOperandRegClass(MRI, TII, &II, 0));
MI->addRegOperand(ResultReg, MachineOperand::Def);
for (unsigned i = 1; i != NumResults; ++i) {
const TargetRegisterClass *RC = TII->getInstrOperandRegClass(&II, i);
const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, &II, i);
assert(RC && "Isn't a register operand!");
MI->addRegOperand(RegMap->createVirtualRegister(RC), MachineOperand::Def);
}
@ -276,7 +291,8 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
// Verify that it is right.
assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
if (II) {
const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum);
const TargetRegisterClass *RC =
getInstrOperandRegClass(MRI, TII, II, IIOpNum);
assert(RC && "Don't have operand info for this instruction!");
assert(RegMap->getRegClass(VReg) == RC &&
"Register class of operand and regclass of use don't agree!");
@ -333,7 +349,8 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
// Verify that it is right.
assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
if (II) {
const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum);
const TargetRegisterClass *RC =
getInstrOperandRegClass(MRI, TII, II, IIOpNum);
assert(RC && "Don't have operand info for this instruction!");
assert(RegMap->getRegClass(VReg) == RC &&
"Register class of operand and regclass of use don't agree!");
@ -389,7 +406,7 @@ void ScheduleDAG::EmitNode(SDNode *Node,
// Otherwise, create new virtual registers.
if (NumResults && VRBase == 0)
VRBase = CreateVirtualRegisters(MI, NumResults, RegMap, TII, II);
VRBase = CreateVirtualRegisters(MRI, MI, NumResults, RegMap, TII, II);
// Emit all of the actual operands of this instruction, adding them to the
// instruction as appropriate.

View File

@ -152,7 +152,7 @@ static const TargetRegisterClass *getRegClass(SUnit *SU,
if (SU->Node->isTargetOpcode()) {
unsigned Opc = SU->Node->getTargetOpcode();
const TargetInstrDescriptor &II = TII->get(Opc);
return II.OpInfo->RegClass;
return MRI->getRegClass(II.OpInfo->RegClass);
} else {
assert(SU->Node->getOpcode() == ISD::CopyFromReg);
unsigned SrcReg = cast<RegisterSDNode>(SU->Node->getOperand(1))->getReg();

View File

@ -137,7 +137,7 @@ void InstrInfoEmitter::run(std::ostream &OS) {
Record *RC = OperandInfo[i];
// FIXME: We only care about register operands for now.
if (RC && RC->isSubClassOf("RegisterClass"))
OS << "{ &" << getQualifiedName(RC) << "RegClass, 0 }, ";
OS << "{ " << getQualifiedName(RC) << "RegClassID, 0 }, ";
else if (RC && RC->getName() == "ptr_rc")
// Ptr value whose register class is resolved via callback.
OS << "{ 0, 1 }, ";

View File

@ -68,6 +68,15 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
if (!RegisterClasses.empty()) {
OS << "namespace " << RegisterClasses[0].Namespace
<< " { // Register classes\n";
OS << " enum {\n";
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
if (i) OS << ",\n";
OS << " " << RegisterClasses[i].getName() << "RegClassID";
if (!i) OS << " = 1";
}
OS << "\n };\n\n";
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
const std::string &Name = RegisterClasses[i].getName();
@ -244,6 +253,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
OS << RC.MethodBodies << "\n";
OS << RC.getName() << "Class::" << RC.getName()
<< "Class() : TargetRegisterClass("
<< RC.getName() + "RegClassID" << ", "
<< RC.getName() + "VTs" << ", "
<< RC.getName() + "Subclasses" << ", "
<< RC.getName() + "Superclasses" << ", "