Hi Evan,
I'm currently testing the attached patch, which seems to fix the
problems for PPC. It extends getCopyToParts and getCopyFromParts
to have an extra parameter to indicate when endian-swapping is
needed. I don't have access to a PPC test environment; I've included
a few trivial regression tests in this patch; I'll do some more
soon.
Copying to virtual registers is always done in little-endian order,
while copying to physical registers, arguments, or return values,
is done in target-endian order. I wonder if it would make sense to
change to using target-endian order for virtual registers as well?
Dan
On Tue, Jul 03, 2007 at 06:35:58PM -0700, Evan Cheng wrote:
> Hi Dan,
>
> This patch is breaking llvm-gcc bootstrapping on PPC.
>
> I am not sure what exactly wrong is it. But the old code has a check
> for endianness while your new code doesn't. Can you check again if
> you are taking endianness into consideration?
>
> Thanks,
>
> Evan
>
> On Jul 2, 2007, at 9:18 AM, Dan Gohman wrote:
>
> >Author: djg
> >Date: Mon Jul 2 11:18:06 2007
> >New Revision: 37843
> >
> >URL: http://llvm.org/viewvc/llvm-project?rev=37843&view=rev
> >Log:
> >Replace ExpandScalarFormalArgs and ExpandScalarCallArgs with the newly
> >refactored getCopyFromParts and getCopyToParts, which are more
> >general.
> >This effectively adds support for lowering illegal by-val vector call
> >arguments.
> >
> >Modified:
> > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> >
> >Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> >URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
> >SelectionDAG/SelectionDAGISel.cpp?
> >rev=37843&r1=37842&r2=37843&view=diff
> >======================================================================
> >========
> >--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> >(original)
> >+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon
> >Jul 2 11:18:06 2007
> >@@ -2861,7 +2861,7 @@
> > if (!MVT::isVector(ValueVT) || NumParts == 1) {
> > // If the value was expanded, copy from the parts.
> > if (NumParts > 1) {
> >- for (unsigned i = 0; i < NumParts; ++i)
> >+ for (unsigned i = 0; i != NumParts; ++i)
> > Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
> > DAG.getConstant(i, MVT::i32));
> > return;
> >@@ -2950,7 +2950,7 @@
> > // Copy the legal parts from the registers.
> > unsigned NumParts = Regs.size();
> > SmallVector<SDOperand, 8> Parts(NumParts);
> >- for (unsigned i = 0; i < NumParts; ++i) {
> >+ for (unsigned i = 0; i != NumParts; ++i) {
> > SDOperand Part = Flag ?
> > DAG.getCopyFromReg(Chain, Regs[i], RegVT,
> >*Flag) :
> > DAG.getCopyFromReg(Chain, Regs[i], RegVT);
> >@@ -2981,7 +2981,7 @@
> > getCopyToParts(DAG, Val, &Parts[0], NumParts, RegVT);
> >
> > // Copy the parts into the registers.
> >- for (unsigned i = 0; i < NumParts; ++i) {
> >+ for (unsigned i = 0; i != NumParts; ++i) {
> > SDOperand Part = Flag ?
> > DAG.getCopyToReg(Chain, R[i], Parts[i], *Flag) :
> > DAG.getCopyToReg(Chain, R[i], Parts[i]);
> >@@ -3746,32 +3746,6 @@
> > 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
> >@@ -3842,8 +3816,8 @@
> > SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS,
> > DAG.getNodeValueTypes(RetVals),
> >RetVals.size(),
> > &Ops[0], Ops.size()).Val;
> >-
> >- DAG.setRoot(SDOperand(Result, Result->getNumValues()-1));
> >+ unsigned NumArgRegs = Result->getNumValues() - 1;
> >+ DAG.setRoot(SDOperand(Result, NumArgRegs));
> >
> > // Set up the return result vector.
> > Ops.clear();
> >@@ -3875,79 +3849,22 @@
> > Ops.push_back(Op);
> > break;
> > }
> >- case Expand:
> >- if (!MVT::isVector(VT)) {
> >- // 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.
> >- const VectorType *PTy = cast<VectorType>(I->getType());
> >- unsigned NumElems = PTy->getNumElements();
> >- const Type *EltTy = PTy->getElementType();
> >-
> >- // Figure out if there is a Packed type corresponding to
> >this Vector
> >- // type. If so, convert to the vector type.
> >- MVT::ValueType TVT =
> >- MVT::getVectorType(getValueType(EltTy), NumElems);
> >- if (TVT != MVT::Other && isTypeLegal(TVT)) {
> >- SDOperand N = SDOperand(Result, i++);
> >- // Handle copies from vectors to registers.
> >- N = DAG.getNode(ISD::BIT_CONVERT, TVT, N);
> >- Ops.push_back(N);
> >- } else {
> >- assert(0 && "Don't support illegal by-val vector
> >arguments yet!");
> >- abort();
> >- }
> >- }
> >+ case Expand: {
> >+ MVT::ValueType PartVT = getRegisterType(VT);
> >+ unsigned NumParts = getNumRegisters(VT);
> >+ SmallVector<SDOperand, 4> Parts(NumParts);
> >+ for (unsigned j = 0; j != NumParts; ++j)
> >+ Parts[j] = SDOperand(Result, i++);
> >+ Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts,
> >PartVT, VT));
> > break;
> > }
> >+ }
> > }
> >+ assert(i == NumArgRegs && "Argument register count mismatch!");
> > return Ops;
> > }
> >
> >
> >-/// 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,
> >- unsigned Flags,
> >- SmallVector<SDOperand, 32> &Ops,
> >- SelectionDAG &DAG,
> >- TargetLowering &TLI,
> >- bool isFirst = true) {
> >-
> >- if (TLI.getTypeAction(VT) != TargetLowering::Expand) {
> >- // if it isn't first piece, alignment must be 1
> >- if (!isFirst)
> >- Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
> >- (1 << ISD::ParamFlags::OrigAlignmentOffs);
> >- Ops.push_back(Arg);
> >- Ops.push_back(DAG.getConstant(Flags, 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, Flags, Ops, DAG, TLI, isFirst);
> >- } 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, Flags, Ops, DAG, TLI, isFirst);
> >- ExpandScalarCallArgs(EVT, Hi, Flags, Ops, DAG, TLI, false);
> >- } 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
> >@@ -4014,35 +3931,24 @@
> > Ops.push_back(Op);
> > Ops.push_back(DAG.getConstant(Flags, MVT::i32));
> > break;
> >- case Expand:
> >- if (!MVT::isVector(VT)) {
> >- // 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.
> >- ExpandScalarCallArgs(VT, Op, Flags, Ops, DAG, *this);
> >- } else {
> >- // Otherwise, this is a vector type. We only support
> >legal vectors
> >- // right now.
> >- const VectorType *PTy = cast<VectorType>(Args[i].Ty);
> >- unsigned NumElems = PTy->getNumElements();
> >- const Type *EltTy = PTy->getElementType();
> >-
> >- // Figure out if there is a Packed type corresponding to
> >this Vector
> >- // type. If so, convert to the vector type.
> >- MVT::ValueType TVT =
> >- MVT::getVectorType(getValueType(EltTy), NumElems);
> >- if (TVT != MVT::Other && isTypeLegal(TVT)) {
> >- // Insert a BIT_CONVERT of the original type to the
> >vector type.
> >- Op = DAG.getNode(ISD::BIT_CONVERT, TVT, Op);
> >- Ops.push_back(Op);
> >- Ops.push_back(DAG.getConstant(Flags, MVT::i32));
> >- } else {
> >- assert(0 && "Don't support illegal by-val vector call
> >args yet!");
> >- abort();
> >- }
> >+ case Expand: {
> >+ MVT::ValueType PartVT = getRegisterType(VT);
> >+ unsigned NumParts = getNumRegisters(VT);
> >+ SmallVector<SDOperand, 4> Parts(NumParts);
> >+ getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT);
> >+ for (unsigned i = 0; i != NumParts; ++i) {
> >+ // if it isn't first piece, alignment must be 1
> >+ unsigned MyFlags = Flags;
> >+ if (i != 0)
> >+ MyFlags = (MyFlags & (~ISD::ParamFlags::OrigAlignment)) |
> >+ (1 << ISD::ParamFlags::OrigAlignmentOffs);
> >+
> >+ Ops.push_back(Parts[i]);
> >+ Ops.push_back(DAG.getConstant(MyFlags, MVT::i32));
> > }
> > break;
> > }
> >+ }
> > }
> >
> > // Figure out the result value types.
> >@@ -4360,7 +4266,7 @@
> >
> > // Copy the value by legal parts into sequential virtual registers.
> > getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT);
> >- for (unsigned i = 0; i < NumRegs; ++i)
> >+ for (unsigned i = 0; i != NumRegs; ++i)
> > Chains[i] = DAG.getCopyToReg(getRoot(), Reg + i, Regs[i]);
> > return DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0],
> >NumRegs);
> > }
> >
> >
> >_______________________________________________
> >llvm-commits mailing list
> >[email protected]
> >http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
Index: test/CodeGen/PowerPC/big-endian-actual-args.ll
===================================================================
--- test/CodeGen/PowerPC/big-endian-actual-args.ll (revision 0)
+++ test/CodeGen/PowerPC/big-endian-actual-args.ll (revision 0)
@@ -0,0 +1,7 @@
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {addc 4, 4, 6}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {adde 3, 3, 5}
+
+define i64 @foo(i64 %x, i64 %y) {
+ %z = add i64 %x, %y
+ ret i64 %z
+}
Index: test/CodeGen/PowerPC/big-endian-formal-args.ll
===================================================================
--- test/CodeGen/PowerPC/big-endian-formal-args.ll (revision 0)
+++ test/CodeGen/PowerPC/big-endian-formal-args.ll (revision 0)
@@ -0,0 +1,11 @@
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {li 6, 3}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {li 4, 2}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {li 3, 0}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {mr 5, 3}
+
+declare void @bar(i64 %x, i64 %y)
+
+define void @foo() {
+ call void @bar(i64 2, i64 3)
+ ret void
+}
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (revision 37907)
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (working copy)
@@ -613,6 +613,195 @@
};
} // end namespace llvm
+
+/// getCopyFromParts - Create a value that contains the
+/// specified legal parts combined into the value they represent.
+static SDOperand getCopyFromParts(SelectionDAG &DAG,
+ const SDOperand *Parts,
+ unsigned NumParts,
+ MVT::ValueType PartVT,
+ MVT::ValueType ValueVT,
+ bool EndianOrder,
+ ISD::NodeType AssertOp = ISD::DELETED_NODE) {
+ if (!MVT::isVector(ValueVT) || NumParts == 1) {
+ SDOperand Val = Parts[0];
+
+ // If the value was expanded, copy from the top part.
+ if (NumParts > 1) {
+ assert(NumParts == 2 &&
+ "Cannot expand to more than 2 elts yet!");
+ SDOperand Hi = Parts[1];
+ if (EndianOrder && !DAG.getTargetLoweringInfo().isLittleEndian())
+ std::swap(Val, Hi);
+ return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
+ }
+
+ // Otherwise, if the value was promoted or extended, truncate it to the
+ // appropriate type.
+ if (PartVT == ValueVT)
+ return Val;
+
+ if (MVT::isVector(PartVT)) {
+ assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
+ return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+ }
+
+ if (MVT::isInteger(PartVT) &&
+ MVT::isInteger(ValueVT)) {
+ if (ValueVT < PartVT) {
+ // For a truncate, see if we have any information to
+ // indicate whether the truncated bits will always be
+ // zero or sign-extension.
+ if (AssertOp != ISD::DELETED_NODE)
+ Val = DAG.getNode(AssertOp, PartVT, Val,
+ DAG.getValueType(ValueVT));
+ return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+ } else {
+ return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+ }
+ }
+
+ if (MVT::isFloatingPoint(PartVT) &&
+ MVT::isFloatingPoint(ValueVT))
+ return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+
+ if (MVT::getSizeInBits(PartVT) ==
+ MVT::getSizeInBits(ValueVT))
+ return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+
+ assert(0 && "Unknown mismatch!");
+ }
+
+ // Handle a multi-element vector.
+ MVT::ValueType IntermediateVT, RegisterVT;
+ unsigned NumIntermediates;
+ unsigned NumRegs =
+ DAG.getTargetLoweringInfo()
+ .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+ RegisterVT);
+
+ assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+ assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+ assert(RegisterVT == Parts[0].getValueType() &&
+ "Part type doesn't match part!");
+
+ // Assemble the parts into intermediate operands.
+ SmallVector<SDOperand, 8> Ops(NumIntermediates);
+ if (NumIntermediates == NumParts) {
+ // If the register was not expanded, truncate or copy the value,
+ // as appropriate.
+ for (unsigned i = 0; i != NumParts; ++i)
+ Ops[i] = getCopyFromParts(DAG, &Parts[i], 1,
+ PartVT, IntermediateVT, EndianOrder);
+ } else if (NumParts > 0) {
+ // If the intermediate type was expanded, build the intermediate operands
+ // from the parts.
+ assert(NumIntermediates % NumParts == 0 &&
+ "Must expand into a divisible number of parts!");
+ unsigned Factor = NumIntermediates / NumParts;
+ for (unsigned i = 0; i != NumIntermediates; ++i)
+ Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
+ PartVT, IntermediateVT, EndianOrder);
+ }
+
+ // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
+ // operands.
+ return DAG.getNode(MVT::isVector(IntermediateVT) ?
+ ISD::CONCAT_VECTORS :
+ ISD::BUILD_VECTOR,
+ ValueVT, &Ops[0], NumParts);
+}
+
+/// getCopyToParts - Create a series of nodes that contain the
+/// specified value split into legal parts.
+static void getCopyToParts(SelectionDAG &DAG,
+ SDOperand Val,
+ SDOperand *Parts,
+ unsigned NumParts,
+ MVT::ValueType PartVT,
+ bool EndianOrder) {
+ MVT::ValueType ValueVT = Val.getValueType();
+
+ if (!MVT::isVector(ValueVT) || NumParts == 1) {
+ // If the value was expanded, copy from the parts.
+ if (NumParts > 1) {
+ for (unsigned i = 0; i != NumParts; ++i)
+ Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
+ DAG.getConstant(i, MVT::i32));
+ if (EndianOrder && !DAG.getTargetLoweringInfo().isLittleEndian())
+ std::reverse(Parts, Parts + NumParts);
+ return;
+ }
+
+ // If there is a single part and the types differ, this must be
+ // a promotion.
+ if (PartVT != ValueVT) {
+ if (MVT::isVector(PartVT)) {
+ assert(MVT::isVector(ValueVT) &&
+ "Not a vector-vector cast?");
+ Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+ } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
+ if (PartVT < ValueVT)
+ Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val);
+ else
+ Val = DAG.getNode(ISD::ANY_EXTEND, PartVT, Val);
+ } else if (MVT::isFloatingPoint(PartVT) &&
+ MVT::isFloatingPoint(ValueVT)) {
+ Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
+ } else if (MVT::getSizeInBits(PartVT) ==
+ MVT::getSizeInBits(ValueVT)) {
+ Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+ } else {
+ assert(0 && "Unknown mismatch!");
+ }
+ }
+ Parts[0] = Val;
+ return;
+ }
+
+ // Handle a multi-element vector.
+ MVT::ValueType IntermediateVT, RegisterVT;
+ unsigned NumIntermediates;
+ unsigned NumRegs =
+ DAG.getTargetLoweringInfo()
+ .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+ RegisterVT);
+ unsigned NumElements = MVT::getVectorNumElements(ValueVT);
+
+ assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+ assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+
+ // Split the vector into intermediate operands.
+ SmallVector<SDOperand, 8> Ops(NumIntermediates);
+ for (unsigned i = 0; i != NumIntermediates; ++i)
+ if (MVT::isVector(IntermediateVT))
+ Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
+ IntermediateVT, Val,
+ DAG.getConstant(i * (NumElements /
NumIntermediates),
+ MVT::i32));
+ else
+ Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+ IntermediateVT, Val,
+ DAG.getConstant(i, MVT::i32));
+
+ // Split the intermediate operands into legal parts.
+ if (NumParts == NumIntermediates) {
+ // If the register was not expanded, promote or copy the value,
+ // as appropriate.
+ for (unsigned i = 0; i != NumParts; ++i)
+ getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT, EndianOrder);
+ } else if (NumParts > 0) {
+ // If the intermediate type was expanded, split each the value into
+ // legal parts.
+ assert(NumParts % NumIntermediates == 0 &&
+ "Must expand into a divisible number of parts!");
+ unsigned Factor = NumParts / NumIntermediates;
+ for (unsigned i = 0; i != NumIntermediates; ++i)
+ getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT,
EndianOrder);
+ }
+}
+
+
SDOperand SelectionDAGLowering::getValue(const Value *V) {
SDOperand &N = NodeMap[V];
if (N.Val) return N;
@@ -713,8 +902,8 @@
SDOperand RetOp = getValue(I.getOperand(i));
// If this is an integer return value, we need to promote it ourselves to
- // the full width of a register, since LegalizeOp will use ANY_EXTEND
rather
- // than sign/zero.
+ // the full width of a register, since getCopyToParts and Legalize will use
+ // ANY_EXTEND rather than sign/zero.
// FIXME: C calling convention requires the return type to be promoted to
// at least 32-bit. But this is not necessary for non-C calling
conventions.
if (MVT::isInteger(RetOp.getValueType()) &&
@@ -732,9 +921,19 @@
if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp);
+ NewValues.push_back(RetOp);
+ NewValues.push_back(DAG.getConstant(false, MVT::i32));
+ } else {
+ MVT::ValueType VT = RetOp.getValueType();
+ unsigned NumParts = TLI.getNumRegisters(VT);
+ MVT::ValueType PartVT = TLI.getRegisterType(VT);
+ SmallVector<SDOperand, 4> Parts(NumParts);
+ getCopyToParts(DAG, RetOp, &Parts[0], NumParts, PartVT, true);
+ for (unsigned i = 0; i < NumParts; ++i) {
+ NewValues.push_back(Parts[i]);
+ NewValues.push_back(DAG.getConstant(false, MVT::i32));
+ }
}
- NewValues.push_back(RetOp);
- NewValues.push_back(DAG.getConstant(false, MVT::i32));
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
&NewValues[0], NewValues.size()));
@@ -2779,197 +2978,14 @@
}
-/// getCopyFromParts - Create a value that contains the
-/// specified legal parts combined into the value they represent.
-static SDOperand getCopyFromParts(SelectionDAG &DAG,
- const SDOperand *Parts,
- unsigned NumParts,
- MVT::ValueType PartVT,
- MVT::ValueType ValueVT,
- ISD::NodeType AssertOp = ISD::DELETED_NODE) {
- if (!MVT::isVector(ValueVT) || NumParts == 1) {
- SDOperand Val = Parts[0];
-
- // If the value was expanded, copy from the top part.
- if (NumParts > 1) {
- assert(NumParts == 2 &&
- "Cannot expand to more than 2 elts yet!");
- SDOperand Hi = Parts[1];
- return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
- }
-
- // Otherwise, if the value was promoted or extended, truncate it to the
- // appropriate type.
- if (PartVT == ValueVT)
- return Val;
-
- if (MVT::isVector(PartVT)) {
- assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
- return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
- }
-
- if (MVT::isInteger(PartVT) &&
- MVT::isInteger(ValueVT)) {
- if (ValueVT < PartVT) {
- // For a truncate, see if we have any information to
- // indicate whether the truncated bits will always be
- // zero or sign-extension.
- if (AssertOp != ISD::DELETED_NODE)
- Val = DAG.getNode(AssertOp, PartVT, Val,
- DAG.getValueType(ValueVT));
- return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
- } else {
- return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
- }
- }
-
- if (MVT::isFloatingPoint(PartVT) &&
- MVT::isFloatingPoint(ValueVT))
- return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
-
- if (MVT::getSizeInBits(PartVT) ==
- MVT::getSizeInBits(ValueVT))
- return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
-
- assert(0 && "Unknown mismatch!");
- }
-
- // Handle a multi-element vector.
- MVT::ValueType IntermediateVT, RegisterVT;
- unsigned NumIntermediates;
- unsigned NumRegs =
- DAG.getTargetLoweringInfo()
- .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
- RegisterVT);
-
- assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
- assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
- assert(RegisterVT == Parts[0].getValueType() &&
- "Part type doesn't match part!");
-
- // Assemble the parts into intermediate operands.
- SmallVector<SDOperand, 8> Ops(NumIntermediates);
- if (NumIntermediates == NumParts) {
- // If the register was not expanded, truncate or copy the value,
- // as appropriate.
- for (unsigned i = 0; i != NumParts; ++i)
- Ops[i] = getCopyFromParts(DAG, &Parts[i], 1, PartVT, IntermediateVT);
- } else if (NumParts > 0) {
- // If the intermediate type was expanded, build the intermediate operands
- // from the parts.
- assert(NumIntermediates % NumParts == 0 &&
- "Must expand into a divisible number of parts!");
- unsigned Factor = NumIntermediates / NumParts;
- for (unsigned i = 0; i != NumIntermediates; ++i)
- Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
- PartVT, IntermediateVT);
- }
-
- // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
- // operands.
- return DAG.getNode(MVT::isVector(IntermediateVT) ?
- ISD::CONCAT_VECTORS :
- ISD::BUILD_VECTOR,
- ValueVT, &Ops[0], NumParts);
-}
-
-/// getCopyToParts - Create a series of nodes that contain the
-/// specified value split into legal parts.
-static void getCopyToParts(SelectionDAG &DAG,
- SDOperand Val,
- SDOperand *Parts,
- unsigned NumParts,
- MVT::ValueType PartVT) {
- MVT::ValueType ValueVT = Val.getValueType();
-
- if (!MVT::isVector(ValueVT) || NumParts == 1) {
- // If the value was expanded, copy from the parts.
- if (NumParts > 1) {
- for (unsigned i = 0; i != NumParts; ++i)
- Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
- DAG.getConstant(i, MVT::i32));
- return;
- }
-
- // If there is a single part and the types differ, this must be
- // a promotion.
- if (PartVT != ValueVT) {
- if (MVT::isVector(PartVT)) {
- assert(MVT::isVector(ValueVT) &&
- "Not a vector-vector cast?");
- Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
- } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
- if (PartVT < ValueVT)
- Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val);
- else
- Val = DAG.getNode(ISD::ANY_EXTEND, PartVT, Val);
- } else if (MVT::isFloatingPoint(PartVT) &&
- MVT::isFloatingPoint(ValueVT)) {
- Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
- } else if (MVT::getSizeInBits(PartVT) ==
- MVT::getSizeInBits(ValueVT)) {
- Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
- } else {
- assert(0 && "Unknown mismatch!");
- }
- }
- Parts[0] = Val;
- return;
- }
-
- // Handle a multi-element vector.
- MVT::ValueType IntermediateVT, RegisterVT;
- unsigned NumIntermediates;
- unsigned NumRegs =
- DAG.getTargetLoweringInfo()
- .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
- RegisterVT);
- unsigned NumElements = MVT::getVectorNumElements(ValueVT);
-
- assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
- assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
-
- // Split the vector into intermediate operands.
- SmallVector<SDOperand, 8> Ops(NumIntermediates);
- for (unsigned i = 0; i != NumIntermediates; ++i)
- if (MVT::isVector(IntermediateVT))
- Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
- IntermediateVT, Val,
- DAG.getConstant(i * (NumElements /
NumIntermediates),
- MVT::i32));
- else
- Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
- IntermediateVT, Val,
- DAG.getConstant(i, MVT::i32));
-
- // Split the intermediate operands into legal parts.
- if (NumParts == NumIntermediates) {
- // If the register was not expanded, promote or copy the value,
- // as appropriate.
- for (unsigned i = 0; i != NumParts; ++i)
- getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT);
- } else if (NumParts > 0) {
- // If the intermediate type was expanded, split each the value into
- // legal parts.
- assert(NumParts % NumIntermediates == 0 &&
- "Must expand into a divisible number of parts!");
- unsigned Factor = NumParts / NumIntermediates;
- for (unsigned i = 0; i != NumIntermediates; ++i)
- getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
- }
-}
-
-
/// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
/// this value and returns the result as a ValueVT value. This uses
/// Chain/Flag as the input and updates them for the output Chain/Flag.
/// If the Flag pointer is NULL, no flag is used.
SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
SDOperand &Chain, SDOperand
*Flag)const{
- // Get the list of registers, in the appropriate order.
+ // Get the list of registers.
std::vector<unsigned> R(Regs);
- if (!DAG.getTargetLoweringInfo().isLittleEndian())
- std::reverse(R.begin(), R.end());
// Copy the legal parts from the registers.
unsigned NumParts = Regs.size();
@@ -2985,7 +3001,7 @@
}
// Assemble the legal parts into the final value.
- return getCopyFromParts(DAG, &Parts[0], NumParts, RegVT, ValueVT);
+ return getCopyFromParts(DAG, &Parts[0], NumParts, RegVT, ValueVT, true);
}
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
@@ -2994,15 +3010,13 @@
/// If the Flag pointer is NULL, no flag is used.
void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
SDOperand &Chain, SDOperand *Flag) const {
- // Get the list of registers, in the appropriate order.
+ // Get the list of registers.
std::vector<unsigned> R(Regs);
- if (!DAG.getTargetLoweringInfo().isLittleEndian())
- std::reverse(R.begin(), R.end());
// Get the list of the values's legal parts.
unsigned NumParts = Regs.size();
SmallVector<SDOperand, 8> Parts(NumParts);
- getCopyToParts(DAG, Val, &Parts[0], NumParts, RegVT);
+ getCopyToParts(DAG, Val, &Parts[0], NumParts, RegVT, true);
// Copy the parts into the registers.
for (unsigned i = 0; i != NumParts; ++i) {
@@ -3879,7 +3893,7 @@
SmallVector<SDOperand, 4> Parts(NumParts);
for (unsigned j = 0; j != NumParts; ++j)
Parts[j] = SDOperand(Result, i++);
- Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT));
+ Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
true));
break;
}
}
@@ -3951,7 +3965,7 @@
MVT::ValueType PartVT = getRegisterType(VT);
unsigned NumParts = getNumRegisters(VT);
SmallVector<SDOperand, 4> Parts(NumParts);
- getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT);
+ getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, true);
for (unsigned i = 0; i != NumParts; ++i) {
// if it isn't first piece, alignment must be 1
unsigned MyFlags = Flags;
@@ -3991,7 +4005,7 @@
SmallVector<SDOperand, 4> Results(NumRegs);
for (unsigned i = 0; i != NumRegs; ++i)
Results[i] = Res.getValue(i);
- Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT,
AssertOp);
+ Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, false,
AssertOp);
}
return std::make_pair(Res, Chain);
@@ -4281,7 +4295,7 @@
SmallVector<SDOperand, 8> Chains(NumRegs);
// Copy the value by legal parts into sequential virtual registers.
- getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT);
+ getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT, false);
for (unsigned i = 0; i != NumRegs; ++i)
Chains[i] = DAG.getCopyToReg(getRoot(), Reg + i, Regs[i]);
return DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumRegs);
_______________________________________________
llvm-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits