Fold constant adds into loads and stores to frame indices.
authorNate Begeman <natebegeman@mac.com>
Thu, 28 Jul 2005 03:02:05 +0000 (03:02 +0000)
committerNate Begeman <natebegeman@mac.com>
Thu, 28 Jul 2005 03:02:05 +0000 (03:02 +0000)
For the following code:
double %ext(int %A.0__, long %A.1__) {
        %A_addr = alloca %typedef.DComplex              ; <%typedef.DComplex*> [#uses=2]
        %tmp.1 = cast %typedef.DComplex* %A_addr to int*                ; <int*> [#uses=1]
        store int %A.0__, int* %tmp.1
        %tmp.2 = getelementptr %typedef.DComplex* %A_addr, int 0, uint 1                ; <double*> [#uses=2]
        %tmp.3 = cast double* %tmp.2 to long*           ; <long*> [#uses=1]
        store long %A.1__, long* %tmp.3
        %tmp.5 = load double* %tmp.2            ; <double> [#uses=1]
        ret double %tmp.5
}

We now generate:
_ext:
.LBB_ext_0:     ;
        stw r3, -12(r1)
        stw r4, -8(r1)
        stw r5, -4(r1)
        lfd f1, -8(r1)
        blr

Instead of:
_ext:
.LBB_ext_0:     ;
        stw r3, -12(r1)
        addi r2, r1, -12
        stw r4, 4(r2)
        stw r5, 8(r2)
        lfd f1, 4(r2)
        blr

This also fires hundreds of times on MultiSource.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22533 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelPattern.cpp

index a21cf5b83eeaa02f53886d8ededa99fa685dbfec..63188420493e74aee02a084bf961f18022de02e2 100644 (file)
@@ -511,7 +511,7 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
 namespace {
 Statistic<>Recorded("ppc-codegen", "Number of recording ops emitted");
 Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
-Statistic<>MultiBranch("ppc-codegen", "Number of setcc logical ops collapsed");
+Statistic<>FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");
 //===--------------------------------------------------------------------===//
 /// ISel - PPC32 specific code to select PPC32 machine instructions for
 /// SelectionDAG operations.
@@ -569,7 +569,7 @@ public:
   unsigned SelectExpr(SDOperand N, bool Recording=false);
   void Select(SDOperand N);
 
-  bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
+  unsigned SelectAddr(SDOperand N, unsigned& Reg, int& offset);
   void SelectBranchCC(SDOperand N);
 };
 
@@ -1189,7 +1189,6 @@ unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
     break;
   case ISD::OR:
   case ISD::AND:
-    ++MultiBranch;
     Tmp1 = SelectCCExpr(N.getOperand(0), Opc, Inv0, Idx0);
     Tmp2 = SelectCCExpr(N.getOperand(1), Opc1, Inv1, Idx1);
     CROpc = getCROpForSetCC(N.getOpcode(), Inv0, Inv1);
@@ -1213,21 +1212,30 @@ unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
 }
 
 /// Check to see if the load is a constant offset from a base register
-bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
+unsigned ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
 {
   unsigned imm = 0, opcode = N.getOpcode();
   if (N.getOpcode() == ISD::ADD) {
-    Reg = SelectExpr(N.getOperand(0));
+    bool isFrame = N.getOperand(0).getOpcode() == ISD::FrameIndex;
     if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) {
       offset = imm;
-      return false;
+      if (isFrame) {
+        ++FrameOff;
+        Reg = cast<FrameIndexSDNode>(N.getOperand(0))->getIndex();
+        return 1;
+      } else {
+        Reg = SelectExpr(N.getOperand(0));
+        return 0;
+      }
+    } else {
+      Reg = SelectExpr(N.getOperand(0));
+      offset = SelectExpr(N.getOperand(1));
+      return 2;
     }
-    offset = SelectExpr(N.getOperand(1));
-    return true;
   }
   Reg = SelectExpr(N);
   offset = 0;
-  return false;
+  return 0;
 }
 
 void ISel::SelectBranchCC(SDOperand N)
@@ -1443,12 +1451,18 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
       }
     } else {
       int offset;
-      bool idx = SelectAddr(Address, Tmp1, offset);
-      if (idx) {
+      switch(SelectAddr(Address, Tmp1, offset)) {
+      default: assert(0 && "Unhandled return value from SelectAddr");
+      case 0:   // imm offset, no frame, no index
+        BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
+        break;
+      case 1:   // imm offset + frame index
+        addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1, offset);
+        break;
+      case 2:   // base+index addressing
         Opc = IndexedOpForOp(Opc);
         BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
-      } else {
-        BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
+        break;
       }
     }
     return Result;
@@ -2495,12 +2509,18 @@ void ISel::Select(SDOperand N) {
       }
     } else {
       int offset;
-      bool idx = SelectAddr(Address, Tmp2, offset);
-      if (idx) {
+      switch(SelectAddr(Address, Tmp2, offset)) {
+      default: assert(0 && "Unhandled return value from SelectAddr");
+      case 0:   // imm offset, no frame, no index
+        BuildMI(BB, Opc, 3).addReg(Tmp1).addSImm(offset).addReg(Tmp2);
+        break;
+      case 1:   // imm offset + frame index
+        addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2, offset);
+        break;
+      case 2:   // base+index addressing
         Opc = IndexedOpForOp(Opc);
         BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
-      } else {
-        BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
+        break;
       }
     }
     return;