Expand formal arguments and call arguments recursively: e.g. f64 -> i64 -> 2 x i32.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32476 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-12-12 07:27:38 +00:00
parent f25212a223
commit b15974a65c

View File

@ -2860,6 +2860,32 @@ void SelectionDAGLowering::visitVACopy(CallInst &I) {
DAG.getSrcValue(I.getOperand(2))));
}
/// ExpandScalarFormalArgs - Recursively expand the formal_argument node, either
/// bit_convert it or join a pair of them with a BUILD_PAIR when appropriate.
static SDOperand ExpandScalarFormalArgs(MVT::ValueType VT, SDNode *Arg,
unsigned &i, SelectionDAG &DAG,
TargetLowering &TLI) {
if (TLI.getTypeAction(VT) != TargetLowering::Expand)
return SDOperand(Arg, i++);
MVT::ValueType EVT = TLI.getTypeToTransformTo(VT);
unsigned NumVals = MVT::getSizeInBits(VT) / MVT::getSizeInBits(EVT);
if (NumVals == 1) {
return DAG.getNode(ISD::BIT_CONVERT, VT,
ExpandScalarFormalArgs(EVT, Arg, i, DAG, TLI));
} else if (NumVals == 2) {
SDOperand Lo = ExpandScalarFormalArgs(EVT, Arg, i, DAG, TLI);
SDOperand Hi = ExpandScalarFormalArgs(EVT, Arg, i, DAG, TLI);
if (!TLI.isLittleEndian())
std::swap(Lo, Hi);
return DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
} else {
// Value scalarized into many values. Unimp for now.
assert(0 && "Cannot expand i64 -> i16 yet!");
}
return SDOperand();
}
/// 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
@ -2890,8 +2916,12 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
// If this is a large integer, it needs to be broken up into small
// integers. Figure out what the destination type is and how many small
// integers it turns into.
MVT::ValueType NVT = getTypeToTransformTo(VT);
unsigned NumVals = MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT);
MVT::ValueType NVT = VT;
unsigned NumVals = 1;
while (getTypeAction(NVT) == Expand) {
NVT = getTypeToTransformTo(NVT);
NumVals *= MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT);
}
for (unsigned i = 0; i != NumVals; ++i)
RetVals.push_back(NVT);
} else {
@ -2949,26 +2979,10 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
}
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);
if (NumVals == 1) {
SDOperand Tmp = SDOperand(Result, i++);
Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp));
} else if (NumVals == 2) {
SDOperand Lo = SDOperand(Result, i++);
SDOperand Hi = SDOperand(Result, i++);
if (!isLittleEndian())
std::swap(Lo, Hi);
Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi));
} else {
// Value scalarized into many values. Unimp for now.
assert(0 && "Cannot expand i64 -> i16 yet!");
}
// If this is a large integer or a floating point node that needs to be
// expanded, it needs to be reassembled from small integers. Figure out
// what the source elt type is and how many small integers it is.
Ops.push_back(ExpandScalarFormalArgs(VT, Result, i, DAG, *this));
} else {
// Otherwise, this is a vector type. We only support legal vectors
// right now.
@ -2998,6 +3012,39 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
}
/// ExpandScalarCallArgs - Recursively expand call argument node by
/// bit_converting it or extract a pair of elements from the larger node.
static void ExpandScalarCallArgs(MVT::ValueType VT, SDOperand Arg,
bool isSigned,
SmallVector<SDOperand, 32> &Ops,
SelectionDAG &DAG,
TargetLowering &TLI) {
if (TLI.getTypeAction(VT) != TargetLowering::Expand) {
Ops.push_back(Arg);
Ops.push_back(DAG.getConstant(isSigned, MVT::i32));
return;
}
MVT::ValueType EVT = TLI.getTypeToTransformTo(VT);
unsigned NumVals = MVT::getSizeInBits(VT) / MVT::getSizeInBits(EVT);
if (NumVals == 1) {
Arg = DAG.getNode(ISD::BIT_CONVERT, EVT, Arg);
ExpandScalarCallArgs(EVT, Arg, isSigned, Ops, DAG, TLI);
} else if (NumVals == 2) {
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, EVT, Arg,
DAG.getConstant(0, TLI.getPointerTy()));
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, EVT, Arg,
DAG.getConstant(1, TLI.getPointerTy()));
if (!TLI.isLittleEndian())
std::swap(Lo, Hi);
ExpandScalarCallArgs(EVT, Lo, isSigned, Ops, DAG, TLI);
ExpandScalarCallArgs(EVT, Hi, isSigned, Ops, DAG, TLI);
} else {
// Value scalarized into many values. Unimp for now.
assert(0 && "Cannot expand i64 -> i16 yet!");
}
}
/// 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
@ -3041,27 +3088,7 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
// 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 == 1) {
Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, VT, Op));
Ops.push_back(DAG.getConstant(isSigned, MVT::i32));
} else 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(DAG.getConstant(isSigned, MVT::i32));
Ops.push_back(Hi);
Ops.push_back(DAG.getConstant(isSigned, MVT::i32));
} else {
// Value scalarized into many values. Unimp for now.
assert(0 && "Cannot expand i64 -> i16 yet!");
}
ExpandScalarCallArgs(VT, Op, isSigned, Ops, DAG, *this);
} else {
// Otherwise, this is a vector type. We only support legal vectors
// right now.
@ -3104,8 +3131,12 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
// 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);
MVT::ValueType NVT = VT;
unsigned NumVals = 1;
while (getTypeAction(NVT) == Expand) {
NVT = getTypeToTransformTo(NVT);
NumVals *= MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT);
}
for (unsigned i = 0; i != NumVals; ++i)
RetTys.push_back(NVT);
} else {