Introduce a new node for holding call argument
flags. This is needed by the new legalize types
infrastructure which wants to expand the 64 bit
constants previously used to hold the flags on
32 bit machines. There are two functional changes:
(1) in LowerArguments, if a parameter has the zext
attribute set then that is marked in the flags;
before it was being ignored; (2) PPC had some bogus
code for handling two word arguments when using the
ELF 32 ABI, which was hard to convert because of
the bogusness. As suggested by the original author
(Nicolas Geoffray), I've disabled it for the moment.
Tested with "make check" and the Ada ACATS testsuite.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48640 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 0326ecf..421a03f 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -367,13 +367,12 @@
HowToPassArgument(MVT::ValueType ObjectVT, unsigned NumGPRs,
unsigned StackOffset, unsigned &NeededGPRs,
unsigned &NeededStackSize, unsigned &GPRPad,
- unsigned &StackPad, ISD::ParamFlags::ParamFlagsTy Flags) {
+ unsigned &StackPad, ISD::ArgFlagsTy Flags) {
NeededStackSize = 0;
NeededGPRs = 0;
StackPad = 0;
GPRPad = 0;
- unsigned align = ((Flags & ISD::ParamFlags::OrigAlignment)
- >> ISD::ParamFlags::OrigAlignmentOffs);
+ unsigned align = Flags.getOrigAlign();
GPRPad = NumGPRs % ((align + 3)/4);
StackPad = StackOffset % align;
unsigned firstGPR = NumGPRs + GPRPad;
@@ -422,7 +421,8 @@
unsigned StackPad;
unsigned GPRPad;
MVT::ValueType ObjectVT = Op.getOperand(5+2*i).getValueType();
- ISD::ParamFlags::ParamFlagsTy Flags = Op.getConstantOperandVal(5+2*i+1);
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(5+2*i+1))->getArgFlags();
HowToPassArgument(ObjectVT, NumGPRs, NumBytes, ObjGPRs, ObjSize,
GPRPad, StackPad, Flags);
NumBytes += ObjSize + StackPad;
@@ -445,7 +445,8 @@
std::vector<SDOperand> MemOpChains;
for (unsigned i = 0; i != NumOps; ++i) {
SDOperand Arg = Op.getOperand(5+2*i);
- ISD::ParamFlags::ParamFlagsTy Flags = Op.getConstantOperandVal(5+2*i+1);
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(5+2*i+1))->getArgFlags();
MVT::ValueType ArgVT = Arg.getValueType();
unsigned ObjSize;
@@ -924,7 +925,8 @@
unsigned ObjGPRs;
unsigned GPRPad;
unsigned StackPad;
- ISD::ParamFlags::ParamFlagsTy Flags = Op.getConstantOperandVal(ArgNo + 3);
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(ArgNo + 3))->getArgFlags();
HowToPassArgument(ObjectVT, NumGPRs, ArgOffset, ObjGPRs,
ObjSize, GPRPad, StackPad, Flags);
NumGPRs += GPRPad;
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index d8f7400..5a3a51f 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1366,14 +1366,12 @@
++ArgNo) {
MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
- ISD::ParamFlags::ParamFlagsTy Flags =
- cast<ConstantSDNode>(Op.getOperand(ArgNo+3))->getValue();
- unsigned isByVal = Flags & ISD::ParamFlags::ByVal;
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(ArgNo+3))->getArgFlags();
- if (isByVal) {
+ if (Flags.isByVal()) {
// ObjSize is the true size, ArgSize rounded up to multiple of regs.
- ObjSize = (Flags & ISD::ParamFlags::ByValSize) >>
- ISD::ParamFlags::ByValSizeOffs;
+ ObjSize = Flags.getByValSize();
unsigned ArgSize =
((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
VecArgOffset += ArgSize;
@@ -1410,7 +1408,7 @@
//
// In the ELF 32 ABI, GPRs and stack are double word align: an argument
// represented with two words (long long or double) must be copied to an
- // even GPR_idx value or to an even ArgOffset value.
+ // even GPR_idx value or to an even ArgOffset value. TODO: implement this.
SmallVector<SDOperand, 8> MemOps;
@@ -1420,25 +1418,19 @@
MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
unsigned ArgSize = ObjSize;
- ISD::ParamFlags::ParamFlagsTy Flags =
- cast<ConstantSDNode>(Op.getOperand(ArgNo+3))->getValue();
- unsigned AlignFlag = ISD::ParamFlags::One
- << ISD::ParamFlags::OrigAlignmentOffs;
- unsigned isByVal = Flags & ISD::ParamFlags::ByVal;
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(ArgNo+3))->getArgFlags();
// See if next argument requires stack alignment in ELF
- bool Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 < e) &&
- (cast<ConstantSDNode>(Op.getOperand(ArgNo+4))->getValue() & AlignFlag) &&
- (!(Flags & AlignFlag)));
+ bool Expand = false; // TODO: implement this.
unsigned CurArgOffset = ArgOffset;
// FIXME alignment for ELF may not be right
// FIXME the codegen can be much improved in some cases.
// We do not have to keep everything in memory.
- if (isByVal) {
+ if (Flags.isByVal()) {
// ObjSize is the true size, ArgSize rounded up to multiple of registers.
- ObjSize = (Flags & ISD::ParamFlags::ByValSize) >>
- ISD::ParamFlags::ByValSizeOffs;
+ ObjSize = Flags.getByValSize();
ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
// Double word align in ELF
if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2);
@@ -1521,10 +1513,10 @@
if (ObjectVT == MVT::i32) {
// PPC64 passes i8, i16, and i32 values in i64 registers. Promote
// value to MVT::i64 and then truncate to the correct register size.
- if (Flags & ISD::ParamFlags::SExt)
+ if (Flags.isSExt())
ArgVal = DAG.getNode(ISD::AssertSext, MVT::i64, ArgVal,
DAG.getValueType(ObjectVT));
- else if (Flags & ISD::ParamFlags::ZExt)
+ else if (Flags.isZExt())
ArgVal = DAG.getNode(ISD::AssertZext, MVT::i64, ArgVal,
DAG.getValueType(ObjectVT));
@@ -1736,11 +1728,9 @@
/// does not fit in registers.
static SDOperand
CreateCopyOfByValArgument(SDOperand Src, SDOperand Dst, SDOperand Chain,
- ISD::ParamFlags::ParamFlagsTy Flags,
- SelectionDAG &DAG, unsigned Size) {
- unsigned Align = ISD::ParamFlags::One <<
- ((Flags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs);
- SDOperand AlignNode = DAG.getConstant(Align, MVT::i32);
+ ISD::ArgFlagsTy Flags, SelectionDAG &DAG,
+ unsigned Size) {
+ SDOperand AlignNode = DAG.getConstant(Flags.getByValAlign(), MVT::i32);
SDOperand SizeNode = DAG.getConstant(Size, MVT::i32);
SDOperand AlwaysInline = DAG.getConstant(0, MVT::i32);
return DAG.getMemcpy(Chain, Dst, Src, SizeNode, AlignNode, AlwaysInline);
@@ -1792,12 +1782,11 @@
NumBytes = ((NumBytes+15)/16)*16;
}
}
- ISD::ParamFlags::ParamFlagsTy Flags =
- cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue();
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(5+2*i+1))->getArgFlags();
unsigned ArgSize =MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8;
- if (Flags & ISD::ParamFlags::ByVal)
- ArgSize = (Flags & ISD::ParamFlags::ByValSize) >>
- ISD::ParamFlags::ByValSizeOffs;
+ if (Flags.isByVal())
+ ArgSize = Flags.getByValSize();
ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
NumBytes += ArgSize;
}
@@ -1862,15 +1851,10 @@
for (unsigned i = 0; i != NumOps; ++i) {
bool inMem = false;
SDOperand Arg = Op.getOperand(5+2*i);
- ISD::ParamFlags::ParamFlagsTy Flags =
- cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue();
- unsigned AlignFlag = ISD::ParamFlags::One <<
- ISD::ParamFlags::OrigAlignmentOffs;
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(5+2*i+1))->getArgFlags();
// See if next argument requires stack alignment in ELF
- unsigned next = 5+2*(i+1)+1;
- bool Expand = (Arg.getValueType() == MVT::f64) || ((i + 1 < NumOps) &&
- (cast<ConstantSDNode>(Op.getOperand(next))->getValue() & AlignFlag) &&
- (!(Flags & AlignFlag)));
+ bool Expand = false; // TODO: implement this.
// PtrOff will be used to store the current argument to the stack if a
// register cannot be found for it.
@@ -1887,15 +1871,15 @@
// On PPC64, promote integers to 64-bit values.
if (isPPC64 && Arg.getValueType() == MVT::i32) {
- unsigned ExtOp = (Flags & 1) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ // FIXME: Should this use ANY_EXTEND if neither sext nor zext?
+ unsigned ExtOp = Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
Arg = DAG.getNode(ExtOp, MVT::i64, Arg);
}
// FIXME Elf untested, what are alignment rules?
// FIXME memcpy is used way more than necessary. Correctness first.
- if (Flags & ISD::ParamFlags::ByVal) {
- unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >>
- ISD::ParamFlags::ByValSizeOffs;
+ if (Flags.isByVal()) {
+ unsigned Size = Flags.getByValSize();
if (isELF32_ABI && Expand) GPR_idx += (GPR_idx % 2);
if (Size==1 || Size==2) {
// Very small objects are passed right-justified.
diff --git a/lib/Target/TargetCallingConv.td b/lib/Target/TargetCallingConv.td
index a3b84f4..05d505a 100644
--- a/lib/Target/TargetCallingConv.td
+++ b/lib/Target/TargetCallingConv.td
@@ -34,7 +34,7 @@
/// CCIfByVal - If the current argument has ByVal parameter attribute, apply
/// Action A.
-class CCIfByVal<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::ByVal", A> {
+class CCIfByVal<CCAction A> : CCIf<"ArgFlags.isByVal()", A> {
}
/// CCIfCC - Match of the current calling convention is 'CC'.
@@ -43,11 +43,11 @@
/// CCIfInReg - If this argument is marked with the 'inreg' attribute, apply
/// the specified action.
-class CCIfInReg<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::InReg", A> {}
+class CCIfInReg<CCAction A> : CCIf<"ArgFlags.isInReg()", A> {}
/// CCIfNest - If this argument is marked with the 'nest' attribute, apply
/// the specified action.
-class CCIfNest<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::Nest", A> {}
+class CCIfNest<CCAction A> : CCIf<"ArgFlags.isNest()", A> {}
/// CCIfNotVarArg - If the current function is not vararg - apply the action
class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 1cbf5ee..9d22fbe 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -969,9 +969,8 @@
unsigned NumOps = (Op.getNumOperands() - 5) / 2;
if (!NumOps)
return false;
-
- ConstantSDNode *Flags = cast<ConstantSDNode>(Op.getOperand(6));
- return Flags->getValue() & ISD::ParamFlags::StructReturn;
+
+ return cast<ARG_FLAGSSDNode>(Op.getOperand(6))->getArgFlags().isSRet();
}
/// ArgsAreStructReturn - Determines whether a FORMAL_ARGUMENTS node uses struct
@@ -980,9 +979,8 @@
unsigned NumArgs = Op.Val->getNumValues() - 1;
if (!NumArgs)
return false;
-
- ConstantSDNode *Flags = cast<ConstantSDNode>(Op.getOperand(3));
- return Flags->getValue() & ISD::ParamFlags::StructReturn;
+
+ return cast<ARG_FLAGSSDNode>(Op.getOperand(3))->getArgFlags().isSRet();
}
/// IsCalleePop - Determines whether a CALL or FORMAL_ARGUMENTS node requires the
@@ -1110,14 +1108,9 @@
/// parameter.
static SDOperand
CreateCopyOfByValArgument(SDOperand Src, SDOperand Dst, SDOperand Chain,
- ISD::ParamFlags::ParamFlagsTy Flags,
- SelectionDAG &DAG) {
- unsigned Align = ISD::ParamFlags::One <<
- ((Flags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs);
- unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >>
- ISD::ParamFlags::ByValSizeOffs;
- SDOperand AlignNode = DAG.getConstant(Align, MVT::i32);
- SDOperand SizeNode = DAG.getConstant(Size, MVT::i32);
+ ISD::ArgFlagsTy Flags, SelectionDAG &DAG) {
+ SDOperand AlignNode = DAG.getConstant(Flags.getByValAlign(), MVT::i32);
+ SDOperand SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32);
SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32);
return DAG.getMemcpy(Chain, Dst, Src, SizeNode, AlignNode, AlwaysInline);
}
@@ -1128,11 +1121,10 @@
unsigned CC,
SDOperand Root, unsigned i) {
// Create the nodes corresponding to a load from this parameter slot.
- ISD::ParamFlags::ParamFlagsTy Flags =
- cast<ConstantSDNode>(Op.getOperand(3 + i))->getValue();
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(3 + i))->getArgFlags();
bool AlwaysUseMutable = (CC==CallingConv::Fast) && PerformTailCallOpt;
- bool isByVal = Flags & ISD::ParamFlags::ByVal;
- bool isImmutable = !AlwaysUseMutable && !isByVal;
+ bool isImmutable = !AlwaysUseMutable && !Flags.isByVal();
// FIXME: For now, all byval parameter objects are marked mutable. This can be
// changed with more analysis.
@@ -1141,7 +1133,7 @@
int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
VA.getLocMemOffset(), isImmutable);
SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
- if (isByVal)
+ if (Flags.isByVal())
return FIN;
return DAG.getLoad(VA.getValVT(), Root, FIN,
PseudoSourceValue::getFixedStack(), FI);
@@ -1346,10 +1338,9 @@
unsigned LocMemOffset = VA.getLocMemOffset();
SDOperand PtrOff = DAG.getIntPtrConstant(LocMemOffset);
PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
- SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
- ISD::ParamFlags::ParamFlagsTy Flags =
- cast<ConstantSDNode>(FlagsOp)->getValue();
- if (Flags & ISD::ParamFlags::ByVal) {
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(Op.getOperand(6+2*VA.getValNo()))->getArgFlags();
+ if (Flags.isByVal()) {
return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG);
}
return DAG.getStore(Chain, Arg, PtrOff,
@@ -1536,8 +1527,8 @@
assert(VA.isMemLoc());
SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
- ISD::ParamFlags::ParamFlagsTy Flags =
- cast<ConstantSDNode>(FlagsOp)->getValue();
+ ISD::ArgFlagsTy Flags =
+ cast<ARG_FLAGSSDNode>(FlagsOp)->getArgFlags();
// Create frame index.
int32_t Offset = VA.getLocMemOffset()+FPDiff;
uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8;
@@ -1554,8 +1545,8 @@
}
assert(IsPossiblyOverwrittenArgumentOfTailCall(Arg, MFI)==false ||
(Found==true && "No corresponding Argument was found"));
-
- if (Flags & ISD::ParamFlags::ByVal) {
+
+ if (Flags.isByVal()) {
// Copy relative to framepointer.
MemOpChains2.push_back(CreateCopyOfByValArgument(Arg, FIN, Chain,
Flags, DAG));