aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/tools/llvm-reduce/deltas
diff options
context:
space:
mode:
authormonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
committermonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
commit06e5c21a835c0e923506c4ff27929f34e00761c2 (patch)
tree75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/libs/llvm12/tools/llvm-reduce/deltas
parent03f024c4412e3aa613bb543cf1660176320ba8f4 (diff)
downloadydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz
fix ya.make
Diffstat (limited to 'contrib/libs/llvm12/tools/llvm-reduce/deltas')
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.cpp180
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.h110
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.cpp53
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.h18
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.cpp126
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.h21
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.cpp200
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.h20
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp150
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.h20
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.cpp57
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.h18
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.cpp77
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.h20
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp52
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.h21
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp74
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVars.h20
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.cpp67
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.h20
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.cpp127
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.h18
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp124
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.h20
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.cpp62
-rw-r--r--contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.h21
26 files changed, 1696 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.cpp
new file mode 100644
index 0000000000..9b0969e936
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.cpp
@@ -0,0 +1,180 @@
+//===- Delta.cpp - Delta Debugging Algorithm Implementation ---------------===//
+//
+// 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 contains the implementation for the Delta Debugging Algorithm:
+// it splits a given set of Targets (i.e. Functions, Instructions, BBs, etc.)
+// into chunks and tries to reduce the number chunks that are interesting.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include <fstream>
+#include <set>
+
+using namespace llvm;
+
+void writeOutput(llvm::Module *M, llvm::StringRef Message);
+
+bool IsReduced(Module &M, TestRunner &Test, SmallString<128> &CurrentFilepath) {
+ // Write Module to tmp file
+ int FD;
+ std::error_code EC =
+ sys::fs::createTemporaryFile("llvm-reduce", "ll", FD, CurrentFilepath);
+ if (EC) {
+ errs() << "Error making unique filename: " << EC.message() << "!\n";
+ exit(1);
+ }
+
+ ToolOutputFile Out(CurrentFilepath, FD);
+ M.print(Out.os(), /*AnnotationWriter=*/nullptr);
+ Out.os().close();
+ if (Out.os().has_error()) {
+ errs() << "Error emitting bitcode to file '" << CurrentFilepath << "'!\n";
+ exit(1);
+ }
+
+ // Current Chunks aren't interesting
+ return Test.run(CurrentFilepath);
+}
+
+/// Counts the amount of lines for a given file
+static int getLines(StringRef Filepath) {
+ int Lines = 0;
+ std::string CurrLine;
+ std::ifstream FileStream{std::string(Filepath)};
+
+ while (std::getline(FileStream, CurrLine))
+ ++Lines;
+
+ return Lines;
+}
+
+/// Splits Chunks in half and prints them.
+/// If unable to split (when chunk size is 1) returns false.
+static bool increaseGranularity(std::vector<Chunk> &Chunks) {
+ errs() << "Increasing granularity...";
+ std::vector<Chunk> NewChunks;
+ bool SplitOne = false;
+
+ for (auto &C : Chunks) {
+ if (C.end - C.begin == 0)
+ NewChunks.push_back(C);
+ else {
+ int Half = (C.begin + C.end) / 2;
+ NewChunks.push_back({C.begin, Half});
+ NewChunks.push_back({Half + 1, C.end});
+ SplitOne = true;
+ }
+ }
+ if (SplitOne) {
+ Chunks = NewChunks;
+ errs() << "Success! New Chunks:\n";
+ for (auto C : Chunks) {
+ errs() << '\t';
+ C.print();
+ errs() << '\n';
+ }
+ }
+ return SplitOne;
+}
+
+/// Runs the Delta Debugging algorithm, splits the code into chunks and
+/// reduces the amount of chunks that are considered interesting by the
+/// given test.
+void llvm::runDeltaPass(
+ TestRunner &Test, int Targets,
+ std::function<void(const std::vector<Chunk> &, Module *)>
+ ExtractChunksFromModule) {
+ assert(Targets >= 0);
+ if (!Targets) {
+ errs() << "\nNothing to reduce\n";
+ return;
+ }
+
+ if (Module *Program = Test.getProgram()) {
+ SmallString<128> CurrentFilepath;
+ if (!IsReduced(*Program, Test, CurrentFilepath)) {
+ errs() << "\nInput isn't interesting! Verify interesting-ness test\n";
+ exit(1);
+ }
+
+ assert(!verifyModule(*Program, &errs()) &&
+ "input module is broken before making changes");
+ }
+
+ std::vector<Chunk> ChunksStillConsideredInteresting = {{1, Targets}};
+ std::unique_ptr<Module> ReducedProgram;
+
+ bool FoundAtLeastOneNewUninterestingChunkWithCurrentGranularity;
+ do {
+ FoundAtLeastOneNewUninterestingChunkWithCurrentGranularity = false;
+
+ std::set<Chunk> UninterestingChunks;
+ for (Chunk &ChunkToCheckForUninterestingness :
+ reverse(ChunksStillConsideredInteresting)) {
+ // Take all of ChunksStillConsideredInteresting chunks, except those we've
+ // already deemed uninteresting (UninterestingChunks) but didn't remove
+ // from ChunksStillConsideredInteresting yet, and additionally ignore
+ // ChunkToCheckForUninterestingness chunk.
+ std::vector<Chunk> CurrentChunks;
+ CurrentChunks.reserve(ChunksStillConsideredInteresting.size() -
+ UninterestingChunks.size() - 1);
+ copy_if(ChunksStillConsideredInteresting,
+ std::back_inserter(CurrentChunks), [&](const Chunk &C) {
+ return !UninterestingChunks.count(C) &&
+ C != ChunkToCheckForUninterestingness;
+ });
+
+ // Clone module before hacking it up..
+ std::unique_ptr<Module> Clone = CloneModule(*Test.getProgram());
+ // Generate Module with only Targets inside Current Chunks
+ ExtractChunksFromModule(CurrentChunks, Clone.get());
+
+ // Some reductions may result in invalid IR. Skip such reductions.
+ if (verifyModule(*Clone.get(), &errs())) {
+ errs() << " **** WARNING | reduction resulted in invalid module, "
+ "skipping\n";
+ continue;
+ }
+
+ errs() << "Ignoring: ";
+ ChunkToCheckForUninterestingness.print();
+ for (const Chunk &C : UninterestingChunks)
+ C.print();
+
+ SmallString<128> CurrentFilepath;
+ if (!IsReduced(*Clone, Test, CurrentFilepath)) {
+ // Program became non-reduced, so this chunk appears to be interesting.
+ errs() << "\n";
+ continue;
+ }
+
+ FoundAtLeastOneNewUninterestingChunkWithCurrentGranularity = true;
+ UninterestingChunks.insert(ChunkToCheckForUninterestingness);
+ ReducedProgram = std::move(Clone);
+ errs() << " **** SUCCESS | lines: " << getLines(CurrentFilepath) << "\n";
+ writeOutput(ReducedProgram.get(), "Saved new best reduction to ");
+ }
+ // Delete uninteresting chunks
+ erase_if(ChunksStillConsideredInteresting,
+ [&UninterestingChunks](const Chunk &C) {
+ return UninterestingChunks.count(C);
+ });
+ } while (!ChunksStillConsideredInteresting.empty() &&
+ (FoundAtLeastOneNewUninterestingChunkWithCurrentGranularity ||
+ increaseGranularity(ChunksStillConsideredInteresting)));
+
+ // If we reduced the testcase replace it
+ if (ReducedProgram)
+ Test.setProgram(std::move(ReducedProgram));
+ errs() << "Couldn't increase anymore.\n";
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.h
new file mode 100644
index 0000000000..7da3c79c95
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/Delta.h
@@ -0,0 +1,110 @@
+//===- Delta.h - Delta Debugging Algorithm Implementation -----------------===//
+//
+// 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 contains the implementation for the Delta Debugging Algorithm:
+// it splits a given set of Targets (i.e. Functions, Instructions, BBs, etc.)
+// into chunks and tries to reduce the number chunks that are interesting.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMREDUCE_LLVMREDUCE_DELTA_H
+#define LLVM_TOOLS_LLVMREDUCE_LLVMREDUCE_DELTA_H
+
+#include "TestRunner.h"
+#include "llvm/ADT/ScopeExit.h"
+#include <functional>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+struct Chunk {
+ int begin;
+ int end;
+
+ /// Helper function to verify if a given Target-index is inside the Chunk
+ bool contains(int Index) const { return Index >= begin && Index <= end; }
+
+ void print() const {
+ errs() << "[" << begin;
+ if (end - begin != 0)
+ errs() << "," << end;
+ errs() << "]";
+ }
+
+ /// Operator when populating CurrentChunks in Generic Delta Pass
+ friend bool operator!=(const Chunk &C1, const Chunk &C2) {
+ return C1.begin != C2.begin || C1.end != C2.end;
+ }
+
+ /// Operator used for sets
+ friend bool operator<(const Chunk &C1, const Chunk &C2) {
+ return std::tie(C1.begin, C1.end) < std::tie(C2.begin, C2.end);
+ }
+};
+
+/// Provides opaque interface for querying into ChunksToKeep without having to
+/// actually understand what is going on.
+class Oracle {
+ /// Out of all the features that we promised to be,
+ /// how many have we already processed? 1-based!
+ int Index = 1;
+
+ /// The actual workhorse, contains the knowledge whether or not
+ /// some particular feature should be preserved this time.
+ ArrayRef<Chunk> ChunksToKeep;
+
+public:
+ explicit Oracle(ArrayRef<Chunk> ChunksToKeep_)
+ : ChunksToKeep(ChunksToKeep_) {}
+
+ /// Should be called for each feature on which we are operating.
+ /// Name is self-explanatory - if returns true, then it should be preserved.
+ bool shouldKeep() {
+ if (ChunksToKeep.empty())
+ return false; // All further features are to be discarded.
+
+ // Does the current (front) chunk contain such a feature?
+ bool ShouldKeep = ChunksToKeep.front().contains(Index);
+ auto _ = make_scope_exit([&]() { ++Index; }); // Next time - next feature.
+
+ // Is this the last feature in the chunk?
+ if (ChunksToKeep.front().end == Index)
+ ChunksToKeep = ChunksToKeep.drop_front(); // Onto next chunk.
+
+ return ShouldKeep;
+ }
+};
+
+/// This function implements the Delta Debugging algorithm, it receives a
+/// number of Targets (e.g. Functions, Instructions, Basic Blocks, etc.) and
+/// splits them in half; these chunks of targets are then tested while ignoring
+/// one chunk, if a chunk is proven to be uninteresting (i.e. fails the test)
+/// it is removed from consideration. The algorithm will attempt to split the
+/// Chunks in half and start the process again until it can't split chunks
+/// anymore.
+///
+/// This function is intended to be called by each specialized delta pass (e.g.
+/// RemoveFunctions) and receives three key parameters:
+/// * Test: The main TestRunner instance which is used to run the provided
+/// interesting-ness test, as well as to store and access the reduced Program.
+/// * Targets: The amount of Targets that are going to be reduced by the
+/// algorithm, for example, the RemoveGlobalVars pass would send the amount of
+/// initialized GVs.
+/// * ExtractChunksFromModule: A function used to tailor the main program so it
+/// only contains Targets that are inside Chunks of the given iteration.
+/// Note: This function is implemented by each specialized Delta pass
+///
+/// Other implementations of the Delta Debugging algorithm can also be found in
+/// the CReduce, Delta, and Lithium projects.
+void runDeltaPass(TestRunner &Test, int Targets,
+ std::function<void(const std::vector<Chunk> &, Module *)>
+ ExtractChunksFromModule);
+} // namespace llvm
+
+#endif
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.cpp
new file mode 100644
index 0000000000..41be4baa98
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.cpp
@@ -0,0 +1,53 @@
+//===- ReduceAliases.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 aliases in the provided Module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceAliases.h"
+#include "Delta.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalValue.h"
+
+using namespace llvm;
+
+/// Removes all aliases aren't inside any of the
+/// desired Chunks.
+static void extractAliasesFromModule(const std::vector<Chunk> &ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ for (auto &GA : make_early_inc_range(Program->aliases())) {
+ if (!O.shouldKeep()) {
+ GA.replaceAllUsesWith(GA.getAliasee());
+ GA.eraseFromParent();
+ }
+ }
+}
+
+/// Counts the amount of aliases and prints their respective name & index.
+static int countAliases(Module *Program) {
+ // TODO: Silence index with --quiet flag
+ errs() << "----------------------------\n";
+ errs() << "Aliases Index Reference:\n";
+ int Count = 0;
+ for (auto &GA : Program->aliases())
+ errs() << "\t" << ++Count << ": " << GA.getName() << "\n";
+
+ errs() << "----------------------------\n";
+ return Count;
+}
+
+void llvm::reduceAliasesDeltaPass(TestRunner &Test) {
+ errs() << "*** Reducing Aliases ...\n";
+ int Functions = countAliases(Test.getProgram());
+ runDeltaPass(Test, Functions, extractAliasesFromModule);
+ errs() << "----------------------------\n";
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.h
new file mode 100644
index 0000000000..0c2886e0c2
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAliases.h
@@ -0,0 +1,18 @@
+//===- ReduceAliases.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 aliases in the provided Module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+
+namespace llvm {
+void reduceAliasesDeltaPass(TestRunner &Test);
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.cpp
new file mode 100644
index 0000000000..c3c7dee83d
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.cpp
@@ -0,0 +1,126 @@
+//===- ReduceArguments.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 uninteresting Arguments from defined functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceArguments.h"
+#include "Delta.h"
+#include "llvm/ADT/SmallVector.h"
+#include <set>
+#include <vector>
+
+using namespace llvm;
+
+/// Goes over OldF calls and replaces them with a call to NewF
+static void replaceFunctionCalls(Function &OldF, Function &NewF,
+ const std::set<int> &ArgIndexesToKeep) {
+ const auto &Users = OldF.users();
+ for (auto I = Users.begin(), E = Users.end(); I != E; )
+ if (auto *CI = dyn_cast<CallInst>(*I++)) {
+ SmallVector<Value *, 8> Args;
+ for (auto ArgI = CI->arg_begin(), E = CI->arg_end(); ArgI != E; ++ArgI)
+ if (ArgIndexesToKeep.count(ArgI - CI->arg_begin()))
+ Args.push_back(*ArgI);
+
+ CallInst *NewCI = CallInst::Create(&NewF, Args);
+ NewCI->setCallingConv(NewF.getCallingConv());
+ if (!CI->use_empty())
+ CI->replaceAllUsesWith(NewCI);
+ ReplaceInstWithInst(CI, NewCI);
+ }
+}
+
+/// Removes out-of-chunk arguments from functions, and modifies their calls
+/// accordingly. It also removes allocations of out-of-chunk arguments.
+static void extractArgumentsFromModule(std::vector<Chunk> ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ std::set<Argument *> ArgsToKeep;
+ std::vector<Function *> Funcs;
+ // Get inside-chunk arguments, as well as their parent function
+ for (auto &F : *Program)
+ if (!F.arg_empty()) {
+ Funcs.push_back(&F);
+ for (auto &A : F.args())
+ if (O.shouldKeep())
+ ArgsToKeep.insert(&A);
+ }
+
+ for (auto *F : Funcs) {
+ ValueToValueMapTy VMap;
+ std::vector<WeakVH> InstToDelete;
+ for (auto &A : F->args())
+ if (!ArgsToKeep.count(&A)) {
+ // By adding undesired arguments to the VMap, CloneFunction will remove
+ // them from the resulting Function
+ VMap[&A] = UndefValue::get(A.getType());
+ for (auto *U : A.users())
+ if (auto *I = dyn_cast<Instruction>(*&U))
+ InstToDelete.push_back(I);
+ }
+ // Delete any (unique) instruction that uses the argument
+ for (Value *V : InstToDelete) {
+ if (!V)
+ continue;
+ auto *I = cast<Instruction>(V);
+ I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ if (!I->isTerminator())
+ I->eraseFromParent();
+ }
+
+ // No arguments to reduce
+ if (VMap.empty())
+ continue;
+
+ std::set<int> ArgIndexesToKeep;
+ for (auto &Arg : enumerate(F->args()))
+ if (ArgsToKeep.count(&Arg.value()))
+ ArgIndexesToKeep.insert(Arg.index());
+
+ auto *ClonedFunc = CloneFunction(F, VMap);
+ // In order to preserve function order, we move Clone after old Function
+ ClonedFunc->removeFromParent();
+ Program->getFunctionList().insertAfter(F->getIterator(), ClonedFunc);
+
+ replaceFunctionCalls(*F, *ClonedFunc, ArgIndexesToKeep);
+ // Rename Cloned Function to Old's name
+ std::string FName = std::string(F->getName());
+ F->replaceAllUsesWith(ConstantExpr::getBitCast(ClonedFunc, F->getType()));
+ F->eraseFromParent();
+ ClonedFunc->setName(FName);
+ }
+}
+
+/// Counts the amount of arguments in non-declaration functions and prints their
+/// respective name, index, and parent function name
+static int countArguments(Module *Program) {
+ // TODO: Silence index with --quiet flag
+ outs() << "----------------------------\n";
+ outs() << "Param Index Reference:\n";
+ int ArgsCount = 0;
+ for (auto &F : *Program)
+ if (!F.arg_empty()) {
+ outs() << " " << F.getName() << "\n";
+ for (auto &A : F.args())
+ outs() << "\t" << ++ArgsCount << ": " << A.getName() << "\n";
+
+ outs() << "----------------------------\n";
+ }
+
+ return ArgsCount;
+}
+
+void llvm::reduceArgumentsDeltaPass(TestRunner &Test) {
+ outs() << "*** Reducing Arguments...\n";
+ int ArgCount = countArguments(Test.getProgram());
+ runDeltaPass(Test, ArgCount, extractArgumentsFromModule);
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.h
new file mode 100644
index 0000000000..d9682b44f7
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceArguments.h
@@ -0,0 +1,21 @@
+//===- ReduceArguments.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 uninteresting Arguments from defined functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+namespace llvm {
+void reduceArgumentsDeltaPass(TestRunner &Test);
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.cpp
new file mode 100644
index 0000000000..cbaf5d5efd
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.cpp
@@ -0,0 +1,200 @@
+//===- ReduceAttributes.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 uninteresting attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceAttributes.h"
+#include "Delta.h"
+#include "TestRunner.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+class LLVMContext;
+} // namespace llvm
+
+using namespace llvm;
+
+namespace {
+
+using AttrPtrVecTy = std::vector<const Attribute *>;
+using AttrPtrIdxVecVecTy = std::pair<unsigned, AttrPtrVecTy>;
+using AttrPtrVecVecTy = SmallVector<AttrPtrIdxVecVecTy, 3>;
+
+/// Given ChunksToKeep, produce a map of global variables/functions/calls
+/// and indexes of attributes to be preserved for each of them.
+class AttributeRemapper : public InstVisitor<AttributeRemapper> {
+ Oracle O;
+
+public:
+ DenseMap<GlobalVariable *, AttrPtrVecTy> GlobalVariablesToRefine;
+ DenseMap<Function *, AttrPtrVecVecTy> FunctionsToRefine;
+ DenseMap<CallBase *, AttrPtrVecVecTy> CallsToRefine;
+
+ explicit AttributeRemapper(ArrayRef<Chunk> ChunksToKeep) : O(ChunksToKeep) {}
+
+ void visitModule(Module &M) {
+ for (GlobalVariable &GV : M.getGlobalList())
+ visitGlobalVariable(GV);
+ }
+
+ void visitGlobalVariable(GlobalVariable &GV) {
+ // Global variables only have one attribute set.
+ const AttributeSet &AS = GV.getAttributes();
+ if (AS.hasAttributes())
+ visitAttributeSet(AS, GlobalVariablesToRefine[&GV]);
+ }
+
+ void visitFunction(Function &F) {
+ if (F.getIntrinsicID() != Intrinsic::not_intrinsic)
+ return; // We can neither add nor remove attributes from intrinsics.
+ visitAttributeList(F.getAttributes(), FunctionsToRefine[&F]);
+ }
+
+ void visitCallBase(CallBase &I) {
+ visitAttributeList(I.getAttributes(), CallsToRefine[&I]);
+ }
+
+ void visitAttributeList(const AttributeList &AL,
+ AttrPtrVecVecTy &AttributeSetsToPreserve) {
+ assert(AttributeSetsToPreserve.empty() && "Should not be sharing vectors.");
+ AttributeSetsToPreserve.reserve(AL.getNumAttrSets());
+ for (unsigned SetIdx : seq(AL.index_begin(), AL.index_end())) {
+ AttrPtrIdxVecVecTy AttributesToPreserve;
+ AttributesToPreserve.first = SetIdx;
+ visitAttributeSet(AL.getAttributes(AttributesToPreserve.first),
+ AttributesToPreserve.second);
+ if (!AttributesToPreserve.second.empty())
+ AttributeSetsToPreserve.emplace_back(std::move(AttributesToPreserve));
+ }
+ }
+
+ void visitAttributeSet(const AttributeSet &AS,
+ AttrPtrVecTy &AttrsToPreserve) {
+ assert(AttrsToPreserve.empty() && "Should not be sharing vectors.");
+ AttrsToPreserve.reserve(AS.getNumAttributes());
+ for (const Attribute &A : AS)
+ if (O.shouldKeep())
+ AttrsToPreserve.emplace_back(&A);
+ }
+};
+
+struct AttributeCounter : public InstVisitor<AttributeCounter> {
+ /// How many features (in this case, attributes) did we count, total?
+ int AttributeCount = 0;
+
+ void visitModule(Module &M) {
+ for (GlobalVariable &GV : M.getGlobalList())
+ visitGlobalVariable(GV);
+ }
+
+ void visitGlobalVariable(GlobalVariable &GV) {
+ // Global variables only have one attribute set.
+ visitAttributeSet(GV.getAttributes());
+ }
+
+ void visitFunction(Function &F) {
+ if (F.getIntrinsicID() != Intrinsic::not_intrinsic)
+ return; // We can neither add nor remove attributes from intrinsics.
+ visitAttributeList(F.getAttributes());
+ }
+
+ void visitCallBase(CallBase &I) { visitAttributeList(I.getAttributes()); }
+
+ void visitAttributeList(const AttributeList &AL) {
+ for (const AttributeSet &AS : AL)
+ visitAttributeSet(AS);
+ }
+
+ void visitAttributeSet(const AttributeSet &AS) {
+ AttributeCount += AS.getNumAttributes();
+ }
+};
+
+} // namespace
+
+AttributeSet
+convertAttributeRefToAttributeSet(LLVMContext &C,
+ ArrayRef<const Attribute *> Attributes) {
+ AttrBuilder B;
+ for (const Attribute *A : Attributes)
+ B.addAttribute(*A);
+ return AttributeSet::get(C, B);
+}
+
+AttributeList convertAttributeRefVecToAttributeList(
+ LLVMContext &C, ArrayRef<AttrPtrIdxVecVecTy> AttributeSets) {
+ std::vector<std::pair<unsigned, AttributeSet>> SetVec;
+ SetVec.reserve(AttributeSets.size());
+
+ transform(AttributeSets, std::back_inserter(SetVec),
+ [&C](const AttrPtrIdxVecVecTy &V) {
+ return std::make_pair(
+ V.first, convertAttributeRefToAttributeSet(C, V.second));
+ });
+
+ sort(SetVec, [](const std::pair<unsigned, AttributeSet> &LHS,
+ const std::pair<unsigned, AttributeSet> &RHS) {
+ return LHS.first < RHS.first; // All values are unique.
+ });
+
+ return AttributeList::get(C, SetVec);
+}
+
+/// Removes out-of-chunk attributes from module.
+static void extractAttributesFromModule(std::vector<Chunk> ChunksToKeep,
+ Module *Program) {
+ AttributeRemapper R(ChunksToKeep);
+ R.visit(Program);
+
+ LLVMContext &C = Program->getContext();
+ for (const auto &I : R.GlobalVariablesToRefine)
+ I.first->setAttributes(convertAttributeRefToAttributeSet(C, I.second));
+ for (const auto &I : R.FunctionsToRefine)
+ I.first->setAttributes(convertAttributeRefVecToAttributeList(C, I.second));
+ for (const auto &I : R.CallsToRefine)
+ I.first->setAttributes(convertAttributeRefVecToAttributeList(C, I.second));
+}
+
+/// Counts the amount of attributes.
+static int countAttributes(Module *Program) {
+ AttributeCounter C;
+
+ // TODO: Silence index with --quiet flag
+ outs() << "----------------------------\n";
+ C.visit(Program);
+ outs() << "Number of attributes: " << C.AttributeCount << "\n";
+
+ return C.AttributeCount;
+}
+
+void llvm::reduceAttributesDeltaPass(TestRunner &Test) {
+ outs() << "*** Reducing Attributes...\n";
+ int AttributeCount = countAttributes(Test.getProgram());
+ runDeltaPass(Test, AttributeCount, extractAttributesFromModule);
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.h
new file mode 100644
index 0000000000..f8deb04556
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceAttributes.h
@@ -0,0 +1,20 @@
+//===- ReduceAttributes.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 uninteresting attributes.
+//
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+class TestRunner;
+
+void reduceAttributesDeltaPass(TestRunner &Test);
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
new file mode 100644
index 0000000000..8c0832dd88
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp
@@ -0,0 +1,150 @@
+//===- ReduceArguments.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 uninteresting Arguments from defined functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceBasicBlocks.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
+
+using namespace llvm;
+
+/// Replaces BB Terminator with one that only contains Chunk BBs
+static void replaceBranchTerminator(BasicBlock &BB,
+ std::set<BasicBlock *> BBsToKeep) {
+ auto Term = BB.getTerminator();
+ std::vector<BasicBlock *> ChunkSucessors;
+ for (auto Succ : successors(&BB))
+ if (BBsToKeep.count(Succ))
+ ChunkSucessors.push_back(Succ);
+
+ // BB only references Chunk BBs
+ if (ChunkSucessors.size() == Term->getNumSuccessors())
+ return;
+
+ bool IsBranch = isa<BranchInst>(Term) || isa<InvokeInst>(Term);
+ Value *Address = nullptr;
+ if (auto IndBI = dyn_cast<IndirectBrInst>(Term))
+ Address = IndBI->getAddress();
+
+ Term->replaceAllUsesWith(UndefValue::get(Term->getType()));
+ Term->eraseFromParent();
+
+ if (ChunkSucessors.empty()) {
+ auto *FnRetTy = BB.getParent()->getReturnType();
+ ReturnInst::Create(BB.getContext(),
+ FnRetTy->isVoidTy() ? nullptr : UndefValue::get(FnRetTy),
+ &BB);
+ return;
+ }
+
+ if (IsBranch)
+ BranchInst::Create(ChunkSucessors[0], &BB);
+
+ if (Address) {
+ auto NewIndBI =
+ IndirectBrInst::Create(Address, ChunkSucessors.size(), &BB);
+ for (auto Dest : ChunkSucessors)
+ NewIndBI->addDestination(Dest);
+ }
+}
+
+/// Removes uninteresting BBs from switch, if the default case ends up being
+/// uninteresting, the switch is replaced with a void return (since it has to be
+/// replace with something)
+static void removeUninterestingBBsFromSwitch(SwitchInst &SwInst,
+ std::set<BasicBlock *> BBsToKeep) {
+ if (!BBsToKeep.count(SwInst.getDefaultDest())) {
+ auto *FnRetTy = SwInst.getParent()->getParent()->getReturnType();
+ ReturnInst::Create(SwInst.getContext(),
+ FnRetTy->isVoidTy() ? nullptr : UndefValue::get(FnRetTy),
+ SwInst.getParent());
+ SwInst.eraseFromParent();
+ } else
+ for (int I = 0, E = SwInst.getNumCases(); I != E; ++I) {
+ auto Case = SwInst.case_begin() + I;
+ if (!BBsToKeep.count(Case->getCaseSuccessor())) {
+ SwInst.removeCase(Case);
+ --I;
+ --E;
+ }
+ }
+}
+
+/// Removes out-of-chunk arguments from functions, and modifies their calls
+/// accordingly. It also removes allocations of out-of-chunk arguments.
+static void extractBasicBlocksFromModule(std::vector<Chunk> ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ std::set<BasicBlock *> BBsToKeep;
+
+ for (auto &F : *Program)
+ for (auto &BB : F)
+ if (O.shouldKeep())
+ BBsToKeep.insert(&BB);
+
+ std::vector<BasicBlock *> BBsToDelete;
+ for (auto &F : *Program)
+ for (auto &BB : F) {
+ if (!BBsToKeep.count(&BB)) {
+ BBsToDelete.push_back(&BB);
+ // Remove out-of-chunk BB from successor phi nodes
+ for (auto *Succ : successors(&BB))
+ Succ->removePredecessor(&BB);
+ }
+ }
+
+ // Replace terminators that reference out-of-chunk BBs
+ for (auto &F : *Program)
+ for (auto &BB : F) {
+ if (auto *SwInst = dyn_cast<SwitchInst>(BB.getTerminator()))
+ removeUninterestingBBsFromSwitch(*SwInst, BBsToKeep);
+ else
+ replaceBranchTerminator(BB, BBsToKeep);
+ }
+
+ // Replace out-of-chunk switch uses
+ for (auto &BB : BBsToDelete) {
+ // Instructions might be referenced in other BBs
+ for (auto &I : *BB)
+ I.replaceAllUsesWith(UndefValue::get(I.getType()));
+ BB->eraseFromParent();
+ }
+}
+
+/// Counts the amount of basic blocks and prints their name & respective index
+static int countBasicBlocks(Module *Program) {
+ // TODO: Silence index with --quiet flag
+ outs() << "----------------------------\n";
+ int BBCount = 0;
+ for (auto &F : *Program)
+ for (auto &BB : F) {
+ if (BB.hasName())
+ outs() << "\t" << ++BBCount << ": " << BB.getName() << "\n";
+ else
+ outs() << "\t" << ++BBCount << ": Unnamed\n";
+ }
+
+ return BBCount;
+}
+
+void llvm::reduceBasicBlocksDeltaPass(TestRunner &Test) {
+ outs() << "*** Reducing Basic Blocks...\n";
+ int BBCount = countBasicBlocks(Test.getProgram());
+ runDeltaPass(Test, BBCount, extractBasicBlocksFromModule);
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.h
new file mode 100644
index 0000000000..cf76a0abbc
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceBasicBlocks.h
@@ -0,0 +1,20 @@
+//===- ReduceArguments.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 uninteresting Arguments from defined functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+namespace llvm {
+void reduceBasicBlocksDeltaPass(TestRunner &Test);
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.cpp
new file mode 100644
index 0000000000..99be76eac3
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.cpp
@@ -0,0 +1,57 @@
+//===- ReduceFunctions.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 function bodies in the provided Module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceFunctionBodies.h"
+#include "Delta.h"
+#include "llvm/IR/GlobalValue.h"
+
+using namespace llvm;
+
+/// Removes all the bodies of defined functions that aren't inside any of the
+/// desired Chunks.
+static void
+extractFunctionBodiesFromModule(const std::vector<Chunk> &ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ // Delete out-of-chunk function bodies
+ std::vector<Function *> FuncDefsToReduce;
+ for (auto &F : *Program)
+ if (!F.isDeclaration() && !O.shouldKeep()) {
+ F.deleteBody();
+ F.setComdat(nullptr);
+ }
+}
+
+/// Counts the amount of non-declaration functions and prints their
+/// respective name & index
+static int countFunctionDefinitions(Module *Program) {
+ // TODO: Silence index with --quiet flag
+ errs() << "----------------------------\n";
+ errs() << "Function Definition Index Reference:\n";
+ int FunctionDefinitionCount = 0;
+ for (auto &F : *Program)
+ if (!F.isDeclaration())
+ errs() << "\t" << ++FunctionDefinitionCount << ": " << F.getName()
+ << "\n";
+
+ errs() << "----------------------------\n";
+ return FunctionDefinitionCount;
+}
+
+void llvm::reduceFunctionBodiesDeltaPass(TestRunner &Test) {
+ errs() << "*** Reducing Function Bodies...\n";
+ int Functions = countFunctionDefinitions(Test.getProgram());
+ runDeltaPass(Test, Functions, extractFunctionBodiesFromModule);
+ errs() << "----------------------------\n";
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.h
new file mode 100644
index 0000000000..8c06c2e4a1
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctionBodies.h
@@ -0,0 +1,18 @@
+//===- ReduceFunctionBodies.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 function bodies in the provided Module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+
+namespace llvm {
+void reduceFunctionBodiesDeltaPass(TestRunner &Test);
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.cpp
new file mode 100644
index 0000000000..d100935ee4
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.cpp
@@ -0,0 +1,77 @@
+//===- ReduceFunctions.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 functions (and any instruction that calls it) in the provided
+// Module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceFunctions.h"
+#include "Delta.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Instructions.h"
+#include <iterator>
+#include <vector>
+
+using namespace llvm;
+
+/// Removes all the Defined Functions
+/// that aren't inside any of the desired Chunks.
+static void extractFunctionsFromModule(const std::vector<Chunk> &ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ // Record all out-of-chunk functions.
+ std::vector<std::reference_wrapper<Function>> FuncsToRemove;
+ copy_if(Program->functions(), std::back_inserter(FuncsToRemove),
+ [&O](Function &F) {
+ // Intrinsics don't have function bodies that are useful to
+ // reduce. Additionally, intrinsics may have additional operand
+ // constraints. But, do drop intrinsics that are not referenced.
+ return (!F.isIntrinsic() || F.use_empty()) && !O.shouldKeep();
+ });
+
+ // Then, drop body of each of them. We want to batch this and do nothing else
+ // here so that minimal number of remaining exteranal uses will remain.
+ for (Function &F : FuncsToRemove)
+ F.dropAllReferences();
+
+ // And finally, we can actually delete them.
+ for (Function &F : FuncsToRemove) {
+ // Replace all *still* remaining uses with undef.
+ F.replaceAllUsesWith(UndefValue::get(F.getType()));
+ // And finally, fully drop it.
+ F.eraseFromParent();
+ }
+}
+
+/// Counts the amount of functions and prints their
+/// respective name & index
+static int countFunctions(Module *Program) {
+ // TODO: Silence index with --quiet flag
+ errs() << "----------------------------\n";
+ errs() << "Function Index Reference:\n";
+ int FunctionCount = 0;
+ for (auto &F : *Program) {
+ if (F.isIntrinsic() && !F.use_empty())
+ continue;
+
+ errs() << '\t' << ++FunctionCount << ": " << F.getName() << '\n';
+ }
+
+ errs() << "----------------------------\n";
+ return FunctionCount;
+}
+
+void llvm::reduceFunctionsDeltaPass(TestRunner &Test) {
+ errs() << "*** Reducing Functions...\n";
+ int Functions = countFunctions(Test.getProgram());
+ runDeltaPass(Test, Functions, extractFunctionsFromModule);
+ errs() << "----------------------------\n";
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.h
new file mode 100644
index 0000000000..7c2cd3f33e
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceFunctions.h
@@ -0,0 +1,20 @@
+//===- ReduceFunctions.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 functions (and any instruction that calls it) in the provided
+// Module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+namespace llvm {
+void reduceFunctionsDeltaPass(TestRunner &Test);
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp
new file mode 100644
index 0000000000..fd5a5d1f02
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.cpp
@@ -0,0 +1,52 @@
+//===- 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"
+#include "llvm/IR/GlobalValue.h"
+
+using namespace llvm;
+
+/// Removes all the Initialized GVs that aren't inside the desired Chunks.
+static void extractGVsFromModule(std::vector<Chunk> 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);
+ GV.setLinkage(GlobalValue::LinkageTypes::ExternalLinkage);
+ GV.setComdat(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/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVarInitializers.h
new file mode 100644
index 0000000000..39288adce8
--- /dev/null
+++ b/contrib/libs/llvm12/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/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp
new file mode 100644
index 0000000000..4b184e5b3e
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp
@@ -0,0 +1,74 @@
+//===- 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 Global Variables in the provided Module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceGlobalVars.h"
+#include "llvm/IR/Constants.h"
+#include <set>
+
+using namespace llvm;
+
+/// Removes all the GVs that aren't inside the desired Chunks.
+static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ // Get GVs inside desired chunks
+ std::set<GlobalVariable *> GVsToKeep;
+ for (auto &GV : Program->globals())
+ if (O.shouldKeep())
+ GVsToKeep.insert(&GV);
+
+ // Delete out-of-chunk GVs and their uses
+ std::vector<GlobalVariable *> ToRemove;
+ std::vector<WeakVH> InstToRemove;
+ for (auto &GV : Program->globals())
+ if (!GVsToKeep.count(&GV)) {
+ for (auto U : GV.users())
+ if (auto *Inst = dyn_cast<Instruction>(U))
+ InstToRemove.push_back(Inst);
+
+ GV.replaceAllUsesWith(UndefValue::get(GV.getType()));
+ ToRemove.push_back(&GV);
+ }
+
+ // Delete (unique) Instruction uses of unwanted GVs
+ for (Value *V : InstToRemove) {
+ if (!V)
+ continue;
+ auto *Inst = cast<Instruction>(V);
+ Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
+ Inst->eraseFromParent();
+ }
+
+ for (auto *GV : ToRemove)
+ GV->eraseFromParent();
+}
+
+/// Counts the amount of 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())
+ outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n";
+ outs() << "----------------------------\n";
+ return GVCount;
+}
+
+void llvm::reduceGlobalsDeltaPass(TestRunner &Test) {
+ outs() << "*** Reducing GVs...\n";
+ int GVCount = countGVs(Test.getProgram());
+ runDeltaPass(Test, GVCount, extractGVsFromModule);
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVars.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceGlobalVars.h
new file mode 100644
index 0000000000..c8ba7eacb8
--- /dev/null
+++ b/contrib/libs/llvm12/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 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
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.cpp
new file mode 100644
index 0000000000..3e37ec5e17
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.cpp
@@ -0,0 +1,67 @@
+//===- ReduceArguments.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 uninteresting Arguments from defined functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceInstructions.h"
+
+using namespace llvm;
+
+/// Removes out-of-chunk arguments from functions, and modifies their calls
+/// accordingly. It also removes allocations of out-of-chunk arguments.
+static void extractInstrFromModule(std::vector<Chunk> ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ std::set<Instruction *> InstToKeep;
+
+ for (auto &F : *Program)
+ for (auto &BB : F) {
+ // Removing the terminator would make the block invalid. Only iterate over
+ // instructions before the terminator.
+ InstToKeep.insert(BB.getTerminator());
+ for (auto &Inst : make_range(BB.begin(), std::prev(BB.end())))
+ if (O.shouldKeep())
+ InstToKeep.insert(&Inst);
+ }
+
+ std::vector<Instruction *> InstToDelete;
+ for (auto &F : *Program)
+ for (auto &BB : F)
+ for (auto &Inst : BB)
+ if (!InstToKeep.count(&Inst)) {
+ Inst.replaceAllUsesWith(UndefValue::get(Inst.getType()));
+ InstToDelete.push_back(&Inst);
+ }
+
+ for (auto &I : InstToDelete)
+ I->eraseFromParent();
+}
+
+/// Counts the amount of basic blocks and prints their name & respective index
+static unsigned countInstructions(Module *Program) {
+ // TODO: Silence index with --quiet flag
+ outs() << "----------------------------\n";
+ int InstCount = 0;
+ for (auto &F : *Program)
+ for (auto &BB : F)
+ // Well-formed blocks have terminators, which we cannot remove.
+ InstCount += BB.getInstList().size() - 1;
+ outs() << "Number of instructions: " << InstCount << "\n";
+
+ return InstCount;
+}
+
+void llvm::reduceInstructionsDeltaPass(TestRunner &Test) {
+ outs() << "*** Reducing Instructions...\n";
+ unsigned InstCount = countInstructions(Test.getProgram());
+ runDeltaPass(Test, InstCount, extractInstrFromModule);
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.h
new file mode 100644
index 0000000000..a9266acd05
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceInstructions.h
@@ -0,0 +1,20 @@
+//===- ReduceArguments.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 uninteresting Arguments from defined functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+namespace llvm {
+void reduceInstructionsDeltaPass(TestRunner &Test);
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.cpp
new file mode 100644
index 0000000000..4587295a00
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.cpp
@@ -0,0 +1,127 @@
+//===- ReduceMetadata.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 two functions used by the Generic Delta Debugging
+// Algorithm, which are used to reduce Metadata nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceMetadata.h"
+#include "Delta.h"
+#include "llvm/ADT/SmallVector.h"
+#include <set>
+#include <vector>
+
+using namespace llvm;
+
+/// Adds all Unnamed Metadata Nodes that are inside desired Chunks to set
+template <class T>
+static void getChunkMetadataNodes(T &MDUser, Oracle &O,
+ std::set<MDNode *> &SeenNodes,
+ std::set<MDNode *> &NodesToKeep) {
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ MDUser.getAllMetadata(MDs);
+ for (auto &MD : MDs) {
+ SeenNodes.insert(MD.second);
+ if (O.shouldKeep())
+ NodesToKeep.insert(MD.second);
+ }
+}
+
+/// Erases out-of-chunk unnamed metadata nodes from its user
+template <class T>
+static void eraseMetadataIfOutsideChunk(T &MDUser,
+ const std::set<MDNode *> &NodesToKeep) {
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ MDUser.getAllMetadata(MDs);
+ for (int I = 0, E = MDs.size(); I != E; ++I)
+ if (!NodesToKeep.count(MDs[I].second))
+ MDUser.setMetadata(I, NULL);
+}
+
+/// Removes all the Named and Unnamed Metadata Nodes, as well as any debug
+/// functions that aren't inside the desired Chunks.
+static void extractMetadataFromModule(const std::vector<Chunk> &ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ std::set<MDNode *> SeenNodes;
+ std::set<MDNode *> NodesToKeep;
+
+ // Add chunk MDNodes used by GVs, Functions, and Instructions to set
+ for (auto &GV : Program->globals())
+ getChunkMetadataNodes(GV, O, SeenNodes, NodesToKeep);
+
+ for (auto &F : *Program) {
+ getChunkMetadataNodes(F, O, SeenNodes, NodesToKeep);
+ for (auto &BB : F)
+ for (auto &Inst : BB)
+ getChunkMetadataNodes(Inst, O, SeenNodes, NodesToKeep);
+ }
+
+ // Once more, go over metadata nodes, but deleting the ones outside chunks
+ for (auto &GV : Program->globals())
+ eraseMetadataIfOutsideChunk(GV, NodesToKeep);
+
+ for (auto &F : *Program) {
+ eraseMetadataIfOutsideChunk(F, NodesToKeep);
+ for (auto &BB : F)
+ for (auto &Inst : BB)
+ eraseMetadataIfOutsideChunk(Inst, NodesToKeep);
+ }
+
+
+ // Get out-of-chunk Named metadata nodes
+ std::vector<NamedMDNode *> NamedNodesToDelete;
+ for (auto &MD : Program->named_metadata())
+ if (!O.shouldKeep())
+ NamedNodesToDelete.push_back(&MD);
+
+ for (auto *NN : NamedNodesToDelete) {
+ for (int I = 0, E = NN->getNumOperands(); I != E; ++I)
+ NN->setOperand(I, NULL);
+ NN->eraseFromParent();
+ }
+}
+
+// Gets unnamed metadata nodes used by a given instruction/GV/function and adds
+// them to the set of seen nodes
+template <class T>
+static void addMetadataToSet(T &MDUser, std::set<MDNode *> &UnnamedNodes) {
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ MDUser.getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ UnnamedNodes.insert(MD.second);
+}
+
+/// Returns the amount of Named and Unnamed Metadata Nodes
+static int countMetadataTargets(Module *Program) {
+ std::set<MDNode *> UnnamedNodes;
+ int NamedMetadataNodes = Program->named_metadata_size();
+
+ // Get metadata nodes used by globals
+ for (auto &GV : Program->globals())
+ addMetadataToSet(GV, UnnamedNodes);
+
+ // Do the same for nodes used by functions & instructions
+ for (auto &F : *Program) {
+ addMetadataToSet(F, UnnamedNodes);
+ for (auto &BB : F)
+ for (auto &I : BB)
+ addMetadataToSet(I, UnnamedNodes);
+ }
+
+ return UnnamedNodes.size() + NamedMetadataNodes;
+}
+
+void llvm::reduceMetadataDeltaPass(TestRunner &Test) {
+ outs() << "*** Reducing Metadata...\n";
+ int MDCount = countMetadataTargets(Test.getProgram());
+ runDeltaPass(Test, MDCount, extractMetadataFromModule);
+ outs() << "----------------------------\n";
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.h
new file mode 100644
index 0000000000..275b44c2aa
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceMetadata.h
@@ -0,0 +1,18 @@
+//===- ReduceMetadata.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 two functions used by the Generic Delta Debugging
+// Algorithm, which are used to reduce Metadata nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestRunner.h"
+
+namespace llvm {
+void reduceMetadataDeltaPass(TestRunner &Test);
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp
new file mode 100644
index 0000000000..77cb73837c
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.cpp
@@ -0,0 +1,124 @@
+//===- ReduceOperandBundes.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 uninteresting operand bundes from calls.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceOperandBundles.h"
+#include "Delta.h"
+#include "TestRunner.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+namespace llvm {
+class Module;
+} // namespace llvm
+
+using namespace llvm;
+
+namespace {
+
+/// Given ChunksToKeep, produce a map of calls and indexes of operand bundles
+/// to be preserved for each call.
+class OperandBundleRemapper : public InstVisitor<OperandBundleRemapper> {
+ Oracle O;
+
+public:
+ DenseMap<CallBase *, std::vector<unsigned>> CallsToRefine;
+
+ explicit OperandBundleRemapper(ArrayRef<Chunk> ChunksToKeep)
+ : O(ChunksToKeep) {}
+
+ /// So far only CallBase sub-classes can have operand bundles.
+ /// Let's see which of the operand bundles of this call are to be kept.
+ void visitCallBase(CallBase &Call) {
+ if (!Call.hasOperandBundles())
+ return; // No bundles to begin with.
+
+ // Insert this call into map, we will likely want to rebuild it.
+ auto &OperandBundlesToKeepIndexes = CallsToRefine[&Call];
+ OperandBundlesToKeepIndexes.reserve(Call.getNumOperandBundles());
+
+ // Enumerate every operand bundle on this call.
+ for (unsigned BundleIndex : seq(0U, Call.getNumOperandBundles()))
+ if (O.shouldKeep()) // Should we keep this one?
+ OperandBundlesToKeepIndexes.emplace_back(BundleIndex);
+ }
+};
+
+struct OperandBundleCounter : public InstVisitor<OperandBundleCounter> {
+ /// How many features (in this case, operand bundles) did we count, total?
+ int OperandBundeCount = 0;
+
+ /// So far only CallBase sub-classes can have operand bundles.
+ void visitCallBase(CallBase &Call) {
+ // Just accumulate the total number of operand bundles.
+ OperandBundeCount += Call.getNumOperandBundles();
+ }
+};
+
+} // namespace
+
+static void maybeRewriteCallWithDifferentBundles(
+ CallBase *OrigCall, ArrayRef<unsigned> OperandBundlesToKeepIndexes) {
+ if (OperandBundlesToKeepIndexes.size() == OrigCall->getNumOperandBundles())
+ return; // Not modifying operand bundles of this call after all.
+
+ std::vector<OperandBundleDef> NewBundles;
+ NewBundles.reserve(OperandBundlesToKeepIndexes.size());
+
+ // Actually copy over the bundles that we want to keep.
+ transform(OperandBundlesToKeepIndexes, std::back_inserter(NewBundles),
+ [OrigCall](unsigned Index) {
+ return OperandBundleDef(OrigCall->getOperandBundleAt(Index));
+ });
+
+ // Finally actually replace the bundles on the call.
+ CallBase *NewCall = CallBase::Create(OrigCall, NewBundles, OrigCall);
+ OrigCall->replaceAllUsesWith(NewCall);
+ OrigCall->eraseFromParent();
+}
+
+/// Removes out-of-chunk operand bundles from calls.
+static void extractOperandBundesFromModule(std::vector<Chunk> ChunksToKeep,
+ Module *Program) {
+ OperandBundleRemapper R(ChunksToKeep);
+ R.visit(Program);
+
+ for (const auto &I : R.CallsToRefine)
+ maybeRewriteCallWithDifferentBundles(I.first, I.second);
+}
+
+/// Counts the amount of operand bundles.
+static int countOperandBundes(Module *Program) {
+ OperandBundleCounter C;
+
+ // TODO: Silence index with --quiet flag
+ outs() << "----------------------------\n";
+ C.visit(Program);
+ outs() << "Number of operand bundles: " << C.OperandBundeCount << "\n";
+
+ return C.OperandBundeCount;
+}
+
+void llvm::reduceOperandBundesDeltaPass(TestRunner &Test) {
+ outs() << "*** Reducing OperandBundes...\n";
+ int OperandBundeCount = countOperandBundes(Test.getProgram());
+ runDeltaPass(Test, OperandBundeCount, extractOperandBundesFromModule);
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.h
new file mode 100644
index 0000000000..382c5cb569
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceOperandBundles.h
@@ -0,0 +1,20 @@
+//===- ReduceOperandBundes.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 uninteresting operand bundes from calls.
+//
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+class TestRunner;
+
+void reduceOperandBundesDeltaPass(TestRunner &Test);
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.cpp b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.cpp
new file mode 100644
index 0000000000..dedeac8287
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.cpp
@@ -0,0 +1,62 @@
+//===- ReduceSpecialGlobals.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 special globals, like @llvm.used, in the provided Module.
+//
+// For more details about special globals, see
+// https://llvm.org/docs/LangRef.html#intrinsic-global-variables
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceSpecialGlobals.h"
+#include "Delta.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalValue.h"
+
+using namespace llvm;
+
+static StringRef SpecialGlobalNames[] = {"llvm.used", "llvm.compiler.used"};
+
+/// Removes all special globals aren't inside any of the
+/// desired Chunks.
+static void
+extractSpecialGlobalsFromModule(const std::vector<Chunk> &ChunksToKeep,
+ Module *Program) {
+ Oracle O(ChunksToKeep);
+
+ for (StringRef Name : SpecialGlobalNames) {
+ if (auto *Used = Program->getNamedGlobal(Name)) {
+ Used->replaceAllUsesWith(UndefValue::get(Used->getType()));
+ Used->eraseFromParent();
+ }
+ }
+}
+
+/// Counts the amount of special globals and prints their
+/// respective name & index
+static int countSpecialGlobals(Module *Program) {
+ // TODO: Silence index with --quiet flag
+ errs() << "----------------------------\n";
+ errs() << "Special Globals Index Reference:\n";
+ int Count = 0;
+ for (StringRef Name : SpecialGlobalNames) {
+ if (auto *Used = Program->getNamedGlobal(Name))
+ errs() << "\t" << ++Count << ": " << Used->getName() << "\n";
+ }
+ errs() << "----------------------------\n";
+ return Count;
+}
+
+void llvm::reduceSpecialGlobalsDeltaPass(TestRunner &Test) {
+ errs() << "*** Reducing Special Globals ...\n";
+ int Functions = countSpecialGlobals(Test.getProgram());
+ runDeltaPass(Test, Functions, extractSpecialGlobalsFromModule);
+ errs() << "----------------------------\n";
+}
diff --git a/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.h b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.h
new file mode 100644
index 0000000000..52ecaed4cd
--- /dev/null
+++ b/contrib/libs/llvm12/tools/llvm-reduce/deltas/ReduceSpecialGlobals.h
@@ -0,0 +1,21 @@
+//===- ReduceSpecialGlobals.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 special globals, like @llvm.used, in the provided Module.
+//
+// For more details about special globals, see
+// https://llvm.org/docs/LangRef.html#intrinsic-global-variables
+//
+//===----------------------------------------------------------------------===//
+
+#include "Delta.h"
+
+namespace llvm {
+void reduceSpecialGlobalsDeltaPass(TestRunner &Test);
+} // namespace llvm