aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-10-21 03:24:31 +0000
committerDan Gohman <gohman@apple.com>2008-10-21 03:24:31 +0000
commit3588f9d4ef8b209133e73ea01fd961e0187ba279 (patch)
tree3e4f2b16af3207fcc5650930342133e53eac4ee6
parent2b5b9ca56863e3614be22708e7a3fd9faffcdc71 (diff)
downloadexternal_llvm-3588f9d4ef8b209133e73ea01fd961e0187ba279.zip
external_llvm-3588f9d4ef8b209133e73ea01fd961e0187ba279.tar.gz
external_llvm-3588f9d4ef8b209133e73ea01fd961e0187ba279.tar.bz2
When the coalescer is doing rematerializing, have it remove
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
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp5
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp11
-rw-r--r--test/CodeGen/X86/ret-i64-0.ll5
3 files changed, 16 insertions, 5 deletions
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 2f2d549..6eeb21c 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -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;
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index b19c8b9..84e113f 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -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
index 0000000..e62008f
--- /dev/null
+++ b/test/CodeGen/X86/ret-i64-0.ll
@@ -0,0 +1,5 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep xor | count 2
+
+define i64 @foo() {
+ ret i64 0
+}