Remove separate vector of implicit refs from MachineInstr, and
authorVikram S. Adve <vadve@cs.uiuc.edu>
Tue, 29 Oct 2002 19:41:18 +0000 (19:41 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Tue, 29 Oct 2002 19:41:18 +0000 (19:41 +0000)
instead record them as extra operands in the operands[] vector.
Also, move CallArgsDescriptor into this class instead of making it an
annotation on the machine instruction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4399 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineInstr.h
include/llvm/CodeGen/MachineInstrAnnot.h
lib/CodeGen/MachineInstr.cpp
lib/CodeGen/MachineInstrAnnot.cpp
lib/Target/SparcV9/MachineInstrAnnot.h

index 5855d149ff2f5779474541e078f660f35299d757..221340e6deb861df7c25306b5e99b8687971f93b 100644 (file)
@@ -89,21 +89,38 @@ private:
                                 // will be set for a value after reg allocation
 private:
   MachineOperand()
-    : immedVal(0), opType(MO_VirtualRegister), flags(0), regNum(-1) {}
+    : immedVal(0),
+      opType(MO_VirtualRegister),
+      flags(0),
+      regNum(-1) {}
+
   MachineOperand(int64_t ImmVal, MachineOperandType OpTy)
-    : immedVal(ImmVal), opType(OpTy), flags(0), regNum(-1) {}
+    : immedVal(ImmVal),
+      opType(OpTy),
+      flags(0),
+      regNum(-1) {}
+
   MachineOperand(int Reg, MachineOperandType OpTy, bool isDef = false)
-    : immedVal(0), opType(OpTy), flags(isDef ? DEFFLAG : 0), regNum(Reg) {}
+    : immedVal(0),
+      opType(OpTy),
+      flags(isDef ? DEFFLAG : 0),
+      regNum(Reg) {}
+
   MachineOperand(Value *V, MachineOperandType OpTy,
                  bool isDef = false, bool isDNU = false)
-    : value(V), opType(OpTy), regNum(-1) {
+    : value(V),
+      opType(OpTy),
+      regNum(-1) {
     flags = (isDef ? DEFFLAG : 0) | (isDNU ? DEFUSEFLAG : 0);
   }
 
 public:
   MachineOperand(const MachineOperand &M)
-    : immedVal(M.immedVal), opType(M.opType), flags(M.flags), regNum(M.regNum) {
-  }
+    : immedVal(M.immedVal),
+      opType(M.opType),
+      flags(M.flags),
+      regNum(M.regNum) {}
+
   ~MachineOperand() {}
   
   // Accessor methods.  Caller is responsible for checking the
@@ -193,21 +210,20 @@ private:
 //      a CALL (if any), and return value of a RETURN.
 //---------------------------------------------------------------------------
 
-class MachineInstr : public Annotable,         // MachineInstrs are annotable
-                     public NonCopyable {      // Disable copy operations
+class MachineInstr: public NonCopyable {      // Disable copy operations
+
   MachineOpCode    opCode;              // the opcode
   std::vector<MachineOperand> operands; // the operands
+  unsigned numImplicitRefs;             // number of implicit operands
 
-  struct ImplicitRef {
-    Value *Val;
-    bool isDef, isDefAndUse;
-
-    ImplicitRef(Value *V, bool D, bool DU) : Val(V), isDef(D), isDefAndUse(DU){}
-  };
-
-  // implicitRefs - Values implicitly referenced by this machine instruction
-  // (eg, call args)
-  std::vector<ImplicitRef> implicitRefs;
+  MachineOperand& getImplicitOp(unsigned i) {
+    assert(i < numImplicitRefs && "implicit ref# out of range!");
+    return operands[i + operands.size() - numImplicitRefs];
+  }
+  const MachineOperand& getImplicitOp(unsigned i) const {
+    assert(i < numImplicitRefs && "implicit ref# out of range!");
+    return operands[i + operands.size() - numImplicitRefs];
+  }
 
   // regsUsed - all machine registers used for this instruction, including regs
   // used to save values across the instruction.  This is a bitset of registers.
@@ -215,6 +231,7 @@ class MachineInstr : public Annotable,         // MachineInstrs are annotable
 
   // OperandComplete - Return true if it's illegal to add a new operand
   bool OperandsComplete() const;
+
 public:
   MachineInstr(MachineOpCode Opcode);
   MachineInstr(MachineOpCode Opcode, unsigned numOperands);
@@ -240,14 +257,14 @@ public:
   //
   // Information about explicit operands of the instruction
   // 
-  unsigned getNumOperands() const { return operands.size(); }
+  unsigned getNumOperands() const { return operands.size() - numImplicitRefs; }
   
   const MachineOperand& getOperand(unsigned i) const {
-    assert(i < operands.size() && "getOperand() out of range!");
+    assert(i < getNumOperands() && "getOperand() out of range!");
     return operands[i];
   }
   MachineOperand& getOperand(unsigned i) {
-    assert(i < operands.size() && "getOperand() out of range!");
+    assert(i < getNumOperands() && "getOperand() out of range!");
     return operands[i];
   }
 
@@ -262,40 +279,30 @@ public:
   bool operandIsDefinedAndUsed(unsigned i) const {
     return getOperand(i).opIsDefAndUse();
   }
-  
+
   //
   // Information about implicit operands of the instruction
   // 
-  unsigned getNumImplicitRefs() const{ return implicitRefs.size();}
+  unsigned getNumImplicitRefs() const{ return numImplicitRefs; }
   
   const Value* getImplicitRef(unsigned i) const {
-    assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
-    return implicitRefs[i].Val;
+    return getImplicitOp(i).getVRegValue();
   }
   Value* getImplicitRef(unsigned i) {
-    assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
-    return implicitRefs[i].Val;
+    return getImplicitOp(i).getVRegValue();
   }
 
   bool implicitRefIsDefined(unsigned i) const {
-    assert(i < implicitRefs.size() && "implicitRefIsDefined() out of range!");
-    return implicitRefs[i].isDef;
+    return getImplicitOp(i).opIsDef();
   }
   bool implicitRefIsDefinedAndUsed(unsigned i) const {
-    assert(i < implicitRefs.size() && "implicitRefIsDef&Used() out of range!");
-    return implicitRefs[i].isDefAndUse;
+    return getImplicitOp(i).opIsDefAndUse();
   }
-  
-  void addImplicitRef(Value* V, bool isDef=false, bool isDefAndUse=false) {
-    implicitRefs.push_back(ImplicitRef(V, isDef, isDefAndUse));
-  }
-  
-  void setImplicitRef(unsigned i, Value* V, bool isDef=false,
-                      bool isDefAndUse=false) {
-    assert(i < implicitRefs.size() && "setImplicitRef() out of range!");
-    implicitRefs[i] = ImplicitRef(V, isDef, isDefAndUse);
-  }
-  
+  inline void addImplicitRef    (Value* V,
+                                 bool isDef=false,bool isDefAndUse=false);
+  inline void setImplicitRef    (unsigned i, Value* V,
+                                 bool isDef=false, bool isDefAndUse=false);
+
   //
   // Information about registers used in this instruction
   // 
@@ -316,22 +323,28 @@ public:
 
   //
   // Define iterators to access the Value operands of the Machine Instruction.
+  // Note that these iterators only enumerate the explicit operands.
   // begin() and end() are defined to produce these iterators...
   //
   template<class _MI, class _V> class ValOpIterator;
   typedef ValOpIterator<const MachineInstr*,const Value*> const_val_op_iterator;
   typedef ValOpIterator<      MachineInstr*,      Value*> val_op_iterator;
 
-
   // Access to set the operands when building the machine instruction
   // 
-  void SetMachineOperandVal(unsigned i,
-                            MachineOperand::MachineOperandType operandType,
-                            Value* V, bool isDef=false, bool isDefAndUse=false);
-  void SetMachineOperandConst(unsigned i,
-                              MachineOperand::MachineOperandType operandType,
-                              int64_t intValue);
-  void SetMachineOperandReg(unsigned i, int regNum, bool isDef=false);
+  void SetMachineOperandVal     (unsigned i,
+                                 MachineOperand::MachineOperandType operandType,
+                                 Value* V,
+                                 bool isDef=false,
+                                 bool isDefAndUse=false);
+
+  void SetMachineOperandConst   (unsigned i,
+                                 MachineOperand::MachineOperandType operandType,
+                                 int64_t intValue);
+
+  void SetMachineOperandReg     (unsigned i,
+                                 int regNum,
+                                 bool isDef=false);
 
   //===--------------------------------------------------------------------===//
   // Accessors to add operands when building up machine instructions
@@ -418,9 +431,9 @@ public:
     
     void skipToNextVal() {
       while (i < MI->getNumOperands() &&
-             !((MI->getOperandType(i) == MachineOperand::MO_VirtualRegister ||
-                MI->getOperandType(i) == MachineOperand::MO_CCRegister)
-               && MI->getOperand(i).getVRegValue() != 0))
+             !( (MI->getOperandType(i) == MachineOperand::MO_VirtualRegister ||
+                 MI->getOperandType(i) == MachineOperand::MO_CCRegister)
+                && MI->getOperand(i).getVRegValue() != 0))
         ++i;
     }
   
@@ -473,14 +486,39 @@ public:
   }
 };
 
+
+// Define here to enable inlining of the functions used.
+// 
+void MachineInstr::addImplicitRef(Value* V,
+                                  bool isDef,
+                                  bool isDefAndUse)
+{
+  ++numImplicitRefs;
+  addRegOperand(V, isDef, isDefAndUse);
+}
+
+void MachineInstr::setImplicitRef(unsigned i,
+                                  Value* V,
+                                  bool isDef,
+                                  bool isDefAndUse)
+{
+  assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!");
+  SetMachineOperandVal(i + getNumImplicitRefs(),
+                       MachineOperand::MO_VirtualRegister,
+                       V, isDef, isDefAndUse);
+}
+
+
 //---------------------------------------------------------------------------
 // Debugging Support
 //---------------------------------------------------------------------------
 
-std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
+std::ostream& operator<<        (std::ostream& os,
+                                 const MachineInstr& minstr);
 
-std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
+std::ostream& operator<<        (std::ostream& os,
+                                 const MachineOperand& mop);
                                         
-void PrintMachineInstructions(const Function *F);
+void PrintMachineInstructions   (const Function *F);
 
 #endif
index be3aaac299d8a67e5964e53f12a6fe5a4d2866c7..d206c6be8770c88aa32c7365a50f75823bec13a5 100644 (file)
@@ -7,7 +7,6 @@
 #ifndef MACHINE_INSTR_ANNOT_h
 #define MACHINE_INSTR_ANNOT_h
 
-#include "llvm/Annotation.h"
 #include "llvm/CodeGen/MachineInstr.h"
 
 class Value;
@@ -50,8 +49,8 @@ public:
 };
 
 
