[PATCH] D29881: [PPC] Reduce stack frame size by allocating parameter area on an on-demand basis for ELFv2 ABI

Hiroshi Inoue via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 12 23:11:16 PST 2017


inouehrs created this revision.

On the ELFv2 ABI, we need to allocate the parameter area in the stack frame only if a callee really uses it, e.g. vararg function.
However, current LLVM always allocates the parameter area conservatively. This inflate the stack size significantly.

This patch reduces the stack frame size by not allocating the parameter area if it is not required.
The average stack frame size for the functions generated while compiling the LLVM source tree is reduced by about 30 bytes (from 182.9 byte to 152.4 byte).


https://reviews.llvm.org/D29881

Files:
  lib/Target/PowerPC/PPCISelLowering.cpp


Index: lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelLowering.cpp
+++ lib/Target/PowerPC/PPCISelLowering.cpp
@@ -5151,10 +5151,30 @@
   };
 
   const unsigned NumGPRs = array_lengthof(GPR);
-  const unsigned NumFPRs = 13;
+  const unsigned NumFPRs = useSoftFloat() ? 0 : 13;
   const unsigned NumVRs  = array_lengthof(VR);
   const unsigned NumQFPRs = NumFPRs;
 
+  // On ELFv2, we can avoid allocating the parameter area if all the arguments 
+  // can be passed to the callee in registers.
+  // For the fast calling convention, there is another check below.
+  // Note: keep consistent with LowerFormalArguments_64SVR4()
+  bool HasParameterArea = !isELFv2ABI || isVarArg;
+  if (!HasParameterArea && CallConv != CallingConv::Fast) {
+    unsigned ParamAreaSize = NumGPRs * PtrByteSize;
+    unsigned AvailableFPRs = NumFPRs;
+    unsigned AvailableVRs = NumVRs;
+    unsigned NumBytesTmp = NumBytes;
+    for (unsigned i = 0; i != NumOps; ++i) {
+      if (Outs[i].Flags.isNest()) continue;
+      if (CalculateStackSlotUsed(Outs[i].VT, Outs[i].ArgVT, Outs[i].Flags,
+                                PtrByteSize, LinkageSize, ParamAreaSize,
+                                NumBytesTmp, AvailableFPRs, AvailableVRs,
+                                Subtarget.hasQPX()))
+        HasParameterArea = true;
+    }
+  }
+
   // When using the fast calling convention, we don't provide backing for
   // arguments that will be in registers.
   unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
@@ -5222,13 +5242,16 @@
 
   unsigned NumBytesActuallyUsed = NumBytes;
 
-  // The prolog code of the callee may store up to 8 GPR argument registers to
+  // In the old ELFv1 ABI, 
+  // the prolog code of the callee may store up to 8 GPR argument registers to
   // the stack, allowing va_start to index over them in memory if its varargs.
   // Because we cannot tell if this is needed on the caller side, we have to
   // conservatively assume that it is needed.  As such, make sure we have at
   // least enough stack space for the caller to store the 8 GPRs.
-  // FIXME: On ELFv2, it may be unnecessary to allocate the parameter area.
-  NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
+  // In the ELFv2 ABI, we allocate the parameter area iff a callee 
+  // really requires memory operands, e.g. a vararg function.
+  if (HasParameterArea)
+    NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
 
   // Tail call needs the stack to be aligned.
   if (getTargetMachine().Options.GuaranteedTailCallOpt &&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29881.88158.patch
Type: text/x-patch
Size: 2632 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170213/fd30ed5c/attachment.bin>


More information about the llvm-commits mailing list