aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h5
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h1
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h125
-rw-r--r--lib/CodeGen/SelectionDAG/CallingConvLower.cpp25
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp44
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp74
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp2
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp14
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp68
-rw-r--r--lib/Target/TargetCallingConv.td6
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp45
-rw-r--r--utils/TableGen/CallingConvEmitter.cpp8
13 files changed, 250 insertions, 168 deletions
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index 34e20903fa..2f83eaaa3c 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -98,7 +98,7 @@ public:
/// reflect the change.
typedef bool CCAssignFn(unsigned ValNo, MVT::ValueType ValVT,
MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
- ISD::ParamFlags::ParamFlagsTy ArgFlags, CCState &State);
+ ISD::ArgFlagsTy ArgFlags, CCState &State);
/// CCState - This class holds information needed while lowering arguments and
@@ -197,8 +197,7 @@ public:
// parameter attribute.
void HandleByVal(unsigned ValNo, MVT::ValueType ValVT,
MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
- int MinSize, int MinAlign,
- ISD::ParamFlags::ParamFlagsTy ArgFlags);
+ int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags);
private:
/// MarkAllocated - Mark a register and all of its aliases as allocated.
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 6e395a5b7f..28535d1273 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -219,6 +219,7 @@ public:
SDOperand getBasicBlock(MachineBasicBlock *MBB);
SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT);
SDOperand getTargetExternalSymbol(const char *Sym, MVT::ValueType VT);
+ SDOperand getArgFlags(ISD::ArgFlagsTy Flags);
SDOperand getValueType(MVT::ValueType);
SDOperand getRegister(unsigned Reg, MVT::ValueType VT);
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 4f2574efc1..3b718b605a 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -56,31 +56,6 @@ struct SDVTList {
/// SelectionDAG node types and value types.
///
namespace ISD {
- namespace ParamFlags {
- typedef uint64_t ParamFlagsTy;
-
- const ParamFlagsTy NoFlagSet = 0ULL;
- const ParamFlagsTy ZExt = 1ULL<<0; ///< Zero extended
- const ParamFlagsTy ZExtOffs = 0;
- const ParamFlagsTy SExt = 1ULL<<1; ///< Sign extended
- const ParamFlagsTy SExtOffs = 1;
- const ParamFlagsTy InReg = 1ULL<<2; ///< Passed in register
- const ParamFlagsTy InRegOffs = 2;
- const ParamFlagsTy StructReturn = 1ULL<<3; ///< Hidden struct-ret ptr
- const ParamFlagsTy StructReturnOffs = 3;
- const ParamFlagsTy ByVal = 1ULL<<4; ///< Struct passed by value
- const ParamFlagsTy ByValOffs = 4;
- const ParamFlagsTy Nest = 1ULL<<5; ///< Nested fn static chain
- const ParamFlagsTy NestOffs = 5;
- const ParamFlagsTy ByValAlign = 0xFULL << 6; //< Struct alignment
- const ParamFlagsTy ByValAlignOffs = 6;
- const ParamFlagsTy OrigAlignment = 0x1FULL<<27;
- const ParamFlagsTy OrigAlignmentOffs = 27;
- const ParamFlagsTy ByValSize = 0xffffffffULL << 32; //< Struct size
- const ParamFlagsTy ByValSizeOffs = 32;
-
- const ParamFlagsTy One = 1LL; //< 1 of this type, for shifts
- }
//===--------------------------------------------------------------------===//
/// ISD::NodeType enum - This enum defines all of the operators valid in a
@@ -107,7 +82,7 @@ namespace ISD {
AssertSext, AssertZext,
// Various leaf nodes.
- STRING, BasicBlock, VALUETYPE, CONDCODE, Register,
+ STRING, BasicBlock, VALUETYPE, ARG_FLAGS, CONDCODE, Register,
Constant, ConstantFP,
GlobalAddress, GlobalTLSAddress, FrameIndex,
JumpTable, ConstantPool, ExternalSymbol,
@@ -659,7 +634,7 @@ namespace ISD {
/// computed and is available in the base pointer. The offset
/// operand is always undefined. In addition to producing a
/// chain, an unindexed load produces one value (result of the
- /// load); an unindexed store does not produces a value.
+ /// load); an unindexed store does not produce a value.
///
/// PRE_INC Similar to the unindexed mode where the effective address is
/// PRE_DEC the value of the base pointer add / subtract the offset.
@@ -1584,6 +1559,102 @@ public:
}
};
+namespace ISD {
+ struct ArgFlagsTy {
+ private:
+ static const uint64_t NoFlagSet = 0ULL;
+ static const uint64_t ZExt = 1ULL<<0; ///< Zero extended
+ static const uint64_t ZExtOffs = 0;
+ static const uint64_t SExt = 1ULL<<1; ///< Sign extended
+ static const uint64_t SExtOffs = 1;
+ static const uint64_t InReg = 1ULL<<2; ///< Passed in register
+ static const uint64_t InRegOffs = 2;
+ static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr
+ static const uint64_t SRetOffs = 3;
+ static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value
+ static const uint64_t ByValOffs = 4;
+ static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
+ static const uint64_t NestOffs = 5;
+ static const uint64_t ByValAlign = 0xFULL << 6; //< Struct alignment
+ static const uint64_t ByValAlignOffs = 6;
+ static const uint64_t OrigAlign = 0x1FULL<<27;
+ static const uint64_t OrigAlignOffs = 27;
+ static const uint64_t ByValSize = 0xffffffffULL << 32; //< Struct size
+ static const uint64_t ByValSizeOffs = 32;
+
+ static const uint64_t One = 1ULL; //< 1 of this type, for shifts
+
+ uint64_t Flags;
+ public:
+ ArgFlagsTy() : Flags(0) { }
+
+ bool isZExt() const { return Flags & ZExt; }
+ void setZExt() { Flags |= One << ZExtOffs; }
+
+ bool isSExt() const { return Flags & SExt; }
+ void setSExt() { Flags |= One << SExtOffs; }
+
+ bool isInReg() const { return Flags & InReg; }
+ void setInReg() { Flags |= One << InRegOffs; }
+
+ bool isSRet() const { return Flags & SRet; }
+ void setSRet() { Flags |= One << SRetOffs; }
+
+ bool isByVal() const { return Flags & ByVal; }
+ void setByVal() { Flags |= One << ByValOffs; }
+
+ bool isNest() const { return Flags & Nest; }
+ void setNest() { Flags |= One << NestOffs; }
+
+ unsigned getByValAlign() const {
+ return (One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2;
+ }
+ void setByValAlign(unsigned A) {
+ Flags = (Flags & ~ByValAlign) |
+ (uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
+ }
+
+ unsigned getOrigAlign() const {
+ return (One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2;
+ }
+ void setOrigAlign(unsigned A) {
+ Flags = (Flags & ~OrigAlign) |
+ (uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
+ }
+
+ unsigned getByValSize() const {
+ return (Flags & ByValSize) >> ByValSizeOffs;
+ }
+ void setByValSize(unsigned S) {
+ Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
+ }
+
+ /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4".
+ std::string getArgFlagsString();
+
+ /// getRawBits - Represent the flags as a bunch of bits.
+ uint64_t getRawBits() const { return Flags; }
+ };
+}
+
+/// ARG_FLAGSSDNode - Leaf node holding parameter flags.
+class ARG_FLAGSSDNode : public SDNode {
+ ISD::ArgFlagsTy TheFlags;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit ARG_FLAGSSDNode(ISD::ArgFlagsTy Flags)
+ : SDNode(ISD::ARG_FLAGS, getSDVTList(MVT::Other)), TheFlags(Flags) {
+ }
+public:
+ ISD::ArgFlagsTy getArgFlags() const { return TheFlags; }
+
+ static bool classof(const ARG_FLAGSSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::ARG_FLAGS;
+ }
+};
+
/// VTSDNode - This class is used to represent MVT::ValueType's, which are used
/// to parameterize some operations.
class VTSDNode : public SDNode {
diff --git a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
index 6b9b31b548..667870d452 100644
--- a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
+++ b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
@@ -35,11 +35,9 @@ CCState::CCState(unsigned CC, bool isVarArg, const TargetMachine &tm,
void CCState::HandleByVal(unsigned ValNo, MVT::ValueType ValVT,
MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
int MinSize, int MinAlign,
- ISD::ParamFlags::ParamFlagsTy ArgFlags) {
- unsigned Align = 1 << ((ArgFlags & ISD::ParamFlags::ByValAlign) >>
- ISD::ParamFlags::ByValAlignOffs);
- unsigned Size = (ArgFlags & ISD::ParamFlags::ByValSize) >>
- ISD::ParamFlags::ByValSizeOffs;
+ ISD::ArgFlagsTy ArgFlags) {
+ unsigned Align = ArgFlags.getByValAlign();
+ unsigned Size = ArgFlags.getByValSize();
if (MinSize > (int)Size)
Size = MinSize;
if (MinAlign > (int)Align)
@@ -65,9 +63,8 @@ void CCState::AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn) {
for (unsigned i = 0; i != NumArgs; ++i) {
MVT::ValueType ArgVT = TheArgs->getValueType(i);
- SDOperand FlagOp = TheArgs->getOperand(3+i);
- ISD::ParamFlags::ParamFlagsTy ArgFlags =
- cast<ConstantSDNode>(FlagOp)->getValue();
+ ISD::ArgFlagsTy ArgFlags =
+ cast<ARG_FLAGSSDNode>(TheArgs->getOperand(3+i))->getArgFlags();
if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
cerr << "Formal argument #" << i << " has unhandled type "
<< MVT::getValueTypeString(ArgVT) << "\n";
@@ -82,8 +79,9 @@ void CCState::AnalyzeReturn(SDNode *TheRet, CCAssignFn Fn) {
// Determine which register each value should be copied into.
for (unsigned i = 0, e = TheRet->getNumOperands() / 2; i != e; ++i) {
MVT::ValueType VT = TheRet->getOperand(i*2+1).getValueType();
- if (Fn(i, VT, VT, CCValAssign::Full,
- cast<ConstantSDNode>(TheRet->getOperand(i*2+2))->getValue(), *this)){
+ ISD::ArgFlagsTy ArgFlags =
+ cast<ARG_FLAGSSDNode>(TheRet->getOperand(i*2+2))->getArgFlags();
+ if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)){
cerr << "Return operand #" << i << " has unhandled type "
<< MVT::getValueTypeString(VT) << "\n";
abort();
@@ -98,9 +96,8 @@ void CCState::AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn) {
unsigned NumOps = (TheCall->getNumOperands() - 5) / 2;
for (unsigned i = 0; i != NumOps; ++i) {
MVT::ValueType ArgVT = TheCall->getOperand(5+2*i).getValueType();
- SDOperand FlagOp = TheCall->getOperand(5+2*i+1);
- ISD::ParamFlags::ParamFlagsTy ArgFlags =
- cast<ConstantSDNode>(FlagOp)->getValue();
+ ISD::ArgFlagsTy ArgFlags =
+ cast<ARG_FLAGSSDNode>(TheCall->getOperand(5+2*i+1))->getArgFlags();
if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
cerr << "Call operand #" << i << " has unhandled type "
<< MVT::getValueTypeString(ArgVT) << "\n";
@@ -114,7 +111,7 @@ void CCState::AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn) {
void CCState::AnalyzeCallResult(SDNode *TheCall, CCAssignFn Fn) {
for (unsigned i = 0, e = TheCall->getNumValues() - 1; i != e; ++i) {
MVT::ValueType VT = TheCall->getValueType(i);
- if (Fn(i, VT, VT, CCValAssign::Full, 0, *this)) {
+ if (Fn(i, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) {
cerr << "Call result #" << i << " has unhandled type "
<< MVT::getValueTypeString(VT) << "\n";
abort();
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 56ac37590b..d318cb4372 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -808,6 +808,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case ISD::MEMOPERAND:
case ISD::STRING:
case ISD::CONDCODE:
+ case ISD::ARG_FLAGS:
// Primitives must all be legal.
assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
"This must be legal!");
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3cd731073c..9331e8b7ee 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -355,6 +355,9 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
// Handle SDNode leafs with special info.
switch (N->getOpcode()) {
default: break; // Normal nodes don't need extra info.
+ case ISD::ARG_FLAGS:
+ ID.AddInteger(cast<ARG_FLAGSSDNode>(N)->getArgFlags().getRawBits());
+ break;
case ISD::TargetConstant:
case ISD::Constant:
ID.Add(cast<ConstantSDNode>(N)->getAPIntValue());
@@ -923,6 +926,19 @@ SDOperand SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
return SDOperand(N, 0);
}
+SDOperand SelectionDAG::getArgFlags(ISD::ArgFlagsTy Flags) {
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::ARG_FLAGS, getVTList(MVT::Other), 0, 0);
+ ID.AddInteger(Flags.getRawBits());
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDOperand(E, 0);
+ SDNode *N = new ARG_FLAGSSDNode(Flags);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDOperand(N, 0);
+}
+
SDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
if (!MVT::isExtendedVT(VT) && (unsigned)VT >= ValueTypeNodes.size())
ValueTypeNodes.resize(VT+1);
@@ -3584,6 +3600,7 @@ void MemOperandSDNode::ANCHOR() {}
void RegisterSDNode::ANCHOR() {}
void ExternalSymbolSDNode::ANCHOR() {}
void CondCodeSDNode::ANCHOR() {}
+void ARG_FLAGSSDNode::ANCHOR() {}
void VTSDNode::ANCHOR() {}
void LoadSDNode::ANCHOR() {}
void StoreSDNode::ANCHOR() {}
@@ -3831,6 +3848,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::STRING: return "String";
case ISD::BasicBlock: return "BasicBlock";
+ case ISD::ARG_FLAGS: return "ArgFlags";
case ISD::VALUETYPE: return "ValueType";
case ISD::Register: return "Register";
@@ -4043,6 +4061,30 @@ const char *SDNode::getIndexedModeName(ISD::MemIndexedMode AM) {
}
}
+std::string ISD::ArgFlagsTy::getArgFlagsString() {
+ std::string S = "< ";
+
+ if (isZExt())
+ S += "zext ";
+ if (isSExt())
+ S += "sext ";
+ if (isInReg())
+ S += "inreg ";
+ if (isSRet())
+ S += "sret ";
+ if (isByVal())
+ S += "byval ";
+ if (isNest())
+ S += "nest ";
+ if (getByValAlign())
+ S += "byval-align:" + utostr(getByValAlign()) + " ";
+ if (getOrigAlign())
+ S += "orig-align:" + utostr(getOrigAlign()) + " ";
+ if (getByValSize())
+ S += "byval-size:" + utostr(getByValSize()) + " ";
+ return S + ">";
+}
+
void SDNode::dump() const { dump(0); }
void SDNode::dump(const SelectionDAG *G) const {
cerr << (void*)this << ": ";
@@ -4138,6 +4180,8 @@ void SDNode::dump(const SelectionDAG *G) const {
cerr << "<" << M->MO.getValue() << ":" << M->MO.getOffset() << ">";
else
cerr << "<null:" << M->MO.getOffset() << ">";
+ } else if (const ARG_FLAGSSDNode *N = dyn_cast<ARG_FLAGSSDNode>(this)) {
+ cerr << N->getArgFlags().getArgFlagsString();
} else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
cerr << ":" << MVT::getValueTypeString(N->getVT());
} else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1e249d0386..d9d58fa037 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1064,7 +1064,7 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
for (unsigned i = 0; i < NumParts; ++i) {
NewValues.push_back(Parts[i]);
- NewValues.push_back(DAG.getConstant(false, MVT::i32));
+ NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
}
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
@@ -4065,39 +4065,34 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
I != E; ++I, ++j) {
MVT::ValueType VT = getValueType(I->getType());
- ISD::ParamFlags::ParamFlagsTy Flags = ISD::ParamFlags::NoFlagSet;
+ ISD::ArgFlagsTy Flags;
unsigned OriginalAlignment =
getTargetData()->getABITypeAlignment(I->getType());
- // FIXME: Distinguish between a formal with no [sz]ext attribute from one
- // that is zero extended!
if (F.paramHasAttr(j, ParamAttr::ZExt))
- Flags &= ~(ISD::ParamFlags::SExt);
+ Flags.setZExt();
if (F.paramHasAttr(j, ParamAttr::SExt))
- Flags |= ISD::ParamFlags::SExt;
+ Flags.setSExt();
if (F.paramHasAttr(j, ParamAttr::InReg))
- Flags |= ISD::ParamFlags::InReg;
+ Flags.setInReg();
if (F.paramHasAttr(j, ParamAttr::StructRet))
- Flags |= ISD::ParamFlags::StructReturn;
+ Flags.setSRet();
if (F.paramHasAttr(j, ParamAttr::ByVal)) {
- Flags |= ISD::ParamFlags::ByVal;
+ Flags.setByVal();
const PointerType *Ty = cast<PointerType>(I->getType());
const Type *ElementTy = Ty->getElementType();
- unsigned FrameAlign = Log2_32(getByValTypeAlignment(ElementTy));
+ unsigned FrameAlign = getByValTypeAlignment(ElementTy);
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
// For ByVal, alignment should be passed from FE. BE will guess if
// this info is not there but there are cases it cannot get right.
if (F.getParamAlignment(j))
- FrameAlign = Log2_32(F.getParamAlignment(j));
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameAlign
- << ISD::ParamFlags::ByValAlignOffs);
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameSize
- << ISD::ParamFlags::ByValSizeOffs);
+ FrameAlign = F.getParamAlignment(j);
+ Flags.setByValAlign(FrameAlign);
+ Flags.setByValSize(FrameSize);
}
if (F.paramHasAttr(j, ParamAttr::Nest))
- Flags |= ISD::ParamFlags::Nest;
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)OriginalAlignment
- << ISD::ParamFlags::OrigAlignmentOffs);
+ Flags.setNest();
+ Flags.setOrigAlign(OriginalAlignment);
MVT::ValueType RegisterVT = getRegisterType(VT);
unsigned NumRegs = getNumRegisters(VT);
@@ -4105,9 +4100,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
RetVals.push_back(RegisterVT);
// if it isn't first piece, alignment must be 1
if (i > 0)
- Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
- (ISD::ParamFlags::One << ISD::ParamFlags::OrigAlignmentOffs);
- Ops.push_back(DAG.getConstant(Flags, MVT::i64));
+ Flags.setOrigAlign(1);
+ Ops.push_back(DAG.getArgFlags(Flags));
}
}
@@ -4183,37 +4177,34 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
MVT::ValueType VT = getValueType(Args[i].Ty);
SDOperand Op = Args[i].Node;
- ISD::ParamFlags::ParamFlagsTy Flags = ISD::ParamFlags::NoFlagSet;
+ ISD::ArgFlagsTy Flags;
unsigned OriginalAlignment =
getTargetData()->getABITypeAlignment(Args[i].Ty);
-
- if (Args[i].isSExt)
- Flags |= ISD::ParamFlags::SExt;
+
if (Args[i].isZExt)
- Flags |= ISD::ParamFlags::ZExt;
+ Flags.setZExt();
+ if (Args[i].isSExt)
+ Flags.setSExt();
if (Args[i].isInReg)
- Flags |= ISD::ParamFlags::InReg;
+ Flags.setInReg();
if (Args[i].isSRet)
- Flags |= ISD::ParamFlags::StructReturn;
+ Flags.setSRet();
if (Args[i].isByVal) {
- Flags |= ISD::ParamFlags::ByVal;
+ Flags.setByVal();
const PointerType *Ty = cast<PointerType>(Args[i].Ty);
const Type *ElementTy = Ty->getElementType();
- unsigned FrameAlign = Log2_32(getByValTypeAlignment(ElementTy));
+ unsigned FrameAlign = getByValTypeAlignment(ElementTy);
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
// For ByVal, alignment should come from FE. BE will guess if this
// info is not there but there are cases it cannot get right.
if (Args[i].Alignment)
- FrameAlign = Log2_32(Args[i].Alignment);
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameAlign
- << ISD::ParamFlags::ByValAlignOffs);
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameSize
- << ISD::ParamFlags::ByValSizeOffs);
+ FrameAlign = Args[i].Alignment;
+ Flags.setByValAlign(FrameAlign);
+ Flags.setByValSize(FrameSize);
}
if (Args[i].isNest)
- Flags |= ISD::ParamFlags::Nest;
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)OriginalAlignment)
- << ISD::ParamFlags::OrigAlignmentOffs;
+ Flags.setNest();
+ Flags.setOrigAlign(OriginalAlignment);
MVT::ValueType PartVT = getRegisterType(VT);
unsigned NumParts = getNumRegisters(VT);
@@ -4229,13 +4220,12 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
for (unsigned i = 0; i != NumParts; ++i) {
// if it isn't first piece, alignment must be 1
- ISD::ParamFlags::ParamFlagsTy MyFlags = Flags;
+ ISD::ArgFlagsTy MyFlags = Flags;
if (i != 0)
- MyFlags = (MyFlags & (~ISD::ParamFlags::OrigAlignment)) |
- (ISD::ParamFlags::One << ISD::ParamFlags::OrigAlignmentOffs);
+ MyFlags.setOrigAlign(1);
Ops.push_back(Parts[i]);
- Ops.push_back(DAG.getConstant(MyFlags, MVT::i64));
+ Ops.push_back(DAG.getArgFlags(MyFlags));
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
index b316d417a9..ad58aa0616 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
@@ -151,6 +151,8 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
Op += "<" + M->MO.getValue()->getName() + ":" + itostr(M->MO.getOffset()) + ">";
else
Op += "<null:" + itostr(M->MO.getOffset()) + ">";
+ } else if (const ARG_FLAGSSDNode *N = dyn_cast<ARG_FLAGSSDNode>(Node)) {
+ Op = Op + " AF=" + N->getArgFlags().getArgFlagsString();
} else if (const VTSDNode *N = dyn_cast<VTSDNode>(Node)) {
Op = Op + " VT=" + MVT::getValueTypeString(N->getVT());
} else if (const StringSDNode *N = dyn_cast<StringSDNode>(Node)) {
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 0326ecf43e..421a03fca0 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -367,13 +367,12 @@ static void
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 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
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 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
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 @@ static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
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 d8f7400c2a..5a3a51f21c 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1366,14 +1366,12 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op,
++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 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op,
//
// 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 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op,
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 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op,
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 @@ static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) {
/// 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 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
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 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
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 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
// 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 a3b84f4b6f..05d505a88d 100644
--- a/lib/Target/TargetCallingConv.td
+++ b/lib/Target/TargetCallingConv.td
@@ -34,7 +34,7 @@ class CCIf<string predicate, CCAction A> : CCPredicateAction<A> {
/// 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 @@ class CCIfCC<string CC, CCAction A>
/// 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/X