From: Vedant Kumar Date: Thu, 17 Jan 2019 22:36:05 +0000 (+0000) Subject: [HotColdSplit] Allow outlining with live outputs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7064dbae35e2b566b0587b231b2c413f032571c0;p=llvm [HotColdSplit] Allow outlining with live outputs Prior to r348205, extracting code regions with live output values was disabled because of a miscompilation (PR39433). Lift the restriction as PR39433 has been addressed. Tested on LNT+externals, on a run of check-llvm in a stage2 build, and with a full build of iOS (with hot/cold splitting enabled). As a drive-by, remove an errant TODO. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351492 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/IPO/HotColdSplitting.cpp b/lib/Transforms/IPO/HotColdSplitting.cpp index 577f270863c..6876ae60259 100644 --- a/lib/Transforms/IPO/HotColdSplitting.cpp +++ b/lib/Transforms/IPO/HotColdSplitting.cpp @@ -252,16 +252,6 @@ Function *HotColdSplitting::extractColdRegion(const BlockSequence &Region, /* AllowAlloca */ false, /* Suffix */ "cold." + std::to_string(Count)); - SetVector Inputs, Outputs, Sinks; - CE.findInputsOutputs(Inputs, Outputs, Sinks); - - // Do not extract regions that have live exit variables. - if (Outputs.size() > 0) { - LLVM_DEBUG(llvm::dbgs() << "Not outlining; live outputs\n"); - return nullptr; - } - - // TODO: Run MergeBasicBlockIntoOnlyPred on the outlined function. Function *OrigF = Region[0]->getParent(); if (Function *OutF = CE.extractCodeRegion()) { User *U = *OutF->user_begin(); diff --git a/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll b/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll new file mode 100644 index 00000000000..6b907ee3cc5 --- /dev/null +++ b/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll @@ -0,0 +1,68 @@ +; RUN: opt -hotcoldsplit-threshold=0 -hotcoldsplit -S < %s | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.14.0" + +; CHECK-LABEL: define {{.*}}@pluto( +; CHECK-NEXT: bb: +; CHECK-NEXT: %tmp8.ce.loc = alloca i1 +; CHECK-NEXT: switch i8 undef, label %codeRepl [ +; CHECK-NEXT: i8 0, label %bb7 +; CHECK-NEXT: i8 1, label %bb7 +; CHECK-NEXT: ] +; +; CHECK: codeRepl: +; CHECK-NEXT: call void @pluto.cold.1(i1* %tmp8.ce.loc) +; CHECK-NEXT: %tmp8.ce.reload = load i1, i1* %tmp8.ce.loc +; CHECK-NEXT: br label %bb7 +; +; CHECK: bb7: +; CHECK: %tmp8 = phi i1 [ true, %bb ], [ true, %bb ], [ %tmp8.ce.reload, %codeRepl ] +; CHECK: ret void + +; CHECK-LABEL: define {{.*}}@pluto.cold.1( +; CHECK: call {{.*}}@sideeffect(i32 1) +; CHECK: call {{.*}}@sink( +; CHECK: call {{.*}}@sideeffect(i32 3) +; CHECK: call {{.*}}@sideeffect(i32 4) +; CHECK: call {{.*}}@sideeffect(i32 5) +define void @pluto() { +bb: + switch i8 undef, label %bb1 [ + i8 0, label %bb7 + i8 1, label %bb7 + ] + +bb1: ; preds = %bb + call void @sideeffect(i32 1) + br label %bb2 + +bb2: ; preds = %bb1 + call void @sink() + br i1 undef, label %bb7, label %bb3 + +bb3: ; preds = %bb2 + call void @sideeffect(i32 3) + br label %bb4 + +bb4: ; preds = %bb3 + call void @sideeffect(i32 4) + br i1 undef, label %bb5, label %bb6 + +bb5: ; preds = %bb4 + call void @sideeffect(i32 5) + br label %bb6 + +bb6: ; preds = %bb5, %bb4 + %tmp = phi i1 [ true, %bb5 ], [ false, %bb4 ] + call void @sideeffect(i32 6) + br label %bb7 + +bb7: ; preds = %bb6, %bb2, %bb, %bb + %tmp8 = phi i1 [ true, %bb ], [ true, %bb ], [ true, %bb2 ], [ %tmp, %bb6 ] + ret void +} + +declare void @sink() cold + +declare void @sideeffect(i32)