-class CallArgsDescriptor: public Annotation { // Annotation for a MachineInstr
-  static AnnotationID AID;              // AnnotationID for this class
+class CallArgsDescriptor {
+
   std::vector<CallArgInfo> argInfoVec;  // Descriptor for each argument
   const CallInst* callInstr;            // The call instruction == result value
   const Value* funcPtr;                 // Pointer for indirect calls 
@@ -68,18 +67,16 @@ public:
   unsigned int    getNumArgs() const          { return argInfoVec.size(); }
   CallArgInfo&    getArgInfo(unsigned int op) { assert(op < argInfoVec.size());
                                                 return argInfoVec[op]; }
+  const CallInst* getCallInst() const         { return callInstr; }
   const CallInst* getReturnValue() const;
   const Value*    getIndirectFuncPtr() const  { return funcPtr; }
   TmpInstruction* getReturnAddrReg() const    { return retAddrReg; }
   bool            isVarArgsFunc() const       { return isVarArgs; }
   bool            hasNoPrototype() const      { return noPrototype; }
 
-  // Annotation mechanism to annotate a MachineInstr with the descriptor.
-  // This is not demand-driven because annotations can only be created
-  // at restricted points during code generation.
-  static inline CallArgsDescriptor *get(const MachineInstr* MI) {
-    return (CallArgsDescriptor *) MI->getAnnotation(AID);
-  }
+  // Mechanism to get the descriptor for a CALL MachineInstr.
+  // 
+  static CallArgsDescriptor *get(const MachineInstr* MI);
 };
 
 
index 2d2487e8687643e9e4c3c13c65faccca1558b0a2..91b5ce7728ea228c0c994e8f7f177df62602d8fb 100644 (file)
@@ -19,24 +19,33 @@ extern const MachineInstrDescriptor *TargetInstrDescriptors;
 // Constructor for instructions with fixed #operands (nearly all)
 MachineInstr::MachineInstr(MachineOpCode _opCode)
   : opCode(_opCode),
-    operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()) {
+    operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()),
+    numImplicitRefs(0)
+{
   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
 }
 
 // Constructor for instructions with variable #operands
 MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned  numOperands)
