From 5799fc79c3fdbc81dd421afae38197009ad605c9 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Sat, 2 Jan 2021 19:56:27 +0300 Subject: [PATCH] [llvm-reduce] Refactor global variable delta pass The limitation of the current pass that it skips initializer-less GV's seems arbitrary, in all the reduced cases i (personally) looked at, the globals weren't needed, yet they were kept. So let's do two things: 1. allow reducing initializer-less globals 2. before reducing globals, reduce their initializers, much like we do function bodies --- llvm/test/Reduce/Inputs/remove-global-vars.py | 18 -------- llvm/test/Reduce/remove-global-vars.ll | 37 +++++++++++++---- llvm/tools/llvm-reduce/CMakeLists.txt | 1 + llvm/tools/llvm-reduce/DeltaManager.h | 2 + .../deltas/ReduceGlobalVarInitializers.cpp | 48 ++++++++++++++++++++++ .../deltas/ReduceGlobalVarInitializers.h | 21 ++++++++++ llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp | 13 +++--- llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h | 2 +- 8 files changed, 109 insertions(+), 33 deletions(-) delete mode 100755 llvm/test/Reduce/Inputs/remove-global-vars.py create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.h diff --git a/llvm/test/Reduce/Inputs/remove-global-vars.py b/llvm/test/Reduce/Inputs/remove-global-vars.py deleted file mode 100755 index 1ae8b0e..0000000 --- a/llvm/test/Reduce/Inputs/remove-global-vars.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -import sys - -InterestingVar = 0 - -input = open(sys.argv[1], "r") -for line in input: - i = line.find(';') - if i >= 0: - line = line[:i] - if line.startswith("@interesting = global") or "@interesting" in line: - InterestingVar += 1 - -if InterestingVar == 4: - sys.exit(0) # interesting! - -sys.exit(1) diff --git a/llvm/test/Reduce/remove-global-vars.ll b/llvm/test/Reduce/remove-global-vars.ll index 4fca4a1..d078cad 100644 --- a/llvm/test/Reduce/remove-global-vars.ll +++ b/llvm/test/Reduce/remove-global-vars.ll @@ -1,24 +1,47 @@ ; Test that llvm-reduce can remove uninteresting Global Variables as well as ; their direct uses (which in turn are replaced with 'undef'). -; -; RUN: llvm-reduce --test %python --test-arg %p/Inputs/remove-global-vars.py %s -o %t -; RUN: cat %t | FileCheck -implicit-check-not=uninteresting %s -; CHECK: @interesting = global +; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL --implicit-check-not=uninteresting %s + +; CHECK-INTERESTINGNESS: @interesting = {{.*}}global i32{{.*}}, align 4 +; CHECK-INTERESTINGNESS: @interesting2 = global i32 0, align 4 +; CHECK-INTERESTINGNESS: @interesting3 = {{.*}}global i32{{.*}}, align 4 + +; CHECK-FINAL: @interesting = external global i32, align 4 +; CHECK-FINAL: @interesting2 = global i32 0, align 4 +; CHECK-FINAL: @interesting3 = external global i32, align 4 @interesting = global i32 0, align 4 +@interesting2 = global i32 0, align 4 +@interesting3 = external global i32, align 4 @uninteresting = global i32 1, align 4 +@uninteresting2 = external global i32, align 4 define i32 @main() { entry: %0 = load i32, i32* @uninteresting, align 4 - ; CHECK: store i32 undef, i32* @interesting, align 4 + + ; CHECK-INTERESTINGNESS: store i32 {{.*}}, i32* @interesting, align 4 + ; CHECK-FINAL: store i32 undef, i32* @interesting, align 4 store i32 %0, i32* @interesting, align 4 - ; CHECK: load i32, i32* @interesting, align 4 + ; CHECK-INTERESTINGNESS: store i32 {{.*}}, i32* @interesting3, align 4 + ; CHECK-FINAL: store i32 undef, i32* @interesting3, align 4 + store i32 %0, i32* @interesting3, align 4 + + ; CHECK-ALL: load i32, i32* @interesting, align 4 %1 = load i32, i32* @interesting, align 4 store i32 %1, i32* @uninteresting, align 4 - ; CHECK: store i32 5, i32* @interesting, align 4 + ; CHECK-ALL: load i32, i32* @interesting3, align 4 + %2 = load i32, i32* @interesting3, align 4 + store i32 %2, i32* @uninteresting2, align 4 + + ; CHECK-ALL: store i32 5, i32* @interesting, align 4 store i32 5, i32* @interesting, align 4 + + ; CHECK-ALL: store i32 5, i32* @interesting3, align 4 + store i32 5, i32* @interesting3, align 4 + ret i32 0 } diff --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt index 3d635d1..b6db920 100644 --- a/llvm/tools/llvm-reduce/CMakeLists.txt +++ b/llvm/tools/llvm-reduce/CMakeLists.txt @@ -19,6 +19,7 @@ add_llvm_tool(llvm-reduce deltas/ReduceBasicBlocks.cpp deltas/ReduceFunctionBodies.cpp deltas/ReduceFunctions.cpp + deltas/ReduceGlobalVarInitializers.cpp deltas/ReduceGlobalVars.cpp deltas/ReduceInstructions.cpp deltas/ReduceMetadata.cpp diff --git a/llvm/tools/llvm-reduce/DeltaManager.h b/llvm/tools/llvm-reduce/DeltaManager.h index 9c18da9..18a6b0d 100644 --- a/llvm/tools/llvm-reduce/DeltaManager.h +++ b/llvm/tools/llvm-reduce/DeltaManager.h @@ -19,6 +19,7 @@ #include "deltas/ReduceBasicBlocks.h" #include "deltas/ReduceFunctionBodies.h" #include "deltas/ReduceFunctions.h" +#include "deltas/ReduceGlobalVarInitializers.h" #include "deltas/ReduceGlobalVars.h" #include "deltas/ReduceInstructions.h" #include "deltas/ReduceMetadata.h" @@ -34,6 +35,7 @@ inline void runDeltaPasses(TestRunner &Tester) { reduceFunctionBodiesDeltaPass(Tester); reduceFunctionsDeltaPass(Tester); reduceBasicBlocksDeltaPass(Tester); + reduceGlobalsInitializersDeltaPass(Tester); reduceGlobalsDeltaPass(Tester); reduceMetadataDeltaPass(Tester); reduceArgumentsDeltaPass(Tester); diff --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp new file mode 100644 index 0000000..1128710 --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp @@ -0,0 +1,48 @@ +//===- ReduceGlobalVars.cpp - Specialized Delta Pass ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements a function which calls the Generic Delta pass in order +// to reduce initializers of Global Variables in the provided Module. +// +//===----------------------------------------------------------------------===// + +#include "ReduceGlobalVarInitializers.h" +#include "llvm/IR/Constants.h" + +using namespace llvm; + +/// Removes all the Initialized GVs that aren't inside the desired Chunks. +static void extractGVsFromModule(std::vector ChunksToKeep, + Module *Program) { + Oracle O(ChunksToKeep); + + // Drop initializers of out-of-chunk GVs + for (auto &GV : Program->globals()) + if (GV.hasInitializer() && !O.shouldKeep()) + GV.setInitializer(nullptr); +} + +/// Counts the amount of initialized GVs and displays their +/// respective name & index +static int countGVs(Module *Program) { + // TODO: Silence index with --quiet flag + outs() << "----------------------------\n"; + outs() << "GlobalVariable Index Reference:\n"; + int GVCount = 0; + for (auto &GV : Program->globals()) + if (GV.hasInitializer()) + outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n"; + outs() << "----------------------------\n"; + return GVCount; +} + +void llvm::reduceGlobalsInitializersDeltaPass(TestRunner &Test) { + outs() << "*** Reducing GVs initializers...\n"; + int GVCount = countGVs(Test.getProgram()); + runDeltaPass(Test, GVCount, extractGVsFromModule); +} diff --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.h b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.h new file mode 100644 index 0000000..39288ad --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.h @@ -0,0 +1,21 @@ +//===- reduceGlobalsInitializersDeltaPass.h - Specialized Delta Pass +//-------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements a function which calls the Generic Delta pass in order +// to reduce initializers of Global Variables in the provided Module. +// +//===----------------------------------------------------------------------===// + +#include "Delta.h" +#include "llvm/IR/Value.h" +#include "llvm/Transforms/Utils/Cloning.h" + +namespace llvm { +void reduceGlobalsInitializersDeltaPass(TestRunner &Test); +} // namespace llvm diff --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp index dc8df73..4b184e5 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // // This file implements a function which calls the Generic Delta pass in order -// to reduce initialized Global Variables in the provided Module. +// to reduce Global Variables in the provided Module. // //===----------------------------------------------------------------------===// @@ -17,7 +17,7 @@ using namespace llvm; -/// Removes all the Initialized GVs that aren't inside the desired Chunks. +/// Removes all the GVs that aren't inside the desired Chunks. static void extractGVsFromModule(std::vector ChunksToKeep, Module *Program) { Oracle O(ChunksToKeep); @@ -25,14 +25,14 @@ static void extractGVsFromModule(std::vector ChunksToKeep, // Get GVs inside desired chunks std::set GVsToKeep; for (auto &GV : Program->globals()) - if (GV.hasInitializer() && O.shouldKeep()) + if (O.shouldKeep()) GVsToKeep.insert(&GV); // Delete out-of-chunk GVs and their uses std::vector ToRemove; std::vector InstToRemove; for (auto &GV : Program->globals()) - if (GV.hasInitializer() && !GVsToKeep.count(&GV)) { + if (!GVsToKeep.count(&GV)) { for (auto U : GV.users()) if (auto *Inst = dyn_cast(U)) InstToRemove.push_back(Inst); @@ -54,7 +54,7 @@ static void extractGVsFromModule(std::vector ChunksToKeep, GV->eraseFromParent(); } -/// Counts the amount of initialized GVs and displays their +/// Counts the amount of GVs and displays their /// respective name & index static int countGVs(Module *Program) { // TODO: Silence index with --quiet flag @@ -62,8 +62,7 @@ static int countGVs(Module *Program) { outs() << "GlobalVariable Index Reference:\n"; int GVCount = 0; for (auto &GV : Program->globals()) - if (GV.hasInitializer()) - outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n"; + outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n"; outs() << "----------------------------\n"; return GVCount; } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h index d4a870a..c8ba7ea 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h +++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // // This file implements a function which calls the Generic Delta pass in order -// to reduce initialized Global Variables in the provided Module. +// to reduce Global Variables in the provided Module. // //===----------------------------------------------------------------------===// -- 2.7.4