X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FCodePlacementOpt.cpp;h=383098e11efdc3d0b470b11803357c5abb208429;hb=74d3f50a803347432b3dc26f67e23297c2a1f232;hp=f6a8421c43480a69486bb4832ee62a555334aa1b;hpb=0ab2dcee5bf751211ca1fc49decb1540b4cb427c;p=oota-llvm.git diff --git a/lib/CodeGen/CodePlacementOpt.cpp b/lib/CodeGen/CodePlacementOpt.cpp index f6a8421c434..383098e11ef 100644 --- a/lib/CodeGen/CodePlacementOpt.cpp +++ b/lib/CodeGen/CodePlacementOpt.cpp @@ -19,17 +19,11 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" using namespace llvm; -static cl::opt -OptLoopBBPlacement("opt-loop-bb-placement", - cl::init(false), cl::Hidden, - cl::desc("Optimize block placements in loops")); - STATISTIC(NumHeaderAligned, "Number of loop header aligned"); STATISTIC(NumIntraElim, "Number of intra loop branches eliminated"); STATISTIC(NumIntraMoved, "Number of intra loop branches moved"); @@ -68,6 +62,8 @@ namespace { private: bool OptimizeIntraLoopEdges(); + bool HeaderShouldBeAligned(MachineBasicBlock *MBB, MachineLoop *L, + SmallPtrSet &DoNotAlign); bool AlignLoops(MachineFunction &MF); }; @@ -108,7 +104,7 @@ FunctionPass *llvm::createCodePlacementOptPass() { /// jcc C, [exit] /// bool CodePlacementOpt::OptimizeIntraLoopEdges() { - if (!OptLoopBBPlacement) + if (!TLI->shouldOptimizeCodePlacement()) return false; bool Changed = false; @@ -138,6 +134,7 @@ bool CodePlacementOpt::OptimizeIntraLoopEdges() { TII->RemoveBranch(*MBB); ChangedMBBs.insert(MBB); ++NumIntraElim; + Changed = true; continue; } @@ -164,10 +161,10 @@ bool CodePlacementOpt::OptimizeIntraLoopEdges() { // A fallthrough. FtMBB = PredMBB; MachineLoop *PL = MLI->getLoopFor(PredMBB); - if (PL && (PL == L || PL->getLoopDepth() >= L->getLoopDepth())) { + if (PL && (PL == L || PL->getLoopDepth() >= L->getLoopDepth())) OkToMove = false; - break; - } + + break; } } @@ -211,7 +208,8 @@ bool CodePlacementOpt::OptimizeIntraLoopEdges() { } else if (!FBB && SSMBB == TBB && Cond.empty()) { TBB = 0; --Cost; - } else if (!TII->ReverseBranchCondition(Cond)) { + } else if (!Cond.empty() && !TII->ReverseBranchCondition(Cond)) { + assert(SSMBB == TBB); TBB = FBB; FBB = 0; --Cost; @@ -234,6 +232,7 @@ bool CodePlacementOpt::OptimizeIntraLoopEdges() { TII->InsertBranch(*FtMBB, FtTBB, FtFBB, FtCond); ChangedMBBs.insert(FtMBB); } + Changed = true; // If BB is the loop latch, we may have a new loop headr. if (MBB == L->getLoopLatch()) { @@ -248,6 +247,43 @@ bool CodePlacementOpt::OptimizeIntraLoopEdges() { return Changed; } +/// HeaderShouldBeAligned - Return true if the specified loop header block +/// should be aligned. For now, we will not align it if all the predcessors +/// (i.e. loop back edges) are laid out above the header. FIXME: Do not +/// align small loops. +bool +CodePlacementOpt::HeaderShouldBeAligned(MachineBasicBlock *MBB, MachineLoop *L, + SmallPtrSet &DoNotAlign) { + if (DoNotAlign.count(MBB)) + return false; + + bool BackEdgeBelow = false; + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + MachineBasicBlock *PredMBB = *PI; + if (PredMBB == MBB || PredMBB->getNumber() > MBB->getNumber()) { + BackEdgeBelow = true; + break; + } + } + + if (!BackEdgeBelow) + return false; + + // Ok, we are going to align this loop header. If it's an inner loop, + // do not align its outer loop. + MachineBasicBlock *PreHeader = L->getLoopPreheader(); + if (PreHeader) { + MachineLoop *L = MLI->getLoopFor(PreHeader); + if (L) { + MachineBasicBlock *HeaderBlock = L->getHeader(); + HeaderBlock->setAlignment(0); + DoNotAlign.insert(HeaderBlock); + } + } + return true; +} + /// AlignLoops - Align loop headers to target preferred alignments. /// bool CodePlacementOpt::AlignLoops(MachineFunction &MF) { @@ -263,12 +299,16 @@ bool CodePlacementOpt::AlignLoops(MachineFunction &MF) { MF.RenumberBlocks(); bool Changed = false; + SmallPtrSet DoNotAlign; for (unsigned i = 0, e = LoopHeaders.size(); i != e; ++i) { MachineBasicBlock *HeaderMBB = LoopHeaders[i]; MachineBasicBlock *PredMBB = prior(MachineFunction::iterator(HeaderMBB)); - if (MLI->getLoopFor(HeaderMBB) != MLI->getLoopFor(PredMBB)) { + MachineLoop *L = MLI->getLoopFor(HeaderMBB); + if (L == MLI->getLoopFor(PredMBB)) // If previously BB is in the same loop, don't align this BB. We want // to prevent adding noop's inside a loop. + continue; + if (HeaderShouldBeAligned(HeaderMBB, L, DoNotAlign)) { HeaderMBB->setAlignment(Align); Changed = true; ++NumHeaderAligned;