-  : opCode(OpCode), operands(numOperands, MachineOperand()) {
+  : opCode(OpCode),
+    operands(numOperands, MachineOperand()),
+    numImplicitRefs(0)
+{
 }
 
 MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands,
-                           bool XX, bool YY) : opCode(Opcode) {
+                           bool XX, bool YY)
+  : opCode(Opcode),
+    numImplicitRefs(0)
+{
   operands.reserve(numOperands);
 }
 
 // OperandComplete - Return true if it's illegal to add a new operand
-bool MachineInstr::OperandsComplete() const {
+bool MachineInstr::OperandsComplete() const
+{
   int NumOperands = TargetInstrDescriptors[opCode].numOperands;
-  if (NumOperands >= 0 && operands.size() >= (unsigned)NumOperands)
+  if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
     return true;  // Broken!
   return false;
 }
@@ -47,7 +56,10 @@ bool MachineInstr::OperandsComplete() const {
 // This only resets the size of the operand vector and initializes it.
 // The new operands must be set explicitly later.
 // 
-void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands) {
+void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands)
+{
+  assert(getNumImplicitRefs() == 0 &&
+         "This is probably broken because implicit refs are going to be lost.");
   opCode = Opcode;
   operands.clear();
   operands.resize(numOperands, MachineOperand());
@@ -60,7 +72,7 @@ MachineInstr::SetMachineOperandVal(unsigned i,
                                    bool isdef,
                                    bool isDefAndUse)
 {
-  assert(i < operands.size());
+  assert(i < operands.size());          // may be explicit or implicit op
   operands[i].opType = opType;
   operands[i].value = V;
   operands[i].regNum = -1;
@@ -77,7 +89,7 @@ MachineInstr::SetMachineOperandConst(unsigned i,
                                MachineOperand::MachineOperandType operandType,
                                      int64_t intValue)
 {
-  assert(i < operands.size());
+  assert(i < getNumOperands());          // must be explicit op
   assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
          "immed. constant cannot be defined");
 
@@ -92,7 +104,7 @@ void
 MachineInstr::SetMachineOperandReg(unsigned i,
                                    int regNum,
                                    bool isdef) {
-  assert(i < operands.size());
+  assert(i < getNumOperands());          // must be explicit op
 
   operands[i].opType = MachineOperand::MO_MachineRegister;
   operands[i].value = NULL;
@@ -107,6 +119,7 @@ MachineInstr::SetMachineOperandReg(unsigned i,
 void
 MachineInstr::SetRegForOperand(unsigned i, int regNum)
 {
+  assert(i < getNumOperands());          // must be explicit op
   operands[i].setRegForValue(regNum);
   insertUsedReg(regNum);
 }
@@ -129,11 +142,11 @@ MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly)
         }
 
   // Subsitute implicit refs
-  for (unsigned i=0, N=implicitRefs.size(); i < N; ++i)
+  for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
     if (getImplicitRef(i) == oldVal)
       if (!defsOnly || implicitRefIsDefined(i))
         {
-          implicitRefs[i].Val = newVal;
+          getImplicitOp(i).value = newVal;
           ++numSubst;
         }
 
index b4809a6be8071582a670122a3e9e288bd02caf05..27cf7ad931ce76880fe0abd109c32c5bf7e017b5 100644 (file)
@@ -6,18 +6,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/MachineInstrAnnot.h"
-#include "llvm/Annotation.h"
+#include "llvm/CodeGen/InstrSelection.h"
+#include "llvm/CodeGen/InstrSelectionSupport.h"
+#include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/iOther.h"
 #include "llvm/Type.h"
 
-AnnotationID CallArgsDescriptor::AID(AnnotationManager::
-                                     getID("CodeGen::CallArgsDescriptor"));
 
 CallArgsDescriptor::CallArgsDescriptor(const CallInst* _callInstr,
                                        TmpInstruction* _retAddrReg,
                                        bool _isVarArgs, bool _noPrototype)
-  : Annotation(AID),
-    callInstr(_callInstr),
+  : callInstr(_callInstr),
     funcPtr(isa<Function>(_callInstr->getCalledValue())
             ? NULL : _callInstr->getCalledValue()),
     retAddrReg(_retAddrReg),
@@ -30,6 +29,10 @@ CallArgsDescriptor::CallArgsDescriptor(const CallInst* _callInstr,
          && "Operand 0 is ignored in the loop below!");
   for (unsigned int i=1; i < numArgs; ++i)
     argInfoVec.push_back(CallArgInfo(callInstr->getOperand(i)));
+
+  // Enter this object in the MachineCodeForInstr object of the CallInst.
+  // This transfers ownership of this object.
+  MachineCodeForInstruction::get(callInstr).setCallArgsDescriptor(this); 
 }
 
 
@@ -38,3 +41,26 @@ CallArgsDescriptor::getReturnValue() const
 {
   return (callInstr->getType() == Type::VoidTy? NULL : callInstr);
 }
+
+
+// Mechanism to get the descriptor for a CALL MachineInstr.
+// We get the LLVM CallInstr from the ret. addr. register argument
+// of the CALL MachineInstr, then get the CallArgsDescriptor from the
+// MachineCodeForInstruction object for the CallInstr.
+// This is roundabout but avoids adding a new map or annotation just
+// to keep track of CallArgsDescriptors.
+// 
+CallArgsDescriptor *CallArgsDescriptor::get(const MachineInstr* MI)
+{
+  const TmpInstruction* retAddrReg =
+    cast<TmpInstruction>(MI->getImplicitRef(MI->getNumImplicitRefs()-1));
+  assert(retAddrReg->getNumOperands() == 1 &&
+         isa<CallInst>(retAddrReg->getOperand(0)) &&
+         "Order of implicit args of CALL instr. changed. FIX THIS CODE!");
+  const CallInst* callInstr = cast<CallInst>(retAddrReg->getOperand(0));
+
+  CallArgsDescriptor* desc =
+    MachineCodeForInstruction::get(callInstr).getCallArgsDescriptor(); 
+  assert(desc->getCallInst()==callInstr && "Incorrect call args descriptor?");
+  return desc;
+}
index be3aaac299d8a67e5964e53f12a6fe5a4d2866c7..d206c6be8770c88aa32c7365a50f75823bec13a5 100644 (file)
@@ -7,7 +7,6 @@
 #ifndef MACHINE_INSTR_ANNOT_h
 #define MACHINE_INSTR_ANNOT_h
 
-#include "llvm/Annotation.h"
 #include "llvm/CodeGen/MachineInstr.h"
 
 class Value;
@@ -50,8 +49,8 @@ public:
 };
 
 
-class CallArgsDescriptor: public Annotation { // Annotation for a MachineInstr
-  static AnnotationID AID;              // AnnotationID for this class
+class CallArgsDescriptor {
+
   std::vector<CallArgInfo> argInfoVec;  // Descriptor for each argument
   const CallInst* callInstr;            // The call instruction == result value
   const Value* funcPtr;                 // Pointer for indirect calls 
@@ -68,18 +67,16 @@ public:
   unsigned int    getNumArgs() const          { return argInfoVec.size(); }
   CallArgInfo&    getArgInfo(unsigned int op) { assert(op < argInfoVec.size());
                                                 return argInfoVec[op]; }
+  const CallInst* getCallInst() const         { return callInstr; }
   const CallInst* getReturnValue() const;
   const Value*    getIndirectFuncPtr() const  { return funcPtr; }
   TmpInstruction* getReturnAddrReg() const    { return retAddrReg; }
   bool            isVarArgsFunc() const       { return isVarArgs; }
   bool            hasNoPrototype() const      { return noPrototype; }
 
-  // Annotation mechanism to annotate a MachineInstr with the descriptor.
-  // This is not demand-driven because annotations can only be created
-  // at restricted points during code generation.
-  static inline CallArgsDescriptor *get(const MachineInstr* MI) {
-    return (CallArgsDescriptor *) MI->getAnnotation(AID);
-  }
+  // Mechanism to get the descriptor for a CALL MachineInstr.
+  // 
+  static CallArgsDescriptor *get(const MachineInstr* MI);
 };