summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-10-16 00:22:51 +0000
committerAndrew Trick <atrick@apple.com>2012-10-16 00:22:51 +0000
commit27c28cef11da5373d9a146060f9c10a3c6ab58e3 (patch)
tree161cadfaad5b7070fea7b421c0db22404a659ca0
parentfeab72c20acc97f8942148189c06e443b29df841 (diff)
misched: Added handleMove support for updating all kill flags, not just for allocatable regs.
This is a medium term workaround until we have a more robust solution in the form of a register liveness utility for postRA passes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166001 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h9
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp27
-rw-r--r--lib/CodeGen/MachineScheduler.cpp2
-rw-r--r--test/CodeGen/X86/misched-new.ll29
4 files changed, 55 insertions, 12 deletions
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index a04c9029e41..73def2cd1d6 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -260,15 +260,20 @@ namespace llvm {
/// instruction 'mi' has been moved within a basic block. This will update
/// the live intervals for all operands of mi. Moves between basic blocks
/// are not supported.
- void handleMove(MachineInstr* MI);
+ ///
+ /// \param updateFlags Update live intervals for nonallocatable physregs.
+ void handleMove(MachineInstr* MI, bool UpdateFlags = false);
/// moveIntoBundle - Update intervals for operands of MI so that they
/// begin/end on the SlotIndex for BundleStart.
///
+ /// \param updateFlags Update live intervals for nonallocatable physregs.
+ ///
/// Requires MI and BundleStart to have SlotIndexes, and assumes
/// existing liveness is accurate. BundleStart should be the first
/// instruction in the Bundle.
- void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart);
+ void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
+ bool UpdateFlags = false);
// Register mask functions.
//
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 15fc69db308..65bc4af99e2 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1011,12 +1011,24 @@ private:
SlotIndex OldIdx;
SlotIndex NewIdx;
SmallPtrSet<LiveInterval*, 8> Updated;
+ bool UpdateFlags;
public:
HMEditor(LiveIntervals& LIS, const MachineRegisterInfo& MRI,
const TargetRegisterInfo& TRI,
- SlotIndex OldIdx, SlotIndex NewIdx)
- : LIS(LIS), MRI(MRI), TRI(TRI), OldIdx(OldIdx), NewIdx(NewIdx) {}
+ SlotIndex OldIdx, SlotIndex NewIdx, bool UpdateFlags)
+ : LIS(LIS), MRI(MRI), TRI(TRI), OldIdx(OldIdx), NewIdx(NewIdx),
+ UpdateFlags(UpdateFlags) {}
+
+ // FIXME: UpdateFlags is a workaround that creates live intervals for all
+ // physregs, even those that aren't needed for regalloc, in order to update
+ // kill flags. This is wasteful. Eventually, LiveVariables will strip all kill
+ // flags, and postRA passes will use a live register utility instead.
+ LiveInterval *getRegUnitLI(unsigned Unit) {
+ if (UpdateFlags)
+ return &LIS.getRegUnit(Unit);
+ return LIS.getCachedRegUnit(Unit);
+ }
/// Update all live ranges touched by MI, assuming a move from OldIdx to
/// NewIdx.
@@ -1044,7 +1056,7 @@ public:
// For physregs, only update the regunits that actually have a
// precomputed live range.
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
- if (LiveInterval *LI = LIS.getCachedRegUnit(*Units))
+ if (LiveInterval *LI = getRegUnitLI(*Units))
updateRange(*LI);
}
if (hasRegMask)
@@ -1288,7 +1300,7 @@ private:
}
};
-void LiveIntervals::handleMove(MachineInstr* MI) {
+void LiveIntervals::handleMove(MachineInstr* MI, bool UpdateFlags) {
assert(!MI->isBundled() && "Can't handle bundled instructions yet.");
SlotIndex OldIndex = Indexes->getInstructionIndex(MI);
Indexes->removeMachineInstrFromMaps(MI);
@@ -1297,14 +1309,15 @@ void LiveIntervals::handleMove(MachineInstr* MI) {
OldIndex < getMBBEndIdx(MI->getParent()) &&
"Cannot handle moves across basic block boundaries.");
- HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex);
+ HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex, UpdateFlags);
HME.updateAllRanges(MI);
}
void LiveIntervals::handleMoveIntoBundle(MachineInstr* MI,
- MachineInstr* BundleStart) {
+ MachineInstr* BundleStart,
+ bool UpdateFlags) {
SlotIndex OldIndex = Indexes->getInstructionIndex(MI);
SlotIndex NewIndex = Indexes->getInstructionIndex(BundleStart);
- HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex);
+ HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex, UpdateFlags);
HME.updateAllRanges(MI);
}
diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp
index 74190e93541..c55e8b78988 100644
--- a/lib/CodeGen/MachineScheduler.cpp
+++ b/lib/CodeGen/MachineScheduler.cpp
@@ -360,7 +360,7 @@ void ScheduleDAGMI::moveInstruction(MachineInstr *MI,
BB->splice(InsertPos, BB, MI);
// Update LiveIntervals
- LIS->handleMove(MI);
+ LIS->handleMove(MI, /*UpdateFlags=*/true);
// Recede RegionBegin if an instruction moves above the first.
if (RegionBegin == InsertPos)
diff --git a/test/CodeGen/X86/misched-new.ll b/test/CodeGen/X86/misched-new.ll
index 6dfb3e36ed7..cec04b534fb 100644
--- a/test/CodeGen/X86/misched-new.ll
+++ b/test/CodeGen/X86/misched-new.ll
@@ -1,5 +1,6 @@
-; RUN: llc < %s -march=x86-64 -mcpu=core2 -enable-misched \
-; RUN: -misched=shuffle -misched-bottomup | FileCheck %s
+; RUN: llc < %s -march=x86-64 -mcpu=core2 -x86-early-ifcvt -enable-misched \
+; RUN: -misched=shuffle -misched-bottomup -verify-machineinstrs \
+; RUN: | FileCheck %s
; REQUIRES: asserts
;
; Interesting MachineScheduler cases.
@@ -26,3 +27,27 @@ for.cond.preheader: ; preds = %entry
if.end: ; preds = %entry
ret void
}
+
+; The machine verifier checks that EFLAGS kill flags are updated when
+; the scheduler reorders cmovel instructions.
+;
+; CHECK: test
+; CHECK: cmovel
+; CHECK: cmovel
+; CHECK: call
+define void @foo(i32 %b) nounwind uwtable ssp {
+entry:
+ %tobool = icmp ne i32 %b, 0
+ br i1 %tobool, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %v1 = phi i32 [1, %entry], [2, %if.then]
+ %v2 = phi i32 [3, %entry], [4, %if.then]
+ call void @bar(i32 %v1, i32 %v2)
+ ret void
+}
+
+declare void @bar(i32,i32)