[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