Allow machine operands to represent global variables with offsets. This is

useful when you have a reference like:

int A[100];

void foo() { A[10] = 1; }

In this case, &A[10] is a single constant and should be treated as such.

Only MO_GlobalAddress and MO_ExternalSymbol are allowed to use this field, no
other operand type is.

This is another fine patch contributed by Jeff Cohen!!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17007 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2004-10-15 04:38:41 +00:00
parent 47eb6567e2
commit ca4f6ebefc
3 changed files with 53 additions and 26 deletions

View File

@@ -126,48 +126,60 @@ private:
char flags; // see bit field definitions above char flags; // see bit field definitions above
MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. MachineOperandType opType:8; // Pack into 8 bits efficiently after flags.
int regNum; // register number for an explicit register union {
int regNum; // register number for an explicit register
// will be set for a value after reg allocation // will be set for a value after reg allocation
private:
int offset; // Offset to address of global or external, only
// valid for MO_GlobalAddress and MO_ExternalSym
} extra;
void zeroContents () { void zeroContents () {
memset (&contents, 0, sizeof (contents)); memset (&contents, 0, sizeof (contents));
memset (&extra, 0, sizeof (extra));
} }
MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister) MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
: flags(0), opType(OpTy), regNum(-1) { : flags(0), opType(OpTy) {
zeroContents (); zeroContents ();
contents.immedVal = ImmVal; contents.immedVal = ImmVal;
extra.regNum = -1;
} }
MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy) MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy)
: flags(UseTy), opType(OpTy), regNum(Reg) { : flags(UseTy), opType(OpTy) {
zeroContents (); zeroContents ();
extra.regNum = Reg;
} }
MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy, MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy,
bool isPCRelative = false) bool isPCRelative = false, int Offset = 0)
: flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy), regNum(-1) { : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) {
zeroContents (); zeroContents ();
contents.value = V; contents.value = V;
extra.offset = Offset;
} }
MachineOperand(MachineBasicBlock *mbb) MachineOperand(MachineBasicBlock *mbb)
: flags(0), opType(MO_MachineBasicBlock), regNum(-1) { : flags(0), opType(MO_MachineBasicBlock) {
zeroContents (); zeroContents ();
contents.MBB = mbb; contents.MBB = mbb;
extra.regNum = -1;
} }
MachineOperand(const std::string &SymName, bool isPCRelative) MachineOperand(const std::string &SymName, bool isPCRelative, int Offset)
: flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol), regNum(-1) { : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol) {
zeroContents (); zeroContents ();
contents.SymbolName = new std::string (SymName); contents.SymbolName = new std::string (SymName);
extra.offset = Offset;
} }
public: public:
MachineOperand(const MachineOperand &M) MachineOperand(const MachineOperand &M)
: flags(M.flags), opType(M.opType), regNum(M.regNum) { : flags(M.flags), opType(M.opType) {
zeroContents (); zeroContents ();
contents = M.contents; contents = M.contents;
extra = M.extra;
if (isExternalSymbol()) if (isExternalSymbol())
contents.SymbolName = new std::string(M.getSymbolName()); contents.SymbolName = new std::string(M.getSymbolName());
} }
@@ -184,7 +196,7 @@ public:
contents = MO.contents; contents = MO.contents;
flags = MO.flags; flags = MO.flags;
opType = MO.opType; opType = MO.opType;
regNum = MO.regNum; extra = MO.extra;
if (isExternalSymbol()) if (isExternalSymbol())
contents.SymbolName = new std::string(MO.getSymbolName()); contents.SymbolName = new std::string(MO.getSymbolName());
return *this; return *this;
@@ -245,7 +257,7 @@ public:
} }
int getMachineRegNum() const { int getMachineRegNum() const {
assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor"); assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor");
return regNum; return extra.regNum;
} }
int getImmedValue() const { int getImmedValue() const {
assert(isImmediate() && "Wrong MachineOperand accessor"); assert(isImmediate() && "Wrong MachineOperand accessor");
@@ -271,6 +283,11 @@ public:
assert(isGlobalAddress() && "Wrong MachineOperand accessor"); assert(isGlobalAddress() && "Wrong MachineOperand accessor");
return (GlobalValue*)contents.value; return (GlobalValue*)contents.value;
} }
int getOffset() const {
assert((isGlobalAddress() || isExternalSymbol()) &&
"Wrong MachineOperand accessor");
return extra.offset;
}
const std::string &getSymbolName() const { const std::string &getSymbolName() const {
assert(isExternalSymbol() && "Wrong MachineOperand accessor"); assert(isExternalSymbol() && "Wrong MachineOperand accessor");
return *contents.SymbolName; return *contents.SymbolName;
@@ -292,7 +309,7 @@ public:
/// allocated to this operand. /// allocated to this operand.
/// ///
bool hasAllocatedReg() const { bool hasAllocatedReg() const {
return (regNum >= 0 && return (extra.regNum >= 0 &&
(opType == MO_VirtualRegister || opType == MO_CCRegister || (opType == MO_VirtualRegister || opType == MO_CCRegister ||
opType == MO_MachineRegister)); opType == MO_MachineRegister));
} }
@@ -302,7 +319,7 @@ public:
/// ///
unsigned getReg() const { unsigned getReg() const {
assert(hasAllocatedReg()); assert(hasAllocatedReg());
return regNum; return extra.regNum;
} }
/// MachineOperand mutators... /// MachineOperand mutators...
@@ -311,7 +328,7 @@ public:
// This method's comment used to say: 'TODO: get rid of this duplicate // This method's comment used to say: 'TODO: get rid of this duplicate
// code.' It's not clear where the duplication is. // code.' It's not clear where the duplication is.
assert(hasAllocatedReg() && "This operand cannot have a register number!"); assert(hasAllocatedReg() && "This operand cannot have a register number!");
regNum = Reg; extra.regNum = Reg;
} }
void setValueReg(Value *val) { void setValueReg(Value *val) {
@@ -324,6 +341,12 @@ public:
contents.immedVal = immVal; contents.immedVal = immVal;
} }
void setOffset(int Offset) {
assert((isGlobalAddress() || isExternalSymbol()) &&
"Wrong MachineOperand accessor");
extra.offset = Offset;
}
friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
/// markHi32, markLo32, etc. - These methods are deprecated and only used by /// markHi32, markLo32, etc. - These methods are deprecated and only used by
@@ -342,7 +365,7 @@ private:
void setRegForValue(int reg) { void setRegForValue(int reg) {
assert(opType == MO_VirtualRegister || opType == MO_CCRegister || assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
opType == MO_MachineRegister); opType == MO_MachineRegister);
regNum = reg; extra.regNum = reg;
} }
friend class MachineInstr; friend class MachineInstr;
@@ -615,18 +638,18 @@ public:
operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex)); operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex));
} }
void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative) { void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative, int Offset) {
assert(!OperandsComplete() && assert(!OperandsComplete() &&
"Trying to add an operand to a machine instr that is already done!"); "Trying to add an operand to a machine instr that is already done!");
operands.push_back( operands.push_back(
MachineOperand((Value*)GV, MachineOperand::MO_GlobalAddress, MachineOperand((Value*)GV, MachineOperand::MO_GlobalAddress,
MachineOperand::Use, isPCRelative)); MachineOperand::Use, isPCRelative, Offset));
} }
/// addExternalSymbolOperand - Add an external symbol operand to this instr /// addExternalSymbolOperand - Add an external symbol operand to this instr
/// ///
void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) { void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) {
operands.push_back(MachineOperand(SymName, isPCRelative)); operands.push_back(MachineOperand(SymName, isPCRelative, 0));
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@@ -124,8 +124,8 @@ public:
} }
const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV, const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
bool isPCRelative = false) const { bool isPCRelative = false, int Offset = 0) const {
MI->addGlobalAddressOperand(GV, isPCRelative); MI->addGlobalAddressOperand(GV, isPCRelative, Offset);
return *this; return *this;
} }

