[llvm-commits] [llvm] r82767 - in /llvm/trunk: include/llvm/Target/TargetFrameInfo.h lib/CodeGen/PrologEpilogInserter.cpp lib/Target/ARM/ARMFrameInfo.h test/CodeGen/ARM/2009-09-24-spill-align.ll

Evan Cheng evan.cheng at apple.com
Fri Sep 25 14:26:54 CDT 2009


On Sep 25, 2009, at 7:41 AM, Bob Wilson wrote:

> Author: bwilson
> Date: Fri Sep 25 09:41:49 2009
> New Revision: 82767
>
> URL: http://llvm.org/viewvc/llvm-project?rev=82767&view=rev
> Log:
> pr4926: ARM requires the stack pointer to be aligned, even for leaf  
> functions.

Is this true even if the function does not use sp at all?

Evan

> For the AAPCS ABI, SP must always be 4-byte aligned, and at any  
> "public
> interface" it must be 8-byte aligned.  For the older ARM APCS ABI,  
> the stack
> alignment is just always 4 bytes.  For X86, we currently align SP at
> entry to a function (e.g., to 16 bytes for Darwin), but no stack  
> alignment
> is needed at other times, such as for a leaf function.
>
> After discussing this with Dan, I decided to go with the approach of  
> adding
> a new "TransientStackAlignment" field to TargetFrameInfo.  This value
> specifies the stack alignment that must be maintained even in  
> between calls.
> It defaults to 1 except for ARM, where it is 4.  (Some other targets  
> may
> also want to set this if they have similar stack requirements. It's  
> not
> currently required for PPC because it sets  
> targetHandlesStackFrameRounding
> and handles the alignment in target-specific code.) The existing  
> StackAlignment
> value specifies the alignment upon entry to a function, which is how  
> we've
> been using it anyway.
>
> Added:
>    llvm/trunk/test/CodeGen/ARM/2009-09-24-spill-align.ll
> Modified:
>    llvm/trunk/include/llvm/Target/TargetFrameInfo.h
>    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
>    llvm/trunk/lib/Target/ARM/ARMFrameInfo.h
>
> Modified: llvm/trunk/include/llvm/Target/TargetFrameInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetFrameInfo.h?rev=82767&r1=82766&r2=82767&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/Target/TargetFrameInfo.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetFrameInfo.h Fri Sep 25  
> 09:41:49 2009
> @@ -34,10 +34,13 @@
> private:
>   StackDirection StackDir;
>   unsigned StackAlignment;
> +  unsigned TransientStackAlignment;
>   int LocalAreaOffset;
> public:
> -  TargetFrameInfo(StackDirection D, unsigned StackAl, int LAO)
> -    : StackDir(D), StackAlignment(StackAl), LocalAreaOffset(LAO) {}
> +  TargetFrameInfo(StackDirection D, unsigned StackAl, int LAO,
> +                  unsigned TransAl = 1)
> +    : StackDir(D), StackAlignment(StackAl), TransientStackAlignment 
> (TransAl),
> +      LocalAreaOffset(LAO) {}
>
>   virtual ~TargetFrameInfo();
>
> @@ -48,12 +51,20 @@
>   ///
>   StackDirection getStackGrowthDirection() const { return StackDir; }
>
> -  /// getStackAlignment - This method returns the number of bytes  
> that the stack
> -  /// pointer must be aligned to.  Typically, this is the largest  
> alignment for
> -  /// any data object in the target.
> +  /// getStackAlignment - This method returns the number of bytes  
> to which the
> +  /// stack pointer must be aligned on entry to a function.   
> Typically, this
> +  /// is the largest alignment for any data object in the target.
>   ///
>   unsigned getStackAlignment() const { return StackAlignment; }
>
> +  /// getTransientStackAlignment - This method returns the number  
> of bytes to
> +  /// which the stack pointer must be aligned at all times, even  
> between
> +  /// calls.
> +  ///
> +  unsigned getTransientStackAlignment() const {
> +    return TransientStackAlignment;
> +  }
> +
>   /// getOffsetOfLocalArea - This method returns the offset of the  
> local area
>   /// from the stack pointer on entrance to a function.
>   ///
>
> Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=82767&r1=82766&r2=82767&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)
> +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Fri Sep 25  
> 09:41:49 2009
> @@ -484,7 +484,7 @@
>   // Loop over all of the stack objects, assigning sequential  
> addresses...
>   MachineFrameInfo *FFI = Fn.getFrameInfo();
>
> -  unsigned MaxAlign = FFI->getMaxAlignment();
> +  unsigned MaxAlign = 1;
>
>   // Start at the beginning of the local area.
>   // The Offset is the distance from the stack top in the direction
> @@ -586,23 +586,28 @@
>       AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign);
>   }
>
> -  // Round up the size to a multiple of the alignment, but only if  
> there are
> -  // calls or alloca's in the function.  This ensures that any  
> calls to
> -  // subroutines have their stack frames suitably aligned.
> -  // Also do this if we need runtime alignment of the stack.  In  
> this case
> -  // offsets will be relative to SP not FP; round up the stack size  
> so this
> -  // works.
> -  if (!RegInfo->targetHandlesStackFrameRounding() &&
> -      (FFI->hasCalls() || FFI->hasVarSizedObjects() ||
> -       (RegInfo->needsStackRealignment(Fn) &&
> -        FFI->getObjectIndexEnd() != 0))) {
> +  if (!RegInfo->targetHandlesStackFrameRounding()) {
>     // If we have reserved argument space for call sites in the  
> function
>     // immediately on entry to the current function, count it as  
> part of the
>     // overall stack size.
> -    if (RegInfo->hasReservedCallFrame(Fn))
> +    if (FFI->hasCalls() && RegInfo->hasReservedCallFrame(Fn))
>       Offset += FFI->getMaxCallFrameSize();
>
> -    unsigned AlignMask = std::max(TFI.getStackAlignment(),  
> MaxAlign) - 1;
> +    // Round up the size to a multiple of the alignment.  If the  
> function has
> +    // any calls or alloca's, align to the target's StackAlignment  
> value to
> +    // ensure that the callee's frame or the alloca data is  
> suitably aligned;
> +    // otherwise, for leaf functions, align to the  
> TransientStackAlignment
> +    // value.
> +    unsigned StackAlign;
> +    if (FFI->hasCalls() || FFI->hasVarSizedObjects() ||
> +        (RegInfo->needsStackRealignment(Fn) && FFI- 
> >getObjectIndexEnd() != 0))
> +      StackAlign = TFI.getStackAlignment();
> +    else
> +      StackAlign = TFI.getTransientStackAlignment();
> +    // If the frame pointer is eliminated, all frame offsets will  
> be relative
> +    // to SP not FP; align to MaxAlign so this works.
> +    StackAlign = std::max(StackAlign, MaxAlign);
> +    unsigned AlignMask = StackAlign - 1;
>     Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
>   }
>
> @@ -611,7 +616,8 @@
>
>   // Remember the required stack alignment in case targets need it  
> to perform
>   // dynamic stack alignment.
> -  FFI->setMaxAlignment(MaxAlign);
> +  if (MaxAlign > FFI->getMaxAlignment())
> +    FFI->setMaxAlignment(MaxAlign);
> }
>
>
>
> Modified: llvm/trunk/lib/Target/ARM/ARMFrameInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameInfo.h?rev=82767&r1=82766&r2=82767&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMFrameInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMFrameInfo.h Fri Sep 25 09:41:49 2009
> @@ -23,7 +23,7 @@
> class ARMFrameInfo : public TargetFrameInfo {
> public:
>   explicit ARMFrameInfo(const ARMSubtarget &ST)
> -    : TargetFrameInfo(StackGrowsDown, ST.getStackAlignment(), 0) {
> +    : TargetFrameInfo(StackGrowsDown, ST.getStackAlignment(), 0, 4) {
>   }
> };
>
>
> Added: llvm/trunk/test/CodeGen/ARM/2009-09-24-spill-align.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-09-24-spill-align.ll?rev=82767&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/CodeGen/ARM/2009-09-24-spill-align.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/2009-09-24-spill-align.ll Fri Sep 25  
> 09:41:49 2009
> @@ -0,0 +1,17 @@
> +; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
> +; pr4926
> +
> +define arm_apcscc void @test_vget_lanep16() nounwind {
> +entry:
> +  %arg0_poly16x4_t = alloca <4 x i16>             ; <<4 x i16>*>  
> [#uses=1]
> +  %out_poly16_t = alloca i16                      ; <i16*> [#uses=1]
> +  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
> +; CHECK: fldd
> +  %0 = load <4 x i16>* %arg0_poly16x4_t, align 8  ; <<4 x i16>>  
> [#uses=1]
> +  %1 = extractelement <4 x i16> %0, i32 1         ; <i16> [#uses=1]
> +  store i16 %1, i16* %out_poly16_t, align 2
> +  br label %return
> +
> +return:                                           ; preds = %entry
> +  ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list