[llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp AlphaInstrInfo.td
Andrew Lenharth
alenhar2 at cs.uiuc.edu
Sat Apr 2 14:32:55 PST 2005
Changes in directory llvm/lib/Target/Alpha:
AlphaISelPattern.cpp updated: 1.76 -> 1.77
AlphaInstrInfo.td updated: 1.37 -> 1.38
---
Log message:
Select optimization
---
Diffs of the changes: (+143 -56)
AlphaISelPattern.cpp | 197 ++++++++++++++++++++++++++++++++++++---------------
AlphaInstrInfo.td | 2
2 files changed, 143 insertions(+), 56 deletions(-)
Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp
diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.76 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.77
--- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.76 Sat Apr 2 15:06:51 2005
+++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Sat Apr 2 16:32:39 2005
@@ -335,6 +335,8 @@
void SelectBranchCC(SDOperand N);
void MoveFP2Int(unsigned src, unsigned dst, bool isDouble);
void MoveInt2FP(unsigned src, unsigned dst, bool isDouble);
+ //returns whether the sense of the comparison was inverted
+ bool SelectFPSetCC(SDOperand N, unsigned dst);
};
}
@@ -418,6 +420,64 @@
}
}
+bool ISel::SelectFPSetCC(SDOperand N, unsigned dst)
+{
+ SDNode *Node = N.Val;
+ unsigned Opc, Tmp1, Tmp2, Tmp3;
+ SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node);
+
+ //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
+ bool rev = false;
+ bool inv = false;
+
+ switch (SetCC->getCondition()) {
+ default: Node->dump(); assert(0 && "Unknown FP comparison!");
+ case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
+ case ISD::SETLT: Opc = Alpha::CMPTLT; break;
+ case ISD::SETLE: Opc = Alpha::CMPTLE; break;
+ case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
+ case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
+ case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
+ }
+
+ //FIXME: check for constant 0.0
+ ConstantFPSDNode *CN;
+ if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
+ && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
+ Tmp1 = Alpha::F31;
+ else
+ Tmp1 = SelectExpr(N.getOperand(0));
+
+ if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
+ && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
+ Tmp2 = Alpha::F31;
+ else
+ Tmp2 = SelectExpr(N.getOperand(1));
+
+ //Can only compare doubles, and dag won't promote for me
+ if (SetCC->getOperand(0).getValueType() == MVT::f32)
+ {
+ //assert(0 && "Setcc On float?\n");
+ std::cerr << "Setcc on float!\n";
+ Tmp3 = MakeReg(MVT::f64);
+ BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
+ Tmp1 = Tmp3;
+ }
+ if (SetCC->getOperand(1).getValueType() == MVT::f32)
+ {
+ //assert (0 && "Setcc On float?\n");
+ std::cerr << "Setcc on float!\n";
+ Tmp3 = MakeReg(MVT::f64);
+ BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
+ Tmp2 = Tmp3;
+ }
+
+ if (rev) std::swap(Tmp1, Tmp2);
+ //do the comparison
+ BuildMI(BB, Opc, 2, dst).addReg(Tmp1).addReg(Tmp2);
+ return inv;
+}
+
//Check to see if the load is a constant offset from a base register
void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
{
@@ -1318,62 +1378,15 @@
}
}
} else {
- //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
- bool rev = false;
- bool inv = false;
-
- switch (SetCC->getCondition()) {
- default: Node->dump(); assert(0 && "Unknown FP comparison!");
- case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
- case ISD::SETLT: Opc = Alpha::CMPTLT; break;
- case ISD::SETLE: Opc = Alpha::CMPTLE; break;
- case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
- case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
- case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
- }
-
- //FIXME: check for constant 0.0
- ConstantFPSDNode *CN;
- if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
- && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
- Tmp1 = Alpha::F31;
- else
- Tmp1 = SelectExpr(N.getOperand(0));
-
- if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
- && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
- Tmp2 = Alpha::F31;
- else
- Tmp2 = SelectExpr(N.getOperand(1));
-
- //Can only compare doubles, and dag won't promote for me
- if (SetCC->getOperand(0).getValueType() == MVT::f32)
- {
- //assert(0 && "Setcc On float?\n");
- std::cerr << "Setcc on float!\n";
- Tmp3 = MakeReg(MVT::f64);
- BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
- Tmp1 = Tmp3;
- }
- if (SetCC->getOperand(1).getValueType() == MVT::f32)
- {
- //assert (0 && "Setcc On float?\n");
- std::cerr << "Setcc on float!\n";
- Tmp3 = MakeReg(MVT::f64);
- BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
- Tmp2 = Tmp3;
- }
-
- if (rev) std::swap(Tmp1, Tmp2);
- Tmp3 = MakeReg(MVT::f64);
//do the comparison
- BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
-
+ Tmp1 = MakeReg(MVT::f64);
+ bool inv = SelectFPSetCC(N, Tmp1);
+
//now arrange for Result (int) to have a 1 or 0
- unsigned Tmp4 = MakeReg(MVT::i64);
- BuildMI(BB, Alpha::ADDQi, 2, Tmp4).addReg(Alpha::R31).addImm(1);
+ Tmp2 = MakeReg(MVT::i64);
+ BuildMI(BB, Alpha::ADDQi, 2, Tmp2).addReg(Alpha::R31).addImm(1);
Opc = inv?Alpha::CMOVNEi_FP:Alpha::CMOVEQi_FP;
- BuildMI(BB, Opc, 3, Result).addReg(Tmp4).addImm(0).addReg(Tmp3);
+ BuildMI(BB, Opc, 3, Result).addReg(Tmp2).addImm(0).addReg(Tmp1);
}
}
return Result;
@@ -1554,16 +1567,88 @@
return Result;
}
- // // case ISD::FP_TO_UINT:
-
case ISD::SELECT:
{
//FIXME: look at parent to decide if intCC can be folded, or if setCC(FP) and can save stack use
- Tmp1 = SelectExpr(N.getOperand(0)); //Cond
+ //Tmp1 = SelectExpr(N.getOperand(0)); //Cond
Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
// Get the condition into the zero flag.
+ //BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
+ SDOperand CC = N.getOperand(0);
+ SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
+
+ if (CC.getOpcode() == ISD::SETCC &&
+ !MVT::isInteger(SetCC->getOperand(0).getValueType()))
+ { //FP Setcc -> Int Select
+ Tmp1 = MakeReg(MVT::f64);
+ bool inv = SelectFPSetCC(CC, Tmp1);
+ BuildMI(BB, inv?Alpha::CMOVNE_FP:Alpha::CMOVEQ_FP, 2, Result)
+ .addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
+ return Result;
+ }
+ if (CC.getOpcode() == ISD::SETCC) {
+ //Int SetCC -> Select
+ //Dropping the CC is only useful if we are comparing to 0
+ if(SetCC->getOperand(1).getOpcode() == ISD::Constant &&
+ cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0)
+ {
+ bool useI = (SetCC->getOperand(1).getOpcode() == ISD::Constant &&
+ cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() <= 255);
+
+ switch (SetCC->getCondition()) {
+ default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
+ case ISD::SETEQ: Opc = useI?Alpha::CMOVEQi:Alpha::CMOVEQ; break;
+ case ISD::SETLT: Opc = useI?Alpha::CMOVGTi:Alpha::CMOVGT; break;
+ case ISD::SETLE: Opc = useI?Alpha::CMOVGEi:Alpha::CMOVGE; break;
+ case ISD::SETGT: Opc = useI?Alpha::CMOVLTi:Alpha::CMOVLT; break;
+ case ISD::SETGE: Opc = useI?Alpha::CMOVLEi:Alpha::CMOVLE; break;
+ case ISD::SETULT: Opc = useI?Alpha::CMOVNEi:Alpha::CMOVNE; 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 = useI?Alpha::CMOVEQi:Alpha::CMOVEQ; break; //Technically you could have this CC
+ case ISD::SETNE: Opc = useI?Alpha::CMOVNEi:Alpha::CMOVNE; break;
+ }
+ if (useI)
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp2).addReg(Tmp3)
+ .addImm(cast<ConstantSDNode>(SetCC->getOperand(1))->getValue());
+ else
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp2).addReg(Tmp3)
+ .addReg(SelectExpr(SetCC->getOperand(1)));
+ return Result;
+ }
+ if(SetCC->getOperand(1).getOpcode() == ISD::Constant &&
+ cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() == 0)
+ {
+ bool useI = (SetCC->getOperand(0).getOpcode() == ISD::Constant &&
+ cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() <= 255);
+
+ switch (SetCC->getCondition()) {
+ default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
+ case ISD::SETEQ: Opc = useI?Alpha::CMOVEQi:Alpha::CMOVEQ; break;
+ case ISD::SETLT: Opc = useI?Alpha::CMOVLTi:Alpha::CMOVLT; break;
+ case ISD::SETLE: Opc = useI?Alpha::CMOVLEi:Alpha::CMOVLE; break;
+ case ISD::SETGT: Opc = useI?Alpha::CMOVGTi:Alpha::CMOVGT; break;
+ case ISD::SETGE: Opc = useI?Alpha::CMOVGEi:Alpha::CMOVGE; break;
+ case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break;
+ case ISD::SETUGT: Opc = useI?Alpha::CMOVNEi:Alpha::CMOVNE; break;
+ case ISD::SETULE: Opc = useI?Alpha::CMOVEQi:Alpha::CMOVEQ; break; //Technically you could have this CC
+ case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
+ case ISD::SETNE: Opc = useI?Alpha::CMOVNEi:Alpha::CMOVNE; break;
+ }
+ if (useI)
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp2).addReg(Tmp3)
+ .addImm(cast<ConstantSDNode>(SetCC->getOperand(0))->getValue());
+ else
+ BuildMI(BB, Opc, 2, Result).addReg(Tmp2).addReg(Tmp3)
+ .addReg(SelectExpr(SetCC->getOperand(0)));
+ return Result;
+ }
+ //Otherwise, fall though
+ }
+ Tmp1 = SelectExpr(N.getOperand(0)); //Cond
BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
+
return Result;
}
Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td
diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.37 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.38
--- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.37 Sat Apr 2 15:06:51 2005
+++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Sat Apr 2 16:32:39 2005
@@ -55,6 +55,7 @@
let isReturn = 1, isTerminator = 1 in
def RETURN : PseudoInstAlpha<(ops ), "ret $$31,($$26),1">; //Return from subroutine
+//These are evil as they get expanded into multiple instructions to take care of reallocation
let Uses = [R29], Defs = [R28] in {
def LOAD_ADDR : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "lda $RA,$DISP">; //Load address
def LDQ_SYM : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "ldq $RA,$DISP">; //Load quadword
@@ -80,6 +81,7 @@
//RESULTS of these go to R27
+//These are also evil as the assembler expands them into calls
let Uses = [R29],
Defs = [R28, R23, R24, R25, R27] in
{
More information about the llvm-commits
mailing list