When an instruction like: A += B had both A and B virtual registers
authorAlkis Evlogimenos <alkis@evlogimenos.com>
Tue, 3 Feb 2004 01:13:07 +0000 (01:13 +0000)
committerAlkis Evlogimenos <alkis@evlogimenos.com>
Tue, 3 Feb 2004 01:13:07 +0000 (01:13 +0000)
spilled, A was loaded from its stack location twice. This fixes the bug.

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

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

index 670f9721ae8c2d870a49ed1de5ee592792dda2df..f76da2fa4a28e822b0191c662160bc92be8ce116 100644 (file)
@@ -207,6 +207,10 @@ public:
     return *this;
   }
 
+  bool operator==(const MachineOperand& rhs) const {
+    return regNum == rhs.regNum && opType == rhs.opType;
+  }
+
   // Accessor methods.  Caller is responsible for checking the
   // operand type before invoking the corresponding accessor.
   // 
@@ -282,8 +286,10 @@ public:
   }
 
   bool          isUse           () const { return flags & USEFLAG; }
+  bool          isEverUsed      (const MachineInstr&) const;
   bool         isDef           () const { return flags & DEFFLAG; }
   bool          isHiBits32      () const { return flags & HIFLAG32; }
+  bool          isEverDefined   (const MachineInstr&) const;
   bool          isLoBits32      () const { return flags & LOFLAG32; }
   bool          isHiBits64      () const { return flags & HIFLAG64; }
   bool          isLoBits64      () const { return flags & LOFLAG64; }
index 9d7b1b2d99f63371480df9568b1d31388634fe2f..869d963d53d04f74cc21d904c6dcfb82a08b8d6f 100644 (file)
@@ -27,6 +27,24 @@ namespace llvm {
 //
 extern const TargetInstrDescriptor *TargetInstrDescriptors;
 
+bool MachineOperand::isEverUsed(const MachineInstr& mi) const
+{
+    for (int i = 0, e = mi.getNumOperands(); i != e; ++i) {
+        if (*this == mi.getOperand(i) && mi.getOperand(i).isUse())
+            return true;
+    }
+    return false;
+}
+
+bool MachineOperand::isEverDefined(const MachineInstr& mi) const
+{
+    for (int i = 0, e = mi.getNumOperands(); i != e; ++i) {
+        if (*this == mi.getOperand(i) && mi.getOperand(i).isDef())
+            return true;
+    }
+    return false;
+}
+
 // Constructor for instructions with variable #operands
 MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned  numOperands)
   : opCode(OpCode),
index 26c1417fa0fa6d0be1be01be8f9eda850a23bca7..b71a13861627d47d9238145709692cc3b0837c75 100644 (file)
@@ -470,7 +470,8 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
             for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
                  i != e; ++i) {
                 MachineOperand& op = (*currentInstr_)->getOperand(i);
-                if (op.isVirtualRegister() && op.isUse() && !op.isDef()) {
+                if (op.isVirtualRegister() && op.isUse() &&
+                    !op.isEverDefined(**currentInstr_)) {
                     unsigned virtReg = op.getAllocatedRegNum();
                     unsigned physReg = 0;
                     Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
@@ -497,7 +498,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
             for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
                  i != e; ++i) {
                 MachineOperand& op = (*currentInstr_)->getOperand(i);
-                if (op.isVirtualRegister() && op.isDef()) {
+                if (op.isVirtualRegister()) {
+                    assert(op.isEverDefined(**currentInstr_) &&
+                           "operand should be defined by this instruction");
                     unsigned virtReg = op.getAllocatedRegNum();
                     unsigned physReg = 0;
                     Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
@@ -506,14 +509,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
                     }
                     else {
                         physReg = getFreeTempPhysReg(virtReg);
-                    }
-                    if (op.isUse()) { // def and use
-                        loadVirt2PhysReg(virtReg, physReg);
-                    }
-                    else {
                         assignVirt2PhysReg(virtReg, physReg);
+                        tempDefOperands_.push_back(virtReg);
                     }
-                    tempDefOperands_.push_back(virtReg);
                     (*currentInstr_)->SetMachineOperandReg(i, physReg);
                 }
             }
@@ -815,8 +813,6 @@ void RA::assignVirt2StackSlot(unsigned virtReg)
 
 int RA::getStackSlot(unsigned virtReg)
 {
-    // use lower_bound so that we can do a possibly O(1) insert later
-    // if necessary
     Virt2StackSlotMap::iterator it = v2ssMap_.find(virtReg);
     assert(it != v2ssMap_.end() &&
            "attempt to get stack slot on register that does not live on the stack");