diff options
author | Chris Lattner <sabre@nondot.org> | 2004-06-18 00:50:37 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-06-18 00:50:37 +0000 |
commit | 667ea024b55a902ad551e6c57c820f402c7da89f (patch) | |
tree | 998591a96faa25ee6aaf75a063e615f2dde21381 /lib | |
parent | a6f9fe6dbc9c1ffd45ae999710dbafa0afae729f (diff) |
Codegen sub C, X a little bit better for register pressure. Instead of
mov REG, C
sub REG, X
generate:
neg X
add X, C
which uses one less reg
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14213 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/InstSelectSimple.cpp | 39 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 39 |
2 files changed, 54 insertions, 24 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index f49c6f5efa..454fb2f099 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -2125,24 +2125,39 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB, return; } - // sub 0, X -> neg X if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0)) - if (OperatorClass == 1 && CI->isNullValue()) { - unsigned op1Reg = getReg(Op1, MBB, IP); + if (OperatorClass == 1) { static unsigned const NEGTab[] = { X86::NEG8r, X86::NEG16r, X86::NEG32r, 0, X86::NEG32r }; - BuildMI(*MBB, IP, NEGTab[Class], 1, DestReg).addReg(op1Reg); + + // sub 0, X -> neg X + if (CI->isNullValue()) { + unsigned op1Reg = getReg(Op1, MBB, IP); + BuildMI(*MBB, IP, NEGTab[Class], 1, DestReg).addReg(op1Reg); - if (Class == cLong) { - // We just emitted: Dl = neg Sl - // Now emit : T = addc Sh, 0 - // : Dh = neg T - unsigned T = makeAnotherReg(Type::IntTy); - BuildMI(*MBB, IP, X86::ADC32ri, 2, T).addReg(op1Reg+1).addImm(0); - BuildMI(*MBB, IP, X86::NEG32r, 1, DestReg+1).addReg(T); + if (Class == cLong) { + // We just emitted: Dl = neg Sl + // Now emit : T = addc Sh, 0 + // : Dh = neg T + unsigned T = makeAnotherReg(Type::IntTy); + BuildMI(*MBB, IP, X86::ADC32ri, 2, T).addReg(op1Reg+1).addImm(0); + BuildMI(*MBB, IP, X86::NEG32r, 1, DestReg+1).addReg(T); + } + return; + } else if (Op1->hasOneUse() && Class != cLong) { + // sub C, X -> tmp = neg X; DestReg = add tmp, C. This is better + // than copying C into a temporary register, because of register + // pressure (tmp and destreg can share a register. + static unsigned const ADDRITab[] = { + X86::ADD8ri, X86::ADD16ri, X86::ADD32ri, 0, X86::ADD32ri + }; + unsigned op1Reg = getReg(Op1, MBB, IP); + unsigned Tmp = makeAnotherReg(Op0->getType()); + BuildMI(*MBB, IP, NEGTab[Class], 1, Tmp).addReg(op1Reg); + BuildMI(*MBB, IP, ADDRITab[Class], 2, DestReg).addReg(Tmp).addImm(CI->getRawValue()); + return; } - return; } // Special case: op Reg, <const int> diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index f49c6f5efa..454fb2f099 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -2125,24 +2125,39 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB, return; } - // sub 0, X -> neg X if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0)) - if (OperatorClass == 1 && CI->isNullValue()) { - unsigned op1Reg = getReg(Op1, MBB, IP); + if (OperatorClass == 1) { static unsigned const NEGTab[] = { X86::NEG8r, X86::NEG16r, X86::NEG32r, 0, X86::NEG32r }; - BuildMI(*MBB, IP, NEGTab[Class], 1, DestReg).addReg(op1Reg); + + // sub 0, X -> neg X + if (CI->isNullValue()) { + unsigned op1Reg = getReg(Op1, MBB, IP); + BuildMI(*MBB, IP, NEGTab[Class], 1, DestReg).addReg(op1Reg); - if (Class == cLong) { - // We just emitted: Dl = neg Sl - // Now emit : T = addc Sh, 0 - // : Dh = neg T - unsigned T = makeAnotherReg(Type::IntTy); - BuildMI(*MBB, IP, X86::ADC32ri, 2, T).addReg(op1Reg+1).addImm(0); - BuildMI(*MBB, IP, X86::NEG32r, 1, DestReg+1).addReg(T); + if (Class == cLong) { + // We just emitted: Dl = neg Sl + // Now emit : T = addc Sh, 0 + // : Dh = neg T + unsigned T = makeAnotherReg(Type::IntTy); + BuildMI(*MBB, IP, X86::ADC32ri, 2, T).addReg(op1Reg+1).addImm(0); + BuildMI(*MBB, IP, X86::NEG32r, 1, DestReg+1).addReg(T); + } + return; + } else if (Op1->hasOneUse() && Class != cLong) { + // sub C, X -> tmp = neg X; DestReg = add tmp, C. This is better + // than copying C into a temporary register, because of register + // pressure (tmp and destreg can share a register. + static unsigned const ADDRITab[] = { + X86::ADD8ri, X86::ADD16ri, X86::ADD32ri, 0, X86::ADD32ri + }; + unsigned op1Reg = getReg(Op1, MBB, IP); + unsigned Tmp = makeAnotherReg(Op0->getType()); + BuildMI(*MBB, IP, NEGTab[Class], 1, Tmp).addReg(op1Reg); + BuildMI(*MBB, IP, ADDRITab[Class], 2, DestReg).addReg(Tmp).addImm(CI->getRawValue()); + return; } - return; } // Special case: op Reg, <const int> |