[PATCH] D152556: [FuncSpec] Promote stack values before specialization

Manolis Tsamis via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 9 09:45:02 PDT 2023


mtsamis created this revision.
mtsamis added reviewers: ChuanqiXu, chill, jaykang10.
Herald added subscribers: hoy, ormris, hiraditya.
Herald added a project: All.
mtsamis requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

After each iteration of the function specializer, constant
stack values are promoted to constant globals in order to
enable recursive function specialization.

This should also be done once before running the specializer:

- Since by default the specializer is ran once, without an initial call to this function worthwhile specialization opportunities may be missed. This is especially true for Fortran programs where function arguments are passed by reference.
- This also results in more consistent specialization behaviour when the specializer is ran more than once. Currently there are cases where functions will be specialized depending on if an unrelated specializable function is added.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152556

Files:
  llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h
  llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
  llvm/lib/Transforms/IPO/SCCP.cpp
  llvm/test/Transforms/FunctionSpecialization/function-specialization-recursive5.ll


Index: llvm/test/Transforms/FunctionSpecialization/function-specialization-recursive5.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/FunctionSpecialization/function-specialization-recursive5.ll
@@ -0,0 +1,48 @@
+; RUN: opt -passes="ipsccp<func-spec>,inline,instcombine" -force-specialization -funcspec-max-iters=1 -S < %s | FileCheck %s --check-prefix=ITERS1
+; RUN: opt -passes="ipsccp<func-spec>,inline,instcombine" -force-specialization -funcspec-max-iters=4 -S < %s | FileCheck %s --check-prefix=ITERS4
+
+define internal void @recursiveFunc(ptr nocapture readonly %lo, i32 %step, ptr nocapture readonly %hi) {
+  %lo.temp = alloca i32, align 4
+  %hi.temp = alloca i32, align 4
+  %lo.load = load i32, ptr %lo, align 4
+  %hi.load = load i32, ptr %hi, align 4
+  %cmp = icmp ne i32 %lo.load, %hi.load
+  br i1 %cmp, label %block6, label %ret.block
+
+block6:
+  call void @print_val(i32 %lo.load, i32 %hi.load)
+  %add = add nsw i32 %lo.load, %step
+  %sub = sub nsw i32 %hi.load, %step
+  store i32 %add, ptr %lo.temp, align 4
+  store i32 %sub, ptr %hi.temp, align 4
+  call void @recursiveFunc(ptr nonnull %lo.temp, i32 %step, ptr nonnull %hi.temp)
+  br label %ret.block
+
+ret.block:
+  ret void
+}
+
+; ITERS1:  @funcspec.arg.3 = internal constant i32 1
+; ITERS1:  @funcspec.arg.4 = internal constant i32 5
+
+define i32 @main() {
+; ITERS1-LABEL: @main(
+; ITERS1-NEXT:    call void @print_val(i32 0, i32 6)
+; ITERS1-NEXT:    call void @recursiveFunc(ptr nonnull @funcspec.arg.3, i32 1, ptr nonnull @funcspec.arg.4)
+; ITERS1-NEXT:    ret i32 0
+;
+; ITERS4-LABEL: @main(
+; ITERS4-NEXT:    call void @print_val(i32 0, i32 6)
+; ITERS4-NEXT:    call void @print_val(i32 1, i32 5)
+; ITERS4-NEXT:    call void @print_val(i32 2, i32 4)
+; ITERS4-NEXT:    ret i32 0
+;
+  %low.arg = alloca i32, align 4
+  %high.arg = alloca i32, align 4
+  store i32 0, ptr %low.arg, align 4
+  store i32 6, ptr %high.arg, align 4
+  call void @recursiveFunc(ptr nonnull %low.arg, i32 1, ptr nonnull %high.arg)
+  ret i32 0
+}
+
+declare dso_local void @print_val(i32, i32)
Index: llvm/lib/Transforms/IPO/SCCP.cpp
===================================================================
--- llvm/lib/Transforms/IPO/SCCP.cpp
+++ llvm/lib/Transforms/IPO/SCCP.cpp
@@ -160,6 +160,7 @@
   Solver.solveWhileResolvedUndefsIn(M);
 
   if (IsFuncSpecEnabled) {
+    Specializer.init();
     unsigned Iters = 0;
     while (Iters++ < FuncSpecMaxIters && Specializer.run());
   }
Index: llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
===================================================================
--- llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -463,6 +463,15 @@
   cleanUpSSA();
 }
 
+/// Should be called once before any calls to run.
+void FunctionSpecializer::init() {
+  // Promote constant stack values once before entering the run loop.
+  // Apart from generally increasing specialization opportunities, this is
+  // critical for Fortran programs where function arguments are passed by
+  // reference.
+  promoteConstantStackValues();
+}
+
 /// Attempt to specialize functions in the module to enable constant
 /// propagation across function boundaries.
 ///
Index: llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h
===================================================================
--- llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h
+++ llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h
@@ -184,6 +184,7 @@
 
   ~FunctionSpecializer();
 
+  void init();
   bool run();
 
   InstCostVisitor getInstCostVisitorFor(Function *F) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D152556.529996.patch
Type: text/x-patch
Size: 3683 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230609/52d406ff/attachment.bin>


More information about the llvm-commits mailing list