View File

@@ -127,7 +127,7 @@ void MachineInstr::SetMachineOperandVal(unsigned i,
assert(i < operands.size()); // may be explicit or implicit op assert(i < operands.size()); // may be explicit or implicit op
operands[i].opType = opTy; operands[i].opType = opTy;
operands[i].contents.value = V; operands[i].contents.value = V;
operands[i].regNum = -1; operands[i].extra.regNum = -1;
} }
void void
@@ -141,7 +141,7 @@ MachineInstr::SetMachineOperandConst(unsigned i,
operands[i].opType = opTy; operands[i].opType = opTy;
operands[i].contents.value = NULL; operands[i].contents.value = NULL;
operands[i].contents.immedVal = intValue; operands[i].contents.immedVal = intValue;
operands[i].regNum = -1; operands[i].extra.regNum = -1;
operands[i].flags = 0; operands[i].flags = 0;
} }
@@ -150,7 +150,7 @@ void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
operands[i].opType = MachineOperand::MO_MachineRegister; operands[i].opType = MachineOperand::MO_MachineRegister;
operands[i].contents.value = NULL; operands[i].contents.value = NULL;
operands[i].regNum = regNum; operands[i].extra.regNum = regNum;
} }
// Used only by the SPARC back-end. // Used only by the SPARC back-end.
@@ -302,10 +302,14 @@ static void print(const MachineOperand &MO, std::ostream &OS,
OS << "<cp#" << MO.getConstantPoolIndex() << ">"; OS << "<cp#" << MO.getConstantPoolIndex() << ">";
break; break;
case MachineOperand::MO_GlobalAddress: case MachineOperand::MO_GlobalAddress:
OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">"; OS << "<ga:" << ((Value*)MO.getGlobal())->getName();
if (MO.getOffset()) OS << "+" << MO.getOffset();
OS << ">";
break; break;
case MachineOperand::MO_ExternalSymbol: case MachineOperand::MO_ExternalSymbol:
OS << "<es:" << MO.getSymbolName() << ">"; OS << "<es:" << MO.getSymbolName();
if (MO.getOffset()) OS << "+" << MO.getOffset();
OS << ">";
break; break;
default: default:
assert(0 && "Unrecognized operand type"); assert(0 && "Unrecognized operand type");