[llvm] r342277 - HotColdSplit: fix invalid SSA due to outlining

Sebastian Pop via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 14 13:36:21 PDT 2018


Author: spop
Date: Fri Sep 14 13:36:19 2018
New Revision: 342277

URL: http://llvm.org/viewvc/llvm-project?rev=342277&view=rev
Log:
HotColdSplit: fix invalid SSA due to outlining

The test used to fail with an invalid phi node: the two predecessors were outlined
and the SSA representation was left invalid. The patch adds the exit block to the
cold region.

Added:
    llvm/trunk/test/Transforms/HotColdSplit/split-cold-2.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp
    llvm/trunk/test/Transforms/HotColdSplit/split-cold-1.ll

Modified: llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp?rev=342277&r1=342276&r2=342277&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp Fri Sep 14 13:36:19 2018
@@ -219,9 +219,8 @@ public:
 
 private:
   bool shouldOutlineFrom(const Function &F) const;
-  Function *outlineColdBlocks(Function &F,
-                              const DenseSetBB &ColdBlock,
-                              DominatorTree *DT, PostDomTree *PDT);
+  const Function *outlineColdBlocks(Function &F, const DenseSetBB &ColdBlock,
+                                    DominatorTree *DT, PostDomTree *PDT);
   Function *extractColdRegion(const SmallVectorImpl<BasicBlock *> &Region,
                               DominatorTree *DT, BlockFrequencyInfo *BFI,
                               OptimizationRemarkEmitter &ORE);
@@ -264,9 +263,12 @@ public:
 } // end anonymous namespace
 
 // Returns false if the function should not be considered for hot-cold split
-// optimization. Already outlined functions have coldcc so no need to check
-// for them here.
+// optimization.
 bool HotColdSplitting::shouldOutlineFrom(const Function &F) const {
+  // Do not try to outline again from an already outlined cold function.
+  if (OutlinedFunctions.count(&F))
+    return false;
+
   if (F.size() <= 2)
     return false;
 
@@ -314,7 +316,7 @@ HotColdSplitting::extractColdRegion(cons
       CS.setCallingConv(CallingConv::Cold);
     }
     CI->setIsNoInline();
-    LLVM_DEBUG(llvm::dbgs() << "Outlined Region at block: " << Region.front());
+    LLVM_DEBUG(llvm::dbgs() << "Outlined Region: " << *OutF);
     return OutF;
   }
 
@@ -328,10 +330,10 @@ HotColdSplitting::extractColdRegion(cons
 }
 
 // Return the function created after outlining, nullptr otherwise.
-Function *HotColdSplitting::outlineColdBlocks(Function &F,
-                                              const DenseSetBB &HotBlocks,
-                                              DominatorTree *DT,
-                                              PostDomTree *PDT) {
+const Function *HotColdSplitting::outlineColdBlocks(Function &F,
+                                                    const DenseSetBB &HotBlocks,
+                                                    DominatorTree *DT,
+                                                    PostDomTree *PDT) {
   auto BFI = GetBFI(F);
   auto &ORE = (*GetORE)(F);
   // Walking the dominator tree allows us to find the largest
@@ -342,12 +344,10 @@ Function *HotColdSplitting::outlineColdB
     if (PSI->isColdBB(BB, BFI) || !HotBlocks.count(BB)) {
       SmallVector<BasicBlock *, 4> ValidColdRegion, Region;
       BasicBlock *Exit = (*PDT)[BB]->getIDom()->getBlock();
-      // We might need a virtual exit which post-dominates all basic blocks.
-      if (!Exit)
-        continue;
       BasicBlock *ExitColdRegion = nullptr;
+
       // Estimated cold region between a BB and its dom-frontier.
-      while (isSingleEntrySingleExit(BB, Exit, DT, PDT, Region) &&
+      while (Exit && isSingleEntrySingleExit(BB, Exit, DT, PDT, Region) &&
              isOutlineCandidate(Region, Exit)) {
         ExitColdRegion = Exit;
         ValidColdRegion = Region;
@@ -361,6 +361,7 @@ Function *HotColdSplitting::outlineColdB
           continue;
 
         ++NumColdSESEFound;
+        ValidColdRegion.push_back(ExitColdRegion);
         // Candidate for outlining. FIXME: Continue outlining.
         return extractColdRegion(ValidColdRegion, DT, BFI, ORE);
       }
@@ -380,7 +381,7 @@ bool HotColdSplitting::run(Module &M) {
     if (EnableStaticAnalyis) // Static analysis of cold blocks.
       HotBlocks = getHotBlocks(F);
 
-    auto Outlined = outlineColdBlocks(F, HotBlocks, &DT, &PDT);
+    const Function *Outlined = outlineColdBlocks(F, HotBlocks, &DT, &PDT);
     if (Outlined)
       OutlinedFunctions.insert(Outlined);
   }

Modified: llvm/trunk/test/Transforms/HotColdSplit/split-cold-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/HotColdSplit/split-cold-1.ll?rev=342277&r1=342276&r2=342277&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/HotColdSplit/split-cold-1.ll (original)
+++ llvm/trunk/test/Transforms/HotColdSplit/split-cold-1.ll Fri Sep 14 13:36:19 2018
@@ -1,15 +1,9 @@
 ; RUN: opt -hotcoldsplit -S < %s | FileCheck %s
-source_filename = "bugpoint-output-054409e.bc"
-target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-apple-macosx10.13.0"
-
-declare i32 @__gxx_personality_v0(...)
 
 ; Outlined function is called from a basic block named codeRepl
 ; CHECK: codeRepl:
 ; CHECK-NEXT: call void @foo
-; Function Attrs: ssp uwtable
-define hidden void @foo() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+define void @foo() {
 entry:
   br i1 undef, label %if.then, label %if.end
 
@@ -28,5 +22,3 @@ cleanup40:
 return:                                           ; preds = %cleanup40
   ret void
 }
-
-

Added: llvm/trunk/test/Transforms/HotColdSplit/split-cold-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/HotColdSplit/split-cold-2.ll?rev=342277&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/HotColdSplit/split-cold-2.ll (added)
+++ llvm/trunk/test/Transforms/HotColdSplit/split-cold-2.ll Fri Sep 14 13:36:19 2018
@@ -0,0 +1,28 @@
+; RUN: opt -hotcoldsplit -S < %s
+
+; Make sure this compiles. This test used to fail with an invalid phi node: the
+; two predecessors were outlined and the SSA representation was invalid.
+
+define void @fun() {
+entry:
+  br i1 undef, label %if.then, label %if.else
+
+if.then:
+  unreachable
+
+if.else:
+  br label %if.then4
+
+if.then4:
+  br i1 undef, label %if.then5, label %if.end
+
+if.then5:
+  br label %cleanup
+
+if.end:
+  br label %cleanup
+
+cleanup:
+  %cleanup.dest.slot.0 = phi i32 [ 1, %if.then5 ], [ 0, %if.end ]
+  unreachable
+}




More information about the llvm-commits mailing list