From d1ffcd07456bc8b64056eeec223e87b48fca93b9 Mon Sep 17 00:00:00 2001 From: Diego Trevino Ferrer Date: Wed, 14 Aug 2019 21:01:19 +0000 Subject: [PATCH] [Bugpoint redesign] Added Pass to Remove Global Variables Summary: This pass tries to remove Global Variables, as well as their derived uses. For example if a variable `@x` is used by `%call1` and `%call2`, both these uses and the definition of `@x` are deleted. Moreover if `%call1` or `%call2` are used elsewhere those uses are also deleted, and so on recursively. I'm still uncertain if this pass should remove derived uses, I'm open to suggestions. Subscribers: mgorny, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64176 llvm-svn: 368918 --- llvm/test/Reduce/Inputs/remove-global-vars.py | 10 +++ llvm/test/Reduce/remove-funcs.ll | 2 +- llvm/test/Reduce/remove-global-vars.ll | 30 +++++++++ llvm/tools/llvm-reduce/CMakeLists.txt | 1 + llvm/tools/llvm-reduce/DeltaManager.h | 5 ++ llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp | 72 ++++++++++++++++++++++ llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h | 20 ++++++ 7 files changed, 139 insertions(+), 1 deletion(-) create mode 100755 llvm/test/Reduce/Inputs/remove-global-vars.py create mode 100644 llvm/test/Reduce/remove-global-vars.ll create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h diff --git a/llvm/test/Reduce/Inputs/remove-global-vars.py b/llvm/test/Reduce/Inputs/remove-global-vars.py new file mode 100755 index 0000000..81fbea9 --- /dev/null +++ b/llvm/test/Reduce/Inputs/remove-global-vars.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +import sys + +input = open(sys.argv[1], "r") +for line in input: + if "@interesting = global" in line: + sys.exit(0) + +sys.exit(1) # IR isn't interesting diff --git a/llvm/test/Reduce/remove-funcs.ll b/llvm/test/Reduce/remove-funcs.ll index 7d6fba8..a0ce24a 100644 --- a/llvm/test/Reduce/remove-funcs.ll +++ b/llvm/test/Reduce/remove-funcs.ll @@ -3,7 +3,7 @@ ; ; RUN: llvm-reduce --test %p/Inputs/remove-funcs.py %s ; RUN: cat reduced.ll | FileCheck %s -; REQUIRES: plugins, shell +; REQUIRES: plugins ; CHECK-NOT: uninteresting1() define i32 @uninteresting1() { diff --git a/llvm/test/Reduce/remove-global-vars.ll b/llvm/test/Reduce/remove-global-vars.ll new file mode 100644 index 0000000..1241cd2 --- /dev/null +++ b/llvm/test/Reduce/remove-global-vars.ll @@ -0,0 +1,30 @@ +; 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 %p/Inputs/remove-global-vars.py %s +; RUN: cat reduced.ll | FileCheck %s +; REQUIRES: plugins + +; CHECK: @interesting = global +@interesting = global i32 0, align 4 +; CHECK-NOT: global +@uninteresting = global i32 1, align 4 + +define i32 @main() { +entry: + ; CHECK-NOT: load i32, i32* @uninteresting, align 4 + %0 = load i32, i32* @uninteresting, align 4 + ; CHECK: store i32 undef, i32* @interesting, align 4 + store i32 %0, i32* @interesting, align 4 + + ; CHECK: load i32, i32* @interesting, align 4 + %1 = load i32, i32* @interesting, align 4 + ; CHECK-NOT: store i32 %1, i32* @uninteresting, align 4 + store i32 %1, i32* @uninteresting, align 4 + + ; CHECK: %inc = add nsw i32 undef, 1 + %inc = add nsw i32 %0, 1 + ; CHECK: store i32 %inc, i32* @interesting, align 4 + store i32 %inc, i32* @interesting, align 4 + ret i32 0 +} diff --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt index 8edc4f7..3ff7b7a 100644 --- a/llvm/tools/llvm-reduce/CMakeLists.txt +++ b/llvm/tools/llvm-reduce/CMakeLists.txt @@ -18,6 +18,7 @@ add_llvm_tool(llvm-reduce TestRunner.cpp deltas/Delta.cpp deltas/ReduceFunctions.cpp + deltas/ReduceGlobalVars.cpp DEPENDS intrinsics_gen diff --git a/llvm/tools/llvm-reduce/DeltaManager.h b/llvm/tools/llvm-reduce/DeltaManager.h index 28d1cd9..8033d76 100644 --- a/llvm/tools/llvm-reduce/DeltaManager.h +++ b/llvm/tools/llvm-reduce/DeltaManager.h @@ -14,11 +14,16 @@ #include "TestRunner.h" #include "deltas/Delta.h" #include "deltas/ReduceFunctions.h" +#include "deltas/ReduceGlobalVars.h" namespace llvm { +// TODO: Add CLI option to run only specified Passes (for unit tests) inline void runDeltaPasses(TestRunner &Tester) { + outs() << "Reducing functions...\n"; reduceFunctionsDeltaPass(Tester); + outs() << "Reducing GVs...\n"; + reduceGlobalsDeltaPass(Tester); // TODO: Implement the remaining Delta Passes } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp new file mode 100644 index 0000000..15bb5a7 --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp @@ -0,0 +1,72 @@ +//===- 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 initialized Global Variables in the provided Module. +// +//===----------------------------------------------------------------------===// + +#include "ReduceGlobalVars.h" + +/// Removes all the Initialized GVs that aren't inside the desired Chunks. +/// @returns the Module stripped of out-of-chunk GVs +static void extractGVsFromModule(std::vector ChunksToKeep, + Module *Program) { + // Get GVs inside desired chunks + std::set GVsToKeep; + unsigned I = 0, GVCount = 0; + for (auto &GV : Program->globals()) + if (GV.hasInitializer() && I < ChunksToKeep.size()) { + if (ChunksToKeep[I].contains(++GVCount)) + GVsToKeep.insert(&GV); + if (GVCount == ChunksToKeep[I].end) + ++I; + } + + // 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)) { + for (auto U : GV.users()) + if (auto *Inst = dyn_cast(U)) + InstToRemove.push_back(Inst); + + GV.replaceAllUsesWith(UndefValue::get(GV.getType())); + ToRemove.push_back(&GV); + } + + // Delete Instruction uses of unwanted GVs + for (auto *Inst : InstToRemove) { + Inst->replaceAllUsesWith(UndefValue::get(Inst->getType())); + Inst->eraseFromParent(); + } + + for (auto *GV : ToRemove) + GV->eraseFromParent(); +} + +/// 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::reduceGlobalsDeltaPass(TestRunner &Test) { + outs() << "*** Reducing GVs...\n"; + unsigned GVCount = countGVs(Test.getProgram()); + runDeltaPass(Test, GVCount, extractGVsFromModule); +} diff --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h new file mode 100644 index 0000000..d4a870a --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.h @@ -0,0 +1,20 @@ +//===- ReduceGlobalVars.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 initialized Global Variables in the provided Module. +// +//===----------------------------------------------------------------------===// + +#include "Delta.h" +#include "llvm/IR/Value.h" +#include "llvm/Transforms/Utils/Cloning.h" + +namespace llvm { +void reduceGlobalsDeltaPass(TestRunner &Test); +} // namespace llvm -- 2.7.4