Codegen sub C, X a little bit better for register pressure. Instead of
authorChris Lattner <sabre@nondot.org>
Fri, 18 Jun 2004 00:50:37 +0000 (00:50 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 18 Jun 2004 00:50:37 +0000 (00:50 +0000)
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

lib/Target/X86/InstSelectSimple.cpp
lib/Target/X86/X86ISelSimple.cpp

index f49c6f5efa28680a40fd8c1dbfc9530c93e8b6ea..454fb2f09978a886eb3c9979f25b2fe911467296 100644 (file)
@@ -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>
index f49c6f5efa28680a40fd8c1dbfc9530c93e8b6ea..454fb2f09978a886eb3c9979f25b2fe911467296 100644 (file)
@@ -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>