Allow machine operands to represent global variables with offsets. This is
authorChris Lattner <sabre@nondot.org>
Fri, 15 Oct 2004 04:38:41 +0000 (04:38 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 15 Oct 2004 04:38:41 +0000 (04:38 +0000)
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

include/llvm/CodeGen/MachineInstr.h
include/llvm/CodeGen/MachineInstrBuilder.h
lib/CodeGen/MachineInstr.cpp

index a9f1352b47b6079b2ef59e1c15ee04ae7bf7a39d..d23252e5b80a8a92e3dfbd034b9df5e729dab1cd 100644 (file)
@@ -126,48 +126,60 @@ private:
 
   char flags;                   // see bit field definitions above
   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
-private:
+
+    int offset;                 // Offset to address of global or external, only
+                                // valid for MO_GlobalAddress and MO_ExternalSym
+  } extra;
+
   void zeroContents () { 
     memset (&contents, 0, sizeof (contents));
+    memset (&extra, 0, sizeof (extra));
   }
 
   MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
-    : flags(0), opType(OpTy), regNum(-1) {
+    : flags(0), opType(OpTy) {
     zeroContents ();
     contents.immedVal = ImmVal;
+    extra.regNum = -1;
   }
 
   MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy)
-    : flags(UseTy), opType(OpTy), regNum(Reg) {
+    : flags(UseTy), opType(OpTy) {
     zeroContents ();
+    extra.regNum = Reg;
   }
 
   MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy,
-                bool isPCRelative = false)
-    : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy), regNum(-1) {
+                bool isPCRelative = false, int Offset = 0)
+    : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) {
     zeroContents ();
     contents.value = V;
+    extra.offset = Offset;
   }
 
   MachineOperand(MachineBasicBlock *mbb)
-    : flags(0), opType(MO_MachineBasicBlock), regNum(-1) {
+    : flags(0), opType(MO_MachineBasicBlock) {
     zeroContents ();
     contents.MBB = mbb;
+    extra.regNum = -1;
   }
 
-  MachineOperand(const std::string &SymName, bool isPCRelative)
-    : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol), regNum(-1) {
+  MachineOperand(const std::string &SymName, bool isPCRelative, int Offset)
+    : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol) {
     zeroContents ();
     contents.SymbolName = new std::string (SymName);
+    extra.offset = Offset;
   }
 
 public:
   MachineOperand(const MachineOperand &M)
-    : flags(M.flags), opType(M.opType), regNum(M.regNum) {
+    : flags(M.flags), opType(M.opType) {
     zeroContents ();
     contents = M.contents;
+    extra = M.extra;
     if (isExternalSymbol())
       contents.SymbolName = new std::string(M.getSymbolName());
   }
@@ -184,7 +196,7 @@ public:
     contents = MO.contents;
     flags    = MO.flags;
     opType   = MO.opType;
-    regNum   = MO.regNum;
+    extra    = MO.extra;
     if (isExternalSymbol())
       contents.SymbolName = new std::string(MO.getSymbolName());
     return *this;
@@ -245,7 +257,7 @@ public:
   }
   int getMachineRegNum() const {
     assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor");
-    return regNum;
+    return extra.regNum;
   }
   int getImmedValue() const {
     assert(isImmediate() && "Wrong MachineOperand accessor");
@@ -271,6 +283,11 @@ public:
     assert(isGlobalAddress() && "Wrong MachineOperand accessor");
     return (GlobalValue*)contents.value;
   }
