summaryrefslogtreecommitdiff
path: root/clang-r353983/include/llvm/Transforms/IPO
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/llvm/Transforms/IPO')
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/AlwaysInliner.h45
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/ArgumentPromotion.h35
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/CalledValuePropagation.h34
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/ConstantMerge.h36
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/CrossDSOCFI.h27
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/DeadArgumentElimination.h143
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/ElimAvailExtern.h32
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/ForceFunctionAttrs.h32
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/FunctionAttrs.h77
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/FunctionImport.h223
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/GlobalDCE.h56
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/GlobalOpt.h32
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/GlobalSplit.h33
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/HotColdSplitting.h30
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/InferFunctionAttrs.h35
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/Inliner.h113
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/Internalize.h78
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/LowerTypeTests.h210
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/PartialInlining.h31
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/PassManagerBuilder.h216
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/SCCP.h37
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/SampleProfile.h42
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/StripDeadPrototypes.h31
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h19
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h40
-rw-r--r--clang-r353983/include/llvm/Transforms/IPO/WholeProgramDevirt.h233
26 files changed, 1920 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/Transforms/IPO/AlwaysInliner.h b/clang-r353983/include/llvm/Transforms/IPO/AlwaysInliner.h
new file mode 100644
index 00000000..64e25230
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/AlwaysInliner.h
@@ -0,0 +1,45 @@
+//===-- AlwaysInliner.h - Pass to inline "always_inline" functions --------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Provides passes to inlining "always_inline" functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_ALWAYSINLINER_H
+#define LLVM_TRANSFORMS_IPO_ALWAYSINLINER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Inlines functions marked as "always_inline".
+///
+/// Note that this does not inline call sites marked as always_inline and does
+/// not delete the functions even when all users are inlined. The normal
+/// inliner should be used to handle call site inlining, this pass's goal is to
+/// be the simplest possible pass to remove always_inline function definitions'
+/// uses by inlining them. The \c GlobalDCE pass can be used to remove these
+/// functions once all users are gone.
+class AlwaysInlinerPass : public PassInfoMixin<AlwaysInlinerPass> {
+ bool InsertLifetime;
+
+public:
+ AlwaysInlinerPass(bool InsertLifetime = true)
+ : InsertLifetime(InsertLifetime) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+/// Create a legacy pass manager instance of a pass to inline and remove
+/// functions marked as "always_inline".
+Pass *createAlwaysInlinerLegacyPass(bool InsertLifetime = true);
+
+}
+
+#endif // LLVM_TRANSFORMS_IPO_ALWAYSINLINER_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/ArgumentPromotion.h b/clang-r353983/include/llvm/Transforms/IPO/ArgumentPromotion.h
new file mode 100644
index 00000000..c8afb7bd
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/ArgumentPromotion.h
@@ -0,0 +1,35 @@
+//===- ArgumentPromotion.h - Promote by-reference arguments -----*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_ARGUMENTPROMOTION_H
+#define LLVM_TRANSFORMS_IPO_ARGUMENTPROMOTION_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Argument promotion pass.
+///
+/// This pass walks the functions in each SCC and for each one tries to
+/// transform it and all of its callers to replace indirect arguments with
+/// direct (by-value) arguments.
+class ArgumentPromotionPass : public PassInfoMixin<ArgumentPromotionPass> {
+ unsigned MaxElements;
+
+public:
+ ArgumentPromotionPass(unsigned MaxElements = 3u) : MaxElements(MaxElements) {}
+
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_ARGUMENTPROMOTION_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/CalledValuePropagation.h b/clang-r353983/include/llvm/Transforms/IPO/CalledValuePropagation.h
new file mode 100644
index 00000000..c2626d08
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/CalledValuePropagation.h
@@ -0,0 +1,34 @@
+//===- CalledValuePropagation.h - Propagate called values -------*- C++ -*-===//
+//
+// 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 transformation that attaches !callees metadata to
+// indirect call sites. For a given call site, the metadata, if present,
+// indicates the set of functions the call site could possibly target at
+// run-time. This metadata is added to indirect call sites when the set of
+// possible targets can be determined by analysis and is known to be small. The
+// analysis driving the transformation is similar to constant propagation and
+// makes uses of the generic sparse propagation solver.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_CALLEDVALUEPROPAGATION_H
+#define LLVM_TRANSFORMS_IPO_CALLEDVALUEPROPAGATION_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class CalledValuePropagationPass
+ : public PassInfoMixin<CalledValuePropagationPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_CALLEDVALUEPROPAGATION_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/ConstantMerge.h b/clang-r353983/include/llvm/Transforms/IPO/ConstantMerge.h
new file mode 100644
index 00000000..12d38b5f
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/ConstantMerge.h
@@ -0,0 +1,36 @@
+//===- ConstantMerge.h - Merge duplicate global constants -------*- C++ -*-===//
+//
+// 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 defines the interface to a pass that merges duplicate global
+// constants together into a single constant that is shared. This is useful
+// because some passes (ie TraceValues) insert a lot of string constants into
+// the program, regardless of whether or not an existing string is available.
+//
+// Algorithm: ConstantMerge is designed to build up a map of available constants
+// and eliminate duplicates when it is initialized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H
+#define LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// A pass that merges duplicate global constants into a single constant.
+class ConstantMergePass : public PassInfoMixin<ConstantMergePass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/CrossDSOCFI.h b/clang-r353983/include/llvm/Transforms/IPO/CrossDSOCFI.h
new file mode 100644
index 00000000..8440df63
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/CrossDSOCFI.h
@@ -0,0 +1,27 @@
+//===-- CrossDSOCFI.cpp - Externalize this module's CFI checks --*- C++ -*-===//
+//
+// 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 pass exports all llvm.bitset's found in the module in the form of a
+// __cfi_check function, which can be used to verify cross-DSO call targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_CROSSDSOCFI_H
+#define LLVM_TRANSFORMS_IPO_CROSSDSOCFI_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class CrossDSOCFIPass : public PassInfoMixin<CrossDSOCFIPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+}
+#endif // LLVM_TRANSFORMS_IPO_CROSSDSOCFI_H
+
diff --git a/clang-r353983/include/llvm/Transforms/IPO/DeadArgumentElimination.h b/clang-r353983/include/llvm/Transforms/IPO/DeadArgumentElimination.h
new file mode 100644
index 00000000..73797bc1
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/DeadArgumentElimination.h
@@ -0,0 +1,143 @@
+//===- DeadArgumentElimination.h - Eliminate Dead Args ----------*- C++ -*-===//
+//
+// 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 pass deletes dead arguments from internal functions. Dead argument
+// elimination removes arguments which are directly dead, as well as arguments
+// only passed into function calls as dead arguments of other functions. This
+// pass also deletes dead return values in a similar way.
+//
+// This pass is often useful as a cleanup pass to run after aggressive
+// interprocedural passes, which add possibly-dead arguments or return values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_DEADARGUMENTELIMINATION_H
+#define LLVM_TRANSFORMS_IPO_DEADARGUMENTELIMINATION_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/PassManager.h"
+#include <map>
+#include <set>
+#include <string>
+#include <tuple>
+
+namespace llvm {
+
+class Module;
+class Use;
+class Value;
+
+/// Eliminate dead arguments (and return values) from functions.
+class DeadArgumentEliminationPass
+ : public PassInfoMixin<DeadArgumentEliminationPass> {
+public:
+ /// Struct that represents (part of) either a return value or a function
+ /// argument. Used so that arguments and return values can be used
+ /// interchangeably.
+ struct RetOrArg {
+ const Function *F;
+ unsigned Idx;
+ bool IsArg;
+
+ RetOrArg(const Function *F, unsigned Idx, bool IsArg)
+ : F(F), Idx(Idx), IsArg(IsArg) {}
+
+ /// Make RetOrArg comparable, so we can put it into a map.
+ bool operator<(const RetOrArg &O) const {
+ return std::tie(F, Idx, IsArg) < std::tie(O.F, O.Idx, O.IsArg);
+ }
+
+ /// Make RetOrArg comparable, so we can easily iterate the multimap.
+ bool operator==(const RetOrArg &O) const {
+ return F == O.F && Idx == O.Idx && IsArg == O.IsArg;
+ }
+
+ std::string getDescription() const {
+ return (Twine(IsArg ? "Argument #" : "Return value #") + Twine(Idx) +
+ " of function " + F->getName())
+ .str();
+ }
+ };
+
+ /// Liveness enum - During our initial pass over the program, we determine
+ /// that things are either alive or maybe alive. We don't mark anything
+ /// explicitly dead (even if we know they are), since anything not alive
+ /// with no registered uses (in Uses) will never be marked alive and will
+ /// thus become dead in the end.
+ enum Liveness { Live, MaybeLive };
+
+ DeadArgumentEliminationPass(bool ShouldHackArguments_ = false)
+ : ShouldHackArguments(ShouldHackArguments_) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+
+ /// Convenience wrapper
+ RetOrArg CreateRet(const Function *F, unsigned Idx) {
+ return RetOrArg(F, Idx, false);
+ }
+
+ /// Convenience wrapper
+ RetOrArg CreateArg(const Function *F, unsigned Idx) {
+ return RetOrArg(F, Idx, true);
+ }
+
+ using UseMap = std::multimap<RetOrArg, RetOrArg>;
+
+ /// This maps a return value or argument to any MaybeLive return values or
+ /// arguments it uses. This allows the MaybeLive values to be marked live
+ /// when any of its users is marked live.
+ /// For example (indices are left out for clarity):
+ /// - Uses[ret F] = ret G
+ /// This means that F calls G, and F returns the value returned by G.
+ /// - Uses[arg F] = ret G
+ /// This means that some function calls G and passes its result as an
+ /// argument to F.
+ /// - Uses[ret F] = arg F
+ /// This means that F returns one of its own arguments.
+ /// - Uses[arg F] = arg G
+ /// This means that G calls F and passes one of its own (G's) arguments
+ /// directly to F.
+ UseMap Uses;
+
+ using LiveSet = std::set<RetOrArg>;
+ using LiveFuncSet = std::set<const Function *>;
+
+ /// This set contains all values that have been determined to be live.
+ LiveSet LiveValues;
+
+ /// This set contains all values that are cannot be changed in any way.
+ LiveFuncSet LiveFunctions;
+
+ using UseVector = SmallVector<RetOrArg, 5>;
+
+ /// This allows this pass to do double-duty as the dead arg hacking pass
+ /// (used only by bugpoint).
+ bool ShouldHackArguments = false;
+
+private:
+ Liveness MarkIfNotLive(RetOrArg Use, UseVector &MaybeLiveUses);
+ Liveness SurveyUse(const Use *U, UseVector &MaybeLiveUses,
+ unsigned RetValNum = -1U);
+ Liveness SurveyUses(const Value *V, UseVector &MaybeLiveUses);
+
+ void SurveyFunction(const Function &F);
+ void MarkValue(const RetOrArg &RA, Liveness L,
+ const UseVector &MaybeLiveUses);
+ void MarkLive(const RetOrArg &RA);
+ void MarkLive(const Function &F);
+ void PropagateLiveness(const RetOrArg &RA);
+ bool RemoveDeadStuffFromFunction(Function *F);
+ bool DeleteDeadVarargs(Function &Fn);
+ bool RemoveDeadArgumentsFromCallers(Function &Fn);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_DEADARGUMENTELIMINATION_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/ElimAvailExtern.h b/clang-r353983/include/llvm/Transforms/IPO/ElimAvailExtern.h
new file mode 100644
index 00000000..92c319b3
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/ElimAvailExtern.h
@@ -0,0 +1,32 @@
+//===- ElimAvailExtern.h - Optimize Global Variables ------------*- C++ -*-===//
+//
+// 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 transform is designed to eliminate available external global
+// definitions from the program, turning them into declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_ELIMAVAILEXTERN_H
+#define LLVM_TRANSFORMS_IPO_ELIMAVAILEXTERN_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// A pass that transforms external global definitions into declarations.
+class EliminateAvailableExternallyPass
+ : public PassInfoMixin<EliminateAvailableExternallyPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_ELIMAVAILEXTERN_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/ForceFunctionAttrs.h b/clang-r353983/include/llvm/Transforms/IPO/ForceFunctionAttrs.h
new file mode 100644
index 00000000..7379009b
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/ForceFunctionAttrs.h
@@ -0,0 +1,32 @@
+//===-- ForceFunctionAttrs.h - Force function attrs for debugging ---------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// Super simple passes to force specific function attrs from the commandline
+/// into the IR for debugging purposes.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_FORCEFUNCTIONATTRS_H
+#define LLVM_TRANSFORMS_IPO_FORCEFUNCTIONATTRS_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Pass which forces specific function attributes into the IR, primarily as
+/// a debugging tool.
+struct ForceFunctionAttrsPass : PassInfoMixin<ForceFunctionAttrsPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+/// Create a legacy pass manager instance of a pass to force function attrs.
+Pass *createForceFunctionAttrsLegacyPass();
+
+}
+
+#endif // LLVM_TRANSFORMS_IPO_FORCEFUNCTIONATTRS_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/FunctionAttrs.h b/clang-r353983/include/llvm/Transforms/IPO/FunctionAttrs.h
new file mode 100644
index 00000000..ce61eea0
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/FunctionAttrs.h
@@ -0,0 +1,77 @@
+//===- FunctionAttrs.h - Compute function attributes ------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Provides passes for computing function attributes based on interprocedural
+/// analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
+#define LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class AAResults;
+class Function;
+class Module;
+class Pass;
+
+/// The three kinds of memory access relevant to 'readonly' and
+/// 'readnone' attributes.
+enum MemoryAccessKind {
+ MAK_ReadNone = 0,
+ MAK_ReadOnly = 1,
+ MAK_MayWrite = 2,
+ MAK_WriteOnly = 3
+};
+
+/// Returns the memory access properties of this copy of the function.
+MemoryAccessKind computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR);
+
+/// Computes function attributes in post-order over the call graph.
+///
+/// By operating in post-order, this pass computes precise attributes for
+/// called functions prior to processsing their callers. This "bottom-up"
+/// approach allows powerful interprocedural inference of function attributes
+/// like memory access patterns, etc. It can discover functions that do not
+/// access memory, or only read memory, and give them the readnone/readonly
+/// attribute. It also discovers function arguments that are not captured by
+/// the function and marks them with the nocapture attribute.
+struct PostOrderFunctionAttrsPass : PassInfoMixin<PostOrderFunctionAttrsPass> {
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
+};
+
+/// Create a legacy pass manager instance of a pass to compute function attrs
+/// in post-order.
+Pass *createPostOrderFunctionAttrsLegacyPass();
+
+/// A pass to do RPO deduction and propagation of function attributes.
+///
+/// This pass provides a general RPO or "top down" propagation of
+/// function attributes. For a few (rare) cases, we can deduce significantly
+/// more about function attributes by working in RPO, so this pass
+/// provides the complement to the post-order pass above where the majority of
+/// deduction is performed.
+// FIXME: Currently there is no RPO CGSCC pass structure to slide into and so
+// this is a boring module pass, but eventually it should be an RPO CGSCC pass
+// when such infrastructure is available.
+class ReversePostOrderFunctionAttrsPass
+ : public PassInfoMixin<ReversePostOrderFunctionAttrsPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/FunctionImport.h b/clang-r353983/include/llvm/Transforms/IPO/FunctionImport.h
new file mode 100644
index 00000000..bbf270c4
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/FunctionImport.h
@@ -0,0 +1,223 @@
+//===- llvm/Transforms/IPO/FunctionImport.h - ThinLTO importing -*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
+#define LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Error.h"
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <unordered_set>
+#include <utility>
+
+namespace llvm {
+
+class Module;
+
+/// The function importer is automatically importing function from other modules
+/// based on the provided summary informations.
+class FunctionImporter {
+public:
+ /// Set of functions to import from a source module. Each entry is a set
+ /// containing all the GUIDs of all functions to import for a source module.
+ using FunctionsToImportTy = std::unordered_set<GlobalValue::GUID>;
+
+ /// The different reasons selectCallee will chose not to import a
+ /// candidate.
+ enum ImportFailureReason {
+ None,
+ // We can encounter a global variable instead of a function in rare
+ // situations with SamplePGO. See comments where this failure type is
+ // set for more details.
+ GlobalVar,
+ // Found to be globally dead, so we don't bother importing.
+ NotLive,
+ // Instruction count over the current threshold.
+ TooLarge,
+ // Don't import something with interposable linkage as we can't inline it
+ // anyway.
+ InterposableLinkage,
+ // Generally we won't end up failing due to this reason, as we expect
+ // to find at least one summary for the GUID that is global or a local
+ // in the referenced module for direct calls.
+ LocalLinkageNotInModule,
+ // This corresponds to the NotEligibleToImport being set on the summary,
+ // which can happen in a few different cases (e.g. local that can't be
+ // renamed or promoted because it is referenced on a llvm*.used variable).
+ NotEligible,
+ // This corresponds to NoInline being set on the function summary,
+ // which will happen if it is known that the inliner will not be able
+ // to inline the function (e.g. it is marked with a NoInline attribute).
+ NoInline
+ };
+
+ /// Information optionally tracked for candidates the importer decided
+ /// not to import. Used for optional stat printing.
+ struct ImportFailureInfo {
+ // The ValueInfo corresponding to the candidate. We save an index hash
+ // table lookup for each GUID by stashing this here.
+ ValueInfo VI;
+ // The maximum call edge hotness for all failed imports of this candidate.
+ CalleeInfo::HotnessType MaxHotness;
+ // most recent reason for failing to import (doesn't necessarily correspond
+ // to the attempt with the maximum hotness).
+ ImportFailureReason Reason;
+ // The number of times we tried to import candidate but failed.
+ unsigned Attempts;
+ ImportFailureInfo(ValueInfo VI, CalleeInfo::HotnessType MaxHotness,
+ ImportFailureReason Reason, unsigned Attempts)
+ : VI(VI), MaxHotness(MaxHotness), Reason(Reason), Attempts(Attempts) {}
+ };
+
+ /// Map of callee GUID considered for import into a given module to a pair
+ /// consisting of the largest threshold applied when deciding whether to
+ /// import it and, if we decided to import, a pointer to the summary instance
+ /// imported. If we decided not to import, the summary will be nullptr.
+ using ImportThresholdsTy =
+ DenseMap<GlobalValue::GUID,
+ std::tuple<unsigned, const GlobalValueSummary *,
+ std::unique_ptr<ImportFailureInfo>>>;
+
+ /// The map contains an entry for every module to import from, the key being
+ /// the module identifier to pass to the ModuleLoader. The value is the set of
+ /// functions to import.
+ using ImportMapTy = StringMap<FunctionsToImportTy>;
+
+ /// The set contains an entry for every global value the module exports.
+ using ExportSetTy = std::unordered_set<GlobalValue::GUID>;
+
+ /// A function of this type is used to load modules referenced by the index.
+ using ModuleLoaderTy =
+ std::function<Expected<std::unique_ptr<Module>>(StringRef Identifier)>;
+
+ /// Create a Function Importer.
+ FunctionImporter(const ModuleSummaryIndex &Index, ModuleLoaderTy ModuleLoader)
+ : Index(Index), ModuleLoader(std::move(ModuleLoader)) {}
+
+ /// Import functions in Module \p M based on the supplied import list.
+ Expected<bool> importFunctions(Module &M, const ImportMapTy &ImportList);
+
+private:
+ /// The summaries index used to trigger importing.
+ const ModuleSummaryIndex &Index;
+
+ /// Factory function to load a Module for a given identifier
+ ModuleLoaderTy ModuleLoader;
+};
+
+/// The function importing pass
+class FunctionImportPass : public PassInfoMixin<FunctionImportPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+/// Compute all the imports and exports for every module in the Index.
+///
+/// \p ModuleToDefinedGVSummaries contains for each Module a map
+/// (GUID -> Summary) for every global defined in the module.
+///
+/// \p ImportLists will be populated with an entry for every Module we are
+/// importing into. This entry is itself a map that can be passed to
+/// FunctionImporter::importFunctions() above (see description there).
+///
+/// \p ExportLists contains for each Module the set of globals (GUID) that will
+/// be imported by another module, or referenced by such a function. I.e. this
+/// is the set of globals that need to be promoted/renamed appropriately.
+void ComputeCrossModuleImport(
+ const ModuleSummaryIndex &Index,
+ const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
+ StringMap<FunctionImporter::ImportMapTy> &ImportLists,
+ StringMap<FunctionImporter::ExportSetTy> &ExportLists);
+
+/// Compute all the imports for the given module using the Index.
+///
+/// \p ImportList will be populated with a map that can be passed to
+/// FunctionImporter::importFunctions() above (see description there).
+void ComputeCrossModuleImportForModule(
+ StringRef ModulePath, const ModuleSummaryIndex &Index,
+ FunctionImporter::ImportMapTy &ImportList);
+
+/// Mark all external summaries in \p Index for import into the given module.
+/// Used for distributed builds using a distributed index.
+///
+/// \p ImportList will be populated with a map that can be passed to
+/// FunctionImporter::importFunctions() above (see description there).
+void ComputeCrossModuleImportForModuleFromIndex(
+ StringRef ModulePath, const ModuleSummaryIndex &Index,
+ FunctionImporter::ImportMapTy &ImportList);
+
+/// PrevailingType enum used as a return type of callback passed
+/// to computeDeadSymbols. Yes and No values used when status explicitly
+/// set by symbols resolution, otherwise status is Unknown.
+enum class PrevailingType { Yes, No, Unknown };
+
+/// Compute all the symbols that are "dead": i.e these that can't be reached
+/// in the graph from any of the given symbols listed in
+/// \p GUIDPreservedSymbols. Non-prevailing symbols are symbols without a
+/// prevailing copy anywhere in IR and are normally dead, \p isPrevailing
+/// predicate returns status of symbol.
+void computeDeadSymbols(
+ ModuleSummaryIndex &Index,
+ const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
+ function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing);
+
+/// Compute dead symbols and run constant propagation in combined index
+/// after that.
+void computeDeadSymbolsWithConstProp(
+ ModuleSummaryIndex &Index,
+ const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
+ function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,
+ bool ImportEnabled);
+
+/// Converts value \p GV to declaration, or replaces with a declaration if
+/// it is an alias. Returns true if converted, false if replaced.
+bool convertToDeclaration(GlobalValue &GV);
+
+/// Compute the set of summaries needed for a ThinLTO backend compilation of
+/// \p ModulePath.
+//
+/// This includes summaries from that module (in case any global summary based
+/// optimizations were recorded) and from any definitions in other modules that
+/// should be imported.
+//
+/// \p ModuleToSummariesForIndex will be populated with the needed summaries
+/// from each required module path. Use a std::map instead of StringMap to get
+/// stable order for bitcode emission.
+void gatherImportedSummariesForModule(
+ StringRef ModulePath,
+ const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
+ const FunctionImporter::ImportMapTy &ImportList,
+ std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
+
+/// Emit into \p OutputFilename the files module \p ModulePath will import from.
+std::error_code EmitImportsFiles(
+ StringRef ModulePath, StringRef OutputFilename,
+ const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
+
+/// Resolve prevailing symbol linkages in \p TheModule based on the information
+/// recorded in the summaries during global summary-based analysis.
+void thinLTOResolvePrevailingInModule(Module &TheModule,
+ const GVSummaryMapTy &DefinedGlobals);
+
+/// Internalize \p TheModule based on the information recorded in the summaries
+/// during global summary-based analysis.
+void thinLTOInternalizeModule(Module &TheModule,
+ const GVSummaryMapTy &DefinedGlobals);
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/GlobalDCE.h b/clang-r353983/include/llvm/Transforms/IPO/GlobalDCE.h
new file mode 100644
index 00000000..c434484d
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/GlobalDCE.h
@@ -0,0 +1,56 @@
+//===-- GlobalDCE.h - DCE unreachable internal functions ------------------===//
+//
+// 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 transform is designed to eliminate unreachable internal globals from the
+// program. It uses an aggressive algorithm, searching out globals that are
+// known to be alive. After it finds all of the globals which are needed, it
+// deletes whatever is left over. This allows it to delete recursive chunks of
+// the program which are unreachable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_GLOBALDCE_H
+#define LLVM_TRANSFORMS_IPO_GLOBALDCE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include <unordered_map>
+
+namespace llvm {
+
+/// Pass to remove unused function declarations.
+class GlobalDCEPass : public PassInfoMixin<GlobalDCEPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+
+private:
+ SmallPtrSet<GlobalValue*, 32> AliveGlobals;
+
+ /// Global -> Global that uses this global.
+ DenseMap<GlobalValue *, SmallPtrSet<GlobalValue *, 4>> GVDependencies;
+
+ /// Constant -> Globals that use this global cache.
+ std::unordered_map<Constant *, SmallPtrSet<GlobalValue *, 8>>
+ ConstantDependenciesCache;
+
+ /// Comdat -> Globals in that Comdat section.
+ std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
+
+ void UpdateGVDependencies(GlobalValue &GV);
+ void MarkLive(GlobalValue &GV,
+ SmallVectorImpl<GlobalValue *> *Updates = nullptr);
+ bool RemoveUnusedGlobalValue(GlobalValue &GV);
+
+ void ComputeDependencies(Value *V, SmallPtrSetImpl<GlobalValue *> &U);
+};
+
+}
+
+#endif // LLVM_TRANSFORMS_IPO_GLOBALDCE_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/GlobalOpt.h b/clang-r353983/include/llvm/Transforms/IPO/GlobalOpt.h
new file mode 100644
index 00000000..48a861ff
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/GlobalOpt.h
@@ -0,0 +1,32 @@
+//===- GlobalOpt.h - Optimize Global Variables ------------------*- C++ -*-===//
+//
+// 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 pass transforms simple global variables that never have their address
+// taken. If obviously true, it marks read/write globals as constant, deletes
+// variables only stored to, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_GLOBALOPT_H
+#define LLVM_TRANSFORMS_IPO_GLOBALOPT_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// Optimize globals that never have their address taken.
+class GlobalOptPass : public PassInfoMixin<GlobalOptPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_GLOBALOPT_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/GlobalSplit.h b/clang-r353983/include/llvm/Transforms/IPO/GlobalSplit.h
new file mode 100644
index 00000000..690b23a2
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/GlobalSplit.h
@@ -0,0 +1,33 @@
+//===- GlobalSplit.h - global variable splitter -----------------*- C++ -*-===//
+//
+// 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 pass uses inrange annotations on GEP indices to split globals where
+// beneficial. Clang currently attaches these annotations to references to
+// virtual table globals under the Itanium ABI for the benefit of the
+// whole-program virtual call optimization and control flow integrity passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_GLOBALSPLIT_H
+#define LLVM_TRANSFORMS_IPO_GLOBALSPLIT_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// Pass to perform split of global variables.
+class GlobalSplitPass : public PassInfoMixin<GlobalSplitPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_GLOBALSPLIT_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/HotColdSplitting.h b/clang-r353983/include/llvm/Transforms/IPO/HotColdSplitting.h
new file mode 100644
index 00000000..73668844
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/HotColdSplitting.h
@@ -0,0 +1,30 @@
+//===- HotColdSplitting.h ---- Outline Cold Regions -------------*- C++ -*-===//
+//
+// 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 pass outlines cold regions to a separate function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H
+#define LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// Pass to outline cold regions.
+class HotColdSplittingPass : public PassInfoMixin<HotColdSplittingPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H
+
diff --git a/clang-r353983/include/llvm/Transforms/IPO/InferFunctionAttrs.h b/clang-r353983/include/llvm/Transforms/IPO/InferFunctionAttrs.h
new file mode 100644
index 00000000..bb7907fb
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/InferFunctionAttrs.h
@@ -0,0 +1,35 @@
+//===-- InferFunctionAttrs.h - Infer implicit function attributes ---------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Interfaces for passes which infer implicit function attributes from the
+/// name and signature of function declarations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_INFERFUNCTIONATTRS_H
+#define LLVM_TRANSFORMS_IPO_INFERFUNCTIONATTRS_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// A pass which infers function attributes from the names and signatures of
+/// function declarations in a module.
+struct InferFunctionAttrsPass : PassInfoMixin<InferFunctionAttrsPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+/// Create a legacy pass manager instance of a pass to infer function
+/// attributes.
+Pass *createInferFunctionAttrsLegacyPass();
+
+}
+
+#endif // LLVM_TRANSFORMS_IPO_INFERFUNCTIONATTRS_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/Inliner.h b/clang-r353983/include/llvm/Transforms/IPO/Inliner.h
new file mode 100644
index 00000000..8202b94d
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/Inliner.h
@@ -0,0 +1,113 @@
+//===- Inliner.h - Inliner pass and infrastructure --------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_INLINER_H
+#define LLVM_TRANSFORMS_IPO_INLINER_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/Analysis/InlineCost.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h"
+#include <utility>
+
+namespace llvm {
+
+class AssumptionCacheTracker;
+class CallGraph;
+class ProfileSummaryInfo;
+
+/// This class contains all of the helper code which is used to perform the
+/// inlining operations that do not depend on the policy. It contains the core
+/// bottom-up inlining infrastructure that specific inliner passes use.
+struct LegacyInlinerBase : public CallGraphSCCPass {
+ explicit LegacyInlinerBase(char &ID);
+ explicit LegacyInlinerBase(char &ID, bool InsertLifetime);
+
+ /// For this class, we declare that we require and preserve the call graph.
+ /// If the derived class implements this method, it should always explicitly
+ /// call the implementation here.
+ void getAnalysisUsage(AnalysisUsage &Info) const override;
+
+ bool doInitialization(CallGraph &CG) override;
+
+ /// Main run interface method, this implements the interface required by the
+ /// Pass class.
+ bool runOnSCC(CallGraphSCC &SCC) override;
+
+ using llvm::Pass::doFinalization;
+
+ /// Remove now-dead linkonce functions at the end of processing to avoid
+ /// breaking the SCC traversal.
+ bool doFinalization(CallGraph &CG) override;
+
+ /// This method must be implemented by the subclass to determine the cost of
+ /// inlining the specified call site. If the cost returned is greater than
+ /// the current inline threshold, the call site is not inlined.
+ virtual InlineCost getInlineCost(CallSite CS) = 0;
+
+ /// Remove dead functions.
+ ///
+ /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
+ /// which restricts it to deleting functions with an 'AlwaysInline'
+ /// attribute. This is useful for the InlineAlways pass that only wants to
+ /// deal with that subset of the functions.
+ bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false);
+
+ /// This function performs the main work of the pass. The default of
+ /// Inlinter::runOnSCC() calls skipSCC() before calling this method, but
+ /// derived classes which cannot be skipped can override that method and call
+ /// this function unconditionally.
+ bool inlineCalls(CallGraphSCC &SCC);
+
+private:
+ // Insert @llvm.lifetime intrinsics.
+ bool InsertLifetime = true;
+
+protected:
+ AssumptionCacheTracker *ACT;
+ ProfileSummaryInfo *PSI;
+ ImportedFunctionsInliningStatistics ImportedFunctionsStats;
+};
+
+/// The inliner pass for the new pass manager.
+///
+/// This pass wires together the inlining utilities and the inline cost
+/// analysis into a CGSCC pass. It considers every call in every function in
+/// the SCC and tries to inline if profitable. It can be tuned with a number of
+/// parameters to control what cost model is used and what tradeoffs are made
+/// when making the decision.
+///
+/// It should be noted that the legacy inliners do considerably more than this
+/// inliner pass does. They provide logic for manually merging allocas, and
+/// doing considerable DCE including the DCE of dead functions. This pass makes
+/// every attempt to be simpler. DCE of functions requires complex reasoning
+/// about comdat groups, etc. Instead, it is expected that other more focused
+/// passes be composed to achieve the same end result.
+class InlinerPass : public PassInfoMixin<InlinerPass> {
+public:
+ InlinerPass(InlineParams Params = getInlineParams())
+ : Params(std::move(Params)) {}
+ ~InlinerPass();
+ InlinerPass(InlinerPass &&Arg)
+ : Params(std::move(Arg.Params)),
+ ImportedFunctionsStats(std::move(Arg.ImportedFunctionsStats)) {}
+
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
+
+private:
+ InlineParams Params;
+ std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_INLINER_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/Internalize.h b/clang-r353983/include/llvm/Transforms/IPO/Internalize.h
new file mode 100644
index 00000000..a7efd3e1
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/Internalize.h
@@ -0,0 +1,78 @@
+//====- Internalize.h - Internalization API ---------------------*- C++ -*-===//
+//
+// 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 pass loops over all of the functions and variables in the input module.
+// If the function or variable does not need to be preserved according to the
+// client supplied callback, it is marked as internal.
+//
+// This transformation would not be legal in a regular compilation, but it gets
+// extra information from the linker about what is safe.
+//
+// For example: Internalizing a function with external linkage. Only if we are
+// told it is only used from within this module, it is safe to do it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_INTERNALIZE_H
+#define LLVM_TRANSFORMS_IPO_INTERNALIZE_H
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/PassManager.h"
+#include <functional>
+#include <set>
+
+namespace llvm {
+class Module;
+class CallGraph;
+
+/// A pass that internalizes all functions and variables other than those that
+/// must be preserved according to \c MustPreserveGV.
+class InternalizePass : public PassInfoMixin<InternalizePass> {
+ /// Client supplied callback to control wheter a symbol must be preserved.
+ const std::function<bool(const GlobalValue &)> MustPreserveGV;
+ /// Set of symbols private to the compiler that this pass should not touch.
+ StringSet<> AlwaysPreserved;
+
+ /// Return false if we're allowed to internalize this GV.
+ bool shouldPreserveGV(const GlobalValue &GV);
+ /// Internalize GV if it is possible to do so, i.e. it is not externally
+ /// visible and is not a member of an externally visible comdat.
+ bool maybeInternalize(GlobalValue &GV,
+ const std::set<const Comdat *> &ExternalComdats);
+ /// If GV is part of a comdat and is externally visible, keep track of its
+ /// comdat so that we don't internalize any of its members.
+ void checkComdatVisibility(GlobalValue &GV,
+ std::set<const Comdat *> &ExternalComdats);
+
+public:
+ InternalizePass();
+ InternalizePass(std::function<bool(const GlobalValue &)> MustPreserveGV)
+ : MustPreserveGV(std::move(MustPreserveGV)) {}
+
+ /// Run the internalizer on \p TheModule, returns true if any changes was
+ /// made.
+ ///
+ /// If the CallGraph \p CG is supplied, it will be updated when
+ /// internalizing a function (by removing any edge from the "external node")
+ bool internalizeModule(Module &TheModule, CallGraph *CG = nullptr);
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+/// Helper function to internalize functions and variables in a Module.
+inline bool
+internalizeModule(Module &TheModule,
+ std::function<bool(const GlobalValue &)> MustPreserveGV,
+ CallGraph *CG = nullptr) {
+ return InternalizePass(std::move(MustPreserveGV))
+ .internalizeModule(TheModule, CG);
+}
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_INTERNALIZE_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/LowerTypeTests.h b/clang-r353983/include/llvm/Transforms/IPO/LowerTypeTests.h
new file mode 100644
index 00000000..39b23f59
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/LowerTypeTests.h
@@ -0,0 +1,210 @@
+//===- LowerTypeTests.h - type metadata lowering pass -----------*- C++ -*-===//
+//
+// 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 defines parts of the type test lowering pass implementation that
+// may be usefully unit tested.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H
+#define LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/PassManager.h"
+#include <cstdint>
+#include <cstring>
+#include <limits>
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+class Module;
+class ModuleSummaryIndex;
+class raw_ostream;
+
+namespace lowertypetests {
+
+struct BitSetInfo {
+ // The indices of the set bits in the bitset.
+ std::set<uint64_t> Bits;
+
+ // The byte offset into the combined global represented by the bitset.
+ uint64_t ByteOffset;
+
+ // The size of the bitset in bits.
+ uint64_t BitSize;
+
+ // Log2 alignment of the bit set relative to the combined global.
+ // For example, a log2 alignment of 3 means that bits in the bitset
+ // represent addresses 8 bytes apart.
+ unsigned AlignLog2;
+
+ bool isSingleOffset() const {
+ return Bits.size() == 1;
+ }
+
+ bool isAllOnes() const {
+ return Bits.size() == BitSize;
+ }
+
+ bool containsGlobalOffset(uint64_t Offset) const;
+
+ void print(raw_ostream &OS) const;
+};
+
+struct BitSetBuilder {
+ SmallVector<uint64_t, 16> Offsets;
+ uint64_t Min = std::numeric_limits<uint64_t>::max();
+ uint64_t Max = 0;
+
+ BitSetBuilder() = default;
+
+ void addOffset(uint64_t Offset) {
+ if (Min > Offset)
+ Min = Offset;
+ if (Max < Offset)
+ Max = Offset;
+
+ Offsets.push_back(Offset);
+ }
+
+ BitSetInfo build();
+};
+
+/// This class implements a layout algorithm for globals referenced by bit sets
+/// that tries to keep members of small bit sets together. This can
+/// significantly reduce bit set sizes in many cases.
+///
+/// It works by assembling fragments of layout from sets of referenced globals.
+/// Each set of referenced globals causes the algorithm to create a new
+/// fragment, which is assembled by appending each referenced global in the set
+/// into the fragment. If a referenced global has already been referenced by an
+/// fragment created earlier, we instead delete that fragment and append its
+/// contents into the fragment we are assembling.
+///
+/// By starting with the smallest fragments, we minimize the size of the
+/// fragments that are copied into larger fragments. This is most intuitively
+/// thought about when considering the case where the globals are virtual tables
+/// and the bit sets represent their derived classes: in a single inheritance
+/// hierarchy, the optimum layout would involve a depth-first search of the
+/// class hierarchy (and in fact the computed layout ends up looking a lot like
+/// a DFS), but a naive DFS would not work well in the presence of multiple
+/// inheritance. This aspect of the algorithm ends up fitting smaller
+/// hierarchies inside larger ones where that would be beneficial.
+///
+/// For example, consider this class hierarchy:
+///
+/// A B
+/// \ / | \
+/// C D E
+///
+/// We have five bit sets: bsA (A, C), bsB (B, C, D, E), bsC (C), bsD (D) and
+/// bsE (E). If we laid out our objects by DFS traversing B followed by A, our
+/// layout would be {B, C, D, E, A}. This is optimal for bsB as it needs to
+/// cover the only 4 objects in its hierarchy, but not for bsA as it needs to
+/// cover 5 objects, i.e. the entire layout. Our algorithm proceeds as follows:
+///
+/// Add bsC, fragments {{C}}
+/// Add bsD, fragments {{C}, {D}}
+/// Add bsE, fragments {{C}, {D}, {E}}
+/// Add bsA, fragments {{A, C}, {D}, {E}}
+/// Add bsB, fragments {{B, A, C, D, E}}
+///
+/// This layout is optimal for bsA, as it now only needs to cover two (i.e. 3
+/// fewer) objects, at the cost of bsB needing to cover 1 more object.
+///
+/// The bit set lowering pass assigns an object index to each object that needs
+/// to be laid out, and calls addFragment for each bit set passing the object
+/// indices of its referenced globals. It then assembles a layout from the
+/// computed layout in the Fragments field.
+struct GlobalLayoutBuilder {
+ /// The computed layout. Each element of this vector contains a fragment of
+ /// layout (which may be empty) consisting of object indices.
+ std::vector<std::vector<uint64_t>> Fragments;
+
+ /// Mapping from object index to fragment index.
+ std::vector<uint64_t> FragmentMap;
+
+ GlobalLayoutBuilder(uint64_t NumObjects)
+ : Fragments(1), FragmentMap(NumObjects) {}
+
+ /// Add F to the layout while trying to keep its indices contiguous.
+ /// If a previously seen fragment uses any of F's indices, that
+ /// fragment will be laid out inside F.
+ void addFragment(const std::set<uint64_t> &F);
+};
+
+/// This class is used to build a byte array containing overlapping bit sets. By
+/// loading from indexed offsets into the byte array and applying a mask, a
+/// program can test bits from the bit set with a relatively short instruction
+/// sequence. For example, suppose we have 15 bit sets to lay out:
+///
+/// A (16 bits), B (15 bits), C (14 bits), D (13 bits), E (12 bits),
+/// F (11 bits), G (10 bits), H (9 bits), I (7 bits), J (6 bits), K (5 bits),
+/// L (4 bits), M (3 bits), N (2 bits), O (1 bit)
+///
+/// These bits can be laid out in a 16-byte array like this:
+///
+/// Byte Offset
+/// 0123456789ABCDEF
+/// Bit
+/// 7 HHHHHHHHHIIIIIII
+/// 6 GGGGGGGGGGJJJJJJ
+/// 5 FFFFFFFFFFFKKKKK
+/// 4 EEEEEEEEEEEELLLL
+/// 3 DDDDDDDDDDDDDMMM
+/// 2 CCCCCCCCCCCCCCNN
+/// 1 BBBBBBBBBBBBBBBO
+/// 0 AAAAAAAAAAAAAAAA
+///
+/// For example, to test bit X of A, we evaluate ((bits[X] & 1) != 0), or to
+/// test bit X of I, we evaluate ((bits[9 + X] & 0x80) != 0). This can be done
+/// in 1-2 machine instructions on x86, or 4-6 instructions on ARM.
+///
+/// This is a byte array, rather than (say) a 2-byte array or a 4-byte array,
+/// because for one thing it gives us better packing (the more bins there are,
+/// the less evenly they will be filled), and for another, the instruction
+/// sequences can be slightly shorter, both on x86 and ARM.
+struct ByteArrayBuilder {
+ /// The byte array built so far.
+ std::vector<uint8_t> Bytes;
+
+ enum { BitsPerByte = 8 };
+
+ /// The number of bytes allocated so far for each of the bits.
+ uint64_t BitAllocs[BitsPerByte];
+
+ ByteArrayBuilder() {
+ memset(BitAllocs, 0, sizeof(BitAllocs));
+ }
+
+ /// Allocate BitSize bits in the byte array where Bits contains the bits to
+ /// set. AllocByteOffset is set to the offset within the byte array and
+ /// AllocMask is set to the bitmask for those bits. This uses the LPT (Longest
+ /// Processing Time) multiprocessor scheduling algorithm to lay out the bits
+ /// efficiently; the pass allocates bit sets in decreasing size order.
+ void allocate(const std::set<uint64_t> &Bits, uint64_t BitSize,
+ uint64_t &AllocByteOffset, uint8_t &AllocMask);
+};
+
+} // end namespace lowertypetests
+
+class LowerTypeTestsPass : public PassInfoMixin<LowerTypeTestsPass> {
+public:
+ ModuleSummaryIndex *ExportSummary;
+ const ModuleSummaryIndex *ImportSummary;
+ LowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
+ const ModuleSummaryIndex *ImportSummary)
+ : ExportSummary(ExportSummary), ImportSummary(ImportSummary) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/PartialInlining.h b/clang-r353983/include/llvm/Transforms/IPO/PartialInlining.h
new file mode 100644
index 00000000..3b8297d6
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/PartialInlining.h
@@ -0,0 +1,31 @@
+//===- PartialInlining.h - Inline parts of functions ------------*- C++ -*-===//
+//
+// 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 pass performs partial inlining, typically by inlining an if statement
+// that surrounds the body of the function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_PARTIALINLINING_H
+#define LLVM_TRANSFORMS_IPO_PARTIALINLINING_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// Pass to remove unused function declarations.
+class PartialInlinerPass : public PassInfoMixin<PartialInlinerPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_PARTIALINLINING_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/PassManagerBuilder.h b/clang-r353983/include/llvm/Transforms/IPO/PassManagerBuilder.h
new file mode 100644
index 00000000..f82cfdc0
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -0,0 +1,216 @@
+// llvm/Transforms/IPO/PassManagerBuilder.h - Build Standard Pass -*- C++ -*-=//
+//
+// 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 defines the PassManagerBuilder class, which is used to set up a
+// "standard" optimization sequence suitable for languages like C and C++.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
+#define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+class ModuleSummaryIndex;
+class Pass;
+class TargetLibraryInfoImpl;
+class TargetMachine;
+
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class FunctionPassManager;
+class PassManagerBase;
+}
+
+/// PassManagerBuilder - This class is used to set up a standard optimization
+/// sequence for languages like C and C++, allowing some APIs to customize the
+/// pass sequence in various ways. A simple example of using it would be:
+///
+/// PassManagerBuilder Builder;
+/// Builder.OptLevel = 2;
+/// Builder.populateFunctionPassManager(FPM);
+/// Builder.populateModulePassManager(MPM);
+///
+/// In addition to setting up the basic passes, PassManagerBuilder allows
+/// frontends to vend a plugin API, where plugins are allowed to add extensions
+/// to the default pass manager. They do this by specifying where in the pass
+/// pipeline they want to be added, along with a callback function that adds
+/// the pass(es). For example, a plugin that wanted to add a loop optimization
+/// could do something like this:
+///
+/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) {
+/// if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0)
+/// PM.add(createMyAwesomePass());
+/// }
+/// ...
+/// Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd,
+/// addMyLoopPass);
+/// ...
+class PassManagerBuilder {
+public:
+ /// Extensions are passed the builder itself (so they can see how it is
+ /// configured) as well as the pass manager to add stuff to.
+ typedef std::function<void(const PassManagerBuilder &Builder,
+ legacy::PassManagerBase &PM)>
+ ExtensionFn;
+ enum ExtensionPointTy {
+ /// EP_EarlyAsPossible - This extension point allows adding passes before
+ /// any other transformations, allowing them to see the code as it is coming
+ /// out of the frontend.
+ EP_EarlyAsPossible,
+
+ /// EP_ModuleOptimizerEarly - This extension point allows adding passes
+ /// just before the main module-level optimization passes.
+ EP_ModuleOptimizerEarly,
+
+ /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
+ /// the end of the loop optimizer.
+ EP_LoopOptimizerEnd,
+
+ /// EP_ScalarOptimizerLate - This extension point allows adding optimization
+ /// passes after most of the main optimizations, but before the last
+ /// cleanup-ish optimizations.
+ EP_ScalarOptimizerLate,
+
+ /// EP_OptimizerLast -- This extension point allows adding passes that
+ /// run after everything else.
+ EP_OptimizerLast,
+
+ /// EP_VectorizerStart - This extension point allows adding optimization
+ /// passes before the vectorizer and other highly target specific
+ /// optimization passes are executed.
+ EP_VectorizerStart,
+
+ /// EP_EnabledOnOptLevel0 - This extension point allows adding passes that
+ /// should not be disabled by O0 optimization level. The passes will be
+ /// inserted after the inlining pass.
+ EP_EnabledOnOptLevel0,
+
+ /// EP_Peephole - This extension point allows adding passes that perform
+ /// peephole optimizations similar to the instruction combiner. These passes
+ /// will be inserted after each instance of the instruction combiner pass.
+ EP_Peephole,
+
+ /// EP_LateLoopOptimizations - This extension point allows adding late loop
+ /// canonicalization and simplification passes. This is the last point in
+ /// the loop optimization pipeline before loop deletion. Each pass added
+ /// here must be an instance of LoopPass.
+ /// This is the place to add passes that can remove loops, such as target-
+ /// specific loop idiom recognition.
+ EP_LateLoopOptimizations,
+
+ /// EP_CGSCCOptimizerLate - This extension point allows adding CallGraphSCC
+ /// passes at the end of the main CallGraphSCC passes and before any
+ /// function simplification passes run by CGPassManager.
+ EP_CGSCCOptimizerLate,
+ };
+
+ /// The Optimization Level - Specify the basic optimization level.
+ /// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
+ unsigned OptLevel;
+
+ /// SizeLevel - How much we're optimizing for size.
+ /// 0 = none, 1 = -Os, 2 = -Oz
+ unsigned SizeLevel;
+
+ /// LibraryInfo - Specifies information about the runtime library for the
+ /// optimizer. If this is non-null, it is added to both the function and
+ /// per-module pass pipeline.
+ TargetLibraryInfoImpl *LibraryInfo;
+
+ /// Inliner - Specifies the inliner to use. If this is non-null, it is
+ /// added to the per-module passes.
+ Pass *Inliner;
+
+ /// The module summary index to use for exporting information from the
+ /// regular LTO phase, for example for the CFI and devirtualization type
+ /// tests.
+ ModuleSummaryIndex *ExportSummary = nullptr;
+
+ /// The module summary index to use for importing information to the
+ /// thin LTO backends, for example for the CFI and devirtualization type
+ /// tests.
+ const ModuleSummaryIndex *ImportSummary = nullptr;
+
+ bool DisableTailCalls;
+ bool DisableUnitAtATime;
+ bool DisableUnrollLoops;
+ bool SLPVectorize;
+ bool LoopVectorize;
+ bool RerollLoops;
+ bool NewGVN;
+ bool DisableGVNLoadPRE;
+ bool VerifyInput;
+ bool VerifyOutput;
+ bool MergeFunctions;
+ bool PrepareForLTO;
+ bool PrepareForThinLTO;
+ bool PerformThinLTO;
+ bool DivergentTarget;
+
+ /// Enable profile instrumentation pass.
+ bool EnablePGOInstrGen;
+ /// Profile data file name that the instrumentation will be written to.
+ std::string PGOInstrGen;
+ /// Path of the profile data file.
+ std::string PGOInstrUse;
+ /// Path of the sample Profile data file.
+ std::string PGOSampleUse;
+
+private:
+ /// ExtensionList - This is list of all of the extensions that are registered.
+ std::vector<std::pair<ExtensionPointTy, ExtensionFn>> Extensions;
+
+public:
+ PassManagerBuilder();
+ ~PassManagerBuilder();
+ /// Adds an extension that will be used by all PassManagerBuilder instances.
+ /// This is intended to be used by plugins, to register a set of
+ /// optimisations to run automatically.
+ static void addGlobalExtension(ExtensionPointTy Ty, ExtensionFn Fn);
+ void addExtension(ExtensionPointTy Ty, ExtensionFn Fn);
+
+private:
+ void addExtensionsToPM(ExtensionPointTy ETy,
+ legacy::PassManagerBase &PM) const;
+ void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const;
+ void addLTOOptimizationPasses(legacy::PassManagerBase &PM);
+ void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
+ void addPGOInstrPasses(legacy::PassManagerBase &MPM);
+ void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM);
+ void addInstructionCombiningPass(legacy::PassManagerBase &MPM) const;
+
+public:
+ /// populateFunctionPassManager - This fills in the function pass manager,
+ /// which is expected to be run on each function immediately as it is
+ /// generated. The idea is to reduce the size of the IR in memory.
+ void populateFunctionPassManager(legacy::FunctionPassManager &FPM);
+
+ /// populateModulePassManager - This sets up the primary pass manager.
+ void populateModulePassManager(legacy::PassManagerBase &MPM);
+ void populateLTOPassManager(legacy::PassManagerBase &PM);
+ void populateThinLTOPassManager(legacy::PassManagerBase &PM);
+};
+
+/// Registers a function for adding a standard set of passes. This should be
+/// used by optimizer plugins to allow all front ends to transparently use
+/// them. Create a static instance of this class in your plugin, providing a
+/// private function that the PassManagerBuilder can use to add your passes.
+struct RegisterStandardPasses {
+ RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty,
+ PassManagerBuilder::ExtensionFn Fn) {
+ PassManagerBuilder::addGlobalExtension(Ty, std::move(Fn));
+ }
+};
+
+} // end namespace llvm
+#endif
diff --git a/clang-r353983/include/llvm/Transforms/IPO/SCCP.h b/clang-r353983/include/llvm/Transforms/IPO/SCCP.h
new file mode 100644
index 00000000..3c40d44c
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/SCCP.h
@@ -0,0 +1,37 @@
+//===- SCCP.h - Sparse Conditional Constant Propagation ---------*- C++ -*-===//
+//
+// 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 pass implements interprocedural sparse conditional constant
+// propagation and merging.
+//
+// Specifically, this:
+// * Assumes values are constant unless proven otherwise
+// * Assumes BasicBlocks are dead unless proven otherwise
+// * Proves values to be constant, and replaces them with constants
+// * Proves conditional branches to be unconditional
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_SCCP_H
+#define LLVM_TRANSFORMS_IPO_SCCP_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// Pass to perform interprocedural constant propagation.
+class IPSCCPPass : public PassInfoMixin<IPSCCPPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_SCCP_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/SampleProfile.h b/clang-r353983/include/llvm/Transforms/IPO/SampleProfile.h
new file mode 100644
index 00000000..a5ad4455
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/SampleProfile.h
@@ -0,0 +1,42 @@
+//===- SampleProfile.h - SamplePGO pass ---------- --------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file provides the interface for the sampled PGO loader pass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_SAMPLEPROFILE_H
+#define LLVM_TRANSFORMS_IPO_SAMPLEPROFILE_H
+
+#include "llvm/IR/PassManager.h"
+#include <string>
+
+namespace llvm {
+
+class Module;
+
+/// The sample profiler data loader pass.
+class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> {
+public:
+ SampleProfileLoaderPass(std::string File = "", std::string RemappingFile = "",
+ bool IsThinLTOPreLink = false)
+ : ProfileFileName(File), ProfileRemappingFileName(RemappingFile),
+ IsThinLTOPreLink(IsThinLTOPreLink) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+
+private:
+ std::string ProfileFileName;
+ std::string ProfileRemappingFileName;
+ bool IsThinLTOPreLink;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SAMPLEPROFILE_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/StripDeadPrototypes.h b/clang-r353983/include/llvm/Transforms/IPO/StripDeadPrototypes.h
new file mode 100644
index 00000000..f4a15c36
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/StripDeadPrototypes.h
@@ -0,0 +1,31 @@
+//===-- StripDeadPrototypes.h - Remove unused function declarations -------===//
+//
+// 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 pass loops over all of the functions in the input module, looking for
+// dead declarations and removes them. Dead declarations are declarations of
+// functions for which no implementation is available (i.e., declarations for
+// unused library functions).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_STRIPDEADPROTOTYPES_H
+#define LLVM_TRANSFORMS_IPO_STRIPDEADPROTOTYPES_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Pass to remove unused function declarations.
+struct StripDeadPrototypesPass : PassInfoMixin<StripDeadPrototypesPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+}
+
+#endif // LLVM_TRANSFORMS_IPO_STRIPDEADPROTOTYPES_H
diff --git a/clang-r353983/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h b/clang-r353983/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h
new file mode 100644
index 00000000..0b3ba86b
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h
@@ -0,0 +1,19 @@
+#ifndef LLVM_TRANSFORMS_IPO_SYNTHETIC_COUNTS_PROPAGATION_H
+#define LLVM_TRANSFORMS_IPO_SYNTHETIC_COUNTS_PROPAGATION_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/ScaledNumber.h"
+
+namespace llvm {
+class Function;
+class Module;
+
+class SyntheticCountsPropagation
+ : public PassInfoMixin<SyntheticCountsPropagation> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+};
+} // namespace llvm
+#endif
diff --git a/clang-r353983/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h b/clang-r353983/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
new file mode 100644
index 00000000..7acb922b
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -0,0 +1,40 @@
+//===- ThinLTOBitcodeWriter.h - Bitcode writing pass for ThinLTO ----------===//
+//
+// 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 pass prepares a module containing type metadata for ThinLTO by splitting
+// it into regular and thin LTO parts if possible, and writing both parts to
+// a multi-module bitcode file. Modules that do not contain type metadata are
+// written unmodified as a single module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+#define LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+
+#include <llvm/IR/PassManager.h>
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+
+class ThinLTOBitcodeWriterPass
+ : public PassInfoMixin<ThinLTOBitcodeWriterPass> {
+ raw_ostream &OS;
+ raw_ostream *ThinLinkOS;
+
+public:
+ // Writes bitcode to OS. Also write thin link file to ThinLinkOS, if
+ // it's not nullptr.
+ ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS)
+ : OS(OS), ThinLinkOS(ThinLinkOS) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/Transforms/IPO/WholeProgramDevirt.h b/clang-r353983/include/llvm/Transforms/IPO/WholeProgramDevirt.h
new file mode 100644
index 00000000..509fcc86
--- /dev/null
+++ b/clang-r353983/include/llvm/Transforms/IPO/WholeProgramDevirt.h
@@ -0,0 +1,233 @@
+//===- WholeProgramDevirt.h - Whole-program devirt pass ---------*- C++ -*-===//
+//
+// 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 defines parts of the whole-program devirtualization pass
+// implementation that may be usefully unit tested.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_WHOLEPROGRAMDEVIRT_H
+#define LLVM_TRANSFORMS_IPO_WHOLEPROGRAMDEVIRT_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+template <typename T> class ArrayRef;
+template <typename T> class MutableArrayRef;
+class Function;
+class GlobalVariable;
+class ModuleSummaryIndex;
+
+namespace wholeprogramdevirt {
+
+// A bit vector that keeps track of which bits are used. We use this to
+// pack constant values compactly before and after each virtual table.
+struct AccumBitVector {
+ std::vector<uint8_t> Bytes;
+
+ // Bits in BytesUsed[I] are 1 if matching bit in Bytes[I] is used, 0 if not.
+ std::vector<uint8_t> BytesUsed;
+
+ std::pair<uint8_t *, uint8_t *> getPtrToData(uint64_t Pos, uint8_t Size) {
+ if (Bytes.size() < Pos + Size) {
+ Bytes.resize(Pos + Size);
+ BytesUsed.resize(Pos + Size);
+ }
+ return std::make_pair(Bytes.data() + Pos, BytesUsed.data() + Pos);
+ }
+
+ // Set little-endian value Val with size Size at bit position Pos,
+ // and mark bytes as used.
+ void setLE(uint64_t Pos, uint64_t Val, uint8_t Size) {
+ assert(Pos % 8 == 0);
+ auto DataUsed = getPtrToData(Pos / 8, Size);
+ for (unsigned I = 0; I != Size; ++I) {
+ DataUsed.first[I] = Val >> (I * 8);
+ assert(!DataUsed.second[I]);
+ DataUsed.second[I] = 0xff;
+ }
+ }
+
+ // Set big-endian value Val with size Size at bit position Pos,
+ // and mark bytes as used.
+ void setBE(uint64_t Pos, uint64_t Val, uint8_t Size) {
+ assert(Pos % 8 == 0);
+ auto DataUsed = getPtrToData(Pos / 8, Size);
+ for (unsigned I = 0; I != Size; ++I) {
+ DataUsed.first[Size - I - 1] = Val >> (I * 8);
+ assert(!DataUsed.second[Size - I - 1]);
+ DataUsed.second[Size - I - 1] = 0xff;
+ }
+ }
+
+ // Set bit at bit position Pos to b and mark bit as used.
+ void setBit(uint64_t Pos, bool b) {
+ auto DataUsed = getPtrToData(Pos / 8, 1);
+ if (b)
+ *DataUsed.first |= 1 << (Pos % 8);
+ assert(!(*DataUsed.second & (1 << Pos % 8)));
+ *DataUsed.second |= 1 << (Pos % 8);
+ }
+};
+
+// The bits that will be stored before and after a particular vtable.
+struct VTableBits {
+ // The vtable global.
+ GlobalVariable *GV;
+
+ // Cache of the vtable's size in bytes.
+ uint64_t ObjectSize = 0;
+
+ // The bit vector that will be laid out before the vtable. Note that these
+ // bytes are stored in reverse order until the globals are rebuilt. This means
+ // that any values in the array must be stored using the opposite endianness
+ // from the target.
+ AccumBitVector Before;
+
+ // The bit vector that will be laid out after the vtable.
+ AccumBitVector After;
+};
+
+// Information about a member of a particular type identifier.
+struct TypeMemberInfo {
+ // The VTableBits for the vtable.
+ VTableBits *Bits;
+
+ // The offset in bytes from the start of the vtable (i.e. the address point).
+ uint64_t Offset;
+
+ bool operator<(const TypeMemberInfo &other) const {
+ return Bits < other.Bits || (Bits == other.Bits && Offset < other.Offset);
+ }
+};
+
+// A virtual call target, i.e. an entry in a particular vtable.
+struct VirtualCallTarget {
+ VirtualCallTarget(Function *Fn, const TypeMemberInfo *TM);
+
+ // For testing only.
+ VirtualCallTarget(const TypeMemberInfo *TM, bool IsBigEndian)
+ : Fn(nullptr), TM(TM), IsBigEndian(IsBigEndian), WasDevirt(false) {}
+
+ // The function stored in the vtable.
+ Function *Fn;
+
+ // A pointer to the type identifier member through which the pointer to Fn is
+ // accessed.
+ const TypeMemberInfo *TM;
+
+ // When doing virtual constant propagation, this stores the return value for
+ // the function when passed the currently considered argument list.
+ uint64_t RetVal;
+
+ // Whether the target is big endian.
+ bool IsBigEndian;
+
+ // Whether at least one call site to the target was devirtualized.
+ bool WasDevirt;
+
+ // The minimum byte offset before the address point. This covers the bytes in
+ // the vtable object before the address point (e.g. RTTI, access-to-top,
+ // vtables for other base classes) and is equal to the offset from the start
+ // of the vtable object to the address point.
+ uint64_t minBeforeBytes() const { return TM->Offset; }
+
+ // The minimum byte offset after the address point. This covers the bytes in
+ // the vtable object after the address point (e.g. the vtable for the current
+ // class and any later base classes) and is equal to the size of the vtable
+ // object minus the offset from the start of the vtable object to the address
+ // point.
+ uint64_t minAfterBytes() const { return TM->Bits->ObjectSize - TM->Offset; }
+
+ // The number of bytes allocated (for the vtable plus the byte array) before
+ // the address point.
+ uint64_t allocatedBeforeBytes() const {
+ return minBeforeBytes() + TM->Bits->Before.Bytes.size();
+ }
+
+ // The number of bytes allocated (for the vtable plus the byte array) after
+ // the address point.
+ uint64_t allocatedAfterBytes() const {
+ return minAfterBytes() + TM->Bits->After.Bytes.size();
+ }
+
+ // Set the bit at position Pos before the address point to RetVal.
+ void setBeforeBit(uint64_t Pos) {
+ assert(Pos >= 8 * minBeforeBytes());
+ TM->Bits->Before.setBit(Pos - 8 * minBeforeBytes(), RetVal);
+ }
+
+ // Set the bit at position Pos after the address point to RetVal.
+ void setAfterBit(uint64_t Pos) {
+ assert(Pos >= 8 * minAfterBytes());
+ TM->Bits->After.setBit(Pos - 8 * minAfterBytes(), RetVal);
+ }
+
+ // Set the bytes at position Pos before the address point to RetVal.
+ // Because the bytes in Before are stored in reverse order, we use the
+ // opposite endianness to the target.
+ void setBeforeBytes(uint64_t Pos, uint8_t Size) {
+ assert(Pos >= 8 * minBeforeBytes());
+ if (IsBigEndian)
+ TM->Bits->Before.setLE(Pos - 8 * minBeforeBytes(), RetVal, Size);
+ else
+ TM->Bits->Before.setBE(Pos - 8 * minBeforeBytes(), RetVal, Size);
+ }
+
+ // Set the bytes at position Pos after the address point to RetVal.
+ void setAfterBytes(uint64_t Pos, uint8_t Size) {
+ assert(Pos >= 8 * minAfterBytes());
+ if (IsBigEndian)
+ TM->Bits->After.setBE(Pos - 8 * minAfterBytes(), RetVal, Size);
+ else
+ TM->Bits->After.setLE(Pos - 8 * minAfterBytes(), RetVal, Size);
+ }
+};
+
+// Find the minimum offset that we may store a value of size Size bits at. If
+// IsAfter is set, look for an offset before the object, otherwise look for an
+// offset after the object.
+uint64_t findLowestOffset(ArrayRef<VirtualCallTarget> Targets, bool IsAfter,
+ uint64_t Size);
+
+// Set the stored value in each of Targets to VirtualCallTarget::RetVal at the
+// given allocation offset before the vtable address. Stores the computed
+// byte/bit offset to OffsetByte/OffsetBit.
+void setBeforeReturnValues(MutableArrayRef<VirtualCallTarget> Targets,
+ uint64_t AllocBefore, unsigned BitWidth,
+ int64_t &OffsetByte, uint64_t &OffsetBit);
+
+// Set the stored value in each of Targets to VirtualCallTarget::RetVal at the
+// given allocation offset after the vtable address. Stores the computed
+// byte/bit offset to OffsetByte/OffsetBit.
+void setAfterReturnValues(MutableArrayRef<VirtualCallTarget> Targets,
+ uint64_t AllocAfter, unsigned BitWidth,
+ int64_t &OffsetByte, uint64_t &OffsetBit);
+
+} // end namespace wholeprogramdevirt
+
+struct WholeProgramDevirtPass : public PassInfoMixin<WholeProgramDevirtPass> {
+ ModuleSummaryIndex *ExportSummary;
+ const ModuleSummaryIndex *ImportSummary;
+ WholeProgramDevirtPass(ModuleSummaryIndex *ExportSummary,
+ const ModuleSummaryIndex *ImportSummary)
+ : ExportSummary(ExportSummary), ImportSummary(ImportSummary) {
+ assert(!(ExportSummary && ImportSummary));
+ }
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_WHOLEPROGRAMDEVIRT_H