forked from OSchip/llvm-project
Pass alignment on ByVal parameters, from FE, all
the way through. It is now used for codegen. llvm-svn: 47484
This commit is contained in:
parent
eac159c1f0
commit
eabc5f39af
|
@ -166,6 +166,9 @@ public:
|
|||
/// @brief Determine whether the function has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const;
|
||||
|
||||
/// @brief Determine if the function cannot return.
|
||||
bool doesNotReturn() const;
|
||||
|
||||
|
|
|
@ -941,6 +941,9 @@ public:
|
|||
/// @brief Determine whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, unsigned attr) const;
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const;
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const;
|
||||
|
||||
|
@ -1738,6 +1741,9 @@ public:
|
|||
/// @brief Determine whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const;
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const;
|
||||
|
||||
|
|
|
@ -69,6 +69,12 @@ const Attributes MutuallyIncompatible[3] = {
|
|||
/// @brief Which attributes cannot be applied to a type.
|
||||
Attributes typeIncompatible (const Type *Ty);
|
||||
|
||||
/// This turns an int alignment (a power of 2, normally) into the
|
||||
/// form used internally in ParameterAttributes.
|
||||
ParamAttr::Attributes inline constructAlignmentFromInt(uint32_t i) {
|
||||
return (i << 16);
|
||||
}
|
||||
|
||||
} // end namespace ParamAttr
|
||||
|
||||
/// @brief A more friendly way to reference the attributes.
|
||||
|
@ -176,6 +182,13 @@ class ParamAttrsList : public FoldingSetNode {
|
|||
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const {
|
||||
return getParamAttrs(i) & attr;
|
||||
}
|
||||
|
||||
/// This extracts the alignment for the \p ith function parameter.
|
||||
/// @returns 0 if unknown, else the alignment in bytes
|
||||
/// @brief Extract the Alignment
|
||||
uint16_t getParamAlignment(uint16_t i) const {
|
||||
return (getParamAttrs(i) & ParamAttr::Alignment) >> 16;
|
||||
}
|
||||
|
||||
/// This returns whether the given attribute is set for at least one
|
||||
/// parameter or for the return value.
|
||||
|
|
|
@ -68,6 +68,9 @@ public:
|
|||
/// paramHasAttr - whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const;
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const;
|
||||
|
||||
|
|
|
@ -918,9 +918,10 @@ public:
|
|||
bool isSRet;
|
||||
bool isNest;
|
||||
bool isByVal;
|
||||
uint16_t Alignment;
|
||||
|
||||
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
|
||||
isSRet(false), isNest(false), isByVal(false) { }
|
||||
isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
|
||||
};
|
||||
typedef std::vector<ArgListEntry> ArgListTy;
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
|
|
|
@ -1234,7 +1234,8 @@ ParamAttr : ZEROEXT { $$ = ParamAttr::ZExt; }
|
|||
| NOALIAS { $$ = ParamAttr::NoAlias; }
|
||||
| BYVAL { $$ = ParamAttr::ByVal; }
|
||||
| NEST { $$ = ParamAttr::Nest; }
|
||||
| ALIGN EUINT64VAL { $$ = $2 << 16; }
|
||||
| ALIGN EUINT64VAL { $$ =
|
||||
ParamAttr::constructAlignmentFromInt($2); }
|
||||
;
|
||||
|
||||
OptParamAttrs : /* empty */ { $$ = ParamAttr::None; }
|
||||
|
|
|
@ -3118,6 +3118,7 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDOperand Callee,
|
|||
Entry.isSRet = CS.paramHasAttr(attrInd, ParamAttr::StructRet);
|
||||
Entry.isNest = CS.paramHasAttr(attrInd, ParamAttr::Nest);
|
||||
Entry.isByVal = CS.paramHasAttr(attrInd, ParamAttr::ByVal);
|
||||
Entry.Alignment = CS.getParamAlignment(attrInd);
|
||||
Args.push_back(Entry);
|
||||
}
|
||||
|
||||
|
@ -4146,6 +4147,10 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||
const Type *ElementTy = Ty->getElementType();
|
||||
unsigned FrameAlign = Log2_32(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 |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs);
|
||||
Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs);
|
||||
}
|
||||
|
@ -4255,6 +4260,10 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
const Type *ElementTy = Ty->getElementType();
|
||||
unsigned FrameAlign = Log2_32(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 |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs);
|
||||
Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs);
|
||||
}
|
||||
|
|
|
@ -143,6 +143,11 @@ bool Function::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
|
|||
return ParamAttrs && ParamAttrs->paramHasAttr(i, attr);
|
||||
}
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t Function::getParamAlignment(uint16_t i) const {
|
||||
return ParamAttrs ? ParamAttrs->getParamAlignment(i) : 0;
|
||||
}
|
||||
|
||||
/// @brief Determine if the function cannot return.
|
||||
bool Function::doesNotReturn() const {
|
||||
return paramHasAttr(0, ParamAttr::NoReturn);
|
||||
|
|
|
@ -61,6 +61,13 @@ bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
|
|||
else
|
||||
return cast<InvokeInst>(I)->paramHasAttr(i, attr);
|
||||
}
|
||||
uint16_t CallSite::getParamAlignment(uint16_t i) const {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I))
|
||||
return CI->getParamAlignment(i);
|
||||
else
|
||||
return cast<InvokeInst>(I)->getParamAlignment(i);
|
||||
}
|
||||
|
||||
bool CallSite::doesNotAccessMemory() const {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I))
|
||||
return CI->doesNotAccessMemory();
|
||||
|
@ -384,6 +391,14 @@ bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
uint16_t CallInst::getParamAlignment(uint16_t i) const {
|
||||
if (ParamAttrs && ParamAttrs->getParamAlignment(i))
|
||||
return ParamAttrs->getParamAlignment(i);
|
||||
if (const Function *F = getCalledFunction())
|
||||
return F->getParamAlignment(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool CallInst::doesNotAccessMemory() const {
|
||||
return paramHasAttr(0, ParamAttr::ReadNone);
|
||||
|
@ -508,6 +523,13 @@ bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
uint16_t InvokeInst::getParamAlignment(uint16_t i) const {
|
||||
if (ParamAttrs && ParamAttrs->getParamAlignment(i))
|
||||
return ParamAttrs->getParamAlignment(i);
|
||||
if (const Function *F = getCalledFunction())
|
||||
return F->getParamAlignment(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool InvokeInst::doesNotAccessMemory() const {
|
||||
|
|
Loading…
Reference in New Issue