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

Tom Stellard thomas.stellard at amd.com
Wed Jun 6 08:25:35 PDT 2012


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
-------------- 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..88d1851 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,15 @@ 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.
   if (StructType *ST = dyn_cast<StructType>(T))
-    return ST->getNumElements() <= 32;
+    return ST->getNumElements() <= StructMemberThreshold;
   // Arrays are much less likely to be safe for SROA; only consider
   // them if they are very small.
   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