When the coalescer is doing rematerializing, have it remove
authorDan Gohman <gohman@apple.com>
Tue, 21 Oct 2008 03:24:31 +0000 (03:24 +0000)
committerDan Gohman <gohman@apple.com>
Tue, 21 Oct 2008 03:24:31 +0000 (03:24 +0000)
the copy instruction from the instruction list before asking the
target to create the new instruction. This gets the old instruction
out of the way so that it doesn't interfere with the target's
rematerialization code. In the case of x86, this helps it find
more cases where EFLAGS is not live.

Also, in the X86InstrInfo.cpp, teach isSafeToClobberEFLAGS to check
to see if it reached the end of the block after scanning each
instruction, instead of just before. This lets it notice when the
end of the block is only two instructions away, without doing any
additional scanning.

These changes allow rematerialization to clobber EFLAGS in more
cases, for example using xor instead of mov to set the return value
to zero in the included testcase.

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

lib/CodeGen/SimpleRegisterCoalescing.cpp
lib/Target/X86/X86InstrInfo.cpp
test/CodeGen/X86/ret-i64-0.ll [new file with mode: 0644]

index 2f2d549a1952399af55145fdd07514e96018c2a7..6eeb21c1bf7cac8414dbeeaa40bdee997147b9db 100644 (file)
@@ -471,8 +471,9 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
     }
   }
 
-  MachineBasicBlock::iterator MII = CopyMI;
   MachineBasicBlock *MBB = CopyMI->getParent();
+  MachineBasicBlock::iterator MII = next(MachineBasicBlock::iterator(CopyMI));
+  CopyMI->removeFromParent();
   tii_->reMaterialize(*MBB, MII, DstReg, DefMI);
   MachineInstr *NewMI = prior(MII);
   // CopyMI may have implicit operands, transfer them over to the newly
@@ -491,7 +492,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
   }
 
   li_->ReplaceMachineInstrInMaps(CopyMI, NewMI);
-  CopyMI->eraseFromParent();
+  MBB->getParent()->DeleteMachineInstr(CopyMI);
   ReMatCopies.insert(CopyMI);
   ReMatDefs.insert(DefMI);
   ++NumReMats;
index b19c8b903159f27fc2ea1bfe515a317fda5aa580..84e113f885e1b63b6b53351cf5b4ccdad4b6f580 100644 (file)
@@ -848,12 +848,13 @@ X86InstrInfo::isReallyTriviallyReMaterializable(const MachineInstr *MI) const {
 /// two instructions it assumes it's not safe.
 static bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator I) {
+  // It's always safe to clobber EFLAGS at the end of a block.
+  if (I == MBB.end())
+    return true;
+
   // For compile time consideration, if we are not able to determine the
   // safety after visiting 2 instructions, we will assume it's not safe.
   for (unsigned i = 0; i < 2; ++i) {
-    if (I == MBB.end())
-      // Reached end of block, it's safe.
-      return true;
     bool SeenDef = false;
     for (unsigned j = 0, e = I->getNumOperands(); j != e; ++j) {
       MachineOperand &MO = I->getOperand(j);
@@ -870,6 +871,10 @@ static bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB,
       // This instruction defines EFLAGS, no need to look any further.
       return true;
     ++I;
+
+    // If we make it to the end of the block, it's safe to clobber EFLAGS.
+    if (I == MBB.end())
+      return true;
   }
 
   // Conservative answer.
diff --git a/test/CodeGen/X86/ret-i64-0.ll b/test/CodeGen/X86/ret-i64-0.ll
new file mode 100644 (file)
index 0000000..e62008f
--- /dev/null
@@ -0,0 +1,5 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep xor | count 2
+
+define i64 @foo() {
+  ret i64 0
+}