Pass alignment on ByVal parameters, from FE, all
authorDale Johannesen <dalej@apple.com>
Fri, 22 Feb 2008 17:49:45 +0000 (17:49 +0000)
committerDale Johannesen <dalej@apple.com>
Fri, 22 Feb 2008 17:49:45 +0000 (17:49 +0000)
the way through.  It is now used for codegen.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47484 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Function.h
include/llvm/Instructions.h
include/llvm/ParameterAttributes.h
include/llvm/Support/CallSite.h
include/llvm/Target/TargetLowering.h
lib/AsmParser/llvmAsmParser.y
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/VMCore/Function.cpp
lib/VMCore/Instructions.cpp

index e2b41fe25da847f648af2f215a3b7a68289f6885..40b9c46de235d6749ec369f092ce4edf64d625c8 100644 (file)
@@ -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;
 
index b6d5de0f525907d63695968120be90a7fcc985f3..8321d6ff5562c90d4c5e3712a7f0aff2caeb917a 100644 (file)
@@ -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;
 
index c3a52fbac320083b15f05bb7d5f76141dc3992bb..33cc95c95d5e0864f7e6baf7014c145d8b94db44 100644 (file)
@@ -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.
index 401e5588db1c92444b61d501585d7a090b9fad75..3bd4ef256c5b10672ddcecbcb3cbb5b1d76f88b8 100644 (file)
@@ -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;
 
index 4515b90b2baa18dda04d9422eb9913f5087829ab..783c0f82d5cc39ba276274005dc5ed3f4b7b5e8b 100644 (file)
@@ -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>
index b0cdbc7c9bc262f764da036748c09b936918abf7..137bd58ea71924fe4bb020f67ec5b89bd157f5ba 100644 (file)
@@ -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; }
index 96dde98be9c2d2c800d770bf671c0a661cdf309c..62610dbe228ff78c957421c9d6207b792449541e 100644 (file)
@@ -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);
     }
index 49d770d5bd3ba6af2134399f900e763fb2a937b7..0cf808c507c51cd9573977c61ab264c48a2120dd 100644 (file)
@@ -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);
index 4197f80c922a775e30adb6824dc79b4590e1435a..b3a78b729f5cf4f3ad9306b112a22a893028ede9 100644 (file)
@@ -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 {