[llvm] r252722 - [X86] Replace LEAs with INC/DEC when profitable
Michael Kuperstein via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 11 03:44:34 PST 2015
- Previous message: [PATCH] D14217: [x86] translating "fp" (floating point) instructions from {fadd, fdiv, fmul, fsub, fsubr, fdivr} to {faddp, fdivp, fmulp, fsubp, fsubrp, fdivrp}
- Next message: [llvm] r252722 - [X86] Replace LEAs with INC/DEC when profitable
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: mkuper
Date: Wed Nov 11 05:44:31 2015
New Revision: 252722
URL: http://llvm.org/viewvc/llvm-project?rev=252722&view=rev
Log:
[X86] Replace LEAs with INC/DEC when profitable
If possible and profitable, replace lea %reg, 1(%reg) and lea %reg, -1(%reg) with inc %reg and dec %reg respectively.
Patch by: anton.nadolsky at intel.com
Differential Revision: http://reviews.llvm.org/D14059
Added:
llvm/trunk/test/CodeGen/X86/fixup-lea.ll
Modified:
llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp
llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll
Modified: llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp?rev=252722&r1=252721&r2=252722&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp Wed Nov 11 05:44:31 2015
@@ -9,6 +9,7 @@
//
// This file defines the pass that finds instructions that can be
// re-written as LEA instructions in order to reduce pipeline delays.
+// When optimizing for size it replaces suitable LEAs with INC or DEC.
//
//===----------------------------------------------------------------------===//
@@ -61,6 +62,11 @@ class FixupLEAPass : public MachineFunct
void processInstructionForSLM(MachineBasicBlock::iterator &I,
MachineFunction::iterator MFI);
+ /// \brief Look for LEAs that add 1 to reg or subtract 1 from reg
+ /// and convert them to INC or DEC respectively.
+ bool fixupIncDec(MachineBasicBlock::iterator &I,
+ MachineFunction::iterator MFI) const;
+
/// \brief Determine if an instruction references a machine register
/// and, if so, whether it reads or writes the register.
RegUsageState usesRegister(MachineOperand &p, MachineBasicBlock::iterator I);
@@ -89,6 +95,8 @@ public:
private:
MachineFunction *MF;
const X86InstrInfo *TII; // Machine instruction info.
+ bool OptIncDec;
+ bool OptLEA;
};
char FixupLEAPass::ID = 0;
}
@@ -150,7 +158,10 @@ FunctionPass *llvm::createX86FixupLEAs()
bool FixupLEAPass::runOnMachineFunction(MachineFunction &Func) {
MF = &Func;
const X86Subtarget &ST = Func.getSubtarget<X86Subtarget>();
- if (!ST.LEAusesAG() && !ST.slowLEA())
+ OptIncDec = !ST.slowIncDec() || Func.getFunction()->optForMinSize();
+ OptLEA = ST.LEAusesAG() || ST.slowLEA();
+
+ if (!OptLEA && !OptIncDec)
return false;
TII = ST.getInstrInfo();
@@ -222,6 +233,60 @@ FixupLEAPass::searchBackwards(MachineOpe
return nullptr;
}
+static inline bool isLEA(const int opcode) {
+ return opcode == X86::LEA16r || opcode == X86::LEA32r ||
+ opcode == X86::LEA64r || opcode == X86::LEA64_32r;
+}
+
+/// isLEASimpleIncOrDec - Does this LEA have one these forms:
+/// lea %reg, 1(%reg)
+/// lea %reg, -1(%reg)
+static inline bool isLEASimpleIncOrDec(MachineInstr *LEA) {
+ unsigned SrcReg = LEA->getOperand(1 + X86::AddrBaseReg).getReg();
+ unsigned DstReg = LEA->getOperand(0).getReg();
+ unsigned AddrDispOp = 1 + X86::AddrDisp;
+ return SrcReg == DstReg &&
+ LEA->getOperand(1 + X86::AddrIndexReg).getReg() == 0 &&
+ LEA->getOperand(1 + X86::AddrSegmentReg).getReg() == 0 &&
+ LEA->getOperand(AddrDispOp).isImm() &&
+ (LEA->getOperand(AddrDispOp).getImm() == 1 ||
+ LEA->getOperand(AddrDispOp).getImm() == -1);
+}
+
+bool FixupLEAPass::fixupIncDec(MachineBasicBlock::iterator &I,
+ MachineFunction::iterator MFI) const {
+ MachineInstr *MI = I;
+ int Opcode = MI->getOpcode();
+ if (!isLEA(Opcode))
+ return false;
+
+ if (isLEASimpleIncOrDec(MI) && TII->isSafeToClobberEFLAGS(*MFI, I)) {
+ int NewOpcode;
+ bool isINC = MI->getOperand(4).getImm() == 1;
+ switch (Opcode) {
+ case X86::LEA16r:
+ NewOpcode = isINC ? X86::INC16r : X86::DEC16r;
+ break;
+ case X86::LEA32r:
+ case X86::LEA64_32r:
+ NewOpcode = isINC ? X86::INC32r : X86::DEC32r;
+ break;
+ case X86::LEA64r:
+ NewOpcode = isINC ? X86::INC64r : X86::DEC64r;
+ break;
+ }
+
+ MachineInstr *NewMI =
+ BuildMI(*MFI, I, MI->getDebugLoc(), TII->get(NewOpcode))
+ .addOperand(MI->getOperand(0))
+ .addOperand(MI->getOperand(1));
+ MFI->erase(I);
+ I = static_cast<MachineBasicBlock::iterator>(NewMI);
+ return true;
+ }
+ return false;
+}
+
void FixupLEAPass::processInstruction(MachineBasicBlock::iterator &I,
MachineFunction::iterator MFI) {
// Process a load, store, or LEA instruction.
@@ -265,8 +330,7 @@ void FixupLEAPass::processInstructionFor
MachineFunction::iterator MFI) {
MachineInstr *MI = I;
const int opcode = MI->getOpcode();
- if (opcode != X86::LEA16r && opcode != X86::LEA32r && opcode != X86::LEA64r &&
- opcode != X86::LEA64_32r)
+ if (!isLEA(opcode))
return;
if (MI->getOperand(5).getReg() != 0 || !MI->getOperand(4).isImm() ||
!TII->isSafeToClobberEFLAGS(*MFI, I))
@@ -280,7 +344,8 @@ void FixupLEAPass::processInstructionFor
return;
int addrr_opcode, addri_opcode;
switch (opcode) {
- default: llvm_unreachable("Unexpected LEA instruction");
+ default:
+ llvm_unreachable("Unexpected LEA instruction");
case X86::LEA16r:
addrr_opcode = X86::ADD16rr;
addri_opcode = X86::ADD16ri;
@@ -330,10 +395,16 @@ bool FixupLEAPass::processBasicBlock(Mac
MachineFunction::iterator MFI) {
for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) {
- if (MF.getSubtarget<X86Subtarget>().isSLM())
- processInstructionForSLM(I, MFI);
- else
- processInstruction(I, MFI);
+ if (OptIncDec)
+ if (fixupIncDec(I, MFI))
+ continue;
+
+ if (OptLEA) {
+ if (MF.getSubtarget<X86Subtarget>().isSLM())
+ processInstructionForSLM(I, MFI);
+ else
+ processInstruction(I, MFI);
+ }
}
return false;
}
Added: llvm/trunk/test/CodeGen/X86/fixup-lea.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fixup-lea.ll?rev=252722&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fixup-lea.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fixup-lea.ll Wed Nov 11 05:44:31 2015
@@ -0,0 +1,34 @@
+;RUN: llc < %s -march=x86 | FileCheck %s
+
+define void @foo(i32 inreg %dns) minsize {
+entry:
+; CHECK-LABEL: foo
+; CHECK: dec
+ br label %for.body
+
+for.body:
+ %i.05 = phi i16 [ %dec, %for.body ], [ 0, %entry ]
+ %dec = add i16 %i.05, -1
+ %conv = zext i16 %dec to i32
+ %cmp = icmp slt i32 %conv, %dns
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+ ret void
+}
+
+define void @bar(i32 inreg %dns) minsize {
+entry:
+; CHECK-LABEL: bar
+; CHECK: inc
+ br label %for.body
+
+for.body:
+ %i.05 = phi i16 [ %inc, %for.body ], [ 0, %entry ]
+ %inc = add i16 %i.05, 1
+ %conv = zext i16 %inc to i32
+ %cmp = icmp slt i32 %conv, %dns
+ br i1 %cmp, label %for.body, label %for.end
+for.end:
+ ret void
+}
Modified: llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll?rev=252722&r1=252721&r2=252722&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll (original)
+++ llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll Wed Nov 11 05:44:31 2015
@@ -18,7 +18,7 @@
; ATOM-NEXT: movsd A(,%rax,8)
; ATOM-NEXT: mulsd
; ATOM-NEXT: movsd
-; ATOM-NEXT: leaq 1(%rax), %rax
+; ATOM-NEXT: incq %rax
@A = external global [0 x double]
- Previous message: [PATCH] D14217: [x86] translating "fp" (floating point) instructions from {fadd, fdiv, fmul, fsub, fsubr, fdivr} to {faddp, fdivp, fmulp, fsubp, fsubrp, fdivrp}
- Next message: [llvm] r252722 - [X86] Replace LEAs with INC/DEC when profitable
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the llvm-commits
mailing list