1 //===-- OptimizeCmps.cpp - Optimize comparison instrs ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This pass performs optimization of comparison instructions. For instance, in
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.
21 //===----------------------------------------------------------------------===//
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"
34 STATISTIC(NumEliminated, "Number of compares eliminated");
37 EnableOptCmps("enable-optimize-cmps", cl::init(false), cl::Hidden);
40 class OptimizeCmps : public MachineFunctionPass {
41 const TargetMachine *TM;
42 const TargetInstrInfo *TII;
43 MachineRegisterInfo *MRI;
45 bool OptimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB);
48 static char ID; // Pass identification
49 OptimizeCmps() : MachineFunctionPass(&ID) {}
51 virtual bool runOnMachineFunction(MachineFunction &MF);
53 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
55 MachineFunctionPass::getAnalysisUsage(AU);
60 char OptimizeCmps::ID = 0;
61 INITIALIZE_PASS(OptimizeCmps, "opt-cmps",
62 "Optimize comparison instrs", false, false);
64 FunctionPass *llvm::createOptimizeCmpsPass() { return new OptimizeCmps(); }
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.
75 if (!TII->isCompareInstr(MI, SrcReg, CmpValue) ||
76 TargetRegisterInfo::isPhysicalRegister(SrcReg) ||
80 MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg);
81 if (llvm::next(DI) != MRI->def_end())
82 // Only support one definition.
85 // Attempt to convert the defining instruction to set the "zero" flag.
86 if (TII->convertToSetZeroFlag(&*DI, MI)) {
94 bool OptimizeCmps::runOnMachineFunction(MachineFunction &MF) {
96 TII = TM->getInstrInfo();
97 MRI = &MF.getRegInfo();
99 if (!EnableOptCmps) return false;
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);