[llvm-branch-commits] [llvm] fe43110 - [IROutliner] Adding option to enable outlining from linkonceodr functions

Andrew Litteken via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Dec 30 10:24:09 PST 2020


Author: Andrew Litteken
Date: 2020-12-30T12:08:04-06:00
New Revision: fe431103b633278da9ece1e03d6b441c1d44d977

URL: https://github.com/llvm/llvm-project/commit/fe431103b633278da9ece1e03d6b441c1d44d977
DIFF: https://github.com/llvm/llvm-project/commit/fe431103b633278da9ece1e03d6b441c1d44d977.diff

LOG: [IROutliner] Adding option to enable outlining from linkonceodr functions

There are functions that the linker is able to automatically
deduplicate, we do not outline from these functions by default. This
allows for outlining from those functions.

Tests:
llvm/test/Transforms/IROutliner/outlining-odr.ll

Reviewers: jroelofs, paquette

Differential Revision: https://reviews.llvm.org/D87309

Added: 
    llvm/test/Transforms/IROutliner/outlining-odr.ll

Modified: 
    llvm/include/llvm/Transforms/IPO/IROutliner.h
    llvm/lib/Transforms/IPO/IROutliner.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h
index 6291af741184..947a70866b04 100644
--- a/llvm/include/llvm/Transforms/IPO/IROutliner.h
+++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h
@@ -258,6 +258,10 @@ class IROutliner {
                                     std::vector<Function *> &FuncsToRemove,
                                     unsigned &OutlinedFunctionNum);
 
+  /// If true, enables us to outline from functions that have LinkOnceFromODR
+  /// linkages.
+  bool OutlineFromLinkODRs = false;
+
   /// If false, we do not worry if the cost is greater than the benefit.  This
   /// is for debugging and testing, so that we can test small cases to ensure
   /// that the outlining is being done correctly.

diff  --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp
index 5289826f4a9a..908ba0c70e70 100644
--- a/llvm/lib/Transforms/IPO/IROutliner.cpp
+++ b/llvm/lib/Transforms/IPO/IROutliner.cpp
@@ -30,6 +30,16 @@
 using namespace llvm;
 using namespace IRSimilarity;
 
+// Set to true if the user wants the ir outliner to run on linkonceodr linkage
+// functions. This is false by default because the linker can dedupe linkonceodr
+// functions. Since the outliner is confined to a single module (modulo LTO),
+// this is off by default. It should, however, be the default behavior in
+// LTO.
+static cl::opt<bool> EnableLinkOnceODRIROutlining(
+    "enable-linkonceodr-ir-outlining", cl::Hidden,
+    cl::desc("Enable the IR outliner on linkonceodr functions"),
+    cl::init(false));
+
 // This is a debug option to test small pieces of code to ensure that outlining
 // works correctly.
 static cl::opt<bool> NoCostModel(
@@ -1243,6 +1253,10 @@ void IROutliner::pruneIncompatibleRegions(
     if (IRSC.getStartBB()->hasAddressTaken())
       continue;
 
+    if (IRSC.front()->Inst->getFunction()->hasLinkOnceODRLinkage() &&
+        !OutlineFromLinkODRs)
+      continue;
+
     // Greedily prune out any regions that will overlap with already chosen
     // regions.
     if (CurrentEndIdx != 0 && StartIdx <= CurrentEndIdx)
@@ -1659,6 +1673,7 @@ unsigned IROutliner::doOutline(Module &M) {
 
 bool IROutliner::run(Module &M) {
   CostModel = !NoCostModel;
+  OutlineFromLinkODRs = EnableLinkOnceODRIROutlining;
 
   return doOutline(M) > 0;
 }

diff  --git a/llvm/test/Transforms/IROutliner/outlining-odr.ll b/llvm/test/Transforms/IROutliner/outlining-odr.ll
new file mode 100644
index 000000000000..074de37c40bf
--- /dev/null
+++ b/llvm/test/Transforms/IROutliner/outlining-odr.ll
@@ -0,0 +1,70 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -verify -iroutliner --ir-outlining-no-cost < %s | FileCheck %s
+; RUN: opt -S -verify -iroutliner -enable-linkonceodr-ir-outlining --ir-outlining-no-cost < %s | FileCheck -check-prefix=ODR %s
+
+; This test looks at the constants in the regions, and if it they are the
+; same it outlines them as constants rather than elevating them to arguments.
+
+define linkonce_odr void @outline_odr1() {
+; ODR-LABEL: @outline_odr1(
+; ODR-NEXT:  entry:
+; ODR-NEXT:    [[A:%.*]] = alloca i32, align 4
+; ODR-NEXT:    [[B:%.*]] = alloca i32, align 4
+; ODR-NEXT:    [[C:%.*]] = alloca i32, align 4
+; ODR-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
+; ODR-NEXT:    ret void
+; CHECK-LABEL: @outline_odr1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    store i32 2, i32* [[A]], align 4
+; CHECK-NEXT:    store i32 3, i32* [[B]], align 4
+; CHECK-NEXT:    store i32 4, i32* [[C]], align 4
+; CHECK-NEXT:    [[AL:%.*]] = load i32, i32* [[A]], align 4
+; CHECK-NEXT:    [[BL:%.*]] = load i32, i32* [[B]], align 4
+; CHECK-NEXT:    [[CL:%.*]] = load i32, i32* [[C]], align 4
+entry:
+  %a = alloca i32, align 4
+  %b = alloca i32, align 4
+  %c = alloca i32, align 4
+  store i32 2, i32* %a, align 4
+  store i32 3, i32* %b, align 4
+  store i32 4, i32* %c, align 4
+  %al = load i32, i32* %a
+  %bl = load i32, i32* %b
+  %cl = load i32, i32* %c
+  ret void
+}
+
+define void @outline_odr2() {
+; ODR-LABEL: @outline_odr2(
+; ODR-NEXT:  entry:
+; ODR-NEXT:    [[A:%.*]] = alloca i32, align 4
+; ODR-NEXT:    [[B:%.*]] = alloca i32, align 4
+; ODR-NEXT:    [[C:%.*]] = alloca i32, align 4
+; ODR-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
+; ODR-NEXT:    ret void
+; CHECK-LABEL: @outline_odr2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    store i32 2, i32* [[A]], align 4
+; CHECK-NEXT:    store i32 3, i32* [[B]], align 4
+; CHECK-NEXT:    store i32 4, i32* [[C]], align 4
+; CHECK-NEXT:    [[AL:%.*]] = load i32, i32* [[A]], align 4
+; CHECK-NEXT:    [[BL:%.*]] = load i32, i32* [[B]], align 4
+; CHECK-NEXT:    [[CL:%.*]] = load i32, i32* [[C]], align 4
+entry:
+  %a = alloca i32, align 4
+  %b = alloca i32, align 4
+  %c = alloca i32, align 4
+  store i32 2, i32* %a, align 4
+  store i32 3, i32* %b, align 4
+  store i32 4, i32* %c, align 4
+  %al = load i32, i32* %a
+  %bl = load i32, i32* %b
+  %cl = load i32, i32* %c
+  ret void
+}


        


More information about the llvm-branch-commits mailing list