[PATCH] D129525: [GlobalOpt] Drop SRA split limit for struct types.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 11 17:26:28 PDT 2022


fhahn created this revision.
fhahn added reviewers: reames, nikic.
Herald added subscribers: ormris, hiraditya.
Herald added a project: All.
fhahn requested review of this revision.
Herald added a project: LLVM.

4796b4ae7bccc7 <https://reviews.llvm.org/rG4796b4ae7bccc7b75a26b666fbd554c49b274404> limited the SRA to 16 types for all globals, while the
code previously did not have a similar limit for globals with
struct-typed initializers AFAICT.

This is causing notable size regressions for some large workloads. This
patch skips the size check for struct types, similar to code before
4796b4ae7bccc7 <https://reviews.llvm.org/rG4796b4ae7bccc7b75a26b666fbd554c49b274404> to recover the regression.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129525

Files:
  llvm/lib/Transforms/IPO/GlobalOpt.cpp
  llvm/test/Transforms/GlobalOpt/sra-many-stores.ll


Index: llvm/test/Transforms/GlobalOpt/sra-many-stores.ll
===================================================================
--- llvm/test/Transforms/GlobalOpt/sra-many-stores.ll
+++ llvm/test/Transforms/GlobalOpt/sra-many-stores.ll
@@ -5,19 +5,12 @@
 
 @global = internal global %struct.widget zeroinitializer
 
-;.
-; CHECK: @[[GLOBAL:[a-zA-Z0-9_$"\\.-]+]] = internal unnamed_addr global [[STRUCT_WIDGET:%.*]] zeroinitializer
-;.
 define internal i32 @fn1() {
-; CHECK-LABEL: @fn1(
-; CHECK-NEXT:    ret i32 0
-;
   ret i32 0
 }
 
 define internal void @fn2() {
 ; CHECK-LABEL: @fn2(
-; CHECK-NEXT:    [[TMP:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_WIDGET:%.*]], ptr @global, i64 0, i32 16), align 8
 ; CHECK-NEXT:    ret void
 ;
   %tmp = load ptr, ptr getelementptr inbounds (%struct.widget, ptr @global, i64 0, i32 16), align 8
@@ -26,22 +19,6 @@
 
 define internal void @write() {
 ; CHECK-LABEL: @write(
-; CHECK-NEXT:    store ptr null, ptr @global, align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET:%.*]], ptr @global, i64 0, i32 1), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 2), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 3), align 8
-; CHECK-NEXT:    store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 4), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 5), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 6), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 7), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 8), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 9), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 10), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 11), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 12), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 13), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 14), align 8
-; CHECK-NEXT:    store ptr null, ptr getelementptr inbounds ([[STRUCT_WIDGET]], ptr @global, i64 0, i32 15), align 8
 ; CHECK-NEXT:    tail call fastcc void @fn2()
 ; CHECK-NEXT:    ret void
 ;
Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -463,8 +463,9 @@
   if (Types.size() == 1 && Types.begin()->second == GV->getValueType())
     return nullptr;
 
+  Constant *OrigInit = GV->getInitializer();
   // Don't perform SRA if we would have to split into many globals.
-  if (Types.size() > 16)
+  if (!isa<StructType>(OrigInit->getType()) && Types.size() > 16)
     return nullptr;
 
   // Sort by offset.
@@ -488,7 +489,6 @@
     return nullptr;
 
   // Collect initializers for new globals.
-  Constant *OrigInit = GV->getInitializer();
   DenseMap<uint64_t, Constant *> Initializers;
   for (const auto &Pair : Types) {
     Constant *NewInit = ConstantFoldLoadFromConst(OrigInit, Pair.second,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D129525.443792.patch
Type: text/x-patch
Size: 3679 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220712/60015b8a/attachment.bin>


More information about the llvm-commits mailing list