[llvm-commits] [llvm] r63274 - /llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp
Owen Anderson
resistor at mac.com
Wed Jan 28 21:28:55 PST 2009
Author: resistor
Date: Wed Jan 28 23:28:55 2009
New Revision: 63274
URL: http://llvm.org/viewvc/llvm-project?rev=63274&view=rev
Log:
Add support for aggressive load-use-store folding. This takes care of the
vast majority of code size regressions introduced by pre-alloc-splitting.
Modified:
llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp
Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=63274&r1=63273&r2=63274&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original)
+++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Wed Jan 28 23:28:55 2009
@@ -37,8 +37,9 @@
using namespace llvm;
static cl::opt<int> PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden);
+static cl::opt<int> DeadSplitLimit("dead-split-limit", cl::init(-1), cl::Hidden);
-STATISTIC(NumTotalSplits, "Number of intervals split");
+STATISTIC(NumSplits, "Number of intervals split");
STATISTIC(NumRemats, "Number of intervals split by rematerialization");
STATISTIC(NumFolds, "Number of intervals split with spill folding");
STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers");
@@ -77,8 +78,6 @@
// Def2SpillMap - A map from a def instruction index to spill index.
DenseMap<unsigned, unsigned> Def2SpillMap;
-
- unsigned NumSplits;
public:
static char ID;
@@ -162,8 +161,8 @@
void RenumberValno(VNInfo* VN);
void ReconstructLiveInterval(LiveInterval* LI);
bool removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split);
- unsigned getNumberOfSpills(SmallPtrSet<MachineInstr*, 4>& MIs,
- unsigned Reg, int FrameIndex);
+ unsigned getNumberOfNonSpills(SmallPtrSet<MachineInstr*, 4>& MIs,
+ unsigned Reg, int FrameIndex, bool& TwoAddr);
VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use,
MachineBasicBlock* MBB,
LiveInterval* LI,
@@ -789,6 +788,10 @@
MO.setReg(NewVReg);
}
+ // The renumbered vreg shares a stack slot with the old register.
+ if (IntervalSSMap.count(CurrLI->reg))
+ IntervalSSMap[NewVReg] = IntervalSSMap[CurrLI->reg];
+
NumRenumbers++;
}
@@ -1042,19 +1045,24 @@
return Change;
}
-unsigned PreAllocSplitting::getNumberOfSpills(
+unsigned PreAllocSplitting::getNumberOfNonSpills(
SmallPtrSet<MachineInstr*, 4>& MIs,
- unsigned Reg, int FrameIndex) {
- unsigned Spills = 0;
+ unsigned Reg, int FrameIndex,
+ bool& FeedsTwoAddr) {
+ unsigned NonSpills = 0;
for (SmallPtrSet<MachineInstr*, 4>::iterator UI = MIs.begin(), UE = MIs.end();
- UI != UI; ++UI) {
+ UI != UE; ++UI) {
int StoreFrameIndex;
unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
- if (StoreVReg == Reg && StoreFrameIndex == FrameIndex)
- Spills++;
+ if (StoreVReg != Reg || StoreFrameIndex != FrameIndex)
+ NonSpills++;
+
+ int DefIdx = (*UI)->findRegisterDefOperandIdx(Reg);
+ if (DefIdx != -1 && (*UI)->isRegReDefinedByTwoAddr(DefIdx))
+ FeedsTwoAddr = true;
}
- return Spills;
+ return NonSpills;
}
/// removeDeadSpills - After doing splitting, filter through all intervals we've
@@ -1077,6 +1085,10 @@
for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(),
VE = (*LI)->vni_end(); VI != VE; ++VI) {
+
+ if (DeadSplitLimit != -1 && (int)NumDeadSpills == DeadSplitLimit)
+ return changed;
+
VNInfo* CurrVN = *VI;
if (CurrVN->hasPHIKill) continue;
@@ -1096,9 +1108,67 @@
continue;
}
- unsigned SpillCount = getNumberOfSpills(VNUseCount[CurrVN],
- (*LI)->reg, FrameIndex);
- if (SpillCount != VNUseCount[CurrVN].size()) continue;
+ bool FeedsTwoAddr = false;
+ unsigned NonSpillCount = getNumberOfNonSpills(VNUseCount[CurrVN],
+ (*LI)->reg, FrameIndex,
+ FeedsTwoAddr);
+
+ if (NonSpillCount == 1 && !FeedsTwoAddr) {
+ SmallPtrSet<MachineInstr*, 4>::iterator UI = VNUseCount[CurrVN].begin();
+ int StoreFrameIndex;
+ unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
+ while (UI != VNUseCount[CurrVN].end() &&
+ (StoreVReg == (*LI)->reg && StoreFrameIndex == FrameIndex)) {
+ ++UI;
+ if (UI != VNUseCount[CurrVN].end())
+ StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
+ }
+
+ if (UI == VNUseCount[CurrVN].end()) continue;
+
+ MachineInstr* use = *UI;
+
+ int OpIdx = use->findRegisterUseOperandIdx((*LI)->reg, false);
+ if (OpIdx == -1) continue;
+
+ SmallVector<unsigned, 1> Ops;
+ Ops.push_back(OpIdx);
+
+ if (!TII->canFoldMemoryOperand(use, Ops)) continue;
+
+ MachineInstr* NewMI =
+ TII->foldMemoryOperand(*use->getParent()->getParent(),
+ use, Ops, FrameIndex);
+
+ if (!NewMI) continue;
+
+ LIs->RemoveMachineInstrFromMaps(DefMI);
+ LIs->ReplaceMachineInstrInMaps(use, NewMI);
+ (*LI)->removeValNo(CurrVN);
+
+ DefMI->eraseFromParent();
+ MachineBasicBlock* MBB = use->getParent();
+ NewMI = MBB->insert(MBB->erase(use), NewMI);
+ VNUseCount[CurrVN].erase(use);
+
+ for (SmallPtrSet<MachineInstr*, 4>::iterator II =
+ VNUseCount[CurrVN].begin(), IE = VNUseCount[CurrVN].end();
+ II != IE; ++II) {
+ LIs->RemoveMachineInstrFromMaps(*II);
+ (*II)->eraseFromParent();
+ }
+
+ for (DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> >::iterator
+ VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI)
+ if (VI->second.erase(use))
+ VI->second.insert(NewMI);
+
+ NumDeadSpills++;
+ changed = true;
+ continue;
+ }
+
+ if (NonSpillCount) continue;
for (SmallPtrSet<MachineInstr*, 4>::iterator UI =
VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end();
@@ -1193,7 +1263,6 @@
LSs = &getAnalysis<LiveStacks>();
bool MadeChange = false;
- NumSplits = 0;
// Make sure blocks are numbered in order.
MF.RenumberBlocks();
@@ -1220,9 +1289,6 @@
}
MadeChange |= removeDeadSpills(Split);
-
- if (NumSplits)
- NumTotalSplits += NumSplits;
return MadeChange;
}
More information about the llvm-commits
mailing list