[llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Mon Feb 7 16:40:18 PST 2005



Changes in directory llvm/lib/Target/Alpha:

AlphaISelPattern.cpp updated: 1.46 -> 1.47
---
Log message:

BranchCC, nifty

---
Diffs of the changes:  (+117 -7)

 AlphaISelPattern.cpp |  124 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 117 insertions(+), 7 deletions(-)


Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp
diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.46 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.47
--- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.46	Mon Feb  7 17:02:23 2005
+++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp	Mon Feb  7 18:40:03 2005
@@ -288,6 +288,9 @@
     static const unsigned notIn = (unsigned)(-1);
     std::map<SDOperand, unsigned> ExprMap;
 
+    //CCInvMap sometimes (SetNE) we have the inverse CC code for free
+    std::map<SDOperand, unsigned> CCInvMap;
+
   public:
     ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
     }
@@ -300,6 +303,7 @@
 
       // Clear state used for selection.
       ExprMap.clear();
+      CCInvMap.clear();
     }
 
     unsigned SelectExpr(SDOperand N);
@@ -307,6 +311,7 @@
     void Select(SDOperand N);
 
     void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
+    void SelectBranchCC(SDOperand N);
   };
 }
 
@@ -354,6 +359,115 @@
   return;
 }
 
+void ISel::SelectBranchCC(SDOperand N)
+{
+  assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
+  MachineBasicBlock *Dest = cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
+  unsigned Opc;
+
+  Select(N.getOperand(0));  //chain
+  SDOperand CC = N.getOperand(1);
+
+  if (CC.getOpcode() == ISD::SETCC)
+    {
+      SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
+      if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
+        //Dropping the CC is only useful if we are comparing to 0
+        bool isZero0 = false;
+        bool isZero1 = false;
+        bool isNE = false;
+
+        if(SetCC->getOperand(0).getOpcode() == ISD::Constant &&
+           cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0)
+          isZero0 = true;
+        if(SetCC->getOperand(1).getOpcode() == ISD::Constant &&
+           cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() == 0)
+          isZero1 = true;
+        if(SetCC->getCondition() == ISD::SETNE)
+          isNE = true;
+
+        if (isZero0)
+          {
+            switch (SetCC->getCondition()) {
+            default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
+            case ISD::SETEQ:  Opc = Alpha::BEQ; break;
+            case ISD::SETLT:  Opc = Alpha::BGT; break;
+            case ISD::SETLE:  Opc = Alpha::BGE; break;
+            case ISD::SETGT:  Opc = Alpha::BLT; break;
+            case ISD::SETGE:  Opc = Alpha::BLE; break;
+            case ISD::SETULT: Opc = Alpha::BNE; break;
+            case ISD::SETUGT: assert(0 && "0 > (unsigned) x is never true"); break;
+            case ISD::SETULE: assert(0 && "0 <= (unsigned) x is always true"); break;
+            case ISD::SETUGE: Opc = Alpha::BEQ; break; //Technically you could have this CC
+            case ISD::SETNE:  Opc = Alpha::BNE; break;
+            }
+            unsigned Tmp1 = SelectExpr(SetCC->getOperand(1));
+            BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
+            return;
+          }
+        else if (isZero1)
+          {
+            switch (SetCC->getCondition()) {
+            default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
+            case ISD::SETEQ:  Opc = Alpha::BEQ; break;
+            case ISD::SETLT:  Opc = Alpha::BLT; break;
+            case ISD::SETLE:  Opc = Alpha::BLE; break;
+            case ISD::SETGT:  Opc = Alpha::BGT; break;
+            case ISD::SETGE:  Opc = Alpha::BGE; break;
+            case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break;
+            case ISD::SETUGT: Opc = Alpha::BNE; break;
+            case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC
+            case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
+            case ISD::SETNE:  Opc = Alpha::BNE; break;
+            }
+            unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
+            BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
+            return;
+          }
+        else
+          {
+            unsigned Tmp1 = SelectExpr(CC);
+            if (isNE)
+              BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
+            else
+              BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
+            return;
+          }
+      } else { //FP
+        //Any comparison between 2 values should be codegened as an folded branch, as moving
+        //CC to the integer register is very expensive
+        //for a cmp b: c = a - b;
+        //a = b: c = 0
+        //a < b: c < 0
+        //a > b: c > 0
+        unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
+        unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
+        unsigned Tmp3 = MakeReg(MVT::f64);
+        BuildMI(BB, Alpha::SUBT, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+
+        switch (SetCC->getCondition()) {
+        default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
+        case ISD::SETEQ: Opc = Alpha::FBEQ; break;
+        case ISD::SETLT: Opc = Alpha::FBLT; break;
+        case ISD::SETLE: Opc = Alpha::FBLE; break;
+        case ISD::SETGT: Opc = Alpha::FBGT; break;
+        case ISD::SETGE: Opc = Alpha::FBGE; break;
+        case ISD::SETNE: Opc = Alpha::FBNE; break;
+        }
+        BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest);
+        return;
+      }
+      abort(); //Should never be reached
+    }
+  else
+    { //Giveup and do the stupid thing
+      unsigned Tmp1 = SelectExpr(CC);
+      BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
+      return;
+    }
+  abort(); //Should never be reached
+}
+
 unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
 {
   unsigned Tmp1, Tmp2, Tmp3;
@@ -886,6 +1000,8 @@
             Tmp2 = SelectExpr(N.getOperand(1));
             Tmp3 = MakeReg(MVT::i64);
             BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+            //Remeber we have the Inv for this CC
+            CCInvMap[N] = Tmp3;
             //and invert
             BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
             return Result;
@@ -1180,13 +1296,7 @@
     assert(0 && "Node not handled yet!");
 
   case ISD::BRCOND: {
-    MachineBasicBlock *Dest =
-      cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
-
-    Select(N.getOperand(0));  //chain
-
-    Tmp1 = SelectExpr(N.getOperand(1));
-    BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
+    SelectBranchCC(N);
     return;
   }
 






More information about the llvm-commits mailing list