[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PowerPCInstrInfo.td

Nate Begeman natebegeman at mac.com
Thu Apr 14 02:45:19 PDT 2005



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelPattern.cpp updated: 1.71 -> 1.72
PowerPCInstrInfo.td updated: 1.63 -> 1.64
---
Log message:

Implement multi-way branches through logical ops on condition registers.
This can generate considerably shorter code, reducing the size of crafty
by almost 1%.  Also fix the printing of mcrf.  The code is currently
disabled until it gets a bit more testing, but should work as-is.


---
Diffs of the changes:  (+69 -3)

 PPC32ISelPattern.cpp |   70 +++++++++++++++++++++++++++++++++++++++++++++++++--
 PowerPCInstrInfo.td  |    2 -
 2 files changed, 69 insertions(+), 3 deletions(-)


Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.71 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.72
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.71	Wed Apr 13 18:15:44 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp	Thu Apr 14 04:45:08 2005
@@ -474,6 +474,7 @@
 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");
 //===--------------------------------------------------------------------===//
 /// ISel - PPC32 specific code to select PPC32 machine instructions for
 /// SelectionDAG operations.
@@ -689,6 +690,43 @@
   return 0;
 }
 
+/// getCROpForOp - Return the condition register opcode (or inverted opcode)
+/// associated with the SelectionDAG opcode.
+static unsigned getCROpForSetCC(unsigned Opcode, bool Inv1, bool Inv2) {
+  switch (Opcode) {
+  default: assert(0 && "Unknown opcode!"); abort();
+  case ISD::AND:
+    if (Inv1 && Inv2) return PPC::CRNOR; // De Morgan's Law
+    if (!Inv1 && !Inv2) return PPC::CRAND;
+    if (Inv1 ^ Inv2) return PPC::CRANDC;
+  case ISD::OR:
+    if (Inv1 && Inv2) return PPC::CRNAND; // De Morgan's Law
+    if (!Inv1 && !Inv2) return PPC::CROR;
+    if (Inv1 ^ Inv2) return PPC::CRORC;
+  }
+  return 0;
+}
+
+/// getCRIdxForSetCC - Return the index of the condition register field
+/// associated with the SetCC condition, and whether or not the field is
+/// treated as inverted.  That is, lt = 0; ge = 0 inverted.
+static unsigned getCRIdxForSetCC(unsigned Condition, bool& Inv) {
+  switch (Condition) {
+  default: assert(0 && "Unknown condition!"); abort();
+  case ISD::SETULT: 
+  case ISD::SETLT:  Inv = false;  return 0;
+  case ISD::SETUGE:
+  case ISD::SETGE:  Inv = true;   return 0;
+  case ISD::SETUGT:
+  case ISD::SETGT:  Inv = false;  return 1;
+  case ISD::SETULE:
+  case ISD::SETLE:  Inv = true;   return 1;
+  case ISD::SETEQ:  Inv = false;  return 2;
+  case ISD::SETNE:  Inv = true;   return 2;
+  }
+  return 0;
+}
+
 /// IndexedOpForOp - Return the indexed variant for each of the PowerPC load
 /// and store immediate instructions.
 static unsigned IndexedOpForOp(unsigned Opcode) {
@@ -1009,7 +1047,8 @@
         Tmp1 = SelectExpr(SetCC->getOperand(0), true);
         if (RecordSuccess) {
           ++Recorded;
-          return PPC::CR0;
+          BuildMI(BB, PPC::MCRF, 1, Result).addReg(PPC::CR0);
+          return Result;
         }
         AlreadySelected = true;
       }
@@ -1028,6 +1067,33 @@
       BuildMI(BB, CompareOpc, 2, Result).addReg(Tmp1).addReg(Tmp2);
     }
   } else {
+#if 0
+    if (CC.getOpcode() == ISD::AND || CC.getOpcode() == ISD::OR)
+      if (CC.getOperand(0).Val->hasOneUse() &&
+          CC.getOperand(1).Val->hasOneUse()) {
+        SetCCSDNode* Op0CC = dyn_cast<SetCCSDNode>(CC.getOperand(0).Val);
+        SetCCSDNode* Op1CC = dyn_cast<SetCCSDNode>(CC.getOperand(1).Val);
+        if (Op0CC && Op1CC) {
+          ++MultiBranch;
+          bool Inv0, Inv1;
+          unsigned Opc1;
+          unsigned Idx0 = getCRIdxForSetCC(Op0CC->getCondition(), Inv0);
+          unsigned Idx1 = getCRIdxForSetCC(Op1CC->getCondition(), Inv1);
+          unsigned CROpc = getCROpForSetCC(CC.getOpcode(), Inv0, Inv1);
+          Tmp1 = SelectCC(CC.getOperand(0), Opc);
+          Tmp2 = SelectCC(CC.getOperand(1), Opc1);
+          if (Inv0 && !Inv1) {
+            std::swap(Tmp1, Tmp2);
+            std::swap(Idx0, Idx1);
+            Opc = Opc1;
+          }
+          if (Inv0 && Inv1) Opc = PPC32InstrInfo::invertPPCBranchOpcode(Opc);
+          BuildMI(BB, CROpc, 5, Result).addImm(Idx0).addReg(Tmp1).addImm(Idx0)
+            .addReg(Tmp2).addImm(Idx1);
+          return Result;
+        }
+    }
+#endif
     Opc = PPC::BNE;
     Tmp1 = SelectExpr(CC);
     BuildMI(BB, PPC::CMPLWI, 2, Result).addReg(Tmp1).addImm(0);
@@ -2033,7 +2099,7 @@
         if (CN->getValue() == 0) {
           Tmp1 = SelectExpr(SetCC->getOperand(0));
           switch (SetCC->getCondition()) {
-          default: assert(0 && "Unhandled SetCC condition"); abort();
+          default: SetCC->dump(); assert(0 && "Unhandled SetCC condition"); abort();
           case ISD::SETEQ:
             Tmp2 = MakeReg(MVT::i32);
             BuildMI(BB, PPC::CNTLZW, 1, Tmp2).addReg(Tmp1);


Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.63 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.64
--- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.63	Wed Apr 13 22:20:38 2005
+++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td	Thu Apr 14 04:45:08 2005
@@ -360,7 +360,7 @@
                       CRRC:$A, crbit:$Ab, CRRC:$B, crbit:$Bb),
                       "crxor $Db, $Ab, $Bb">;
 def MCRF   : XLForm_3<19, 0, 0, 0, (ops CRRC:$BF, CRRC:$BFA),
-                      "mfcr $BF, $BFA">;
+                      "mcrf $BF, $BFA">;
 
 // XFX-Form instructions.  Instructions that deal with SPRs
 //






More information about the llvm-commits mailing list