Code refactoring.
[oota-llvm.git] / lib / CodeGen / CodePlacementOpt.cpp
1 //===-- CodePlacementOpt.cpp - Code Placement pass. -----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the pass that optimize code placement and align loop
11 // headers to target specific alignment boundary.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "code-placement"
16 #include "llvm/CodeGen/MachineLoopInfo.h"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/Target/TargetLowering.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Debug.h"
23 using namespace llvm;
24
25 namespace {
26   class CodePlacementOpt : public MachineFunctionPass {
27     const MachineLoopInfo *MLI;
28
29   public:
30     static char ID;
31     CodePlacementOpt() : MachineFunctionPass(&ID) {}
32
33     virtual bool runOnMachineFunction(MachineFunction &MF);
34     virtual const char *getPassName() const {
35       return "Code Placement Optimizater";
36     }
37
38     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
39       AU.addRequired<MachineLoopInfo>();
40       AU.addPreserved<MachineLoopInfo>();
41       AU.addPreservedID(MachineDominatorsID);
42       MachineFunctionPass::getAnalysisUsage(AU);
43     }
44
45   private:
46     bool AlignLoops(MachineFunction &MF);
47   };
48
49   char CodePlacementOpt::ID = 0;
50 } // end anonymous namespace
51
52 FunctionPass *llvm::createCodePlacementOptPass() {
53   return new CodePlacementOpt();
54 }
55
56 /// AlignLoops - Align loop headers to target preferred alignments.
57 ///
58 bool CodePlacementOpt::AlignLoops(MachineFunction &MF) {
59   const TargetLowering *TLI = MF.getTarget().getTargetLowering();
60   if (!TLI)
61     return false;
62
63   unsigned Align = TLI->getPrefLoopAlignment();
64   if (!Align)
65     return false;  // Don't care about loop alignment.
66
67   const Function *F = MF.getFunction();
68   if (F->hasFnAttr(Attribute::OptimizeForSize))
69     return false;
70
71   bool Changed = false;
72   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
73     MachineBasicBlock *MBB = I;
74     if (MLI->isLoopHeader(MBB)) {
75       MachineBasicBlock *PredBB = prior(I);
76       if (MLI->getLoopFor(MBB) == MLI->getLoopFor(PredBB))
77         // If previously BB is in the same loop, don't align this BB. We want
78         // to prevent adding noop's inside a loop.
79         continue;
80       MBB->setAlignment(Align);
81       Changed = true;
82     }
83   }
84
85   return Changed;
86 }
87
88 bool CodePlacementOpt::runOnMachineFunction(MachineFunction &MF) {
89   MLI = &getAnalysis<MachineLoopInfo>();
90   if (MLI->empty())
91     return false;  // No loops.
92
93   bool Changed = false;
94   Changed |= AlignLoops(MF);
95
96   return Changed;
97 }