54121afefda09bd8b3c1cbea9891cf59f0f638b2
[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   public:
28     static char ID;
29     CodePlacementOpt() : MachineFunctionPass(&ID) {}
30
31     virtual bool runOnMachineFunction(MachineFunction &MF);
32     virtual const char *getPassName() const {
33       return "Code Placement Optimizater";
34     }
35
36     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
37       AU.addRequired<MachineLoopInfo>();
38       AU.addPreserved<MachineLoopInfo>();
39       AU.addPreservedID(MachineDominatorsID);
40       MachineFunctionPass::getAnalysisUsage(AU);
41     }
42   };
43
44   char CodePlacementOpt::ID = 0;
45 } // end anonymous namespace
46
47 FunctionPass *llvm::createCodePlacementOptPass() {
48   return new CodePlacementOpt();
49 }
50
51 bool CodePlacementOpt::runOnMachineFunction(MachineFunction &MF) {
52   const MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfo>();
53
54   if (MLI->empty())
55     return false;  // No loops.
56
57   const TargetLowering *TLI = MF.getTarget().getTargetLowering();
58   if (!TLI)
59     return false;
60
61   unsigned Align = TLI->getPrefLoopAlignment();
62   if (!Align)
63     return false;  // Don't care about loop alignment.
64
65   const Function *F = MF.getFunction();
66   if (F->hasFnAttr(Attribute::OptimizeForSize))
67     return false;
68
69   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
70     MachineBasicBlock *MBB = I;
71     if (MLI->isLoopHeader(MBB)) {
72       MachineBasicBlock *PredBB = prior(I);
73       if (MLI->getLoopFor(MBB) == MLI->getLoopFor(PredBB))
74         // If previously BB is in the same loop, don't align this BB. We want
75         // to prevent adding noop's inside a loop.
76         continue;
77       MBB->setAlignment(Align);
78     }
79   }
80
81   return true;
82 }