[PATCH] D71993: [Transforms][GlobalSRA] huge array causes long compilation time and huge memory usage.

Alexey Lapshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 30 03:49:01 PST 2019


avl created this revision.
avl added reviewers: craig.topper, rnk, efriedma, fhahn.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

For artificial cases (huge array, few usages), Global SRA optimization creates
a lot of redundant data. It creates an instance of GlobalVariable for each array
element. For huge array, that means huge compilation time and huge memory usage.
Following example compiles for 10 minutes and requires 40GB of memory.

namespace {

  char LargeBuffer[64 * 1024 * 1024];

}

int main ( void ) {

  LargeBuffer[0] = 0;
  
  printf("\n ");
  
  return LargeBuffer[0] == 0;

}

The fix is to avoid Global SRA for large arrays.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71993

Files:
  llvm/lib/Transforms/IPO/GlobalOpt.cpp
  llvm/test/Transforms/GlobalOpt/long-compilation-global-sra.ll


Index: llvm/test/Transforms/GlobalOpt/long-compilation-global-sra.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/GlobalOpt/long-compilation-global-sra.ll
@@ -0,0 +1,53 @@
+; RUN: opt %s --O0 -globalopt -S -o -
+
+; This is a regression test against very slow execution...
+; In bad case it should fail by timeout.
+
+; Hand-reduced from this example.
+; clang++ -mllvm -disable-llvm-optzns
+
+;#include <stdio.h>
+;
+;namespace {
+;  char LargeBuffer[64 * 1024 * 1024];
+;}
+;
+;int main ( void ) {
+;
+;    LargeBuffer[0] = 0;
+;
+;    printf("");
+;
+;    return LargeBuffer[0] == 0;
+;}
+
+; ModuleID = 'test.cpp'
+source_filename = "test.cpp"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at _ZN12_GLOBAL__N_111LargeBufferE = internal global [67108864 x i8] zeroinitializer, align 16
+ at .str = private unnamed_addr constant [1 x i8] c"\00", align 1
+
+; Function Attrs: norecurse uwtable
+define dso_local i32 @main() #0 {
+  %1 = alloca i32, align 4
+  store i32 0, i32* %1, align 4
+  store i8 0, i8* getelementptr inbounds ([67108864 x i8], [67108864 x i8]* @_ZN12_GLOBAL__N_111LargeBufferE, i64 0, i64 0), align 16
+  %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0))
+  %3 = load i8, i8* getelementptr inbounds ([67108864 x i8], [67108864 x i8]* @_ZN12_GLOBAL__N_111LargeBufferE, i64 0, i64 0), align 16
+  %4 = sext i8 %3 to i32
+  %5 = icmp eq i32 %4, 0
+  %6 = zext i1 %5 to i32
+  ret i32 %6
+}
+
+declare dso_local i32 @printf(i8*, ...) #0
+
+attributes #0 = { norecurse uwtable }
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 10.0.0 "}
Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -509,7 +509,7 @@
     }
   } else if (SequentialType *STy = dyn_cast<SequentialType>(Ty)) {
     unsigned NumElements = STy->getNumElements();
-    if (NumElements > 16 && GV->hasNUsesOrMore(16))
+    if (NumElements > 16)
       return nullptr; // It's not worth it.
     NewGlobals.reserve(NumElements);
     auto ElTy = STy->getElementType();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D71993.235576.patch
Type: text/x-patch
Size: 2373 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191230/16e9ae94/attachment.bin>


More information about the llvm-commits mailing list