diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Function.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/Instructions.h | 6 | ||||
| -rw-r--r-- | llvm/include/llvm/ParameterAttributes.h | 13 | ||||
| -rw-r--r-- | llvm/include/llvm/Support/CallSite.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/Target/TargetLowering.h | 3 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/llvmAsmParser.y | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 9 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Function.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Instructions.cpp | 22 | 
9 files changed, 65 insertions, 2 deletions
diff --git a/llvm/include/llvm/Function.h b/llvm/include/llvm/Function.h index e2b41fe25da..40b9c46de23 100644 --- a/llvm/include/llvm/Function.h +++ b/llvm/include/llvm/Function.h @@ -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; diff --git a/llvm/include/llvm/Instructions.h b/llvm/include/llvm/Instructions.h index b6d5de0f525..8321d6ff556 100644 --- a/llvm/include/llvm/Instructions.h +++ b/llvm/include/llvm/Instructions.h @@ -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; diff --git a/llvm/include/llvm/ParameterAttributes.h b/llvm/include/llvm/ParameterAttributes.h index c3a52fbac32..33cc95c95d5 100644 --- a/llvm/include/llvm/ParameterAttributes.h +++ b/llvm/include/llvm/ParameterAttributes.h @@ -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. diff --git a/llvm/include/llvm/Support/CallSite.h b/llvm/include/llvm/Support/CallSite.h index 401e5588db1..3bd4ef256c5 100644 --- a/llvm/include/llvm/Support/CallSite.h +++ b/llvm/include/llvm/Support/CallSite.h @@ -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; diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index 4515b90b2ba..783c0f82d5c 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -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> diff --git a/llvm/lib/AsmParser/llvmAsmParser.y b/llvm/lib/AsmParser/llvmAsmParser.y index b0cdbc7c9bc..137bd58ea71 100644 --- a/llvm/lib/AsmParser/llvmAsmParser.y +++ b/llvm/lib/AsmParser/llvmAsmParser.y @@ -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; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 96dde98be9c..62610dbe228 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -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);      } diff --git a/llvm/lib/VMCore/Function.cpp b/llvm/lib/VMCore/Function.cpp index 49d770d5bd3..0cf808c507c 100644 --- a/llvm/lib/VMCore/Function.cpp +++ b/llvm/lib/VMCore/Function.cpp @@ -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); diff --git a/llvm/lib/VMCore/Instructions.cpp b/llvm/lib/VMCore/Instructions.cpp index 4197f80c922..b3a78b729f5 100644 --- a/llvm/lib/VMCore/Instructions.cpp +++ b/llvm/lib/VMCore/Instructions.cpp @@ -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 {  | 

