From 4bfc2097218e2386807336d3fc885905edbd7215 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 29 Jan 2009 05:41:02 +0000 Subject: [PATCH] Comments are good. :-) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63276 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/PreAllocSplitting.cpp | 33 ++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp index f4540889f6a..44819aabbab 100644 --- a/lib/CodeGen/PreAllocSplitting.cpp +++ b/lib/CodeGen/PreAllocSplitting.cpp @@ -1070,10 +1070,14 @@ unsigned PreAllocSplitting::getNumberOfNonSpills( bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { bool changed = false; + // Walk over all of the live intervals that were touched by the splitter, + // and see if we can do any DCE and/or folding. for (SmallPtrSet::iterator LI = split.begin(), LE = split.end(); LI != LE; ++LI) { DenseMap > VNUseCount; + // First, collect all the uses of the vreg, and sort them by their + // reaching definition (VNInfo). for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg), UE = MRI->use_end(); UI != UE; ++UI) { unsigned index = LIs->getInstructionIndex(&*UI); @@ -1083,6 +1087,8 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { VNUseCount[LR->valno].insert(&*UI); } + // Now, take the definitions (VNInfo's) one at a time and try to DCE + // and/or fold them away. for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(), VE = (*LI)->vni_end(); VI != VE; ++VI) { @@ -1090,15 +1096,24 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { return changed; VNInfo* CurrVN = *VI; + + // We don't currently try to handle definitions with PHI kills, because + // it would involve processing more than one VNInfo at once. if (CurrVN->hasPHIKill) continue; + // We also don't try to handle the results of PHI joins, since there's + // no defining instruction to analyze. unsigned DefIdx = CurrVN->def; if (DefIdx == ~0U || DefIdx == ~1U) continue; + // We're only interested in eliminating cruft introduced by the splitter, + // is of the form load-use or load-use-store. First, check that the + // definition is a load, and remember what stack slot we loaded it from. MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx); int FrameIndex; if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue; + // If the definition has no uses at all, just DCE it. if (VNUseCount[CurrVN].size() == 0) { LIs->RemoveMachineInstrFromMaps(DefMI); (*LI)->removeValNo(CurrVN); @@ -1108,12 +1123,17 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { continue; } + // Second, get the number of non-store uses of the definition, as well as + // a flag indicating whether it feeds into a later two-address definition. bool FeedsTwoAddr = false; unsigned NonSpillCount = getNumberOfNonSpills(VNUseCount[CurrVN], (*LI)->reg, FrameIndex, FeedsTwoAddr); + // If there's one non-store use and it doesn't feed a two-addr, then + // this is a load-use-store case that we can try to fold. if (NonSpillCount == 1 && !FeedsTwoAddr) { + // Start by finding the non-store use MachineInstr. SmallPtrSet::iterator UI = VNUseCount[CurrVN].begin(); int StoreFrameIndex; unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex); @@ -1123,17 +1143,15 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { if (UI != VNUseCount[CurrVN].end()) StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex); } - if (UI == VNUseCount[CurrVN].end()) continue; MachineInstr* use = *UI; + // Attempt to fold it away! int OpIdx = use->findRegisterUseOperandIdx((*LI)->reg, false); if (OpIdx == -1) continue; - SmallVector Ops; Ops.push_back(OpIdx); - if (!TII->canFoldMemoryOperand(use, Ops)) continue; MachineInstr* NewMI = @@ -1142,6 +1160,7 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { if (!NewMI) continue; + // Update relevant analyses. LIs->RemoveMachineInstrFromMaps(DefMI); LIs->ReplaceMachineInstrInMaps(use, NewMI); (*LI)->removeValNo(CurrVN); @@ -1151,9 +1170,14 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { NewMI = MBB->insert(MBB->erase(use), NewMI); VNUseCount[CurrVN].erase(use); + // Remove deleted instructions. Note that we need to remove them from + // the VNInfo->use map as well, just to be safe. for (SmallPtrSet::iterator II = VNUseCount[CurrVN].begin(), IE = VNUseCount[CurrVN].end(); II != IE; ++II) { + for (DenseMap >::iterator + VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI) + VI->second.erase(*II); LIs->RemoveMachineInstrFromMaps(*II); (*II)->eraseFromParent(); } @@ -1168,8 +1192,11 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { continue; } + // If there's more than one non-store instruction, we can't profitably + // fold it, so bail. if (NonSpillCount) continue; + // Otherwise, this is a load-store case, so DCE them. for (SmallPtrSet::iterator UI = VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end(); UI != UI; ++UI) {