cd396cc2eae477d822fef1e82dd89aa3bc508719
[oota-llvm.git] / lib / CodeGen / OptimizeCmps.cpp
1 //===-- OptimizeCmps.cpp - Optimize comparison instrs ---------------------===//
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 pass performs optimization of comparison instructions. For instance, in
11 // this code:
12 //
13 //     sub r1, 1
14 //     cmp r1, 0
15 //     bz  L1
16 //
17 // If the "sub" instruction all ready sets (or could be modified to set) the
18 // same flag that the "cmp" instruction sets and that "bz" uses, then we can
19 // eliminate the "cmp" instruction.
20 //
21 //===----------------------------------------------------------------------===//
22
23 #define DEBUG_TYPE "opt-compares"
24 #include "llvm/CodeGen/Passes.h"
25 #include "llvm/CodeGen/MachineFunctionPass.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/Target/TargetInstrInfo.h"
29 #include "llvm/Target/TargetRegisterInfo.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/ADT/Statistic.h"
32 using namespace llvm;
33
34 STATISTIC(NumEliminated, "Number of compares eliminated");
35
36 static cl::opt<bool>
37 EnableOptCmps("enable-optimize-cmps", cl::init(false), cl::Hidden);
38
39 namespace {
40   class OptimizeCmps : public MachineFunctionPass {
41     const TargetMachine   *TM;
42     const TargetInstrInfo *TII;
43     MachineRegisterInfo   *MRI;
44
45     bool OptimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB);
46
47   public:
48     static char ID; // Pass identification
49     OptimizeCmps() : MachineFunctionPass(&ID) {}
50
51     virtual bool runOnMachineFunction(MachineFunction &MF);
52
53     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
54       AU.setPreservesCFG();
55       MachineFunctionPass::getAnalysisUsage(AU);
56     }
57   };
58 }
59
60 char OptimizeCmps::ID = 0;
61 INITIALIZE_PASS(OptimizeCmps, "opt-cmps",
62                 "Optimize comparison instrs", false, false);
63
64 FunctionPass *llvm::createOptimizeCmpsPass() { return new OptimizeCmps(); }
65
66 /// OptimizeCmpInstr - If the instruction is a compare and the previous
67 /// instruction it's comparing against all ready sets (or could be modified to
68 /// set) the same flag as the compare, then we can remove the comparison and use
69 /// the flag from the previous instruction.
70 bool OptimizeCmps::OptimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB) {
71   // If this instruction is a comparison against zero and isn't comparing a
72   // physical register, we can try to optimize it.
73   unsigned SrcReg;
74   int CmpValue;
75   if (!TII->isCompareInstr(MI, SrcReg, CmpValue) ||
76       TargetRegisterInfo::isPhysicalRegister(SrcReg) ||
77       CmpValue != 0)
78     return false;
79
80   MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg);
81   if (llvm::next(DI) != MRI->def_end())
82     // Only support one definition.
83     return false;
84
85   // Attempt to convert the defining instruction to set the "zero" flag.
86   if (TII->convertToSetZeroFlag(&*DI, MI)) {
87     ++NumEliminated;
88     return true;
89   }
90
91   return false;
92 }
93
94 bool OptimizeCmps::runOnMachineFunction(MachineFunction &MF) {
95   TM = &MF.getTarget();
96   TII = TM->getInstrInfo();
97   MRI = &MF.getRegInfo();
98
99   if (!EnableOptCmps) return false;
100
101   bool Changed = false;
102   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
103     MachineBasicBlock *MBB = &*I;
104     for (MachineBasicBlock::iterator
105            MII = MBB->begin(), ME = MBB->end(); MII != ME; ) {
106       MachineInstr *MI = &*MII++;
107       Changed |= OptimizeCmpInstr(MI, MBB);
108     }
109   }
110
111   return Changed;
112 }