[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Jul 15 17:20:11 PDT 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.140 -> 1.141
---
Log message:
Break the code for expanding UINT_TO_FP operations out into its own
SelectionDAGLegalize::ExpandLegalUINT_TO_FP method.
Add a new method, PromoteLegalUINT_TO_FP, which allows targets to request
that UINT_TO_FP operations be promoted to a larger input type. This is
useful for targets that have some UINT_TO_FP or SINT_TO_FP operations but
not all of them (like X86).
The same should be done with SINT_TO_FP, but this patch does not do that
yet.
---
Diffs of the changes: (+116 -35)
LegalizeDAG.cpp | 151 +++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 116 insertions(+), 35 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.140 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.141
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.140 Tue Jul 12 21:00:04 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Jul 15 19:19:57 2005
@@ -124,6 +124,10 @@
SDOperand &Hi);
SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
SDOperand Source);
+
+ SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
+ SDOperand PromoteLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
+
bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
SDOperand &Lo, SDOperand &Hi);
void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt,
@@ -147,6 +151,102 @@
"Too many value types for ValueTypeActions to hold!");
}
+/// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a
+/// UINT_TO_FP operation of the specified operand when the target requests that
+/// we expand it. At this point, we know that the result and operand types are
+/// legal for the target.
+SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
+ MVT::ValueType DestVT) {
+ assert(Op0.getValueType() == MVT::i32 &&
+ "This code only works for i32 input: extend in the future");
+ SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
+
+ SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),
+ Op0,
+ DAG.getConstant(0,
+ Op0.getValueType()));
+ SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+ SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
+ SignSet, Four, Zero);
+
+ uint64_t FF = 0x5f800000ULL;
+ if (TLI.isLittleEndian()) FF <<= 32;
+ static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
+
+ MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
+ SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
+ TLI.getPointerTy());
+ CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
+ SDOperand FudgeInReg;
+ if (DestVT == MVT::f32)
+ FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
+ DAG.getSrcValue(NULL));
+ else {
+ assert(DestVT == MVT::f64 && "Unexpected conversion");
+ FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
+ DAG.getEntryNode(), CPIdx,
+ DAG.getSrcValue(NULL), MVT::f32));
+ }
+
+ NeedsAnotherIteration = true;
+ return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg);
+}
+
+/// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a
+/// UINT_TO_FP operation of the specified operand when the target requests that
+/// we promote it. At this point, we know that the result and operand types are
+/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
+/// operation that takes a larger input.
+SDOperand SelectionDAGLegalize::PromoteLegalUINT_TO_FP(SDOperand LegalOp,
+ MVT::ValueType DestVT) {
+ // First step, figure out the appropriate *INT_TO_FP operation to use.
+ MVT::ValueType NewInTy = LegalOp.getValueType();
+
+ unsigned OpToUse = 0;
+
+ // Scan for the appropriate larger type to use.
+ while (1) {
+ NewInTy = (MVT::ValueType)(NewInTy+1);
+ assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
+
+ // If the target supports SINT_TO_FP of this type, use it.
+ switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
+ default: break;
+ case TargetLowering::Legal:
+ if (!TLI.hasNativeSupportFor(NewInTy))
+ break; // Can't use this datatype.
+ // FALL THROUGH.
+ case TargetLowering::Custom:
+ OpToUse = ISD::SINT_TO_FP;
+ break;
+ }
+ if (OpToUse) break;
+
+ // If the target supports UINT_TO_FP of this type, use it.
+ switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
+ default: break;
+ case TargetLowering::Legal:
+ if (!TLI.hasNativeSupportFor(NewInTy))
+ break; // Can't use this datatype.
+ // FALL THROUGH.
+ case TargetLowering::Custom:
+ OpToUse = ISD::UINT_TO_FP;
+ break;
+ }
+ if (OpToUse) break;
+
+ // Otherwise, try a larger type.
+ }
+
+ // Make sure to legalize any nodes we create here in the next pass.
+ NeedsAnotherIteration = true;
+
+ // Okay, we found the operation and type to use. Zero extend our input to the
+ // desired type then run the operation on it.
+ return DAG.getNode(OpToUse, DestVT,
+ DAG.getNode(ISD::ZERO_EXTEND, NewInTy, LegalOp));
+}
+
void SelectionDAGLegalize::LegalizeDAG() {
SDOperand OldRoot = DAG.getRoot();
SDOperand NewRoot = LegalizeOp(OldRoot);
@@ -1338,42 +1438,23 @@
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case Legal:
//still made need to expand if the op is illegal, but the types are legal
- if (Node->getOpcode() == ISD::UINT_TO_FP &&
- TLI.getOperationAction(Node->getOpcode(),
- Node->getOperand(0).getValueType())
- == TargetLowering::Expand) {
- SDOperand Op0 = LegalizeOp(Node->getOperand(0));
- Tmp1 = DAG.getNode(ISD::SINT_TO_FP, Node->getValueType(0),
- Op0);
-
- SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),
- Op0,
- DAG.getConstant(0,
- Op0.getValueType()));
- SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
- SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
- SignSet, Four, Zero);
- uint64_t FF = 0x5f800000ULL;
- if (TLI.isLittleEndian()) FF <<= 32;
- static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
-
- MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
- SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
- TLI.getPointerTy());
- CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
- SDOperand FudgeInReg;
- if (Node->getValueType(0) == MVT::f32)
- FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
- DAG.getSrcValue(NULL));
- else {
- assert(Node->getValueType(0) == MVT::f64 && "Unexpected conversion");
- FudgeInReg =
- LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
- DAG.getEntryNode(), CPIdx,
- DAG.getSrcValue(NULL), MVT::f32));
+ if (Node->getOpcode() == ISD::UINT_TO_FP) {
+ switch (TLI.getOperationAction(Node->getOpcode(),
+ Node->getOperand(0).getValueType())) {
+ default: assert(0 && "Unknown operation action!");
+ case TargetLowering::Expand:
+ Result = ExpandLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
+ Node->getValueType(0));
+ AddLegalizedOperand(Op, Result);
+ return Result;
+ case TargetLowering::Promote:
+ Result = PromoteLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
+ Node->getValueType(0));
+ AddLegalizedOperand(Op, Result);
+ return Result;
+ case TargetLowering::Legal:
+ break;
}
- Result = DAG.getNode(ISD::ADD, Node->getValueType(0), Tmp1, FudgeInReg);
- break;
}
Tmp1 = LegalizeOp(Node->getOperand(0));
if (Tmp1 != Node->getOperand(0))
More information about the llvm-commits
mailing list