[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue May 16 15:53:32 PDT 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.374 -> 1.375
SelectionDAG.cpp updated: 1.307 -> 1.308
SelectionDAGISel.cpp updated: 1.242 -> 1.243
---
Log message:
Add a new ISD::CALL node, make the default impl of TargetLowering::LowerCallTo
produce it.
---
Diffs of the changes: (+143 -3)
LegalizeDAG.cpp | 5 +
SelectionDAG.cpp | 1
SelectionDAGISel.cpp | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 143 insertions(+), 3 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.374 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.375
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.374 Tue May 16 00:49:56 2006
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue May 16 17:53:20 2006
@@ -818,11 +818,12 @@
break;
case ISD::FORMAL_ARGUMENTS:
+ case ISD::CALL:
// The only option for this is to custom lower it.
Result = TLI.LowerOperation(Result.getValue(0), DAG);
- assert(Result.Val && "Target didn't custom lower ISD::FORMAL_ARGUMENTS!");
+ assert(Result.Val && "Target didn't custom lower this node!");
- // Since FORMAL_ARGUMENTS nodes produce multiple values, make sure to
+ // Since CALL/FORMAL_ARGUMENTS nodes produce multiple values, make sure to
// remember that we legalized all of them, so it doesn't get relegalized.
for (unsigned i = 0, e = Result.Val->getNumValues(); i != e; ++i) {
Tmp1 = LegalizeOp(Result.getValue(i));
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.307 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.308
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.307 Fri May 12 13:04:28 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue May 16 17:53:20 2006
@@ -2841,6 +2841,7 @@
case ISD::INLINEASM: return "inlineasm";
case ISD::HANDLENODE: return "handlenode";
case ISD::FORMAL_ARGUMENTS: return "formal_arguments";
+ case ISD::CALL: return "call";
// Unary operators
case ISD::FABS: return "fabs";
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.242 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.243
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.242 Tue May 16 01:45:34 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue May 16 17:53:20 2006
@@ -2344,7 +2344,8 @@
/// TargetLowering::LowerArguments - This is the default LowerArguments
/// implementation, which just inserts a FORMAL_ARGUMENTS node. FIXME: When all
-/// targets are migrated to using FORMAL_ARGUMENTS, this hook should be removed.
+/// targets are migrated to using FORMAL_ARGUMENTS, this hook should be
+/// integrated into SDISel.
std::vector<SDOperand>
TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
// Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node.
@@ -2477,8 +2478,145 @@
return Ops;
}
+
+/// TargetLowering::LowerCallTo - This is the default LowerCallTo
+/// implementation, which just inserts an ISD::CALL node, which is later custom
+/// lowered by the target to something concrete. FIXME: When all targets are
+/// migrated to using ISD::CALL, this hook should be integrated into SDISel.
+std::pair<SDOperand, SDOperand>
+TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
+ unsigned CallingConv, bool isTailCall,
+ SDOperand Callee,
+ ArgListTy &Args, SelectionDAG &DAG) {
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Chain); // Op#0 - Chain
+ Ops.push_back(DAG.getConstant(CallingConv, getPointerTy())); // Op#1 - CC
+ Ops.push_back(DAG.getConstant(isVarArg, getPointerTy())); // Op#2 - VarArg
+ Ops.push_back(DAG.getConstant(isTailCall, getPointerTy())); // Op#3 - Tail
+ Ops.push_back(Callee);
+
+ // Handle all of the outgoing arguments.
+ for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+ MVT::ValueType VT = getValueType(Args[i].second);
+ SDOperand Op = Args[i].first;
+ switch (getTypeAction(VT)) {
+ default: assert(0 && "Unknown type action!");
+ case Legal:
+ Ops.push_back(Op);
+ break;
+ case Promote:
+ if (MVT::isInteger(VT)) {
+ unsigned ExtOp = Args[i].second->isSigned() ?
+ ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ Op = DAG.getNode(ExtOp, getTypeToTransformTo(VT), Op);
+ } else {
+ assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
+ Op = DAG.getNode(ISD::FP_EXTEND, getTypeToTransformTo(VT), Op);
+ }
+ Ops.push_back(Op);
+ break;
+ case Expand:
+ if (VT != MVT::Vector) {
+ // If this is a large integer, it needs to be broken down into small
+ // integers. Figure out what the source elt type is and how many small
+ // integers it is.
+ MVT::ValueType NVT = getTypeToTransformTo(VT);
+ unsigned NumVals = MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT);
+ if (NumVals == 2) {
+ SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Op,
+ DAG.getConstant(0, getPointerTy()));
+ SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Op,
+ DAG.getConstant(1, getPointerTy()));
+ if (!isLittleEndian())
+ std::swap(Lo, Hi);
+
+ Ops.push_back(Lo);
+ Ops.push_back(Hi);
+ } else {
+ // Value scalarized into many values. Unimp for now.
+ assert(0 && "Cannot expand i64 -> i16 yet!");
+ }
+ } else {
+ assert(0 && "Doesn't handle vectors yet!");
+ }
+ break;
+ }
+ }
+
+ // Figure out the result value types.
+ std::vector<MVT::ValueType> RetTys;
+
+ if (RetTy != Type::VoidTy) {
+ MVT::ValueType VT = getValueType(RetTy);
+ switch (getTypeAction(VT)) {
+ default: assert(0 && "Unknown type action!");
+ case Legal:
+ RetTys.push_back(VT);
+ break;
+ case Promote:
+ RetTys.push_back(getTypeToTransformTo(VT));
+ break;
+ case Expand:
+ if (VT != MVT::Vector) {
+ // If this is a large integer, it needs to be reassembled from small
+ // integers. Figure out what the source elt type is and how many small
+ // integers it is.
+ MVT::ValueType NVT = getTypeToTransformTo(VT);
+ unsigned NumVals = MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT);
+ for (unsigned i = 0; i != NumVals; ++i)
+ RetTys.push_back(NVT);
+ } else {
+ assert(0 && "Doesn't handle vectors yet!");
+ }
+ }
+ }
+
+ RetTys.push_back(MVT::Other); // Always has a chain.
+
+ // Finally, create the CALL node.
+ SDOperand Res = DAG.getNode(ISD::CALL, RetTys, Ops);
+
+ // This returns a pair of operands. The first element is the
+ // return value for the function (if RetTy is not VoidTy). The second
+ // element is the outgoing token chain.
+ SDOperand ResVal;
+ if (RetTys.size() != 1) {
+ MVT::ValueType VT = getValueType(RetTy);
+ if (RetTys.size() == 2) {
+ ResVal = Res;
+
+ // If this value was promoted, truncate it down.
+ if (ResVal.getValueType() != VT) {
+ if (MVT::isInteger(VT)) {
+ unsigned AssertOp = RetTy->isSigned() ?
+ ISD::AssertSext : ISD::AssertZext;
+ ResVal = DAG.getNode(AssertOp, ResVal.getValueType(), ResVal,
+ DAG.getValueType(VT));
+ ResVal = DAG.getNode(ISD::TRUNCATE, VT, ResVal);
+ } else {
+ assert(MVT::isFloatingPoint(VT));
+ ResVal = DAG.getNode(ISD::FP_ROUND, VT, ResVal);
+ }
+ }
+ } else if (RetTys.size() == 3) {
+ ResVal = DAG.getNode(ISD::BUILD_PAIR, VT,
+ Res.getValue(0), Res.getValue(1));
+
+ } else {
+ assert(0 && "Case not handled yet!");
+ }
+ }
+
+ return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
+}
+
+
+
// It is always conservatively correct for llvm.returnaddress and
// llvm.frameaddress to return 0.
+//
+// FIXME: Change this to insert a FRAMEADDR/RETURNADDR node, and have that be
+// expanded to 0 if the target wants.
std::pair<SDOperand, SDOperand>
TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain,
unsigned Depth, SelectionDAG &DAG) {
More information about the llvm-commits
mailing list