blob: cd396cc2eae477d822fef1e82dd89aa3bc508719 [file] [log] [blame]
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001//===-- 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"
32using namespace llvm;
33
34STATISTIC(NumEliminated, "Number of compares eliminated");
35
36static cl::opt<bool>
37EnableOptCmps("enable-optimize-cmps", cl::init(false), cl::Hidden);
38
39namespace {
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
60char OptimizeCmps::ID = 0;
61INITIALIZE_PASS(OptimizeCmps, "opt-cmps",
62 "Optimize comparison instrs", false, false);
63
64FunctionPass *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.
70bool 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
94bool 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}