+  int getOffset() const {
+    assert((isGlobalAddress() || isExternalSymbol()) &&
+        "Wrong MachineOperand accessor");
+    return extra.offset;
+  }
   const std::string &getSymbolName() const {
     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
     return *contents.SymbolName;
@@ -292,7 +309,7 @@ public:
   /// allocated to this operand.
   ///
   bool hasAllocatedReg() const {
-    return (regNum >= 0 &&
+    return (extra.regNum >= 0 &&
             (opType == MO_VirtualRegister || opType == MO_CCRegister || 
              opType == MO_MachineRegister));
   }
@@ -302,7 +319,7 @@ public:
   ///
   unsigned getReg() const {
     assert(hasAllocatedReg());
-    return regNum;
+    return extra.regNum;
   }
 
   /// MachineOperand mutators...
@@ -311,7 +328,7 @@ public:
     // This method's comment used to say: 'TODO: get rid of this duplicate
     // code.' It's not clear where the duplication is.
     assert(hasAllocatedReg() && "This operand cannot have a register number!");
-    regNum = Reg;
+    extra.regNum = Reg;
   }  
 
   void setValueReg(Value *val) {
@@ -324,6 +341,12 @@ public:
     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);
 
   /// markHi32, markLo32, etc. - These methods are deprecated and only used by
@@ -342,7 +365,7 @@ private:
   void setRegForValue(int reg) {
     assert(opType == MO_VirtualRegister || opType == MO_CCRegister || 
           opType == MO_MachineRegister);
-    regNum = reg;
+    extra.regNum = reg;
   }
   
   friend class MachineInstr;
@@ -615,18 +638,18 @@ public:
     operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex));
   }
 
-  void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative) {
+  void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative, int Offset) {
     assert(!OperandsComplete() &&
            "Trying to add an operand to a machine instr that is already done!");
     operands.push_back(
       MachineOperand((Value*)GV, MachineOperand::MO_GlobalAddress,
-                     MachineOperand::Use, isPCRelative));
+                     MachineOperand::Use, isPCRelative, Offset));
   }
 
   /// addExternalSymbolOperand - Add an external symbol operand to this instr
   ///
   void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) {
-    operands.push_back(MachineOperand(SymName, isPCRelative));
+    operands.push_back(MachineOperand(SymName, isPCRelative, 0));
   }
 
   //===--------------------------------------------------------------------===//
index eb00ede9ef2dadeb323dfb2ab1550e5251d9e65f..12ca1b4998d4f5162430fc2a5b5bc4b0e44686fa 100644 (file)
@@ -124,8 +124,8 @@ public:
   }
 
   const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
-                                              bool isPCRelative = false) const {
-    MI->addGlobalAddressOperand(GV, isPCRelative);
+                                              bool isPCRelative = false, int Offset = 0) const {
+    MI->addGlobalAddressOperand(GV, isPCRelative, Offset);
     return *this;
   }
 
index a4ae09a64904778f0b7f43bafb789548a2714cf3..3dce6fc85deb8f62e6b99b36625c8c107fa91d77 100644 (file)
@@ -127,7 +127,7 @@ void MachineInstr::SetMachineOperandVal(unsigned i,
   assert(i < operands.size());          // may be explicit or implicit op
   operands[i].opType = opTy;
   operands[i].contents.value = V;
-  operands[i].regNum = -1;
+  operands[i].extra.regNum = -1;
 }
 
 void
@@ -141,7 +141,7 @@ MachineInstr::SetMachineOperandConst(unsigned i,
   operands[i].opType = opTy;
   operands[i].contents.value = NULL;
   operands[i].contents.immedVal = intValue;
-  operands[i].regNum = -1;
+  operands[i].extra.regNum = -1;
   operands[i].flags = 0;
 }
 
@@ -150,7 +150,7 @@ void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
 
   operands[i].opType = MachineOperand::MO_MachineRegister;
   operands[i].contents.value = NULL;
-  operands[i].regNum = regNum;
+  operands[i].extra.regNum = regNum;
 }
 
 // Used only by the SPARC back-end.
@@ -302,10 +302,14 @@ static void print(const MachineOperand &MO, std::ostream &OS,
     OS << "<cp#" << MO.getConstantPoolIndex() << ">";
     break;
   case MachineOperand::MO_GlobalAddress:
-    OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
+    OS << "<ga:" << ((Value*)MO.getGlobal())->getName();
+    if (MO.getOffset()) OS << "+" << MO.getOffset();
+    OS << ">";
     break;
   case MachineOperand::MO_ExternalSymbol:
-    OS << "<es:" << MO.getSymbolName() << ">";
+    OS << "<es:" << MO.getSymbolName();
+    if (MO.getOffset()) OS << "+" << MO.getOffset();
+    OS << ">";
     break;
   default:
     assert(0 && "Unrecognized operand type");