[llvm-commits] [llvm] r110423 - in /llvm/trunk: include/llvm/CodeGen/Passes.h include/llvm/Target/TargetInstrInfo.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/OptimizeCmps.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMBaseInstrInfo.h
Evan Cheng
evan.cheng at apple.com
Fri Aug 6 18:10:23 PDT 2010
On Aug 6, 2010, at 2:24 PM, Chris Lattner wrote:
>
> On Aug 5, 2010, at 6:32 PM, Bill Wendling wrote:
>
>> Author: void
>> Date: Thu Aug 5 20:32:48 2010
>> New Revision: 110423
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=110423&view=rev
>> Log:
>> Add the Optimize Compares pass (disabled by default).
>
> Why do we need an entire new pass to do this? Isn't this just a form of CSE? Why doesn't it go in the MachineCSE pass?
I didn't think of it. That's an interesting idea.
Evan
>
> -Chris
>
>
>>
>> This pass tries to remove comparison instructions when possible. For instance,
>> if you have this code:
>>
>> sub r1, 1
>> cmp r1, 0
>> bz L1
>>
>> and "sub" either sets the same flag as the "cmp" instruction or could be
>> converted to set the same flag, then we can eliminate the "cmp" instruction all
>> together. This is a important for ARM where the ALU instructions could set the
>> CPSR flag, but need a special suffix ('s') to do so.
>>
>> Added:
>> llvm/trunk/lib/CodeGen/OptimizeCmps.cpp
>> Modified:
>> llvm/trunk/include/llvm/CodeGen/Passes.h
>> llvm/trunk/include/llvm/Target/TargetInstrInfo.h
>> llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
>> llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
>> llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
>>
>> Modified: llvm/trunk/include/llvm/CodeGen/Passes.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=110423&r1=110422&r2=110423&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/CodeGen/Passes.h (original)
>> +++ llvm/trunk/include/llvm/CodeGen/Passes.h Thu Aug 5 20:32:48 2010
>> @@ -180,6 +180,10 @@
>> /// to take advantage of opportunities created during DAG legalization.
>> FunctionPass *createOptimizePHIsPass();
>>
>> + /// createOptimizeCmpsPass - This pass performs redundant comparison removal
>> + /// optimization.
>> + FunctionPass *createOptimizeCmpsPass();
>> +
>> /// createStackSlotColoringPass - This pass performs stack slot coloring.
>> FunctionPass *createStackSlotColoringPass(bool);
>>
>>
>> Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=110423&r1=110422&r2=110423&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original)
>> +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Thu Aug 5 20:32:48 2010
>> @@ -576,6 +576,21 @@
>> /// register allocation.
>> virtual ScheduleHazardRecognizer*
>> CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const = 0;
>> +
>> + /// isCompareInstr - If the machine instruction is a comparison instruction,
>> + /// then return true. Also return the source register in SrcReg and the value
>> + /// it compares against in CmpValue.
>> + virtual bool isCompareInstr(const MachineInstr *MI,
>> + unsigned &SrcReg, int &CmpValue) const {
>> + return false;
>> + }
>> +
>> + /// convertToSetZeroFlag - Convert the instruction to set the zero flag so
>> + /// that we can remove a "comparison with zero".
>> + virtual bool convertToSetZeroFlag(MachineInstr *Instr,
>> + MachineInstr *CmpInstr) const {
>> + return false;
>> + }
>> };
>>
>> /// TargetInstrInfoImpl - This is the default implementation of
>>
>> Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=110423&r1=110422&r2=110423&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Thu Aug 5 20:32:48 2010
>> @@ -354,6 +354,7 @@
>> printAndVerify(PM, "After codegen DCE pass");
>>
>> PM.add(createOptimizeExtsPass());
>> + PM.add(createOptimizeCmpsPass());
>> if (!DisableMachineLICM)
>> PM.add(createMachineLICMPass());
>> PM.add(createMachineCSEPass());
>>
>> Added: llvm/trunk/lib/CodeGen/OptimizeCmps.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/OptimizeCmps.cpp?rev=110423&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/OptimizeCmps.cpp (added)
>> +++ llvm/trunk/lib/CodeGen/OptimizeCmps.cpp Thu Aug 5 20:32:48 2010
>> @@ -0,0 +1,112 @@
>> +//===-- OptimizeCmps.cpp - Optimize comparison instrs ---------------------===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +//
>> +// This pass performs optimization of comparison instructions. For instance, in
>> +// this code:
>> +//
>> +// sub r1, 1
>> +// cmp r1, 0
>> +// bz L1
>> +//
>> +// If the "sub" instruction all ready sets (or could be modified to set) the
>> +// same flag that the "cmp" instruction sets and that "bz" uses, then we can
>> +// eliminate the "cmp" instruction.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +#define DEBUG_TYPE "opt-compares"
>> +#include "llvm/CodeGen/Passes.h"
>> +#include "llvm/CodeGen/MachineFunctionPass.h"
>> +#include "llvm/CodeGen/MachineInstrBuilder.h"
>> +#include "llvm/CodeGen/MachineRegisterInfo.h"
>> +#include "llvm/Target/TargetInstrInfo.h"
>> +#include "llvm/Target/TargetRegisterInfo.h"
>> +#include "llvm/Support/CommandLine.h"
>> +#include "llvm/ADT/Statistic.h"
>> +using namespace llvm;
>> +
>> +STATISTIC(NumEliminated, "Number of compares eliminated");
>> +
>> +static cl::opt<bool>
>> +EnableOptCmps("enable-optimize-cmps", cl::init(false), cl::Hidden);
>> +
>> +namespace {
>> + class OptimizeCmps : public MachineFunctionPass {
>> + const TargetMachine *TM;
>> + const TargetInstrInfo *TII;
>> + MachineRegisterInfo *MRI;
>> +
>> + bool OptimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB);
>> +
>> + public:
>> + static char ID; // Pass identification
>> + OptimizeCmps() : MachineFunctionPass(&ID) {}
>> +
>> + virtual bool runOnMachineFunction(MachineFunction &MF);
>> +
>> + virtual void getAnalysisUsage(AnalysisUsage &AU) const {
>> + AU.setPreservesCFG();
>> + MachineFunctionPass::getAnalysisUsage(AU);
>> + }
>> + };
>> +}
>> +
>> +char OptimizeCmps::ID = 0;
>> +INITIALIZE_PASS(OptimizeCmps, "opt-cmps",
>> + "Optimize comparison instrs", false, false);
>> +
>> +FunctionPass *llvm::createOptimizeCmpsPass() { return new OptimizeCmps(); }
>> +
>> +/// OptimizeCmpInstr - If the instruction is a compare and the previous
>> +/// instruction it's comparing against all ready sets (or could be modified to
>> +/// set) the same flag as the compare, then we can remove the comparison and use
>> +/// the flag from the previous instruction.
>> +bool OptimizeCmps::OptimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB) {
>> + // If this instruction is a comparison against zero and isn't comparing a
>> + // physical register, we can try to optimize it.
>> + unsigned SrcReg;
>> + int CmpValue;
>> + if (!TII->isCompareInstr(MI, SrcReg, CmpValue) ||
>> + TargetRegisterInfo::isPhysicalRegister(SrcReg) ||
>> + CmpValue != 0)
>> + return false;
>> +
>> + MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg);
>> + if (llvm::next(DI) != MRI->def_end())
>> + // Only support one definition.
>> + return false;
>> +
>> + // Attempt to convert the defining instruction to set the "zero" flag.
>> + if (TII->convertToSetZeroFlag(&*DI, MI)) {
>> + ++NumEliminated;
>> + return true;
>> + }
>> +
>> + return false;
>> +}
>> +
>> +bool OptimizeCmps::runOnMachineFunction(MachineFunction &MF) {
>> + TM = &MF.getTarget();
>> + TII = TM->getInstrInfo();
>> + MRI = &MF.getRegInfo();
>> +
>> + if (!EnableOptCmps) return false;
>> +
>> + bool Changed = false;
>> + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
>> + MachineBasicBlock *MBB = &*I;
>> + for (MachineBasicBlock::iterator
>> + MII = MBB->begin(), ME = MBB->end(); MII != ME; ) {
>> + MachineInstr *MI = &*MII++;
>> + Changed |= OptimizeCmpInstr(MI, MBB);
>> + }
>> + }
>> +
>> + return Changed;
>> +}
>>
>> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=110423&r1=110422&r2=110423&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original)
>> +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Thu Aug 5 20:32:48 2010
>> @@ -1353,3 +1353,59 @@
>> Offset = (isSub) ? -Offset : Offset;
>> return Offset == 0;
>> }
>> +
>> +bool ARMBaseInstrInfo::
>> +isCompareInstr(const MachineInstr *MI, unsigned &SrcReg, int &CmpValue) const {
>> + switch (MI->getOpcode()) {
>> + default: break;
>> + case ARM::t2CMPri:
>> + case ARM::t2CMPzri:
>> + SrcReg = MI->getOperand(0).getReg();
>> + CmpValue = MI->getOperand(1).getImm();
>> + return true;
>> + }
>> +
>> + return false;
>> +}
>> +
>> +/// convertToSetZeroFlag - Convert the instruction to set the "zero" flag so
>> +/// that we can remove a "comparison with zero".
>> +bool ARMBaseInstrInfo::
>> +convertToSetZeroFlag(MachineInstr *MI, MachineInstr *CmpInstr) const {
>> + // Conservatively refuse to convert an instruction which isn't in the same BB
>> + // as the comparison.
>> + if (MI->getParent() != CmpInstr->getParent())
>> + return false;
>> +
>> + // Check that CPSR isn't set between the comparison instruction and the one we
>> + // want to change.
>> + MachineBasicBlock::const_iterator I = CmpInstr, E = MI;
>> + --I;
>> + for (; I != E; --I) {
>> + const MachineInstr &Instr = *I;
>> +
>> + for (unsigned IO = 0, EO = Instr.getNumOperands(); IO != EO; ++IO) {
>> + const MachineOperand &MO = Instr.getOperand(IO);
>> + if (!MO.isDef() || !MO.isReg()) continue;
>> +
>> + // This instruction modifies CPSR before the one we want to change. We
>> + // can't do this transformation.
>> + if (MO.getReg() == ARM::CPSR)
>> + return false;
>> + }
>> + }
>> +
>> + // Set the "zero" bit in CPSR.
>> + switch (MI->getOpcode()) {
>> + default: break;
>> + case ARM::t2SUBri: {
>> + MI->RemoveOperand(5);
>> + MachineInstrBuilder MB(MI);
>> + MB.addReg(ARM::CPSR, RegState::Define | RegState::Implicit);
>> + CmpInstr->eraseFromParent();
>> + return true;
>> + }
>> + }
>> +
>> + return false;
>> +}
>>
>> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=110423&r1=110422&r2=110423&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original)
>> +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Aug 5 20:32:48 2010
>> @@ -336,6 +336,17 @@
>> unsigned NumInstrs) const {
>> return NumInstrs && NumInstrs == 1;
>> }
>> +
>> + /// isCompareInstr - If the machine instruction is a comparison instruction,
>> + /// then return true. Also return the source register in SrcReg and the value
>> + /// it compares against in CmpValue.
>> + virtual bool isCompareInstr(const MachineInstr *MI, unsigned &SrcReg,
>> + int &CmpValue) const;
>> +
>> + /// convertToSetZeroFlag - Convert the instruction to set the zero flag so
>> + /// that we can remove a "comparison with zero".
>> + virtual bool convertToSetZeroFlag(MachineInstr *Instr,
>> + MachineInstr *CmpInstr) const;
>> };
>>
>> static inline
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list