[llvm-commits] PATCH: Scalar Replacement of Aggregates Pass - Add more threshold parameters

Tom Stellard thomas.stellard at amd.com
Thu Jun 7 07:36:01 PDT 2012


On Wed, Jun 06, 2012 at 06:47:11PM +0000, Rotem, Nadav wrote:
> LGTM. 
> 
> I remember seeing another parameter which controls the size of structs which can be converted into a single wide load instruction. It's also worth adding a parameter for that one.
> 

I wasn't able to find this parameter, but I'm not too familiar with the
code, so I could have easily overlooked it.  If you point me to where it
is, I'll add another argument to the constructor.

Also, here is a v2 patch that updates some comments that were made stale
by this change.

-Tom

> -----Original Message-----
> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Tom Stellard
> Sent: Wednesday, June 06, 2012 18:26
> To: llvm-commits at cs.uiuc.edu
> Subject: [llvm-commits] PATCH: Scalar Replacement of Aggregates Pass - Add more threshold parameters
> 
> Hi,
> 
> The attached pass allows users of the SROA pass to specify threshold values for the maximum number of struct members and number of array elements that can be considered for SROA.
> 
> The current hard-coded threshold value for maximum number of array elements is 8.  This is too small for GPUs targeted by the R600 backend which have 512 general purpose registers, so it would be very useful for these targets to be able to manually specify these threshold values.
> 
> Please Review.
> 
> Thanks,
> Tom
> ---------------------------------------------------------------------
> Intel Israel (74) Limited
> 
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.
> 
> 
-------------- next part --------------
diff --git include/llvm/Transforms/Scalar.h include/llvm/Transforms/Scalar.h
index 06130d1..0322394 100644
--- include/llvm/Transforms/Scalar.h
+++ include/llvm/Transforms/Scalar.h
@@ -74,7 +74,9 @@ FunctionPass *createAggressiveDCEPass();
 // if possible.
 //
 FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1,
-                                             bool UseDomTree = true);
+                                             bool UseDomTree = true,
+                                             signed StructMemberThreshold = -1,
+                                             signed ArrayElementThreshold = -1);
 
 //===----------------------------------------------------------------------===//
 //
diff --git lib/Transforms/Scalar/ScalarReplAggregates.cpp lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 113397f..66ab14b 100644
--- lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -60,12 +60,20 @@ STATISTIC(NumGlobals,   "Number of allocas copied from constant global");
 
 namespace {
   struct SROA : public FunctionPass {
-    SROA(int T, bool hasDT, char &ID)
+    SROA(int T, bool hasDT, char &ID, int ST, int AT)
       : FunctionPass(ID), HasDomTree(hasDT) {
       if (T == -1)
         SRThreshold = 128;
       else
         SRThreshold = T;
+      if (ST == -1)
+        StructMemberThreshold = 32;
+      else
+        StructMemberThreshold = ST;
+      if (AT == -1)
+        ArrayElementThreshold = 8;
+      else
+        ArrayElementThreshold = AT;
     }
 
     bool runOnFunction(Function &F);
@@ -116,8 +124,17 @@ namespace {
           hasSubelementAccess(false), hasALoadOrStore(false) {}
     };
 
+    /// SRThreshold - The maximum alloca size to considered for SROA.
     unsigned SRThreshold;
 
+    /// StructMemberThreshold - The maximum number of members a struct can
+    /// contain to be considered for SROA.
+    unsigned StructMemberThreshold;
+
+    /// ArrayElementThreshold - The maximum number of elements an array can
+    /// have to be considered for SROA.
+    unsigned ArrayElementThreshold;
+
     void MarkUnsafe(AllocaInfo &I, Instruction *User) {
       I.isUnsafe = true;
       DEBUG(dbgs() << "  Transformation preventing inst: " << *User << '\n');
@@ -156,6 +173,7 @@ namespace {
                                        SmallVector<AllocaInst*, 32> &NewElts);
     void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI,
                                       SmallVector<AllocaInst*, 32> &NewElts);
+    bool ShouldAttemptScalarRepl(AllocaInst *AI);
 
     static MemTransferInst *isOnlyCopiedFromConstantGlobal(
         AllocaInst *AI, SmallVector<Instruction*, 4> &ToDelete);
@@ -165,7 +183,7 @@ namespace {
   struct SROA_DT : public SROA {
     static char ID;
   public:
-    SROA_DT(int T = -1) : SROA(T, true, ID) {
+    SROA_DT(int T = -1, int ST = -1, int AT = -1) : SROA(T, true, ID, ST, AT) {
       initializeSROA_DTPass(*PassRegistry::getPassRegistry());
     }
     
@@ -181,7 +199,8 @@ namespace {
   struct SROA_SSAUp : public SROA {
     static char ID;
   public:
-    SROA_SSAUp(int T = -1) : SROA(T, false, ID) {
+    SROA_SSAUp(int T = -1, int ST = -1, int AT = -1) :
+        SROA(T, false, ID, ST, AT) {
       initializeSROA_SSAUpPass(*PassRegistry::getPassRegistry());
     }
     
@@ -210,10 +229,13 @@ INITIALIZE_PASS_END(SROA_SSAUp, "scalarrepl-ssa",
 
 // Public interface to the ScalarReplAggregates pass
 FunctionPass *llvm::createScalarReplAggregatesPass(int Threshold,
-                                                   bool UseDomTree) {
+                                                   bool UseDomTree,
+                                                   int StructMemberThreshold,
+                                                   int ArrayElementThreshold) {
   if (UseDomTree)
-    return new SROA_DT(Threshold);
-  return new SROA_SSAUp(Threshold);
+    return new SROA_DT(Threshold, StructMemberThreshold, ArrayElementThreshold);
+  return new SROA_SSAUp(Threshold, StructMemberThreshold,
+                        ArrayElementThreshold);
 }
 
 
@@ -1335,15 +1357,14 @@ bool SROA::performPromotion(Function &F) {
 
 /// ShouldAttemptScalarRepl - Decide if an alloca is a good candidate for
 /// SROA.  It must be a struct or array type with a small number of elements.
-static bool ShouldAttemptScalarRepl(AllocaInst *AI) {
+bool SROA::ShouldAttemptScalarRepl(AllocaInst *AI) {
   Type *T = AI->getAllocatedType();
-  // Do not promote any struct into more than 32 separate vars.
+  // Do not promote any struct that has too many members.
   if (StructType *ST = dyn_cast<StructType>(T))
-    return ST->getNumElements() <= 32;
-  // Arrays are much less likely to be safe for SROA; only consider
-  // them if they are very small.
+    return ST->getNumElements() <= StructMemberThreshold;
+  // Do not promote any array that has too many elements.
   if (ArrayType *AT = dyn_cast<ArrayType>(T))
-    return AT->getNumElements() <= 8;
+    return AT->getNumElements() <= ArrayElementThreshold;
   return false;
 }
 


More information about the llvm-commits mailing list