Support indexed loads and stores. This drops Shootout/matrix time from
authorNate Begeman <natebegeman@mac.com>
Fri, 1 Apr 2005 04:45:11 +0000 (04:45 +0000)
committerNate Begeman <natebegeman@mac.com>
Fri, 1 Apr 2005 04:45:11 +0000 (04:45 +0000)
18.8 to 14.8 seconds.  The Pattern ISel is now often faster than the
Simple ISel, esp. on memory intensive code.

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

lib/Target/PowerPC/PPCISelPattern.cpp

index 26639435350fee804fa8f62752e1d89141776b5d..3acd5db0c6a209552c04405b472366c18e16a166 100644 (file)
@@ -469,7 +469,7 @@ public:
   unsigned SelectExprFP(SDOperand N, unsigned Result);
   void Select(SDOperand N);
   
-  void SelectAddr(SDOperand N, unsigned& Reg, int& offset);
+  bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
   void SelectBranchCC(SDOperand N);
 };
 
@@ -529,6 +529,22 @@ static unsigned getBCCForSetCC(unsigned Condition, bool& U) {
   case ISD::SETUGE: U = true;
   case ISD::SETGE:  return PPC::BGE;
   }
+  return 0;
+}
+
+/// IndexedOpForOp - Return the indexed variant for each of the PowerPC load
+/// and store immediate instructions.
+static unsigned IndexedOpForOp(unsigned Opcode) {
+  switch(Opcode) {
+  default: assert(0 && "Unknown opcode!"); abort();
+  case PPC::LBZ: return PPC::LBZX;  case PPC::STB: return PPC::STBX;
+  case PPC::LHZ: return PPC::LHZX;  case PPC::STH: return PPC::STHX;
+  case PPC::LHA: return PPC::LHAX;  case PPC::STW: return PPC::STWX;
+  case PPC::LWZ: return PPC::LWZX;  case PPC::STFS: return PPC::STFSX;
+  case PPC::LFS: return PPC::LFSX;  case PPC::STFD: return PPC::STFDX;
+  case PPC::LFD: return PPC::LFDX;
+  }
+  return 0;
 }
 }
 
@@ -598,18 +614,21 @@ unsigned ISel::SelectSetCR0(SDOperand CC) {
 }
 
 /// Check to see if the load is a constant offset from a base register
-void ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
+bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
 {
   unsigned imm = 0, opcode = N.getOpcode();
-  if (N.getOpcode() == ISD::ADD)
+  if (N.getOpcode() == ISD::ADD) {
+    Reg = SelectExpr(N.getOperand(0));
     if (1 == canUseAsImmediateForOpcode(N.getOperand(1), opcode, imm)) {
-      Reg = SelectExpr(N.getOperand(0));
       offset = imm;
-      return;
-    }
+      return false;
+    } 
+    offset = SelectExpr(N.getOperand(1));
+    return true;
+  }
   Reg = SelectExpr(N);
   offset = 0;
-  return;
+  return false;
 }
 
 void ISel::SelectBranchCC(SDOperand N)
@@ -988,8 +1007,13 @@ unsigned ISel::SelectExpr(SDOperand N) {
       addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1);
     } else {
       int offset;
-      SelectAddr(Address, Tmp1, offset);
-      BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
+      bool idx = SelectAddr(Address, Tmp1, offset);
+      if (idx) {
+        Opc = IndexedOpForOp(Opc);
+        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
+      } else {
+        BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
+      }
     }
     return Result;
   }
@@ -1534,8 +1558,13 @@ void ISel::Select(SDOperand N) {
       else
       {
         int offset;
-        SelectAddr(Address, Tmp2, offset);
-        BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
+        bool idx = SelectAddr(Address, Tmp2, offset);
+        if (idx) { 
+          Opc = IndexedOpForOp(Opc);
+          BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
+        } else {
+          BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
+        }
       }
       return;
     }