From 4fde77f8f1a8e4482e69b6a7484bc7d1b99b3c0a Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Thu, 25 May 2017 07:15:09 +0000 Subject: [PATCH] [PM] Teach the PGO instrumentation pasess to run GlobalDCE before instrumenting code. This is important in the new pass manager. The old pass manager's inliner has a small DCE routine embedded within it. The new pass manager relies on the actual GlobalDCE pass for this. Without this patch, instrumentation profiling with the new PM results in massive code bloat in the object files because the instrumentation itself ends up preventing DCE from working to remove the code. We should probably change the instrumentation (and/or DCE) so that we can eliminate dead code even if instrumented, but we shouldn't even spend the time generating instrumentation for that code so this still seems like a good patch. Differential Revision: https://reviews.llvm.org/D33535 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Passes/PassBuilder.cpp | 5 +++++ .../GlobalDCE/externally_available.ll | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index fb56a6f05d3..4845bd2957b 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -437,6 +437,11 @@ static void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging, MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPipeline))); } + // Delete anything that is now dead to make sure that we don't instrument + // dead code. Instrumentation can end up keeping dead code around and + // dramatically increase code size. + MPM.addPass(GlobalDCEPass()); + if (RunProfileGen) { MPM.addPass(PGOInstrumentationGen()); diff --git a/test/Transforms/GlobalDCE/externally_available.ll b/test/Transforms/GlobalDCE/externally_available.ll index fca49b29ec8..bc54db38cee 100644 --- a/test/Transforms/GlobalDCE/externally_available.ll +++ b/test/Transforms/GlobalDCE/externally_available.ll @@ -1,12 +1,21 @@ ; RUN: opt < %s -globaldce -S | FileCheck %s +; test_global should not be emitted to the .s file. +; CHECK-NOT: @test_global = +@test_global = available_externally global i32 4 + +; test_global2 is a normal global using an available externally function. +; CHECK: @test_global2 = +@test_global2 = global i32 ()* @test_function2 + ; test_function should not be emitted to the .s file. -; CHECK-NOT: test_function +; CHECK-NOT: define {{.*}} @test_function() define available_externally i32 @test_function() { ret i32 4 } -; test_global should not be emitted to the .s file. -; CHECK-NOT: test_global -@test_global = available_externally global i32 4 - +; test_function2 isn't actually dead even though it's available externally. +; CHECK: define available_externally i32 @test_function2() +define available_externally i32 @test_function2() { + ret i32 4 +}