[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 09:28:37 PDT 2010
On Aug 5, 2010, at 11:44 PM, Bill Wendling wrote:
> Hi Evan,
>
> When I was implementing it, I realized that I needed to know more about the compare statement then just that it's a compare. (The src reg and compare number for instance.) It just seemed like duplicated effort to have it be both a target instruction property and a target hook call. But it is more expensive, so I can put the instruction property back and do both.
I think the instruction property makes sense. Thanks.
Evan
>
> -bw
>
> On Aug 5, 2010, at 11:02 PM, Evan Cheng wrote:
>
>> Hi Bill,
>>
>> I thought you are adding a new target instruction property? Why do you decide to add the target hook instead?
>>
>> Evan
>>
>> On Aug 5, 2010, at 6:32 PM, Bill Wendling <isanbard at gmail.com> 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).
>>>
>>> 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
>
More information about the llvm-commits
mailing list