mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
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. llvm-svn: 48640
This commit is contained in:
parent
530554ab0a
commit
4153fc30c9
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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!");
|
||||
|
@ -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)) {
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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> {}
|
||||
|
@ -970,8 +970,7 @@ static bool CallIsStructReturn(SDOperand Op) {
|
||||
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
|
||||
@ -981,8 +980,7 @@ static bool ArgsAreStructReturn(SDOperand Op) {
|
||||
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 @@ CopyTailCallClobberedArgumentsToVRegs(SDOperand Chain,
|
||||
/// 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 @@ SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
|
||||
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 @@ SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
|
||||
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 @@ X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
|
||||
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 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
|
||||
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;
|
||||
@ -1555,7 +1546,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
|
||||
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));
|
||||
|
@ -30,7 +30,7 @@ void CallingConvEmitter::run(std::ostream &O) {
|
||||
<< std::string(CCs[i]->getName().size()+13, ' ')
|
||||
<< "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n"
|
||||
<< std::string(CCs[i]->getName().size()+13, ' ')
|
||||
<< "ISD::ParamFlags::ParamFlagsTy ArgFlags, CCState &State);\n";
|
||||
<< "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
|
||||
}
|
||||
|
||||
// Emit each calling convention description in full.
|
||||
@ -48,7 +48,7 @@ void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) {
|
||||
<< std::string(CC->getName().size()+13, ' ')
|
||||
<< "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n"
|
||||
<< std::string(CC->getName().size()+13, ' ')
|
||||
<< "ISD::ParamFlags::ParamFlagsTy ArgFlags, CCState &State) {\n";
|
||||
<< "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
|
||||
// Emit all of the actions, in order.
|
||||
for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
|
||||
O << "\n";
|
||||
@ -134,9 +134,9 @@ void CallingConvEmitter::EmitAction(Record *Action,
|
||||
} else if (Action->isSubClassOf("CCPromoteToType")) {
|
||||
Record *DestTy = Action->getValueAsDef("DestTy");
|
||||
O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
|
||||
O << IndentStr << "if (ArgFlags & ISD::ParamFlags::SExt)\n"
|
||||
O << IndentStr << "if (ArgFlags.isSExt())\n"
|
||||
<< IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
|
||||
<< IndentStr << "else if (ArgFlags & ISD::ParamFlags::ZExt)\n"
|
||||
<< IndentStr << "else if (ArgFlags.isZExt())\n"
|
||||
<< IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
|
||||
<< IndentStr << "else\n"
|
||||
<< IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
|
||||
|
Loading…
Reference in New Issue
Block a user