Eliminate separate enum for operand register type.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Sat, 28 Jul 2001 04:06:37 +0000 (04:06 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Sat, 28 Jul 2001 04:06:37 +0000 (04:06 +0000)
Use union for alternative data for different operand types.
Add iterator over Value* operands in a MachineInstr.

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

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

index 36e11bc6d2963b14329427ff005aec1bc8ad4520..bb2f930d5f534f25bcae469484a088c6e580a8c6 100644 (file)
 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
 #define LLVM_CODEGEN_MACHINEINSTR_H
 
+#include <iterator>
 #include "llvm/CodeGen/InstrForest.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/NonCopyable.h"
 #include "llvm/CodeGen/TargetMachine.h"
 
+template<class _MI, class _V> class ValOpIterator;
+
+
 //---------------------------------------------------------------------------
 // class MachineOperand 
 // 
 //---------------------------------------------------------------------------
 
 class MachineOperand {
-public:
-  friend ostream& operator<<(ostream& os, const MachineOperand& mop);
-
 public:
   enum MachineOperandType {
-    MO_Register,
+    MO_VirtualRegister,                // virtual register for *value
+    MO_MachineRegister,                // pre-assigned machine register `regNum'
     MO_CCRegister,
     MO_SignExtendedImmed,
     MO_UnextendedImmed,
     MO_PCRelativeDisp,
   };
   
-  enum VirtualRegisterType {
-    MO_VirtualReg,             // virtual register for *value
-    MO_MachineReg              // pre-assigned machine register `regNum'
-  };
-  
-  MachineOperandType machineOperandType;
-  
-  VirtualRegisterType vregType;
+private:
+  MachineOperandType opType;
   
-  Value*       value;          // BasicBlockVal for a label operand.
+  union {
+    Value*     value;          // BasicBlockVal for a label operand.
                                // ConstantVal for a non-address immediate.
-                               // Virtual register for a register operand.
+                               // Virtual register for an SSA operand,
+                               // including hidden operands required for
+                               // the generated machine code.
+    
+    unsigned int regNum;       // register number for an explicit register
   
-  unsigned int regNum;         // register number for an explicit register
-  
-  int64_t immedVal;            // constant value for an explicit constant
+    int64_t immedVal;          // constant value for an explicit constant
+  };
   
+public:
   /*ctor*/             MachineOperand  ();
   /*ctor*/             MachineOperand  (MachineOperandType operandType,
                                         Value* _val);
   /*copy ctor*/                MachineOperand  (const MachineOperand&);
   /*dtor*/             ~MachineOperand () {}
   
+  // Accessor methods.  Caller is responsible for checking the
+  // operand type before invoking the corresponding accessor.
+  // 
+  MachineOperandType   getOperandType  () const {
+    return opType;
+  }
+  Value*               getVRegValue    () const {
+    assert(opType == MO_VirtualRegister || opType == MO_CCRegister);
+    return value;
+  }
+  unsigned int         getMachineRegNum() const {
+    assert(opType == MO_MachineRegister);
+    return regNum;
+  }
+  int64_t              getImmedValue   () const {
+    assert(opType >= MO_SignExtendedImmed || opType <= MO_PCRelativeDisp);
+    return immedVal;
+  }
+  
+public:
+  friend ostream& operator<<(ostream& os, const MachineOperand& mop);
+  
+private:
   // These functions are provided so that a vector of operands can be
   // statically allocated and individual ones can be initialized later.
+  // Give class MachineInstr gets access to these functions.
   // 
   void                 Initialize      (MachineOperandType operandType,
                                         Value* _val);
   void                 InitializeConst (MachineOperandType operandType,
                                         int64_t intValue);
   void                 InitializeReg   (unsigned int regNum);
+
+  friend class MachineInstr;
 };
 
 
 inline
 MachineOperand::MachineOperand()
-  : machineOperandType(MO_Register),
-    vregType(MO_VirtualReg),
+  : opType(MO_VirtualRegister),
     value(NULL),
     regNum(0),
     immedVal(0)
@@ -114,8 +140,7 @@ MachineOperand::MachineOperand()
 inline
 MachineOperand::MachineOperand(MachineOperandType operandType,
                               Value* _val)
-  : machineOperandType(operandType),
-    vregType(MO_VirtualReg),
+  : opType(operandType),
     value(_val),
     regNum(0),
     immedVal(0)
@@ -123,19 +148,24 @@ MachineOperand::MachineOperand(MachineOperandType operandType,
 
 inline
 MachineOperand::MachineOperand(const MachineOperand& mo)
-  : machineOperandType(mo.machineOperandType),
-    vregType(mo.vregType),
-    value(mo.value),
-    regNum(mo.regNum),
-    immedVal(mo.immedVal)
+  : opType(mo.opType)
 {
+  switch(opType) {
+  case MO_VirtualRegister:
+  case MO_CCRegister:          value = mo.value; break;
+  case MO_MachineRegister:     regNum = mo.regNum; break;
+  case MO_SignExtendedImmed:
+  case MO_UnextendedImmed:
+  case MO_PCRelativeDisp:      immedVal = mo.immedVal; break;
+  default: assert(0);
+  }
 }
 
 inline void
 MachineOperand::Initialize(MachineOperandType operandType,
                           Value* _val)
 {
-  machineOperandType = operandType;
+  opType = operandType;
   value = _val;
 }
 
@@ -143,7 +173,7 @@ inline void
 MachineOperand::InitializeConst(MachineOperandType operandType,
                                int64_t intValue)
 {
-  machineOperandType = operandType;
+  opType = operandType;
   value = NULL;
   immedVal = intValue;
 }
@@ -151,8 +181,7 @@ MachineOperand::InitializeConst(MachineOperandType operandType,
 inline void
 MachineOperand::InitializeReg(unsigned int _regNum)
 {
-  machineOperandType = MO_Register;
-  vregType = MO_MachineReg;
+  opType = MO_MachineRegister;
   value = NULL;
   regNum = _regNum;
 }
@@ -166,8 +195,6 @@ MachineOperand::InitializeReg(unsigned int _regNum)
 // 
 //   MachineOpCode must be an enum, defined separately for each target.
 //   E.g., It is defined in SparcInstructionSelection.h for the SPARC.
-//   The array MachineInstrInfo TargetMachineInstrInfo[] objects
-//   (indexed by opCode) provides information about each target instruction.
 // 
 //   opCodeMask is used to record variants of an instruction.
 //   E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants):
@@ -181,12 +208,15 @@ class MachineInstr : public NonCopyable {
 private:
   MachineOpCode        opCode;
   OpCodeMask   opCodeMask;             // extra bits for variants of an opcode
-  vector<MachineOperand> operands;     // operand 0 is the result
+  vector<MachineOperand> operands;
+  
+public:
+  typedef ValOpIterator<const MachineInstr, const Value> val_op_const_iterator;
+  typedef ValOpIterator<      MachineInstr,       Value> val_op_iterator;
   
 public:
   /*ctor*/             MachineInstr    (MachineOpCode _opCode,
                                         OpCodeMask    _opCodeMask = 0x0);
-  
   inline               ~MachineInstr   () {}
   
   const MachineOpCode  getOpCode       () const;
@@ -194,11 +224,14 @@ public:
   unsigned int         getNumOperands  () const;
   
   const MachineOperand& getOperand     (unsigned int i) const;
+        MachineOperand& getOperand     (unsigned int i);
   
   void                 dump            (unsigned int indent = 0);
   
 public:
   friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
+  friend val_op_const_iterator;
+  friend val_op_iterator;
 
 public:
   // Access to set the operands when building the machine instruction
@@ -221,10 +254,15 @@ MachineInstr::getOpCode() const
 inline unsigned int
 MachineInstr::getNumOperands() const
 {
-  assert(operands.size() == TargetMachineInstrInfo[opCode].numOperands);
   return operands.size();
 }
 
+inline MachineOperand&
+MachineInstr::getOperand(unsigned int i)
+{
+  return operands[i];
+}
+
 inline const MachineOperand&
 MachineInstr::getOperand(unsigned int i) const
 {
@@ -232,6 +270,38 @@ MachineInstr::getOperand(unsigned int i) const
 }
 
 
+template<class _MI, class _V>
+class ValOpIterator : public std::forward_iterator<_V, ptrdiff_t> {
+private:
+  unsigned int i;
+  int resultPos;
+  _MI*& minstr;
+
+  inline void  skipToNextVal() {
+    while (i < minstr->getNumOperands()
+          && minstr->getOperand(i).getOperandType() != MachineOperand::MO_VirtualRegister
+          && minstr->getOperand(i).getOperandType() != MachineOperand::MO_CCRegister)
+      ++i;
+  }
+  
+public:
+  typedef ValOpIterator<_MI, _V> _Self;
+  
+  inline ValOpIterator(_MI* _minstr) : i(0), minstr(_minstr) {
+    resultPos = TargetInstrDescriptors[minstr->opCode].resultPos;
+    skipToNextVal();
+  };
+  
+  inline _V*   operator*()  const { return minstr->getOperand(i).getVRegValue();}
+  inline _V*   operator->() const { return operator*(); }
+  inline bool  isDef   ()   const { return (((int) i) == resultPos); }
+  inline bool  done    ()   const { return (i == minstr->getNumOperands()); }
+  
+  inline _Self& operator++()      { i++; skipToNextVal(); return *this; }
+  inline _Self  operator++(int)           { _Self tmp = *this; ++*this; return tmp; }
+};
+
+
 //---------------------------------------------------------------------------
 // class MachineInstructionsForVMInstr
 // 
@@ -332,12 +402,11 @@ void              Set3OperandsFromInstr   (MachineInstr* minstr,
 
 MachineOperand::MachineOperandType
                ChooseRegOrImmed(Value* val,
-                            MachineOpCode opCode,
-                            const TargetMachine& targetMachine,
-                            bool canUseImmed,
-                            MachineOperand::VirtualRegisterType& getVRegType,
-                            unsigned int& getMachineRegNum,
-                            int64_t& getImmedValue);
+                                MachineOpCode opCode,
+                                const TargetMachine& targetMachine,
+                                bool canUseImmed,
+                                unsigned int& getMachineRegNum,
+                                int64_t& getImmedValue);
 
 ostream& operator<<(ostream& os, const MachineInstr& minstr);
 
index c43b022bb1d7cd08926dd4e60d8f840b66b71f0d..64fcaa0577174e87a9070f72592541bb0abae0e7 100644 (file)
 //************************ Class Implementations **************************/
 
 
-bool
-MachineInstrInfo::constantFitsInImmedField(int64_t intValue) const
-{
-  // First, check if opCode has an immed field.
-  bool isSignExtended;
-  uint64_t maxImmedValue = this->maxImmedConstant(isSignExtended);
-  if (maxImmedValue != 0)
-    {
-      // Now check if the constant fits
-      if (intValue <= (int64_t) maxImmedValue &&
-         intValue >= -((int64_t) maxImmedValue+1))
-       return true;
-    }
-  
-  return false;
-}
-
 MachineInstr::MachineInstr(MachineOpCode _opCode,
                           OpCodeMask    _opCodeMask)
   : opCode(_opCode),
     opCodeMask(_opCodeMask),
-    operands(TargetMachineInstrInfo[_opCode].numOperands)
+    operands(TargetInstrDescriptors[_opCode].numOperands)
 {
 }
 
@@ -50,7 +33,7 @@ MachineInstr::SetMachineOperand(unsigned int i,
                                MachineOperand::MachineOperandType operandType,
                                Value* _val)
 {
-  assert(i < TargetMachineInstrInfo[opCode].numOperands);
+  assert(i < operands.size());
   operands[i].Initialize(operandType, _val);
 }
 
@@ -59,7 +42,7 @@ MachineInstr::SetMachineOperand(unsigned int i,
                                MachineOperand::MachineOperandType operandType,
                                int64_t intValue)
 {
-  assert(i < TargetMachineInstrInfo[opCode].numOperands);
+  assert(i < operands.size());
   operands[i].InitializeConst(operandType, intValue);
 }
 
@@ -67,7 +50,7 @@ void
 MachineInstr::SetMachineOperand(unsigned int i,
                                unsigned int regNum)
 {
-  assert(i < TargetMachineInstrInfo[opCode].numOperands);
+  assert(i < operands.size());
   operands[i].InitializeReg(regNum);
 }
 
@@ -83,11 +66,22 @@ MachineInstr::dump(unsigned int indent)
 ostream&
 operator<< (ostream& os, const MachineInstr& minstr)
 {
-  os << TargetMachineInstrInfo[minstr.opCode].opCodeString;
+  os << TargetInstrDescriptors[minstr.opCode].opCodeString;
   
   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
     os << "\t" << minstr.getOperand(i);
   
+#undef DEBUG_VAL_OP_ITERATOR
+#ifdef DEBUG_VAL_OP_ITERATOR
+  os << endl << "\tValue operands are: ";
+  for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
+    {
+      const Value* val = *vo;
+      os << val << (vo.isDef()? "(def), " : ", ");
+    }
+  os << endl;
+#endif
+  
   return os;
 }
 
@@ -95,19 +89,17 @@ ostream&
 operator<< (ostream& os, const MachineOperand& mop)
 {
   strstream regInfo;
-  if (mop.machineOperandType == MachineOperand::MO_Register)
-    {
-      if (mop.vregType == MachineOperand::MO_VirtualReg)
-       regInfo << "(val " << mop.value << ")" << ends;
-      else
-       regInfo << "("       << mop.regNum << ")" << ends;
-    }
-  else if (mop.machineOperandType == MachineOperand::MO_CCRegister)
+  if (mop.opType == MachineOperand::MO_VirtualRegister)
+    regInfo << "(val " << mop.value << ")" << ends;
+  else if (mop.opType == MachineOperand::MO_MachineRegister)
+    regInfo << "("       << mop.regNum << ")" << ends;
+  else if (mop.opType == MachineOperand::MO_CCRegister)
     regInfo << "(val " << mop.value << ")" << ends;
   
-  switch(mop.machineOperandType)
+  switch(mop.opType)
     {
-    case MachineOperand::MO_Register:
+    case MachineOperand::MO_VirtualRegister:
+    case MachineOperand::MO_MachineRegister:
       os << "%reg" << regInfo.str();
       free(regInfo.str());
       break;
@@ -169,21 +161,22 @@ operator<< (ostream& os, const MachineOperand& mop)
 void
 Set2OperandsFromInstr(MachineInstr* minstr,
                      InstructionNode* vmInstrNode,
-                     const TargetMachine& targetMachine,
+                     const TargetMachine& target,
                      bool canDiscardResult,
                      int op1Position,
                      int resultPosition)
 {
-  Set3OperandsFromInstr(minstr, vmInstrNode, targetMachine,
+  Set3OperandsFromInstr(minstr, vmInstrNode, target,
                        canDiscardResult, op1Position,
                        /*op2Position*/ -1, resultPosition);
 }
 
-
+#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
+#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
 unsigned
 Set3OperandsFromInstrJUNK(MachineInstr* minstr,
                      InstructionNode* vmInstrNode,
-                     const TargetMachine& targetMachine,
+                     const TargetMachine& target,
                      bool canDiscardResult,
                      int op1Position,
                      int op2Position,
@@ -198,16 +191,16 @@ Set3OperandsFromInstrJUNK(MachineInstr* minstr,
   Value* op1Value = vmInstrNode->leftChild()->getValue();
   bool isValidConstant;
   int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
-  if (isValidConstant && intValue == 0 && targetMachine.zeroRegNum >= 0)
-    minstr->SetMachineOperand(op1Position, /*regNum*/ targetMachine.zeroRegNum);
+  if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
+    minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
   else
     {
       if (op1Value->getValueType() == Value::ConstantVal)
        {// value is constant and must be loaded from constant pool
          returnFlags = returnFlags | (1 << op1Position);
        }
-      minstr->SetMachineOperand(op1Position, MachineOperand::MO_Register,
-                                            op1Value);
+      minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
+                                           op1Value);
     }
   
   // Check if operand 2 (if any) fits in the immediate field of the instruction,
@@ -216,46 +209,45 @@ Set3OperandsFromInstrJUNK(MachineInstr* minstr,
     {
       Value* op2Value = vmInstrNode->rightChild()->getValue();
       int64_t immedValue;
-      MachineOperand::VirtualRegisterType vregType;
       unsigned int machineRegNum;
       
       MachineOperand::MachineOperandType
-       op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(),targetMachine,
+       op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
                                   /*canUseImmed*/ true,
-                                  vregType, machineRegNum, immedValue);
+                                  machineRegNum, immedValue);
       
-      if (op2type == MachineOperand::MO_Register)
+      if (op2type == MachineOperand::MO_MachineRegister)
+       minstr->SetMachineOperand(op2Position, machineRegNum);
+      else if (op2type == MachineOperand::MO_VirtualRegister)
        {
-         if (vregType == MachineOperand::MO_MachineReg)
-           minstr->SetMachineOperand(op2Position, machineRegNum);
-         else
-           {
-             if (op2Value->getValueType() == Value::ConstantVal)
-               {// value is constant and must be loaded from constant pool
-                 returnFlags = returnFlags | (1 << op2Position);
-               }
-             minstr->SetMachineOperand(op2Position, op2type, op2Value);
+         if (op2Value->getValueType() == Value::ConstantVal)
+           {// value is constant and must be loaded from constant pool
+             returnFlags = returnFlags | (1 << op2Position);
            }
+         minstr->SetMachineOperand(op2Position, op2type, op2Value);
        }
       else
-       minstr->SetMachineOperand(op2Position, op2type, immedValue);
+       {
+         assert(op2type != MO_CCRegister);
+         minstr->SetMachineOperand(op2Position, op2type, immedValue);
+       }
     }
   
   // If operand 3 (result) can be discarded, use a dead register if one exists
-  if (canDiscardResult && targetMachine.zeroRegNum >= 0)
-    minstr->SetMachineOperand(resultPosition, targetMachine.zeroRegNum);
+  if (canDiscardResult && target.zeroRegNum >= 0)
+    minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
   else
-    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_Register,
-                                             vmInstrNode->getValue());
+    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
 
   return returnFlags;
 }
+#endif
 
 
 void
 Set3OperandsFromInstr(MachineInstr* minstr,
                      InstructionNode* vmInstrNode,
-                     const TargetMachine& targetMachine,
+                     const TargetMachine& target,
                      bool canDiscardResult,
                      int op1Position,
                      int op2Position,
@@ -265,34 +257,32 @@ Set3OperandsFromInstr(MachineInstr* minstr,
   assert(resultPosition >= 0);
   
   // operand 1
-  minstr->SetMachineOperand(op1Position, MachineOperand::MO_Register,
+  minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
                            vmInstrNode->leftChild()->getValue());   
   
   // operand 2 (if any)
   if (op2Position >= 0)
-    minstr->SetMachineOperand(op2Position, MachineOperand::MO_Register,
+    minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
                              vmInstrNode->rightChild()->getValue());   
   
   // result operand: if it can be discarded, use a dead register if one exists
-  if (canDiscardResult && targetMachine.zeroRegNum >= 0)
-    minstr->SetMachineOperand(resultPosition, targetMachine.zeroRegNum);
+  if (canDiscardResult && target.zeroRegNum >= 0)
+    minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
   else
-    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_Register,
-                                             vmInstrNode->getValue());
+    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
 }
 
 
 MachineOperand::MachineOperandType
 ChooseRegOrImmed(Value* val,
                 MachineOpCode opCode,
-                const TargetMachine& targetMachine,
+                const TargetMachine& target,
                 bool canUseImmed,
-                MachineOperand::VirtualRegisterType& getVRegType,
                 unsigned int& getMachineRegNum,
                 int64_t& getImmedValue)
 {
-  MachineOperand::MachineOperandType opType = MachineOperand::MO_Register;
-  getVRegType = MachineOperand::MO_VirtualReg;
+  MachineOperand::MachineOperandType opType =
+    MachineOperand::MO_VirtualRegister;
   getMachineRegNum = 0;
   getImmedValue = 0;
   
@@ -311,13 +301,13 @@ ChooseRegOrImmed(Value* val,
   
   if (isValidConstant)
     {
-      if (intValue == 0 && targetMachine.zeroRegNum >= 0)
+      if (intValue == 0 && target.zeroRegNum >= 0)
        {
-         getVRegType = MachineOperand::MO_MachineReg;
-         getMachineRegNum = targetMachine.zeroRegNum;
+         opType = MachineOperand::MO_MachineRegister;
+         getMachineRegNum = target.zeroRegNum;
        }
       else if (canUseImmed &&
-              targetMachine.machineInstrInfo[opCode].constantFitsInImmedField(intValue))
+              target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
        {
          opType = MachineOperand::MO_SignExtendedImmed;
          getImmedValue = intValue;