[llvm] annotate interfaces in llvm/Transforms for DLL export (#143413)
## Purpose This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm/Transforms` library. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build. ## Background This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`. The following manual adjustments were also applied after running IDS on Linux: - Removed a redundant `operator<<` from Attributor.h. IDS only auto-annotates the 1st declaration, and the 2nd declaration being un-annotated resulted in an "inconsistent linkage" error on Windows when building LLVM as a DLL. - `#include` the `VirtualFileSystem.h` in PGOInstrumentation.h and remove the local declaration of the `vfs::FileSystem` class. This is required because exporting the `PGOInstrumentationUse` constructor requires the class be fully defined because it is used by an argument. - Add #include "llvm/Support/Compiler.h" to files where it was not auto-added by IDS due to no pre-existing block of include statements. - Add `LLVM_TEMPLATE_ABI` and `LLVM_EXPORT_TEMPLATE` to exported instantiated templates. ## Validation Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#define LLVM_TRANSFORMS_COROUTINES_ABI_H
|
||||
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Coroutines/CoroShape.h"
|
||||
#include "llvm/Transforms/Coroutines/MaterializationUtils.h"
|
||||
#include "llvm/Transforms/Coroutines/SuspendCrossingInfo.h"
|
||||
@@ -37,7 +38,7 @@ namespace coro {
|
||||
// index of an ABI generator for the custom ABI object in a SmallVector passed
|
||||
// to CoroSplitPass ctor.
|
||||
|
||||
class BaseABI {
|
||||
class LLVM_ABI BaseABI {
|
||||
public:
|
||||
BaseABI(Function &F, coro::Shape &S,
|
||||
std::function<bool(Instruction &)> IsMaterializable)
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
std::function<bool(Instruction &I)> IsMaterializable;
|
||||
};
|
||||
|
||||
class SwitchABI : public BaseABI {
|
||||
class LLVM_ABI SwitchABI : public BaseABI {
|
||||
public:
|
||||
SwitchABI(Function &F, coro::Shape &S,
|
||||
std::function<bool(Instruction &)> IsMaterializable)
|
||||
@@ -76,7 +77,7 @@ public:
|
||||
TargetTransformInfo &TTI) override;
|
||||
};
|
||||
|
||||
class AsyncABI : public BaseABI {
|
||||
class LLVM_ABI AsyncABI : public BaseABI {
|
||||
public:
|
||||
AsyncABI(Function &F, coro::Shape &S,
|
||||
std::function<bool(Instruction &)> IsMaterializable)
|
||||
@@ -89,7 +90,7 @@ public:
|
||||
TargetTransformInfo &TTI) override;
|
||||
};
|
||||
|
||||
class AnyRetconABI : public BaseABI {
|
||||
class LLVM_ABI AnyRetconABI : public BaseABI {
|
||||
public:
|
||||
AnyRetconABI(Function &F, coro::Shape &S,
|
||||
std::function<bool(Instruction &)> IsMaterializable)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -237,7 +238,7 @@ class AnyCoroIdRetconInst : public AnyCoroIdInst {
|
||||
enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
|
||||
|
||||
public:
|
||||
void checkWellFormed() const;
|
||||
LLVM_ABI void checkWellFormed() const;
|
||||
|
||||
uint64_t getStorageSize() const {
|
||||
return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
|
||||
@@ -306,7 +307,7 @@ class CoroIdAsyncInst : public AnyCoroIdInst {
|
||||
enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
|
||||
|
||||
public:
|
||||
void checkWellFormed() const;
|
||||
LLVM_ABI void checkWellFormed() const;
|
||||
|
||||
/// The initial async function context size. The fields of which are reserved
|
||||
/// for use by the frontend. The frame will be allocated as a tail of this
|
||||
@@ -568,7 +569,7 @@ public:
|
||||
MustTailCallFuncArg
|
||||
};
|
||||
|
||||
void checkWellFormed() const;
|
||||
LLVM_ABI void checkWellFormed() const;
|
||||
|
||||
unsigned getStorageArgumentIndex() const {
|
||||
auto *Arg = cast<ConstantInt>(getArgOperand(StorageArgNoArg));
|
||||
@@ -722,7 +723,7 @@ class CoroAsyncEndInst : public AnyCoroEndInst {
|
||||
enum { FrameArg, UnwindArg, MustTailCallFuncArg };
|
||||
|
||||
public:
|
||||
void checkWellFormed() const;
|
||||
LLVM_ABI void checkWellFormed() const;
|
||||
|
||||
Function *getMustTailCallFunction() const {
|
||||
if (arg_size() < 3)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Coroutines/CoroInstr.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -78,18 +79,20 @@ struct Shape {
|
||||
}
|
||||
|
||||
// Scan the function and collect the above intrinsics for later processing
|
||||
void analyze(Function &F, SmallVectorImpl<CoroFrameInst *> &CoroFrames,
|
||||
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
|
||||
CoroPromiseInst *&CoroPromise);
|
||||
LLVM_ABI void analyze(Function &F,
|
||||
SmallVectorImpl<CoroFrameInst *> &CoroFrames,
|
||||
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
|
||||
CoroPromiseInst *&CoroPromise);
|
||||
// If for some reason, we were not able to find coro.begin, bailout.
|
||||
void invalidateCoroutine(Function &F,
|
||||
SmallVectorImpl<CoroFrameInst *> &CoroFrames);
|
||||
LLVM_ABI void
|
||||
invalidateCoroutine(Function &F,
|
||||
SmallVectorImpl<CoroFrameInst *> &CoroFrames);
|
||||
// Perform ABI related initial transformation
|
||||
void initABI();
|
||||
LLVM_ABI void initABI();
|
||||
// Remove orphaned and unnecessary intrinsics
|
||||
void cleanCoroutine(SmallVectorImpl<CoroFrameInst *> &CoroFrames,
|
||||
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
|
||||
CoroPromiseInst *CoroPromise);
|
||||
LLVM_ABI void cleanCoroutine(SmallVectorImpl<CoroFrameInst *> &CoroFrames,
|
||||
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
|
||||
CoroPromiseInst *CoroPromise);
|
||||
|
||||
// Field indexes for special fields in the switch lowering.
|
||||
struct SwitchFieldIndex {
|
||||
@@ -256,12 +259,14 @@ struct Shape {
|
||||
/// Allocate memory according to the rules of the active lowering.
|
||||
///
|
||||
/// \param CG - if non-null, will be updated for the new call
|
||||
Value *emitAlloc(IRBuilder<> &Builder, Value *Size, CallGraph *CG) const;
|
||||
LLVM_ABI Value *emitAlloc(IRBuilder<> &Builder, Value *Size,
|
||||
CallGraph *CG) const;
|
||||
|
||||
/// Deallocate memory according to the rules of the active lowering.
|
||||
///
|
||||
/// \param CG - if non-null, will be updated for the new call
|
||||
void emitDealloc(IRBuilder<> &Builder, Value *Ptr, CallGraph *CG) const;
|
||||
LLVM_ABI void emitDealloc(IRBuilder<> &Builder, Value *Ptr,
|
||||
CallGraph *CG) const;
|
||||
|
||||
Shape() = default;
|
||||
explicit Shape(Function &F) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Coroutines/ABI.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -31,20 +32,23 @@ struct CoroSplitPass : PassInfoMixin<CoroSplitPass> {
|
||||
using BaseABITy =
|
||||
std::function<std::unique_ptr<coro::BaseABI>(Function &, coro::Shape &)>;
|
||||
|
||||
CoroSplitPass(bool OptimizeFrame = false);
|
||||
LLVM_ABI CoroSplitPass(bool OptimizeFrame = false);
|
||||
|
||||
CoroSplitPass(SmallVector<BaseABITy> GenCustomABIs,
|
||||
bool OptimizeFrame = false);
|
||||
LLVM_ABI CoroSplitPass(SmallVector<BaseABITy> GenCustomABIs,
|
||||
bool OptimizeFrame = false);
|
||||
|
||||
LLVM_ABI
|
||||
CoroSplitPass(std::function<bool(Instruction &)> MaterializableCallback,
|
||||
bool OptimizeFrame = false);
|
||||
|
||||
LLVM_ABI
|
||||
CoroSplitPass(std::function<bool(Instruction &)> MaterializableCallback,
|
||||
SmallVector<BaseABITy> GenCustomABIs,
|
||||
bool OptimizeFrame = false);
|
||||
|
||||
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
|
||||
LazyCallGraph &CG, CGSCCUpdateResult &UR);
|
||||
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C,
|
||||
CGSCCAnalysisManager &AM, LazyCallGraph &CG,
|
||||
CGSCCUpdateResult &UR);
|
||||
|
||||
static bool isRequired() { return true; }
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Coroutines/SuspendCrossingInfo.h"
|
||||
|
||||
#ifndef LLVM_TRANSFORMS_COROUTINES_MATERIALIZATIONUTILS_H
|
||||
@@ -16,11 +17,12 @@ namespace llvm {
|
||||
namespace coro {
|
||||
|
||||
// True if I is trivially rematerialzable, e.g. InsertElementInst
|
||||
bool isTriviallyMaterializable(Instruction &I);
|
||||
LLVM_ABI bool isTriviallyMaterializable(Instruction &I);
|
||||
|
||||
// Performs rematerialization, invoked from buildCoroutineFrame.
|
||||
void doRematerializations(Function &F, SuspendCrossingInfo &Checker,
|
||||
std::function<bool(Instruction &)> IsMaterializable);
|
||||
LLVM_ABI void
|
||||
doRematerializations(Function &F, SuspendCrossingInfo &Checker,
|
||||
std::function<bool(Instruction &)> IsMaterializable);
|
||||
|
||||
} // namespace coro
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Coroutines/CoroInstr.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -102,19 +103,21 @@ public:
|
||||
ModuleSlotTracker &MST) const;
|
||||
#endif
|
||||
|
||||
LLVM_ABI
|
||||
SuspendCrossingInfo(Function &F,
|
||||
const SmallVectorImpl<AnyCoroSuspendInst *> &CoroSuspends,
|
||||
const SmallVectorImpl<AnyCoroEndInst *> &CoroEnds);
|
||||
|
||||
/// Returns true if there is a path from \p From to \p To crossing a suspend
|
||||
/// point without crossing \p From a 2nd time.
|
||||
bool hasPathCrossingSuspendPoint(BasicBlock *From, BasicBlock *To) const;
|
||||
LLVM_ABI bool hasPathCrossingSuspendPoint(BasicBlock *From,
|
||||
BasicBlock *To) const;
|
||||
|
||||
/// Returns true if there is a path from \p From to \p To crossing a suspend
|
||||
/// point without crossing \p From a 2nd time. If \p From is the same as \p To
|
||||
/// this will also check if there is a looping path crossing a suspend point.
|
||||
bool hasPathOrLoopCrossingSuspendPoint(BasicBlock *From,
|
||||
BasicBlock *To) const;
|
||||
LLVM_ABI bool hasPathOrLoopCrossingSuspendPoint(BasicBlock *From,
|
||||
BasicBlock *To) const;
|
||||
|
||||
bool isDefinitionAcrossSuspend(BasicBlock *DefBB, User *U) const {
|
||||
auto *I = cast<Instruction>(U);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define LLVM_TRANSFORMS_HIPSTDPAR_HIPSTDPAR_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -27,7 +28,7 @@ class Module;
|
||||
class HipStdParAcceleratorCodeSelectionPass
|
||||
: public PassInfoMixin<HipStdParAcceleratorCodeSelectionPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
class HipStdParAllocationInterpositionPass
|
||||
: public PassInfoMixin<HipStdParAllocationInterpositionPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
@@ -24,29 +24,29 @@ class raw_ostream;
|
||||
/// createDeadArgEliminationPass - This pass removes arguments from functions
|
||||
/// which are not used by the body of the function.
|
||||
///
|
||||
ModulePass *createDeadArgEliminationPass();
|
||||
LLVM_ABI ModulePass *createDeadArgEliminationPass();
|
||||
|
||||
/// DeadArgHacking pass - Same as DAE, but delete arguments of external
|
||||
/// functions as well. This is definitely not safe, and should only be used by
|
||||
/// bugpoint.
|
||||
ModulePass *createDeadArgHackingPass();
|
||||
LLVM_ABI ModulePass *createDeadArgHackingPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// createLoopExtractorPass - This pass extracts all natural loops from the
|
||||
/// program into a function if it can.
|
||||
///
|
||||
Pass *createLoopExtractorPass();
|
||||
LLVM_ABI Pass *createLoopExtractorPass();
|
||||
|
||||
/// createSingleLoopExtractorPass - This pass extracts one natural loop from the
|
||||
/// program into a function if it can. This is used by bugpoint.
|
||||
///
|
||||
Pass *createSingleLoopExtractorPass();
|
||||
LLVM_ABI Pass *createSingleLoopExtractorPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// createBarrierNoopPass - This pass is purely a module pass barrier in a pass
|
||||
/// manager.
|
||||
ModulePass *createBarrierNoopPass();
|
||||
LLVM_ABI ModulePass *createBarrierNoopPass();
|
||||
|
||||
/// What to do with the summary when running passes that operate on it.
|
||||
enum class PassSummaryAction {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define LLVM_TRANSFORMS_IPO_ALWAYSINLINER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -36,14 +37,13 @@ public:
|
||||
AlwaysInlinerPass(bool InsertLifetime = true)
|
||||
: InsertLifetime(InsertLifetime) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
/// Create a legacy pass manager instance of a pass to inline and remove
|
||||
/// functions marked as "always_inline".
|
||||
Pass *createAlwaysInlinerLegacyPass(bool InsertLifetime = true);
|
||||
|
||||
LLVM_ABI Pass *createAlwaysInlinerLegacyPass(bool InsertLifetime = true);
|
||||
}
|
||||
|
||||
#endif // LLVM_TRANSFORMS_IPO_ALWAYSINLINER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@
|
||||
#ifndef LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
|
||||
#define LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <vector>
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
@@ -22,9 +23,10 @@ namespace llvm {
|
||||
class BasicBlock;
|
||||
|
||||
struct BlockExtractorPass : PassInfoMixin<BlockExtractorPass> {
|
||||
LLVM_ABI
|
||||
BlockExtractorPass(std::vector<std::vector<BasicBlock *>> &&GroupsOfBlocks,
|
||||
bool EraseFunctions);
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
private:
|
||||
std::vector<std::vector<BasicBlock *>> GroupsOfBlocks;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define LLVM_TRANSFORMS_IPO_EMBEDBITCODEPASS_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
@@ -44,7 +45,7 @@ public:
|
||||
EmbedBitcodePass(bool IsThinLTO, bool EmitLTOSummary)
|
||||
: IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class GlobalValue;
|
||||
@@ -22,9 +23,9 @@ private:
|
||||
bool keepConstInit;
|
||||
|
||||
public:
|
||||
ExtractGVPass(std::vector<GlobalValue *> &GVs, bool deleteS = true,
|
||||
bool keepConstInit = false);
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
LLVM_ABI ExtractGVPass(std::vector<GlobalValue *> &GVs, bool deleteS = true,
|
||||
bool keepConstInit = false);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -28,11 +29,12 @@ class Function;
|
||||
class Module;
|
||||
|
||||
/// Returns the memory access properties of this copy of the function.
|
||||
MemoryEffects computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR);
|
||||
LLVM_ABI MemoryEffects computeFunctionBodyMemoryAccess(Function &F,
|
||||
AAResults &AAR);
|
||||
|
||||
/// Propagate function attributes for function summaries along the index's
|
||||
/// callgraph during thinlink
|
||||
bool thinLTOPropagateFunctionAttrs(
|
||||
LLVM_ABI bool thinLTOPropagateFunctionAttrs(
|
||||
ModuleSummaryIndex &Index,
|
||||
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
|
||||
isPrevailing);
|
||||
@@ -49,11 +51,13 @@ bool thinLTOPropagateFunctionAttrs(
|
||||
struct PostOrderFunctionAttrsPass : PassInfoMixin<PostOrderFunctionAttrsPass> {
|
||||
PostOrderFunctionAttrsPass(bool SkipNonRecursive = false)
|
||||
: SkipNonRecursive(SkipNonRecursive) {}
|
||||
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
|
||||
LazyCallGraph &CG, CGSCCUpdateResult &UR);
|
||||
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C,
|
||||
CGSCCAnalysisManager &AM, LazyCallGraph &CG,
|
||||
CGSCCUpdateResult &UR);
|
||||
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
private:
|
||||
bool SkipNonRecursive;
|
||||
@@ -72,7 +76,7 @@ private:
|
||||
class ReversePostOrderFunctionAttrsPass
|
||||
: public PassInfoMixin<ReversePostOrderFunctionAttrsPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -199,13 +200,14 @@ public:
|
||||
|
||||
// Add the given GUID to ImportList as a definition. If the same GUID has
|
||||
// been added as a declaration previously, that entry is overridden.
|
||||
AddDefinitionStatus addDefinition(StringRef FromModule,
|
||||
GlobalValue::GUID GUID);
|
||||
LLVM_ABI AddDefinitionStatus addDefinition(StringRef FromModule,
|
||||
GlobalValue::GUID GUID);
|
||||
|
||||
// Add the given GUID to ImportList as a declaration. If the same GUID has
|
||||
// been added as a definition previously, that entry takes precedence, and
|
||||
// no change is made.
|
||||
void maybeAddDeclaration(StringRef FromModule, GlobalValue::GUID GUID);
|
||||
LLVM_ABI void maybeAddDeclaration(StringRef FromModule,
|
||||
GlobalValue::GUID GUID);
|
||||
|
||||
void addGUID(StringRef FromModule, GlobalValue::GUID GUID,
|
||||
GlobalValueSummary::ImportKind ImportKind) {
|
||||
@@ -217,9 +219,9 @@ public:
|
||||
|
||||
// Return the list of source modules sorted in the ascending alphabetical
|
||||
// order.
|
||||
SmallVector<StringRef, 0> getSourceModules() const;
|
||||
LLVM_ABI SmallVector<StringRef, 0> getSourceModules() const;
|
||||
|
||||
std::optional<GlobalValueSummary::ImportKind>
|
||||
LLVM_ABI std::optional<GlobalValueSummary::ImportKind>
|
||||
getImportType(StringRef FromModule, GlobalValue::GUID GUID) const;
|
||||
|
||||
// Iterate over the import list. The caller gets tuples of FromModule,
|
||||
@@ -312,7 +314,8 @@ public:
|
||||
ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {}
|
||||
|
||||
/// Import functions in Module \p M based on the supplied import list.
|
||||
Expected<bool> importFunctions(Module &M, const ImportMapTy &ImportList);
|
||||
LLVM_ABI Expected<bool> importFunctions(Module &M,
|
||||
const ImportMapTy &ImportList);
|
||||
|
||||
private:
|
||||
/// The summaries index used to trigger importing.
|
||||
@@ -329,7 +332,7 @@ private:
|
||||
/// The function importing pass
|
||||
class FunctionImportPass : public PassInfoMixin<FunctionImportPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Compute all the imports and exports for every module in the Index.
|
||||
@@ -353,7 +356,7 @@ public:
|
||||
/// are owned by the in-memory ModuleSummaryIndex the importing decisions
|
||||
/// are made from (the module path for each summary is owned by the index's
|
||||
/// module path string table).
|
||||
void ComputeCrossModuleImport(
|
||||
LLVM_ABI void ComputeCrossModuleImport(
|
||||
const ModuleSummaryIndex &Index,
|
||||
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
|
||||
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
|
||||
@@ -370,7 +373,7 @@ enum class PrevailingType { Yes, No, Unknown };
|
||||
/// SamplePGO when needed. Normally this is done during
|
||||
/// computeDeadSymbolsAndUpdateIndirectCalls, but can be called standalone
|
||||
/// when that is not called (e.g. during testing).
|
||||
void updateIndirectCalls(ModuleSummaryIndex &Index);
|
||||
LLVM_ABI void updateIndirectCalls(ModuleSummaryIndex &Index);
|
||||
|
||||
/// 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
|
||||
@@ -379,14 +382,14 @@ void updateIndirectCalls(ModuleSummaryIndex &Index);
|
||||
/// predicate returns status of symbol.
|
||||
/// Also update call edges for indirect calls to local functions added from
|
||||
/// SamplePGO when needed.
|
||||
void computeDeadSymbolsAndUpdateIndirectCalls(
|
||||
LLVM_ABI void computeDeadSymbolsAndUpdateIndirectCalls(
|
||||
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(
|
||||
LLVM_ABI void computeDeadSymbolsWithConstProp(
|
||||
ModuleSummaryIndex &Index,
|
||||
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
|
||||
function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,
|
||||
@@ -394,7 +397,7 @@ void computeDeadSymbolsWithConstProp(
|
||||
|
||||
/// 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);
|
||||
LLVM_ABI bool convertToDeclaration(GlobalValue &GV);
|
||||
|
||||
/// Compute the set of summaries needed for a ThinLTO backend compilation of
|
||||
/// \p ModulePath.
|
||||
@@ -409,7 +412,7 @@ bool convertToDeclaration(GlobalValue &GV);
|
||||
///
|
||||
/// \p DecSummaries will be popluated with the subset of of summary pointers
|
||||
/// that have 'declaration' import type among all summaries the module need.
|
||||
void gatherImportedSummariesForModule(
|
||||
LLVM_ABI void gatherImportedSummariesForModule(
|
||||
StringRef ModulePath,
|
||||
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
|
||||
const FunctionImporter::ImportMapTy &ImportList,
|
||||
@@ -417,12 +420,12 @@ void gatherImportedSummariesForModule(
|
||||
GVSummaryPtrSet &DecSummaries);
|
||||
|
||||
/// Emit into \p OutputFilename the files module \p ModulePath will import from.
|
||||
Error EmitImportsFiles(
|
||||
StringRef ModulePath, StringRef OutputFilename,
|
||||
const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex);
|
||||
LLVM_ABI Error
|
||||
EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename,
|
||||
const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex);
|
||||
|
||||
/// Call \p F passing each of the files module \p ModulePath will import from.
|
||||
void processImportsFiles(
|
||||
LLVM_ABI void processImportsFiles(
|
||||
StringRef ModulePath,
|
||||
const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex,
|
||||
function_ref<void(const std::string &)> F);
|
||||
@@ -433,14 +436,14 @@ void processImportsFiles(
|
||||
/// and consider visibility from other definitions for ELF) in \p TheModule
|
||||
/// 2. (optional) Apply propagated function attributes to \p TheModule if
|
||||
/// PropagateAttrs is true
|
||||
void thinLTOFinalizeInModule(Module &TheModule,
|
||||
const GVSummaryMapTy &DefinedGlobals,
|
||||
bool PropagateAttrs);
|
||||
LLVM_ABI void thinLTOFinalizeInModule(Module &TheModule,
|
||||
const GVSummaryMapTy &DefinedGlobals,
|
||||
bool PropagateAttrs);
|
||||
|
||||
/// Internalize \p TheModule based on the information recorded in the summaries
|
||||
/// during global summary-based analysis.
|
||||
void thinLTOInternalizeModule(Module &TheModule,
|
||||
const GVSummaryMapTy &DefinedGlobals);
|
||||
LLVM_ABI void thinLTOInternalizeModule(Module &TheModule,
|
||||
const GVSummaryMapTy &DefinedGlobals);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/InstVisitor.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Scalar/SCCP.h"
|
||||
#include "llvm/Transforms/Utils/Cloning.h"
|
||||
#include "llvm/Transforms/Utils/SCCPSolver.h"
|
||||
@@ -179,11 +180,11 @@ public:
|
||||
return Solver.isBlockExecutable(BB) && !DeadBlocks.contains(BB);
|
||||
}
|
||||
|
||||
Cost getCodeSizeSavingsForArg(Argument *A, Constant *C);
|
||||
LLVM_ABI Cost getCodeSizeSavingsForArg(Argument *A, Constant *C);
|
||||
|
||||
Cost getCodeSizeSavingsFromPendingPHIs();
|
||||
LLVM_ABI Cost getCodeSizeSavingsFromPendingPHIs();
|
||||
|
||||
Cost getLatencySavingsForKnownConstants();
|
||||
LLVM_ABI Cost getLatencySavingsForKnownConstants();
|
||||
|
||||
private:
|
||||
friend class InstVisitor<InstCostVisitor, Constant *>;
|
||||
@@ -260,9 +261,9 @@ public:
|
||||
: Solver(Solver), M(M), FAM(FAM), GetBFI(GetBFI), GetTLI(GetTLI),
|
||||
GetTTI(GetTTI), GetAC(GetAC) {}
|
||||
|
||||
~FunctionSpecializer();
|
||||
LLVM_ABI ~FunctionSpecializer();
|
||||
|
||||
bool run();
|
||||
LLVM_ABI bool run();
|
||||
|
||||
InstCostVisitor getInstCostVisitorFor(Function *F) {
|
||||
auto &TTI = GetTTI(*F);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace llvm {
|
||||
@@ -37,10 +38,11 @@ class GlobalDCEPass : public PassInfoMixin<GlobalDCEPass> {
|
||||
public:
|
||||
GlobalDCEPass(bool InLTOPostLink = false) : InLTOPostLink(InLTOPostLink) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
private:
|
||||
bool InLTOPostLink = false;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -39,11 +40,13 @@ public:
|
||||
: OnlyMandatory(OnlyMandatory), LTOPhase(LTOPhase) {}
|
||||
InlinerPass(InlinerPass &&Arg) = default;
|
||||
|
||||
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
|
||||
LazyCallGraph &CG, CGSCCUpdateResult &UR);
|
||||
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C,
|
||||
CGSCCAnalysisManager &AM, LazyCallGraph &CG,
|
||||
CGSCCUpdateResult &UR);
|
||||
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
private:
|
||||
InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
|
||||
@@ -61,14 +64,14 @@ private:
|
||||
class ModuleInlinerWrapperPass
|
||||
: public PassInfoMixin<ModuleInlinerWrapperPass> {
|
||||
public:
|
||||
ModuleInlinerWrapperPass(
|
||||
LLVM_ABI ModuleInlinerWrapperPass(
|
||||
InlineParams Params = getInlineParams(), bool MandatoryFirst = true,
|
||||
InlineContext IC = {},
|
||||
InliningAdvisorMode Mode = InliningAdvisorMode::Default,
|
||||
unsigned MaxDevirtIterations = 0);
|
||||
ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default;
|
||||
|
||||
PreservedAnalyses run(Module &, ModuleAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Module &, ModuleAnalysisManager &);
|
||||
|
||||
/// Allow adding more CGSCC passes, besides inlining. This should be called
|
||||
/// before run is called, as part of pass pipeline building.
|
||||
@@ -84,8 +87,9 @@ public:
|
||||
AfterCGMPM.addPass(std::move(Pass));
|
||||
}
|
||||
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
private:
|
||||
const InlineParams Params;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <functional>
|
||||
|
||||
namespace llvm {
|
||||
@@ -61,15 +62,15 @@ class InternalizePass : public PassInfoMixin<InternalizePass> {
|
||||
DenseMap<const Comdat *, ComdatInfo> &ComdatMap);
|
||||
|
||||
public:
|
||||
InternalizePass();
|
||||
LLVM_ABI 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.
|
||||
bool internalizeModule(Module &TheModule);
|
||||
LLVM_ABI bool internalizeModule(Module &TheModule);
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Helper function to internalize functions and variables in a Module.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
@@ -53,9 +54,9 @@ struct BitSetInfo {
|
||||
return Bits.size() == BitSize;
|
||||
}
|
||||
|
||||
bool containsGlobalOffset(uint64_t Offset) const;
|
||||
LLVM_ABI bool containsGlobalOffset(uint64_t Offset) const;
|
||||
|
||||
void print(raw_ostream &OS) const;
|
||||
LLVM_ABI void print(raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
struct BitSetBuilder {
|
||||
@@ -74,7 +75,7 @@ struct BitSetBuilder {
|
||||
Offsets.push_back(Offset);
|
||||
}
|
||||
|
||||
BitSetInfo build();
|
||||
LLVM_ABI BitSetInfo build();
|
||||
};
|
||||
|
||||
/// This class implements a layout algorithm for globals referenced by bit sets
|
||||
@@ -137,7 +138,7 @@ struct GlobalLayoutBuilder {
|
||||
/// 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);
|
||||
LLVM_ABI void addFragment(const std::set<uint64_t> &F);
|
||||
};
|
||||
|
||||
/// This class is used to build a byte array containing overlapping bit sets. By
|
||||
@@ -189,11 +190,11 @@ struct ByteArrayBuilder {
|
||||
/// 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);
|
||||
LLVM_ABI void allocate(const std::set<uint64_t> &Bits, uint64_t BitSize,
|
||||
uint64_t &AllocByteOffset, uint8_t &AllocMask);
|
||||
};
|
||||
|
||||
bool isJumpTableCanonical(Function *F);
|
||||
LLVM_ABI bool isJumpTableCanonical(Function *F);
|
||||
|
||||
/// Specifies how to drop type tests.
|
||||
enum class DropTestKind {
|
||||
@@ -220,12 +221,12 @@ public:
|
||||
lowertypetests::DropTestKind::None)
|
||||
: ExportSummary(ExportSummary), ImportSummary(ImportSummary),
|
||||
DropTypeTests(DropTypeTests) {}
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
class SimplifyTypeTestsPass : public PassInfoMixin<SimplifyTypeTestsPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define LLVM_TRANSFORMS_IPO_MERGEFUNCTIONS_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -25,10 +26,10 @@ class Function;
|
||||
/// Merge identical functions.
|
||||
class MergeFunctionsPass : public PassInfoMixin<MergeFunctionsPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
static bool runOnModule(Module &M);
|
||||
static DenseMap<Function *, Function *>
|
||||
LLVM_ABI static bool runOnModule(Module &M);
|
||||
LLVM_ABI static DenseMap<Function *, Function *>
|
||||
runOnFunctions(ArrayRef<Function *> F);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "llvm/Analysis/InlineAdvisor.h"
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -32,7 +33,7 @@ public:
|
||||
: Params(Params), Mode(Mode), LTOPhase(LTOPhase){};
|
||||
ModuleInlinerPass(ModuleInlinerPass &&Arg) = default;
|
||||
|
||||
PreservedAnalyses run(Module &, ModuleAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Module &, ModuleAnalysisManager &);
|
||||
|
||||
private:
|
||||
InlineAdvisor &getAdvisor(const ModuleAnalysisManager &MAM,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/ProfileData/SampleProf.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
@@ -39,25 +40,27 @@ public:
|
||||
LineLocation CallLoc = {0, 0})
|
||||
: ParentContext(Parent), FuncName(FName), FuncSamples(FSamples),
|
||||
CallSiteLoc(CallLoc){};
|
||||
ContextTrieNode *getChildContext(const LineLocation &CallSite,
|
||||
LLVM_ABI ContextTrieNode *getChildContext(const LineLocation &CallSite,
|
||||
FunctionId ChildName);
|
||||
LLVM_ABI ContextTrieNode *
|
||||
getHottestChildContext(const LineLocation &CallSite);
|
||||
LLVM_ABI ContextTrieNode *
|
||||
getOrCreateChildContext(const LineLocation &CallSite, FunctionId ChildName,
|
||||
bool AllowCreate = true);
|
||||
LLVM_ABI void removeChildContext(const LineLocation &CallSite,
|
||||
FunctionId ChildName);
|
||||
ContextTrieNode *getHottestChildContext(const LineLocation &CallSite);
|
||||
ContextTrieNode *getOrCreateChildContext(const LineLocation &CallSite,
|
||||
FunctionId ChildName,
|
||||
bool AllowCreate = true);
|
||||
void removeChildContext(const LineLocation &CallSite, FunctionId ChildName);
|
||||
std::map<uint64_t, ContextTrieNode> &getAllChildContext();
|
||||
FunctionId getFuncName() const;
|
||||
FunctionSamples *getFunctionSamples() const;
|
||||
void setFunctionSamples(FunctionSamples *FSamples);
|
||||
std::optional<uint32_t> getFunctionSize() const;
|
||||
void addFunctionSize(uint32_t FSize);
|
||||
LineLocation getCallSiteLoc() const;
|
||||
ContextTrieNode *getParentContext() const;
|
||||
void setParentContext(ContextTrieNode *Parent);
|
||||
void setCallSiteLoc(const LineLocation &Loc);
|
||||
void dumpNode();
|
||||
void dumpTree();
|
||||
LLVM_ABI std::map<uint64_t, ContextTrieNode> &getAllChildContext();
|
||||
LLVM_ABI FunctionId getFuncName() const;
|
||||
LLVM_ABI FunctionSamples *getFunctionSamples() const;
|
||||
LLVM_ABI void setFunctionSamples(FunctionSamples *FSamples);
|
||||
LLVM_ABI std::optional<uint32_t> getFunctionSize() const;
|
||||
LLVM_ABI void addFunctionSize(uint32_t FSize);
|
||||
LLVM_ABI LineLocation getCallSiteLoc() const;
|
||||
LLVM_ABI ContextTrieNode *getParentContext() const;
|
||||
LLVM_ABI void setParentContext(ContextTrieNode *Parent);
|
||||
LLVM_ABI void setCallSiteLoc(const LineLocation &Loc);
|
||||
LLVM_ABI void dumpNode();
|
||||
LLVM_ABI void dumpTree();
|
||||
|
||||
private:
|
||||
// Map line+discriminator location to child context
|
||||
@@ -91,48 +94,51 @@ public:
|
||||
using ContextSamplesTy = std::vector<FunctionSamples *>;
|
||||
|
||||
SampleContextTracker() = default;
|
||||
LLVM_ABI
|
||||
SampleContextTracker(SampleProfileMap &Profiles,
|
||||
const DenseMap<uint64_t, StringRef> *GUIDToFuncNameMap);
|
||||
// Populate the FuncToCtxtProfiles map after the trie is built.
|
||||
void populateFuncToCtxtMap();
|
||||
LLVM_ABI void populateFuncToCtxtMap();
|
||||
// Query context profile for a specific callee with given name at a given
|
||||
// call-site. The full context is identified by location of call instruction.
|
||||
FunctionSamples *getCalleeContextSamplesFor(const CallBase &Inst,
|
||||
StringRef CalleeName);
|
||||
LLVM_ABI FunctionSamples *getCalleeContextSamplesFor(const CallBase &Inst,
|
||||
StringRef CalleeName);
|
||||
// Get samples for indirect call targets for call site at given location.
|
||||
std::vector<const FunctionSamples *>
|
||||
LLVM_ABI std::vector<const FunctionSamples *>
|
||||
getIndirectCalleeContextSamplesFor(const DILocation *DIL);
|
||||
// Query context profile for a given location. The full context
|
||||
// is identified by input DILocation.
|
||||
FunctionSamples *getContextSamplesFor(const DILocation *DIL);
|
||||
LLVM_ABI FunctionSamples *getContextSamplesFor(const DILocation *DIL);
|
||||
// Query context profile for a given sample contxt of a function.
|
||||
FunctionSamples *getContextSamplesFor(const SampleContext &Context);
|
||||
LLVM_ABI FunctionSamples *getContextSamplesFor(const SampleContext &Context);
|
||||
// Get all context profile for given function.
|
||||
ContextSamplesTy &getAllContextSamplesFor(const Function &Func);
|
||||
ContextSamplesTy &getAllContextSamplesFor(StringRef Name);
|
||||
ContextTrieNode *getOrCreateContextPath(const SampleContext &Context,
|
||||
bool AllowCreate);
|
||||
LLVM_ABI ContextSamplesTy &getAllContextSamplesFor(const Function &Func);
|
||||
LLVM_ABI ContextSamplesTy &getAllContextSamplesFor(StringRef Name);
|
||||
LLVM_ABI ContextTrieNode *getOrCreateContextPath(const SampleContext &Context,
|
||||
bool AllowCreate);
|
||||
// Query base profile for a given function. A base profile is a merged view
|
||||
// of all context profiles for contexts that are not inlined.
|
||||
FunctionSamples *getBaseSamplesFor(const Function &Func,
|
||||
bool MergeContext = true);
|
||||
LLVM_ABI FunctionSamples *getBaseSamplesFor(const Function &Func,
|
||||
bool MergeContext = true);
|
||||
// Query base profile for a given function by name.
|
||||
FunctionSamples *getBaseSamplesFor(FunctionId Name,
|
||||
bool MergeContext = true);
|
||||
LLVM_ABI FunctionSamples *getBaseSamplesFor(FunctionId Name,
|
||||
bool MergeContext = true);
|
||||
// Retrieve the context trie node for given profile context
|
||||
ContextTrieNode *getContextFor(const SampleContext &Context);
|
||||
LLVM_ABI ContextTrieNode *getContextFor(const SampleContext &Context);
|
||||
// Get real function name for a given trie node.
|
||||
StringRef getFuncNameFor(ContextTrieNode *Node) const;
|
||||
LLVM_ABI StringRef getFuncNameFor(ContextTrieNode *Node) const;
|
||||
// Mark a context profile as inlined when function is inlined.
|
||||
// This makes sure that inlined context profile will be excluded in
|
||||
// function's base profile.
|
||||
void markContextSamplesInlined(const FunctionSamples *InlinedSamples);
|
||||
ContextTrieNode &getRootContext();
|
||||
void promoteMergeContextSamplesTree(const Instruction &Inst,
|
||||
FunctionId CalleeName);
|
||||
LLVM_ABI void
|
||||
markContextSamplesInlined(const FunctionSamples *InlinedSamples);
|
||||
LLVM_ABI ContextTrieNode &getRootContext();
|
||||
LLVM_ABI void promoteMergeContextSamplesTree(const Instruction &Inst,
|
||||
FunctionId CalleeName);
|
||||
|
||||
// Create a merged conext-less profile map.
|
||||
void createContextLessProfileMap(SampleProfileMap &ContextLessProfiles);
|
||||
LLVM_ABI void
|
||||
createContextLessProfileMap(SampleProfileMap &ContextLessProfiles);
|
||||
ContextTrieNode *
|
||||
getContextNodeForProfile(const FunctionSamples *FSamples) const {
|
||||
auto I = ProfileToNodeMap.find(FSamples);
|
||||
@@ -185,7 +191,7 @@ public:
|
||||
std::string getContextString(ContextTrieNode *Node) const;
|
||||
#endif
|
||||
// Dump the internal context profile trie.
|
||||
void dump();
|
||||
LLVM_ABI void dump();
|
||||
|
||||
private:
|
||||
ContextTrieNode *getContextFor(const DILocation *DIL);
|
||||
|
||||
@@ -18,18 +18,19 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Module;
|
||||
|
||||
extern cl::opt<int> SampleHotCallSiteThreshold;
|
||||
extern cl::opt<int> SampleColdCallSiteThreshold;
|
||||
extern cl::opt<int> ProfileInlineGrowthLimit;
|
||||
extern cl::opt<int> ProfileInlineLimitMin;
|
||||
extern cl::opt<int> ProfileInlineLimitMax;
|
||||
extern cl::opt<bool> SortProfiledSCC;
|
||||
LLVM_ABI extern cl::opt<int> SampleHotCallSiteThreshold;
|
||||
LLVM_ABI extern cl::opt<int> SampleColdCallSiteThreshold;
|
||||
LLVM_ABI extern cl::opt<int> ProfileInlineGrowthLimit;
|
||||
LLVM_ABI extern cl::opt<int> ProfileInlineLimitMin;
|
||||
LLVM_ABI extern cl::opt<int> ProfileInlineLimitMax;
|
||||
LLVM_ABI extern cl::opt<bool> SortProfiledSCC;
|
||||
|
||||
namespace vfs {
|
||||
class FileSystem;
|
||||
@@ -38,14 +39,14 @@ class FileSystem;
|
||||
/// The sample profiler data loader pass.
|
||||
class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> {
|
||||
public:
|
||||
SampleProfileLoaderPass(
|
||||
LLVM_ABI SampleProfileLoaderPass(
|
||||
std::string File = "", std::string RemappingFile = "",
|
||||
ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None,
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr,
|
||||
bool DisableSampleProfileInlining = false,
|
||||
bool UseFlattenedProfile = false);
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
private:
|
||||
std::string ProfileFileName;
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
#define LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
|
||||
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/PassInstrumentation.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/ProfileData/SampleProf.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace llvm {
|
||||
@@ -47,10 +48,10 @@ using FuncProbeFactorMap = StringMap<ProbeFactorMap>;
|
||||
// function pass, the factor sum for a probe would be typically 100%.
|
||||
class PseudoProbeVerifier {
|
||||
public:
|
||||
void registerCallbacks(PassInstrumentationCallbacks &PIC);
|
||||
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
|
||||
|
||||
// Implementation of pass instrumentation callbacks for new pass manager.
|
||||
void runAfterPass(StringRef PassID, Any IR);
|
||||
LLVM_ABI void runAfterPass(StringRef PassID, Any IR);
|
||||
|
||||
private:
|
||||
// Allow a little bias due the rounding to integral factors.
|
||||
@@ -74,8 +75,8 @@ private:
|
||||
class SampleProfileProber {
|
||||
public:
|
||||
// Give an empty module id when the prober is not used for instrumentation.
|
||||
SampleProfileProber(Function &F);
|
||||
void instrumentOneFunc(Function &F, TargetMachine *TM);
|
||||
LLVM_ABI SampleProfileProber(Function &F);
|
||||
LLVM_ABI void instrumentOneFunc(Function &F, TargetMachine *TM);
|
||||
|
||||
private:
|
||||
Function *getFunction() const { return F; }
|
||||
@@ -117,7 +118,7 @@ class SampleProfileProbePass : public PassInfoMixin<SampleProfileProbePass> {
|
||||
|
||||
public:
|
||||
SampleProfileProbePass(TargetMachine *TM) : TM(TM) {}
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
// Pseudo probe distribution factor updater.
|
||||
@@ -137,7 +138,7 @@ class PseudoProbeUpdatePass : public PassInfoMixin<PseudoProbeUpdatePass> {
|
||||
|
||||
public:
|
||||
PseudoProbeUpdatePass() = default;
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define LLVM_TRANSFORMS_IPO_STRIPDEADPROTOTYPES_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -24,7 +25,7 @@ class Module;
|
||||
|
||||
/// Pass to remove unused function declarations.
|
||||
struct StripDeadPrototypesPass : PassInfoMixin<StripDeadPrototypesPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,27 +23,28 @@
|
||||
#define LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
struct StripSymbolsPass : PassInfoMixin<StripSymbolsPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct StripNonDebugSymbolsPass : PassInfoMixin<StripNonDebugSymbolsPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct StripDebugDeclarePass : PassInfoMixin<StripDebugDeclarePass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct StripDeadDebugInfoPass : PassInfoMixin<StripDeadDebugInfoPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct StripDeadCGProfilePass : PassInfoMixin<StripDeadCGProfilePass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#ifndef LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
|
||||
#define LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <llvm/IR/PassManager.h>
|
||||
|
||||
namespace llvm {
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
: OS(OS), ThinLinkOS(ThinLinkOS),
|
||||
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
@@ -118,7 +119,7 @@ struct TypeMemberInfo {
|
||||
|
||||
// A virtual call target, i.e. an entry in a particular vtable.
|
||||
struct VirtualCallTarget {
|
||||
VirtualCallTarget(GlobalValue *Fn, const TypeMemberInfo *TM);
|
||||
LLVM_ABI VirtualCallTarget(GlobalValue *Fn, const TypeMemberInfo *TM);
|
||||
|
||||
// For testing only.
|
||||
VirtualCallTarget(const TypeMemberInfo *TM, bool IsBigEndian)
|
||||
@@ -202,22 +203,22 @@ struct VirtualCallTarget {
|
||||
// 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);
|
||||
LLVM_ABI 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);
|
||||
LLVM_ABI 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);
|
||||
LLVM_ABI void setAfterReturnValues(MutableArrayRef<VirtualCallTarget> Targets,
|
||||
uint64_t AllocAfter, unsigned BitWidth,
|
||||
int64_t &OffsetByte, uint64_t &OffsetBit);
|
||||
|
||||
} // end namespace wholeprogramdevirt
|
||||
|
||||
@@ -232,27 +233,28 @@ struct WholeProgramDevirtPass : public PassInfoMixin<WholeProgramDevirtPass> {
|
||||
: ExportSummary(ExportSummary), ImportSummary(ImportSummary) {
|
||||
assert(!(ExportSummary && ImportSummary));
|
||||
}
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
|
||||
};
|
||||
|
||||
struct VTableSlotSummary {
|
||||
StringRef TypeID;
|
||||
uint64_t ByteOffset;
|
||||
};
|
||||
bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO);
|
||||
void updatePublicTypeTestCalls(Module &M,
|
||||
bool WholeProgramVisibilityEnabledInLTO);
|
||||
void updateVCallVisibilityInModule(
|
||||
LLVM_ABI bool
|
||||
hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO);
|
||||
LLVM_ABI void
|
||||
updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO);
|
||||
LLVM_ABI void updateVCallVisibilityInModule(
|
||||
Module &M, bool WholeProgramVisibilityEnabledInLTO,
|
||||
const DenseSet<GlobalValue::GUID> &DynamicExportSymbols,
|
||||
bool ValidateAllVtablesHaveTypeInfos,
|
||||
function_ref<bool(StringRef)> IsVisibleToRegularObj);
|
||||
void updateVCallVisibilityInIndex(
|
||||
LLVM_ABI void updateVCallVisibilityInIndex(
|
||||
ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO,
|
||||
const DenseSet<GlobalValue::GUID> &DynamicExportSymbols,
|
||||
const DenseSet<GlobalValue::GUID> &VisibleToRegularObjSymbols);
|
||||
|
||||
void getVisibleToRegularObjVtableGUIDs(
|
||||
LLVM_ABI void getVisibleToRegularObjVtableGUIDs(
|
||||
ModuleSummaryIndex &Index,
|
||||
DenseSet<GlobalValue::GUID> &VisibleToRegularObjSymbols,
|
||||
function_ref<bool(StringRef)> IsVisibleToRegularObj);
|
||||
@@ -264,13 +266,13 @@ void getVisibleToRegularObjVtableGUIDs(
|
||||
/// locating the corresponding WPD resolution is recorded for the ValueInfo
|
||||
/// in case it is exported by cross module importing (in which case the
|
||||
/// devirtualized target name will need adjustment).
|
||||
void runWholeProgramDevirtOnIndex(
|
||||
LLVM_ABI void runWholeProgramDevirtOnIndex(
|
||||
ModuleSummaryIndex &Summary, std::set<GlobalValue::GUID> &ExportedGUIDs,
|
||||
std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap);
|
||||
|
||||
/// Call after cross-module importing to update the recorded single impl
|
||||
/// devirt target names for any locals that were exported.
|
||||
void updateIndexWPDForExports(
|
||||
LLVM_ABI void updateIndexWPDForExports(
|
||||
ModuleSummaryIndex &Summary,
|
||||
function_ref<bool(StringRef, ValueInfo)> isExported,
|
||||
std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
#define DEBUG_TYPE "instcombine"
|
||||
#include "llvm/Transforms/Utils/InstructionWorklist.h"
|
||||
@@ -52,18 +53,19 @@ private:
|
||||
static char ID;
|
||||
|
||||
public:
|
||||
explicit InstCombinePass(InstCombineOptions Opts = {});
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI explicit InstCombinePass(InstCombineOptions Opts = {});
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// The legacy pass manager's instcombine pass.
|
||||
///
|
||||
/// This is a basic whole-function wrapper around the instcombine utility. It
|
||||
/// will try to combine all instructions in the function.
|
||||
class InstructionCombiningPass : public FunctionPass {
|
||||
class LLVM_ABI InstructionCombiningPass : public FunctionPass {
|
||||
InstructionWorklist Worklist;
|
||||
|
||||
public:
|
||||
@@ -87,7 +89,7 @@ public:
|
||||
// into:
|
||||
// %Z = add int 2, %X
|
||||
//
|
||||
FunctionPass *createInstructionCombiningPass();
|
||||
LLVM_ABI FunctionPass *createInstructionCombiningPass();
|
||||
}
|
||||
|
||||
#undef DEBUG_TYPE
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -38,13 +39,15 @@ struct AddressSanitizerOptions {
|
||||
/// run intependently of the function address sanitizer.
|
||||
class AddressSanitizerPass : public PassInfoMixin<AddressSanitizerPass> {
|
||||
public:
|
||||
LLVM_ABI
|
||||
AddressSanitizerPass(const AddressSanitizerOptions &Options,
|
||||
bool UseGlobalGC = true, bool UseOdrIndicator = true,
|
||||
AsanDtorKind DestructorKind = AsanDtorKind::Global,
|
||||
AsanCtorKind ConstructorKind = AsanCtorKind::Global);
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
static bool isRequired() { return true; }
|
||||
|
||||
private:
|
||||
@@ -61,8 +64,9 @@ struct ASanAccessInfo {
|
||||
const bool IsWrite;
|
||||
const bool CompileKernel;
|
||||
|
||||
explicit ASanAccessInfo(int32_t Packed);
|
||||
ASanAccessInfo(bool IsWrite, bool CompileKernel, uint8_t AccessSizeIndex);
|
||||
LLVM_ABI explicit ASanAccessInfo(int32_t Packed);
|
||||
LLVM_ABI ASanAccessInfo(bool IsWrite, bool CompileKernel,
|
||||
uint8_t AccessSizeIndex);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_BOUNDSCHECKING_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <optional>
|
||||
|
||||
namespace llvm {
|
||||
@@ -33,10 +34,11 @@ public:
|
||||
};
|
||||
|
||||
BoundsCheckingPass(Options Opts) : Opts(Opts) {}
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
private:
|
||||
Options Opts;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_DATAFLOWSANITIZER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -23,7 +24,7 @@ public:
|
||||
DataFlowSanitizerPass(
|
||||
const std::vector<std::string> &ABIListFiles = std::vector<std::string>())
|
||||
: ABIListFiles(ABIListFiles) {}
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_GCOVPROFILER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/Instrumentation.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -20,7 +21,7 @@ namespace llvm {
|
||||
class GCOVProfilerPass : public PassInfoMixin<GCOVProfilerPass> {
|
||||
public:
|
||||
GCOVProfilerPass(const GCOVOptions &Options = GCOVOptions::getDefault()) : GCOVOpts(Options) { }
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
private:
|
||||
GCOVOptions GCOVOpts;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
@@ -40,10 +41,11 @@ class HWAddressSanitizerPass : public PassInfoMixin<HWAddressSanitizerPass> {
|
||||
public:
|
||||
explicit HWAddressSanitizerPass(HWAddressSanitizerOptions Options)
|
||||
: Options(Options){};
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
static bool isRequired() { return true; }
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
private:
|
||||
HWAddressSanitizerOptions Options;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/Instrumentation.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
InstrProfilingLoweringPass(const InstrProfOptions &Options, bool IsCS = false)
|
||||
: Options(Options), IsCS(IsCS) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_KCFI_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class KCFIPass : public PassInfoMixin<KCFIPass> {
|
||||
public:
|
||||
static bool isRequired() { return true; }
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
} // namespace llvm
|
||||
#endif // LLVM_TRANSFORMS_INSTRUMENTATION_KCFI_H
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -30,11 +31,12 @@ public:
|
||||
|
||||
explicit LowerAllowCheckPass(LowerAllowCheckPass::Options Opts)
|
||||
: Opts(std::move(Opts)) {};
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
static bool IsRequested();
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI static bool IsRequested();
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
private:
|
||||
LowerAllowCheckPass::Options Opts;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_MEMPROF_INSTRUMENTATION_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
@@ -28,8 +29,8 @@ class Module;
|
||||
/// record data about the allocations.
|
||||
class MemProfilerPass : public PassInfoMixin<MemProfilerPass> {
|
||||
public:
|
||||
explicit MemProfilerPass();
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI explicit MemProfilerPass();
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
@@ -37,8 +38,8 @@ public:
|
||||
/// to profile memory allocations and accesses.
|
||||
class ModuleMemProfilerPass : public PassInfoMixin<ModuleMemProfilerPass> {
|
||||
public:
|
||||
explicit ModuleMemProfilerPass();
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI explicit ModuleMemProfilerPass();
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/ProfileData/MemProf.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -29,9 +30,10 @@ class FileSystem;
|
||||
|
||||
class MemProfUsePass : public PassInfoMixin<MemProfUsePass> {
|
||||
public:
|
||||
explicit MemProfUsePass(std::string MemoryProfileFile,
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI explicit MemProfUsePass(
|
||||
std::string MemoryProfileFile,
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
private:
|
||||
std::string MemoryProfileFileName;
|
||||
@@ -42,7 +44,7 @@ namespace memprof {
|
||||
|
||||
// Extract all calls from the IR. Arrange them in a map from caller GUIDs to a
|
||||
// list of call sites, each of the form {LineLocation, CalleeGUID}.
|
||||
DenseMap<uint64_t, SmallVector<CallEdgeTy, 0>> extractCallsFromIR(
|
||||
LLVM_ABI DenseMap<uint64_t, SmallVector<CallEdgeTy, 0>> extractCallsFromIR(
|
||||
Module &M, const TargetLibraryInfo &TLI,
|
||||
function_ref<bool(uint64_t)> IsPresentInProfile = [](uint64_t) {
|
||||
return true;
|
||||
@@ -59,7 +61,7 @@ using LocToLocMap =
|
||||
|
||||
// Compute an undrifting map. The result is a map from caller GUIDs to an inner
|
||||
// map that maps source locations in the profile to those in the current IR.
|
||||
DenseMap<uint64_t, LocToLocMap>
|
||||
LLVM_ABI DenseMap<uint64_t, LocToLocMap>
|
||||
computeUndriftMap(Module &M, IndexedInstrProfReader *MemProfReader,
|
||||
const TargetLibraryInfo &TLI);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
@@ -25,8 +26,8 @@ struct MemorySanitizerOptions {
|
||||
MemorySanitizerOptions() : MemorySanitizerOptions(0, false, false, false){};
|
||||
MemorySanitizerOptions(int TrackOrigins, bool Recover, bool Kernel)
|
||||
: MemorySanitizerOptions(TrackOrigins, Recover, Kernel, false) {}
|
||||
MemorySanitizerOptions(int TrackOrigins, bool Recover, bool Kernel,
|
||||
bool EagerChecks);
|
||||
LLVM_ABI MemorySanitizerOptions(int TrackOrigins, bool Recover, bool Kernel,
|
||||
bool EagerChecks);
|
||||
bool Kernel;
|
||||
int TrackOrigins;
|
||||
bool Recover;
|
||||
@@ -42,9 +43,10 @@ struct MemorySanitizerOptions {
|
||||
struct MemorySanitizerPass : public PassInfoMixin<MemorySanitizerPass> {
|
||||
MemorySanitizerPass(MemorySanitizerOptions Options) : Options(Options) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
static bool isRequired() { return true; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -27,7 +28,7 @@ namespace llvm {
|
||||
/// functions aren't declared yet, the pass inserts the declarations.
|
||||
struct NumericalStabilitySanitizerPass
|
||||
: public PassInfoMixin<NumericalStabilitySanitizerPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
|
||||
@@ -19,21 +19,19 @@
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
extern cl::opt<bool> DebugInfoCorrelate;
|
||||
LLVM_ABI extern cl::opt<bool> DebugInfoCorrelate;
|
||||
|
||||
class Function;
|
||||
class Instruction;
|
||||
class Module;
|
||||
|
||||
namespace vfs {
|
||||
class FileSystem;
|
||||
} // namespace vfs
|
||||
|
||||
/// The instrumentation (profile-instr-gen) pass for IR based PGO.
|
||||
// We use this pass to create COMDAT profile variables for context
|
||||
// sensitive PGO (CSPGO). The reason to have a pass for this is CSPGO
|
||||
@@ -46,7 +44,7 @@ public:
|
||||
PGOInstrumentationGenCreateVar(std::string CSInstrName = "",
|
||||
bool Sampling = false)
|
||||
: CSInstrName(CSInstrName), ProfileSampling(Sampling) {}
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
|
||||
private:
|
||||
std::string CSInstrName;
|
||||
@@ -60,7 +58,7 @@ public:
|
||||
PGOInstrumentationGen(
|
||||
PGOInstrumentationType InstrumentationType = PGOInstrumentationType ::FDO)
|
||||
: InstrumentationType(InstrumentationType) {}
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
|
||||
private:
|
||||
// If this is a context sensitive instrumentation.
|
||||
@@ -70,11 +68,12 @@ private:
|
||||
/// The profile annotation (profile-instr-use) pass for IR based PGO.
|
||||
class PGOInstrumentationUse : public PassInfoMixin<PGOInstrumentationUse> {
|
||||
public:
|
||||
LLVM_ABI
|
||||
PGOInstrumentationUse(std::string Filename = "",
|
||||
std::string RemappingFilename = "", bool IsCS = false,
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
|
||||
private:
|
||||
std::string ProfileFileName;
|
||||
@@ -90,7 +89,7 @@ public:
|
||||
PGOIndirectCallPromotion(bool IsInLTO = false, bool SamplePGO = false)
|
||||
: InLTO(IsInLTO), SamplePGO(SamplePGO) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
|
||||
private:
|
||||
bool InLTO;
|
||||
@@ -102,13 +101,14 @@ class PGOMemOPSizeOpt : public PassInfoMixin<PGOMemOPSizeOpt> {
|
||||
public:
|
||||
PGOMemOPSizeOpt() = default;
|
||||
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &MAM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &MAM);
|
||||
};
|
||||
|
||||
void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
|
||||
uint64_t MaxCount);
|
||||
LLVM_ABI void setProfMetadata(Module *M, Instruction *TI,
|
||||
ArrayRef<uint64_t> EdgeCounts, uint64_t MaxCount);
|
||||
|
||||
void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count);
|
||||
LLVM_ABI void setIrrLoopHeaderMetadata(Module *M, Instruction *TI,
|
||||
uint64_t Count);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_REALTIMESANITIZER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Create ctor and init functions.
|
||||
struct RealtimeSanitizerPass : public PassInfoMixin<RealtimeSanitizerPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/Instrumentation.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -50,10 +51,10 @@ inline constexpr char kSanitizerBinaryMetadataAtomicsSection[] =
|
||||
class SanitizerBinaryMetadataPass
|
||||
: public PassInfoMixin<SanitizerBinaryMetadataPass> {
|
||||
public:
|
||||
explicit SanitizerBinaryMetadataPass(
|
||||
LLVM_ABI explicit SanitizerBinaryMetadataPass(
|
||||
SanitizerBinaryMetadataOptions Opts = {},
|
||||
ArrayRef<std::string> IgnorelistFiles = {});
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERCOVERAGE_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/SpecialCaseList.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#include "llvm/Transforms/Utils/Instrumentation.h"
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
Blocklist = SpecialCaseList::createOrDie(BlocklistFiles,
|
||||
*vfs::getRealFileSystem());
|
||||
}
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
@@ -25,7 +26,7 @@ class Module;
|
||||
/// inserts calls to runtime library functions. If the functions aren't declared
|
||||
/// yet, the pass inserts the declarations. Otherwise the existing globals are
|
||||
struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
@@ -34,7 +35,7 @@ struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {
|
||||
/// Create ctor and init functions.
|
||||
struct ModuleThreadSanitizerPass
|
||||
: public PassInfoMixin<ModuleThreadSanitizerPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define LLVM_TRANSFORMS_INSTRUMENTATION_TYPESANITIZER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
@@ -21,7 +22,7 @@ class FunctionPass;
|
||||
class Module;
|
||||
|
||||
struct TypeSanitizerPass : public PassInfoMixin<TypeSanitizerPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define LLVM_TRANSFORMS_OBJCARC_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -24,26 +25,26 @@ class Pass;
|
||||
//
|
||||
// ObjCARCContract - Late ObjC ARC cleanups.
|
||||
//
|
||||
Pass *createObjCARCContractPass();
|
||||
LLVM_ABI Pass *createObjCARCContractPass();
|
||||
|
||||
struct ObjCARCOptPass : public PassInfoMixin<ObjCARCOptPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct ObjCARCContractPass : public PassInfoMixin<ObjCARCContractPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct ObjCARCAPElimPass : public PassInfoMixin<ObjCARCAPElimPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct ObjCARCExpandPass : public PassInfoMixin<ObjCARCExpandPass> {
|
||||
PreservedAnalyses run(Function &M, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &M, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
struct PAEvalPass : public PassInfoMixin<PAEvalPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef LLVM_TRANSFORMS_SCALAR_H
|
||||
#define LLVM_TRANSFORMS_SCALAR_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
|
||||
#include <functional>
|
||||
|
||||
@@ -30,26 +31,26 @@ class Pass;
|
||||
// their other instructions become dead, to eliminate chains of dead
|
||||
// computations.
|
||||
//
|
||||
FunctionPass *createDeadCodeEliminationPass();
|
||||
LLVM_ABI FunctionPass *createDeadCodeEliminationPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// SROA - Replace aggregates or pieces of aggregates with scalar SSA values.
|
||||
//
|
||||
FunctionPass *createSROAPass(bool PreserveCFG = true);
|
||||
LLVM_ABI FunctionPass *createSROAPass(bool PreserveCFG = true);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LICM - This pass is a loop invariant code motion and memory promotion pass.
|
||||
//
|
||||
Pass *createLICMPass();
|
||||
LLVM_ABI Pass *createLICMPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
|
||||
// a loop's canonical induction variable as one of their indices.
|
||||
//
|
||||
Pass *createLoopStrengthReducePass();
|
||||
LLVM_ABI Pass *createLoopStrengthReducePass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -57,17 +58,18 @@ Pass *createLoopStrengthReducePass();
|
||||
// a loop terminator instruction by rewriting it in terms of another IV.
|
||||
// Expected to be run immediately after LSR.
|
||||
//
|
||||
Pass *createLoopTermFoldPass();
|
||||
LLVM_ABI Pass *createLoopTermFoldPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LoopUnroll - This pass is a simple loop unrolling pass.
|
||||
//
|
||||
Pass *createLoopUnrollPass(int OptLevel = 2, bool OnlyWhenForced = false,
|
||||
bool ForgetAllSCEV = false, int Threshold = -1,
|
||||
int Count = -1, int AllowPartial = -1,
|
||||
int Runtime = -1, int UpperBound = -1,
|
||||
int AllowPeeling = -1);
|
||||
LLVM_ABI Pass *createLoopUnrollPass(int OptLevel = 2,
|
||||
bool OnlyWhenForced = false,
|
||||
bool ForgetAllSCEV = false,
|
||||
int Threshold = -1, int Count = -1,
|
||||
int AllowPartial = -1, int Runtime = -1,
|
||||
int UpperBound = -1, int AllowPeeling = -1);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -76,14 +78,14 @@ Pass *createLoopUnrollPass(int OptLevel = 2, bool OnlyWhenForced = false,
|
||||
//
|
||||
// For example: 4 + (x + 5) -> x + (4 + 5)
|
||||
//
|
||||
FunctionPass *createReassociatePass();
|
||||
LLVM_ABI FunctionPass *createReassociatePass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
|
||||
// simplify terminator instructions, convert switches to lookup tables, etc.
|
||||
//
|
||||
FunctionPass *createCFGSimplificationPass(
|
||||
LLVM_ABI FunctionPass *createCFGSimplificationPass(
|
||||
SimplifyCFGOptions Options = SimplifyCFGOptions(),
|
||||
std::function<bool(const Function &)> Ftor = nullptr);
|
||||
|
||||
@@ -92,7 +94,7 @@ FunctionPass *createCFGSimplificationPass(
|
||||
// FlattenCFG - flatten CFG, reduce number of conditional branches by using
|
||||
// parallel-and and parallel-or mode, etc...
|
||||
//
|
||||
FunctionPass *createFlattenCFGPass();
|
||||
LLVM_ABI FunctionPass *createFlattenCFGPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -101,45 +103,45 @@ FunctionPass *createFlattenCFGPass();
|
||||
///
|
||||
/// When \p SkipUniformRegions is true the structizer will not structurize
|
||||
/// regions that only contain uniform branches.
|
||||
Pass *createStructurizeCFGPass(bool SkipUniformRegions = false);
|
||||
LLVM_ABI Pass *createStructurizeCFGPass(bool SkipUniformRegions = false);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// TailCallElimination - This pass eliminates call instructions to the current
|
||||
// function which occur immediately before return instructions.
|
||||
//
|
||||
FunctionPass *createTailCallEliminationPass();
|
||||
LLVM_ABI FunctionPass *createTailCallEliminationPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// EarlyCSE - This pass performs a simple and fast CSE pass over the dominator
|
||||
// tree.
|
||||
//
|
||||
FunctionPass *createEarlyCSEPass(bool UseMemorySSA = false);
|
||||
LLVM_ABI FunctionPass *createEarlyCSEPass(bool UseMemorySSA = false);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// ConstantHoisting - This pass prepares a function for expensive constants.
|
||||
//
|
||||
FunctionPass *createConstantHoistingPass();
|
||||
LLVM_ABI FunctionPass *createConstantHoistingPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Sink - Code Sinking
|
||||
//
|
||||
FunctionPass *createSinkingPass();
|
||||
LLVM_ABI FunctionPass *createSinkingPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LowerAtomic - Lower atomic intrinsics to non-atomic form
|
||||
//
|
||||
Pass *createLowerAtomicPass();
|
||||
LLVM_ABI Pass *createLowerAtomicPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// MergeICmps - Merge integer comparison chains into a memcmp
|
||||
//
|
||||
Pass *createMergeICmpsLegacyPass();
|
||||
LLVM_ABI Pass *createMergeICmpsLegacyPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -148,66 +150,67 @@ Pass *createMergeICmpsLegacyPass();
|
||||
// on the target. If AddressSpace is left to its default value, it will be
|
||||
// obtained from the TargetTransformInfo.
|
||||
//
|
||||
FunctionPass *createInferAddressSpacesPass(unsigned AddressSpace = ~0u);
|
||||
extern char &InferAddressSpacesID;
|
||||
LLVM_ABI FunctionPass *
|
||||
createInferAddressSpacesPass(unsigned AddressSpace = ~0u);
|
||||
LLVM_ABI extern char &InferAddressSpacesID;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// PartiallyInlineLibCalls - Tries to inline the fast path of library
|
||||
// calls such as sqrt.
|
||||
//
|
||||
FunctionPass *createPartiallyInlineLibCallsPass();
|
||||
LLVM_ABI FunctionPass *createPartiallyInlineLibCallsPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// SeparateConstOffsetFromGEP - Split GEPs for better CSE
|
||||
//
|
||||
FunctionPass *createSeparateConstOffsetFromGEPPass(bool LowerGEP = false);
|
||||
LLVM_ABI FunctionPass *
|
||||
createSeparateConstOffsetFromGEPPass(bool LowerGEP = false);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// SpeculativeExecution - Aggressively hoist instructions to enable
|
||||
// speculative execution on targets where branches are expensive.
|
||||
//
|
||||
FunctionPass *createSpeculativeExecutionPass();
|
||||
LLVM_ABI FunctionPass *createSpeculativeExecutionPass();
|
||||
|
||||
// Same as createSpeculativeExecutionPass, but does nothing unless
|
||||
// TargetTransformInfo::hasBranchDivergence() is true.
|
||||
FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass();
|
||||
LLVM_ABI FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// StraightLineStrengthReduce - This pass strength-reduces some certain
|
||||
// instruction patterns in straight-line code.
|
||||
//
|
||||
FunctionPass *createStraightLineStrengthReducePass();
|
||||
LLVM_ABI FunctionPass *createStraightLineStrengthReducePass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// NaryReassociate - Simplify n-ary operations by reassociation.
|
||||
//
|
||||
FunctionPass *createNaryReassociatePass();
|
||||
LLVM_ABI FunctionPass *createNaryReassociatePass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LoopDataPrefetch - Perform data prefetching in loops.
|
||||
//
|
||||
FunctionPass *createLoopDataPrefetchPass();
|
||||
LLVM_ABI FunctionPass *createLoopDataPrefetchPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This pass does instruction simplification on each
|
||||
// instruction in a function.
|
||||
//
|
||||
FunctionPass *createInstSimplifyLegacyPass();
|
||||
|
||||
LLVM_ABI FunctionPass *createInstSimplifyLegacyPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// createScalarizeMaskedMemIntrinPass - Replace masked load, store, gather
|
||||
// and scatter intrinsics with scalar code when target doesn't support them.
|
||||
//
|
||||
FunctionPass *createScalarizeMaskedMemIntrinLegacyPass();
|
||||
LLVM_ABI FunctionPass *createScalarizeMaskedMemIntrinLegacyPass();
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define LLVM_TRANSFORMS_SCALAR_EARLYCSE_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -31,9 +32,10 @@ struct EarlyCSEPass : PassInfoMixin<EarlyCSEPass> {
|
||||
EarlyCSEPass(bool UseMemorySSA = false) : UseMemorySSA(UseMemorySSA) {}
|
||||
|
||||
/// Run the pass over the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
bool UseMemorySSA;
|
||||
};
|
||||
|
||||
@@ -130,25 +130,26 @@ public:
|
||||
GVNPass(GVNOptions Options = {}) : Options(Options) {}
|
||||
|
||||
/// Run the pass over the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
/// This removes the specified instruction from
|
||||
/// our various maps and marks it for deletion.
|
||||
void salvageAndRemoveInstruction(Instruction *I);
|
||||
LLVM_ABI void salvageAndRemoveInstruction(Instruction *I);
|
||||
|
||||
DominatorTree &getDominatorTree() const { return *DT; }
|
||||
AAResults *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
|
||||
MemoryDependenceResults &getMemDep() const { return *MD; }
|
||||
|
||||
bool isPREEnabled() const;
|
||||
bool isLoadPREEnabled() const;
|
||||
bool isLoadInLoopPREEnabled() const;
|
||||
bool isLoadPRESplitBackedgeEnabled() const;
|
||||
bool isMemDepEnabled() const;
|
||||
bool isMemorySSAEnabled() const;
|
||||
LLVM_ABI bool isPREEnabled() const;
|
||||
LLVM_ABI bool isLoadPREEnabled() const;
|
||||
LLVM_ABI bool isLoadInLoopPREEnabled() const;
|
||||
LLVM_ABI bool isLoadPRESplitBackedgeEnabled() const;
|
||||
LLVM_ABI bool isMemDepEnabled() const;
|
||||
LLVM_ABI bool isMemorySSAEnabled() const;
|
||||
|
||||
/// This class holds the mapping between values and value numbers. It is used
|
||||
/// as an efficient mechanism to determine the expression-wise equivalence of
|
||||
@@ -194,29 +195,31 @@ public:
|
||||
bool areAllValsInBB(uint32_t Num, const BasicBlock *BB, GVNPass &GVN);
|
||||
|
||||
public:
|
||||
ValueTable();
|
||||
ValueTable(const ValueTable &Arg);
|
||||
ValueTable(ValueTable &&Arg);
|
||||
~ValueTable();
|
||||
ValueTable &operator=(const ValueTable &Arg);
|
||||
LLVM_ABI ValueTable();
|
||||
LLVM_ABI ValueTable(const ValueTable &Arg);
|
||||
LLVM_ABI ValueTable(ValueTable &&Arg);
|
||||
LLVM_ABI ~ValueTable();
|
||||
LLVM_ABI ValueTable &operator=(const ValueTable &Arg);
|
||||
|
||||
uint32_t lookupOrAdd(Value *V);
|
||||
uint32_t lookup(Value *V, bool Verify = true) const;
|
||||
uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
|
||||
Value *LHS, Value *RHS);
|
||||
uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock,
|
||||
uint32_t Num, GVNPass &GVN);
|
||||
void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock);
|
||||
bool exists(Value *V) const;
|
||||
void add(Value *V, uint32_t Num);
|
||||
void clear();
|
||||
void erase(Value *V);
|
||||
LLVM_ABI uint32_t lookupOrAdd(Value *V);
|
||||
LLVM_ABI uint32_t lookup(Value *V, bool Verify = true) const;
|
||||
LLVM_ABI uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
|
||||
Value *LHS, Value *RHS);
|
||||
LLVM_ABI uint32_t phiTranslate(const BasicBlock *BB,
|
||||
const BasicBlock *PhiBlock, uint32_t Num,
|
||||
GVNPass &GVN);
|
||||
LLVM_ABI void eraseTranslateCacheEntry(uint32_t Num,
|
||||
const BasicBlock &CurrBlock);
|
||||
LLVM_ABI bool exists(Value *V) const;
|
||||
LLVM_ABI void add(Value *V, uint32_t Num);
|
||||
LLVM_ABI void clear();
|
||||
LLVM_ABI void erase(Value *V);
|
||||
void setAliasAnalysis(AAResults *A) { AA = A; }
|
||||
AAResults *getAliasAnalysis() const { return AA; }
|
||||
void setMemDep(MemoryDependenceResults *M) { MD = M; }
|
||||
void setDomTree(DominatorTree *D) { DT = D; }
|
||||
uint32_t getNextUnusedValueNumber() { return NextValueNumber; }
|
||||
void verifyRemoved(const Value *) const;
|
||||
LLVM_ABI void verifyRemoved(const Value *) const;
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -289,9 +292,9 @@ private:
|
||||
leader_iterator(nullptr));
|
||||
}
|
||||
|
||||
void insert(uint32_t N, Value *V, const BasicBlock *BB);
|
||||
void erase(uint32_t N, Instruction *I, const BasicBlock *BB);
|
||||
void verifyRemoved(const Value *Inst) const;
|
||||
LLVM_ABI void insert(uint32_t N, Value *V, const BasicBlock *BB);
|
||||
LLVM_ABI void erase(uint32_t N, Instruction *I, const BasicBlock *BB);
|
||||
LLVM_ABI void verifyRemoved(const Value *Inst) const;
|
||||
void clear() {
|
||||
NumToLeaders.clear();
|
||||
TableAllocator.Reset();
|
||||
@@ -388,20 +391,20 @@ private:
|
||||
};
|
||||
|
||||
/// Create a legacy GVN pass.
|
||||
FunctionPass *createGVNPass();
|
||||
LLVM_ABI FunctionPass *createGVNPass();
|
||||
|
||||
/// A simple and fast domtree-based GVN pass to hoist common expressions
|
||||
/// from sibling branches.
|
||||
struct GVNHoistPass : PassInfoMixin<GVNHoistPass> {
|
||||
/// Run the pass over the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Uses an "inverted" value numbering to decide the similarity of
|
||||
/// expressions and sinks similar expressions into successors.
|
||||
struct GVNSinkPass : PassInfoMixin<GVNSinkPass> {
|
||||
/// Run the pass over the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
||||
#include "llvm/Analysis/DomTreeUpdater.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
@@ -102,36 +103,38 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
|
||||
unsigned DefaultBBDupThreshold;
|
||||
|
||||
public:
|
||||
JumpThreadingPass(int T = -1);
|
||||
LLVM_ABI JumpThreadingPass(int T = -1);
|
||||
|
||||
// Glue for old PM.
|
||||
bool runImpl(Function &F, FunctionAnalysisManager *FAM,
|
||||
TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
|
||||
LazyValueInfo *LVI, AAResults *AA,
|
||||
std::unique_ptr<DomTreeUpdater> DTU,
|
||||
std::optional<BlockFrequencyInfo *> BFI,
|
||||
std::optional<BranchProbabilityInfo *> BPI);
|
||||
LLVM_ABI bool runImpl(Function &F, FunctionAnalysisManager *FAM,
|
||||
TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
|
||||
LazyValueInfo *LVI, AAResults *AA,
|
||||
std::unique_ptr<DomTreeUpdater> DTU,
|
||||
std::optional<BlockFrequencyInfo *> BFI,
|
||||
std::optional<BranchProbabilityInfo *> BPI);
|
||||
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
DomTreeUpdater *getDomTreeUpdater() const { return DTU.get(); }
|
||||
void findLoopHeaders(Function &F);
|
||||
bool processBlock(BasicBlock *BB);
|
||||
bool maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB);
|
||||
void updateSSA(BasicBlock *BB, BasicBlock *NewBB,
|
||||
ValueToValueMapTy &ValueMapping);
|
||||
void cloneInstructions(ValueToValueMapTy &ValueMapping,
|
||||
BasicBlock::iterator BI, BasicBlock::iterator BE,
|
||||
BasicBlock *NewBB, BasicBlock *PredBB);
|
||||
bool tryThreadEdge(BasicBlock *BB,
|
||||
const SmallVectorImpl<BasicBlock *> &PredBBs,
|
||||
BasicBlock *SuccBB);
|
||||
void threadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs,
|
||||
BasicBlock *SuccBB);
|
||||
bool duplicateCondBranchOnPHIIntoPred(
|
||||
LLVM_ABI void findLoopHeaders(Function &F);
|
||||
LLVM_ABI bool processBlock(BasicBlock *BB);
|
||||
LLVM_ABI bool maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB);
|
||||
LLVM_ABI void updateSSA(BasicBlock *BB, BasicBlock *NewBB,
|
||||
ValueToValueMapTy &ValueMapping);
|
||||
LLVM_ABI void cloneInstructions(ValueToValueMapTy &ValueMapping,
|
||||
BasicBlock::iterator BI,
|
||||
BasicBlock::iterator BE, BasicBlock *NewBB,
|
||||
BasicBlock *PredBB);
|
||||
LLVM_ABI bool tryThreadEdge(BasicBlock *BB,
|
||||
const SmallVectorImpl<BasicBlock *> &PredBBs,
|
||||
BasicBlock *SuccBB);
|
||||
LLVM_ABI void threadEdge(BasicBlock *BB,
|
||||
const SmallVectorImpl<BasicBlock *> &PredBBs,
|
||||
BasicBlock *SuccBB);
|
||||
LLVM_ABI bool duplicateCondBranchOnPHIIntoPred(
|
||||
BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs);
|
||||
|
||||
bool computeValueKnownInPredecessorsImpl(
|
||||
LLVM_ABI bool computeValueKnownInPredecessorsImpl(
|
||||
Value *V, BasicBlock *BB, jumpthreading::PredValueInfo &Result,
|
||||
jumpthreading::ConstantPreference Preference,
|
||||
SmallPtrSet<Value *, 4> &RecursionSet, Instruction *CxtI = nullptr);
|
||||
@@ -145,29 +148,34 @@ public:
|
||||
RecursionSet, CxtI);
|
||||
}
|
||||
|
||||
Constant *evaluateOnPredecessorEdge(BasicBlock *BB, BasicBlock *PredPredBB,
|
||||
Value *cond, const DataLayout &DL);
|
||||
bool maybethreadThroughTwoBasicBlocks(BasicBlock *BB, Value *Cond);
|
||||
void threadThroughTwoBasicBlocks(BasicBlock *PredPredBB, BasicBlock *PredBB,
|
||||
BasicBlock *BB, BasicBlock *SuccBB);
|
||||
bool processThreadableEdges(Value *Cond, BasicBlock *BB,
|
||||
jumpthreading::ConstantPreference Preference,
|
||||
Instruction *CxtI = nullptr);
|
||||
LLVM_ABI Constant *evaluateOnPredecessorEdge(BasicBlock *BB,
|
||||
BasicBlock *PredPredBB,
|
||||
Value *cond,
|
||||
const DataLayout &DL);
|
||||
LLVM_ABI bool maybethreadThroughTwoBasicBlocks(BasicBlock *BB, Value *Cond);
|
||||
LLVM_ABI void threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
|
||||
BasicBlock *PredBB, BasicBlock *BB,
|
||||
BasicBlock *SuccBB);
|
||||
LLVM_ABI bool
|
||||
processThreadableEdges(Value *Cond, BasicBlock *BB,
|
||||
jumpthreading::ConstantPreference Preference,
|
||||
Instruction *CxtI = nullptr);
|
||||
|
||||
bool processBranchOnPHI(PHINode *PN);
|
||||
bool processBranchOnXOR(BinaryOperator *BO);
|
||||
bool processImpliedCondition(BasicBlock *BB);
|
||||
LLVM_ABI bool processBranchOnPHI(PHINode *PN);
|
||||
LLVM_ABI bool processBranchOnXOR(BinaryOperator *BO);
|
||||
LLVM_ABI bool processImpliedCondition(BasicBlock *BB);
|
||||
|
||||
bool simplifyPartiallyRedundantLoad(LoadInst *LI);
|
||||
void unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB, SelectInst *SI,
|
||||
PHINode *SIUse, unsigned Idx);
|
||||
LLVM_ABI bool simplifyPartiallyRedundantLoad(LoadInst *LI);
|
||||
LLVM_ABI void unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB,
|
||||
SelectInst *SI, PHINode *SIUse, unsigned Idx);
|
||||
|
||||
bool tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
|
||||
bool tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB);
|
||||
bool tryToUnfoldSelectInCurrBB(BasicBlock *BB);
|
||||
LLVM_ABI bool tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
|
||||
LLVM_ABI bool tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB);
|
||||
LLVM_ABI bool tryToUnfoldSelectInCurrBB(BasicBlock *BB);
|
||||
|
||||
bool processGuards(BasicBlock *BB);
|
||||
bool threadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI);
|
||||
LLVM_ABI bool processGuards(BasicBlock *BB);
|
||||
LLVM_ABI bool threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
|
||||
BranchInst *BI);
|
||||
|
||||
private:
|
||||
BasicBlock *splitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
|
||||
|
||||
@@ -40,8 +40,9 @@
|
||||
#include "llvm/Analysis/LoopAnalysisManager.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopNestAnalysis.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/PassInstrumentation.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/LCSSA.h"
|
||||
#include "llvm/Transforms/Utils/LoopSimplify.h"
|
||||
#include "llvm/Transforms/Utils/LoopUtils.h"
|
||||
@@ -91,11 +92,13 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U);
|
||||
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR,
|
||||
LPMUpdater &U);
|
||||
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
/// Add either a loop pass or a loop-nest pass to the pass manager. Append \p
|
||||
/// Pass to the list of loop passes if it has a dedicated \fn run() method for
|
||||
/// loops and to the list of loop-nest passes if the \fn run() method is for
|
||||
@@ -154,12 +157,12 @@ protected:
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U,
|
||||
PassInstrumentation &PI);
|
||||
|
||||
PreservedAnalyses runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR,
|
||||
LPMUpdater &U);
|
||||
PreservedAnalyses runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR,
|
||||
LPMUpdater &U);
|
||||
LLVM_ABI PreservedAnalyses
|
||||
runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U);
|
||||
LLVM_ABI PreservedAnalyses
|
||||
runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U);
|
||||
|
||||
private:
|
||||
static const Loop &getLoopFromIR(Loop &L) { return L; }
|
||||
@@ -413,9 +416,10 @@ public:
|
||||
}
|
||||
|
||||
/// Runs the loop passes across every loop in the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
static bool isRequired() { return true; }
|
||||
|
||||
@@ -497,11 +501,11 @@ class PrintLoopPass : public PassInfoMixin<PrintLoopPass> {
|
||||
std::string Banner;
|
||||
|
||||
public:
|
||||
PrintLoopPass();
|
||||
PrintLoopPass(raw_ostream &OS, const std::string &Banner = "");
|
||||
LLVM_ABI PrintLoopPass();
|
||||
LLVM_ABI PrintLoopPass(raw_ostream &OS, const std::string &Banner = "");
|
||||
|
||||
PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
|
||||
LoopStandardAnalysisResults &, LPMUpdater &);
|
||||
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
|
||||
LoopStandardAnalysisResults &, LPMUpdater &);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define LLVM_TRANSFORMS_SCALAR_LOWEREXPECTINTRINSIC_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -29,7 +30,7 @@ struct LowerExpectIntrinsicPass : PassInfoMixin<LowerExpectIntrinsicPass> {
|
||||
/// of the probabilities and frequencies of the CFG. After running this pass,
|
||||
/// no more expect intrinsics remain, allowing the rest of the optimizer to
|
||||
/// ignore them.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define LLVM_TRANSFORMS_SCALAR_SCCP_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
@@ -28,7 +29,7 @@ class Function;
|
||||
/// This pass performs function-level constant propagation and merging.
|
||||
class SCCPPass : public PassInfoMixin<SCCPPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define LLVM_TRANSFORMS_SCALAR_SCALARIZER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <optional>
|
||||
|
||||
namespace llvm {
|
||||
@@ -55,7 +56,7 @@ public:
|
||||
ScalarizerPass() = default;
|
||||
ScalarizerPass(const ScalarizerPassOptions &Options) : Options(Options) {}
|
||||
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
void setScalarizeVariableInsertExtract(bool Value) {
|
||||
Options.ScalarizeVariableInsertExtract = Value;
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
};
|
||||
|
||||
/// Create a legacy pass manager instance of the Scalarizer pass
|
||||
FunctionPass *createScalarizerPass(
|
||||
LLVM_ABI FunctionPass *createScalarizerPass(
|
||||
const ScalarizerPassOptions &Options = ScalarizerPassOptions());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -34,16 +35,17 @@ public:
|
||||
/// rather than optimal IR. That is, by default we bypass transformations that
|
||||
/// are likely to improve performance but make analysis for other passes more
|
||||
/// difficult.
|
||||
SimplifyCFGPass();
|
||||
LLVM_ABI SimplifyCFGPass();
|
||||
|
||||
/// Construct a pass with optional optimizations.
|
||||
SimplifyCFGPass(const SimplifyCFGOptions &PassOptions);
|
||||
LLVM_ABI SimplifyCFGPass(const SimplifyCFGOptions &PassOptions);
|
||||
|
||||
/// Run the pass over the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#ifndef LLVM_TRANSFORMS_UTILS_H
|
||||
#define LLVM_TRANSFORMS_UTILS_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ModulePass;
|
||||
@@ -25,16 +27,16 @@ class Pass;
|
||||
// LowerInvoke - This pass removes invoke instructions, converting them to call
|
||||
// instructions.
|
||||
//
|
||||
FunctionPass *createLowerInvokePass();
|
||||
extern char &LowerInvokePassID;
|
||||
LLVM_ABI FunctionPass *createLowerInvokePass();
|
||||
LLVM_ABI extern char &LowerInvokePassID;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LowerSwitch - This pass converts SwitchInst instructions into a sequence of
|
||||
// chained binary branch instructions.
|
||||
//
|
||||
FunctionPass *createLowerSwitchPass();
|
||||
extern char &LowerSwitchID;
|
||||
LLVM_ABI FunctionPass *createLowerSwitchPass();
|
||||
LLVM_ABI extern char &LowerSwitchID;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -43,7 +45,7 @@ extern char &LowerSwitchID;
|
||||
// variants, intended to run pre- and post-inlining, respectively. Only the
|
||||
// post-inlining variant is used with the legacy pass manager.
|
||||
//
|
||||
FunctionPass *createPostInlineEntryExitInstrumenterPass();
|
||||
LLVM_ABI FunctionPass *createPostInlineEntryExitInstrumenterPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -56,16 +58,16 @@ FunctionPass *createPostInlineEntryExitInstrumenterPass();
|
||||
// This pass obviously invalidates the CFG, but can update forward dominator
|
||||
// (set, immediate dominators, tree, and frontier) information.
|
||||
//
|
||||
FunctionPass *createBreakCriticalEdgesPass();
|
||||
extern char &BreakCriticalEdgesID;
|
||||
LLVM_ABI FunctionPass *createBreakCriticalEdgesPass();
|
||||
LLVM_ABI extern char &BreakCriticalEdgesID;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LCSSA - This pass inserts phi nodes at loop boundaries to simplify other loop
|
||||
// optimizations.
|
||||
//
|
||||
Pass *createLCSSAPass();
|
||||
extern char &LCSSAID;
|
||||
LLVM_ABI Pass *createLCSSAPass();
|
||||
LLVM_ABI extern char &LCSSAID;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -79,7 +81,7 @@ extern char &LCSSAID;
|
||||
// %Y = load i32* %X
|
||||
// ret i32 %Y
|
||||
//
|
||||
FunctionPass *createPromoteMemoryToRegisterPass();
|
||||
LLVM_ABI FunctionPass *createPromoteMemoryToRegisterPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -87,7 +89,7 @@ FunctionPass *createPromoteMemoryToRegisterPass();
|
||||
// references. In basically undoes the PromoteMemoryToRegister pass to make cfg
|
||||
// hacking easier.
|
||||
//
|
||||
FunctionPass *createRegToMemWrapperPass();
|
||||
LLVM_ABI FunctionPass *createRegToMemWrapperPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -97,8 +99,8 @@ FunctionPass *createRegToMemWrapperPass();
|
||||
//
|
||||
// AU.addRequiredID(LoopSimplifyID);
|
||||
//
|
||||
Pass *createLoopSimplifyPass();
|
||||
extern char &LoopSimplifyID;
|
||||
LLVM_ABI Pass *createLoopSimplifyPass();
|
||||
LLVM_ABI extern char &LoopSimplifyID;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
@@ -106,27 +108,27 @@ extern char &LoopSimplifyID;
|
||||
// blocks branch to N, and then N distributes control flow to all the original
|
||||
// exit blocks.
|
||||
//
|
||||
FunctionPass *createUnifyLoopExitsPass();
|
||||
LLVM_ABI FunctionPass *createUnifyLoopExitsPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// FixIrreducible - Convert each SCC with irreducible control-flow
|
||||
// into a natural loop.
|
||||
//
|
||||
FunctionPass *createFixIrreduciblePass();
|
||||
LLVM_ABI FunctionPass *createFixIrreduciblePass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// CanonicalizeFreezeInLoops - Canonicalize freeze instructions in loops so they
|
||||
// don't block SCEV.
|
||||
//
|
||||
Pass *createCanonicalizeFreezeInLoopsPass();
|
||||
LLVM_ABI Pass *createCanonicalizeFreezeInLoopsPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LowerGlobalDtorsLegacy - Lower @llvm.global_dtors by creating wrapper
|
||||
// functions that are registered in @llvm.global_ctors and which contain a call
|
||||
// to `__cxa_atexit` to register their destructor functions.
|
||||
ModulePass *createLowerGlobalDtorsLegacyPass();
|
||||
LLVM_ABI ModulePass *createLowerGlobalDtorsLegacyPass();
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_AMDGPUEMITPRINTF_H
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
Value *emitAMDGPUPrintfCall(IRBuilder<> &Builder, ArrayRef<Value *> Args,
|
||||
bool isBuffered);
|
||||
LLVM_ABI Value *emitAMDGPUPrintfCall(IRBuilder<> &Builder,
|
||||
ArrayRef<Value *> Args, bool isBuffered);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -47,7 +48,7 @@ struct ASanStackFrameLayout {
|
||||
uint64_t FrameSize; // Size of the frame in bytes.
|
||||
};
|
||||
|
||||
ASanStackFrameLayout ComputeASanStackFrameLayout(
|
||||
LLVM_ABI ASanStackFrameLayout ComputeASanStackFrameLayout(
|
||||
// The array of stack variables. The elements may get reordered and changed.
|
||||
SmallVectorImpl<ASanStackVariableDescription> &Vars,
|
||||
// AddressSanitizer's shadow granularity. Usually 8, may also be 16, 32, 64.
|
||||
@@ -58,19 +59,19 @@ ASanStackFrameLayout ComputeASanStackFrameLayout(
|
||||
uint64_t MinHeaderSize);
|
||||
|
||||
// Compute frame description, see DescribeAddressIfStack in ASan runtime.
|
||||
SmallString<64> ComputeASanStackFrameDescription(
|
||||
LLVM_ABI SmallString<64> ComputeASanStackFrameDescription(
|
||||
const SmallVectorImpl<ASanStackVariableDescription> &Vars);
|
||||
|
||||
// Returns shadow bytes with marked red zones. This shadow represents the state
|
||||
// if the stack frame when all local variables are inside of the own scope.
|
||||
SmallVector<uint8_t, 64>
|
||||
LLVM_ABI SmallVector<uint8_t, 64>
|
||||
GetShadowBytes(const SmallVectorImpl<ASanStackVariableDescription> &Vars,
|
||||
const ASanStackFrameLayout &Layout);
|
||||
|
||||
// Returns shadow bytes with marked red zones and after scope. This shadow
|
||||
// represents the state if the stack frame when all local variables are outside
|
||||
// of the own scope.
|
||||
SmallVector<uint8_t, 64> GetShadowBytesAfterScope(
|
||||
LLVM_ABI SmallVector<uint8_t, 64> GetShadowBytesAfterScope(
|
||||
// The array of stack variables. The elements may get reordered and changed.
|
||||
const SmallVectorImpl<ASanStackVariableDescription> &Vars,
|
||||
const ASanStackFrameLayout &Layout);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "llvm/Analysis/AssumeBundleQueries.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class AssumeInst;
|
||||
@@ -27,13 +28,13 @@ class Instruction;
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
|
||||
extern cl::opt<bool> EnableKnowledgeRetention;
|
||||
LLVM_ABI extern cl::opt<bool> EnableKnowledgeRetention;
|
||||
|
||||
/// Build a call to llvm.assume to preserve informations that can be derived
|
||||
/// from the given instruction.
|
||||
/// If no information derived from \p I, this call returns null.
|
||||
/// The returned instruction is not inserted anywhere.
|
||||
AssumeInst *buildAssumeFromInst(Instruction *I);
|
||||
LLVM_ABI AssumeInst *buildAssumeFromInst(Instruction *I);
|
||||
|
||||
/// Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert
|
||||
/// if before I. This is usually what need to be done to salvage the knowledge
|
||||
@@ -43,35 +44,35 @@ AssumeInst *buildAssumeFromInst(Instruction *I);
|
||||
/// The DominatorTree can optionally be provided to enable cross-block
|
||||
/// reasoning.
|
||||
/// This returns if a change was made.
|
||||
bool salvageKnowledge(Instruction *I, AssumptionCache *AC = nullptr,
|
||||
DominatorTree *DT = nullptr);
|
||||
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC = nullptr,
|
||||
DominatorTree *DT = nullptr);
|
||||
|
||||
/// Build and return a new assume created from the provided knowledge
|
||||
/// if the knowledge in the assume is fully redundant this will return nullptr
|
||||
AssumeInst *buildAssumeFromKnowledge(ArrayRef<RetainedKnowledge> Knowledge,
|
||||
Instruction *CtxI,
|
||||
AssumptionCache *AC = nullptr,
|
||||
DominatorTree *DT = nullptr);
|
||||
LLVM_ABI AssumeInst *
|
||||
buildAssumeFromKnowledge(ArrayRef<RetainedKnowledge> Knowledge,
|
||||
Instruction *CtxI, AssumptionCache *AC = nullptr,
|
||||
DominatorTree *DT = nullptr);
|
||||
|
||||
/// This pass attempts to minimize the number of assume without loosing any
|
||||
/// information.
|
||||
struct AssumeSimplifyPass : public PassInfoMixin<AssumeSimplifyPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// This pass will try to build an llvm.assume for every instruction in the
|
||||
/// function. Its main purpose is testing.
|
||||
struct AssumeBuilderPass : public PassInfoMixin<AssumeBuilderPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// canonicalize the RetainedKnowledge RK. it is assumed that RK is part of
|
||||
/// Assume. This will return an empty RetainedKnowledge if the knowledge is
|
||||
/// useless.
|
||||
RetainedKnowledge simplifyRetainedKnowledge(AssumeInst *Assume,
|
||||
RetainedKnowledge RK,
|
||||
AssumptionCache *AC,
|
||||
DominatorTree *DT);
|
||||
LLVM_ABI RetainedKnowledge simplifyRetainedKnowledge(AssumeInst *Assume,
|
||||
RetainedKnowledge RK,
|
||||
AssumptionCache *AC,
|
||||
DominatorTree *DT);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
@@ -46,13 +47,14 @@ class Value;
|
||||
/// instruction. If \p Updates is specified, collect all necessary DT updates
|
||||
/// into this vector. If \p KeepOneInputPHIs is true, one-input Phis in
|
||||
/// successors of blocks being deleted will be preserved.
|
||||
void detachDeadBlocks(ArrayRef <BasicBlock *> BBs,
|
||||
SmallVectorImpl<DominatorTree::UpdateType> *Updates,
|
||||
bool KeepOneInputPHIs = false);
|
||||
LLVM_ABI void
|
||||
detachDeadBlocks(ArrayRef<BasicBlock *> BBs,
|
||||
SmallVectorImpl<DominatorTree::UpdateType> *Updates,
|
||||
bool KeepOneInputPHIs = false);
|
||||
|
||||
/// Delete the specified block, which must have no predecessors.
|
||||
void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU = nullptr,
|
||||
bool KeepOneInputPHIs = false);
|
||||
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU = nullptr,
|
||||
bool KeepOneInputPHIs = false);
|
||||
|
||||
/// Delete the specified blocks from \p BB. The set of deleted blocks must have
|
||||
/// no predecessors that are not being deleted themselves. \p BBs must have no
|
||||
@@ -60,29 +62,32 @@ void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU = nullptr,
|
||||
/// relevant loop info updates should be done before this function is called.
|
||||
/// If \p KeepOneInputPHIs is true, one-input Phis in successors of blocks
|
||||
/// being deleted will be preserved.
|
||||
void DeleteDeadBlocks(ArrayRef <BasicBlock *> BBs,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
bool KeepOneInputPHIs = false);
|
||||
LLVM_ABI void DeleteDeadBlocks(ArrayRef<BasicBlock *> BBs,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
bool KeepOneInputPHIs = false);
|
||||
|
||||
/// Delete all basic blocks from \p F that are not reachable from its entry
|
||||
/// node. If \p KeepOneInputPHIs is true, one-input Phis in successors of
|
||||
/// blocks being deleted will be preserved.
|
||||
bool EliminateUnreachableBlocks(Function &F, DomTreeUpdater *DTU = nullptr,
|
||||
bool KeepOneInputPHIs = false);
|
||||
LLVM_ABI bool EliminateUnreachableBlocks(Function &F,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
bool KeepOneInputPHIs = false);
|
||||
|
||||
/// We know that BB has one predecessor. If there are any single-entry PHI nodes
|
||||
/// in it, fold them away. This handles the case when all entries to the PHI
|
||||
/// nodes in a block are guaranteed equal, such as when the block has exactly
|
||||
/// one predecessor.
|
||||
bool FoldSingleEntryPHINodes(BasicBlock *BB,
|
||||
MemoryDependenceResults *MemDep = nullptr);
|
||||
LLVM_ABI bool
|
||||
FoldSingleEntryPHINodes(BasicBlock *BB,
|
||||
MemoryDependenceResults *MemDep = nullptr);
|
||||
|
||||
/// Examine each PHI in the given block and delete it if it is dead. Also
|
||||
/// recursively delete any operands that become dead as a result. This includes
|
||||
/// tracing the def-use list from the PHI to see if it is ultimately unused or
|
||||
/// if it reaches an unused cycle. Return true if any PHIs were deleted.
|
||||
bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
LLVM_ABI bool DeleteDeadPHIs(BasicBlock *BB,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
|
||||
/// Attempts to merge a block into its predecessor, if possible. The return
|
||||
/// value indicates success or failure.
|
||||
@@ -93,12 +98,11 @@ bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr,
|
||||
/// BB, and BB will still be merged into its predecessor and removed.
|
||||
/// If \p DT is not nullptr, update it directly; in that case, DTU must be
|
||||
/// nullptr.
|
||||
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU = nullptr,
|
||||
LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
MemoryDependenceResults *MemDep = nullptr,
|
||||
bool PredecessorWithTwoSuccessors = false,
|
||||
DominatorTree *DT = nullptr);
|
||||
LLVM_ABI bool MergeBlockIntoPredecessor(
|
||||
BasicBlock *BB, DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
MemoryDependenceResults *MemDep = nullptr,
|
||||
bool PredecessorWithTwoSuccessors = false, DominatorTree *DT = nullptr);
|
||||
|
||||
/// Merge block(s) sucessors, if possible. Return true if at least two
|
||||
/// of the blocks were merged together.
|
||||
@@ -107,36 +111,36 @@ bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU = nullptr,
|
||||
/// must be in L. In addition, This utility calls on another utility:
|
||||
/// MergeBlockIntoPredecessor. Blocks are successfully merged when the call to
|
||||
/// MergeBlockIntoPredecessor returns true.
|
||||
bool MergeBlockSuccessorsIntoGivenBlocks(
|
||||
LLVM_ABI bool MergeBlockSuccessorsIntoGivenBlocks(
|
||||
SmallPtrSetImpl<BasicBlock *> &MergeBlocks, Loop *L = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr);
|
||||
|
||||
/// Try to remove redundant dbg.value instructions from given basic block.
|
||||
/// Returns true if at least one instruction was removed. Remove redundant
|
||||
/// pseudo ops when RemovePseudoOp is true.
|
||||
bool RemoveRedundantDbgInstrs(BasicBlock *BB);
|
||||
LLVM_ABI bool RemoveRedundantDbgInstrs(BasicBlock *BB);
|
||||
|
||||
/// Replace all uses of an instruction (specified by BI) with a value, then
|
||||
/// remove and delete the original instruction.
|
||||
void ReplaceInstWithValue(BasicBlock::iterator &BI, Value *V);
|
||||
LLVM_ABI void ReplaceInstWithValue(BasicBlock::iterator &BI, Value *V);
|
||||
|
||||
/// Replace the instruction specified by BI with the instruction specified by I.
|
||||
/// Copies DebugLoc from BI to I, if I doesn't already have a DebugLoc. The
|
||||
/// original instruction is deleted and BI is updated to point to the new
|
||||
/// instruction.
|
||||
void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI,
|
||||
Instruction *I);
|
||||
LLVM_ABI void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI,
|
||||
Instruction *I);
|
||||
|
||||
/// Replace the instruction specified by From with the instruction specified by
|
||||
/// To. Copies DebugLoc from BI to I, if I doesn't already have a DebugLoc.
|
||||
void ReplaceInstWithInst(Instruction *From, Instruction *To);
|
||||
LLVM_ABI void ReplaceInstWithInst(Instruction *From, Instruction *To);
|
||||
|
||||
/// Check if we can prove that all paths starting from this block converge
|
||||
/// to a block that either has a @llvm.experimental.deoptimize call
|
||||
/// prior to its terminating return instruction or is terminated by unreachable.
|
||||
/// All blocks in the traversed sequence must have an unique successor, maybe
|
||||
/// except for the last one.
|
||||
bool IsBlockFollowedByDeoptOrUnreachable(const BasicBlock *BB);
|
||||
LLVM_ABI bool IsBlockFollowedByDeoptOrUnreachable(const BasicBlock *BB);
|
||||
|
||||
/// Option class for critical edge splitting.
|
||||
///
|
||||
@@ -192,8 +196,9 @@ struct CriticalEdgeSplittingOptions {
|
||||
/// exit block. This function inserts the new PHIs, as needed. Preds is a list
|
||||
/// of preds inside the loop, SplitBB is the new loop exit block, and DestBB is
|
||||
/// the old loop exit, now the successor of SplitBB.
|
||||
void createPHIsForSplitLoopExit(ArrayRef<BasicBlock *> Preds,
|
||||
BasicBlock *SplitBB, BasicBlock *DestBB);
|
||||
LLVM_ABI void createPHIsForSplitLoopExit(ArrayRef<BasicBlock *> Preds,
|
||||
BasicBlock *SplitBB,
|
||||
BasicBlock *DestBB);
|
||||
|
||||
/// If this edge is a critical edge, insert a new node to split the critical
|
||||
/// edge. This will update the analyses passed in through the option struct.
|
||||
@@ -211,17 +216,19 @@ void createPHIsForSplitLoopExit(ArrayRef<BasicBlock *> Preds,
|
||||
/// IndirectBrInst. Splitting these edges will almost always create an invalid
|
||||
/// program because the address of the new block won't be the one that is jumped
|
||||
/// to.
|
||||
BasicBlock *SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
|
||||
const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions(),
|
||||
const Twine &BBName = "");
|
||||
LLVM_ABI BasicBlock *
|
||||
SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
|
||||
const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions(),
|
||||
const Twine &BBName = "");
|
||||
|
||||
/// If it is known that an edge is critical, SplitKnownCriticalEdge can be
|
||||
/// called directly, rather than calling SplitCriticalEdge first.
|
||||
BasicBlock *SplitKnownCriticalEdge(Instruction *TI, unsigned SuccNum,
|
||||
const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions(),
|
||||
const Twine &BBName = "");
|
||||
LLVM_ABI BasicBlock *
|
||||
SplitKnownCriticalEdge(Instruction *TI, unsigned SuccNum,
|
||||
const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions(),
|
||||
const Twine &BBName = "");
|
||||
|
||||
/// If an edge from Src to Dst is critical, split the edge and return true,
|
||||
/// otherwise return false. This method requires that there be an edge between
|
||||
@@ -242,33 +249,35 @@ SplitCriticalEdge(BasicBlock *Src, BasicBlock *Dst,
|
||||
|
||||
/// Loop over all of the edges in the CFG, breaking critical edges as they are
|
||||
/// found. Returns the number of broken edges.
|
||||
unsigned SplitAllCriticalEdges(Function &F,
|
||||
const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions());
|
||||
LLVM_ABI unsigned
|
||||
SplitAllCriticalEdges(Function &F, const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions());
|
||||
|
||||
/// Split the edge connecting the specified blocks, and return the newly created
|
||||
/// basic block between \p From and \p To.
|
||||
BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To,
|
||||
DominatorTree *DT = nullptr, LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const Twine &BBName = "");
|
||||
LLVM_ABI BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To,
|
||||
DominatorTree *DT = nullptr,
|
||||
LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const Twine &BBName = "");
|
||||
|
||||
/// Sets the unwind edge of an instruction to a particular successor.
|
||||
void setUnwindEdgeTo(Instruction *TI, BasicBlock *Succ);
|
||||
LLVM_ABI void setUnwindEdgeTo(Instruction *TI, BasicBlock *Succ);
|
||||
|
||||
/// Replaces all uses of OldPred with the NewPred block in all PHINodes in a
|
||||
/// block.
|
||||
void updatePhiNodes(BasicBlock *DestBB, BasicBlock *OldPred,
|
||||
BasicBlock *NewPred, PHINode *Until = nullptr);
|
||||
LLVM_ABI void updatePhiNodes(BasicBlock *DestBB, BasicBlock *OldPred,
|
||||
BasicBlock *NewPred, PHINode *Until = nullptr);
|
||||
|
||||
/// Split the edge connect the specficed blocks in the case that \p Succ is an
|
||||
/// Exception Handling Block
|
||||
BasicBlock *ehAwareSplitEdge(BasicBlock *BB, BasicBlock *Succ,
|
||||
LandingPadInst *OriginalPad = nullptr,
|
||||
PHINode *LandingPadReplacement = nullptr,
|
||||
const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions(),
|
||||
const Twine &BBName = "");
|
||||
LLVM_ABI BasicBlock *
|
||||
ehAwareSplitEdge(BasicBlock *BB, BasicBlock *Succ,
|
||||
LandingPadInst *OriginalPad = nullptr,
|
||||
PHINode *LandingPadReplacement = nullptr,
|
||||
const CriticalEdgeSplittingOptions &Options =
|
||||
CriticalEdgeSplittingOptions(),
|
||||
const Twine &BBName = "");
|
||||
|
||||
/// Split the specified block at the specified instruction.
|
||||
///
|
||||
@@ -280,10 +289,10 @@ BasicBlock *ehAwareSplitEdge(BasicBlock *BB, BasicBlock *Succ,
|
||||
/// branch. The new block with name \p BBName is returned.
|
||||
///
|
||||
/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
|
||||
BasicBlock *SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT,
|
||||
LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const Twine &BBName = "", bool Before = false);
|
||||
LLVM_ABI BasicBlock *SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt,
|
||||
DominatorTree *DT, LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const Twine &BBName = "", bool Before = false);
|
||||
inline BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT,
|
||||
LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
@@ -299,10 +308,11 @@ inline BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTr
|
||||
/// Everything before \p SplitPt stays in \p Old and everything starting with \p
|
||||
/// SplitPt moves to a new block. The two blocks are joined by an unconditional
|
||||
/// branch. The new block with name \p BBName is returned.
|
||||
BasicBlock *SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const Twine &BBName = "", bool Before = false);
|
||||
LLVM_ABI BasicBlock *SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const Twine &BBName = "", bool Before = false);
|
||||
inline BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
@@ -315,9 +325,11 @@ inline BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt,
|
||||
/// instructions after \p SplitPt stay in the old block. The new block and the
|
||||
/// old block are joined by inserting an unconditional branch to the end of the
|
||||
/// new block. The new block with name \p BBName is returned.
|
||||
BasicBlock *splitBlockBefore(BasicBlock *Old, BasicBlock::iterator SplitPt,
|
||||
DomTreeUpdater *DTU, LoopInfo *LI,
|
||||
MemorySSAUpdater *MSSAU, const Twine &BBName = "");
|
||||
LLVM_ABI BasicBlock *splitBlockBefore(BasicBlock *Old,
|
||||
BasicBlock::iterator SplitPt,
|
||||
DomTreeUpdater *DTU, LoopInfo *LI,
|
||||
MemorySSAUpdater *MSSAU,
|
||||
const Twine &BBName = "");
|
||||
inline BasicBlock *splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
|
||||
DomTreeUpdater *DTU, LoopInfo *LI,
|
||||
MemorySSAUpdater *MSSAU, const Twine &BBName = "") {
|
||||
@@ -340,11 +352,10 @@ inline BasicBlock *splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
|
||||
/// split is an exit of a loop with other exits).
|
||||
///
|
||||
/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
|
||||
BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
|
||||
const char *Suffix, DominatorTree *DT,
|
||||
LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
bool PreserveLCSSA = false);
|
||||
LLVM_ABI BasicBlock *SplitBlockPredecessors(
|
||||
BasicBlock *BB, ArrayRef<BasicBlock *> Preds, const char *Suffix,
|
||||
DominatorTree *DT, LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr, bool PreserveLCSSA = false);
|
||||
|
||||
/// This method introduces at least one new basic block into the function and
|
||||
/// moves some of the predecessors of BB to be predecessors of the new block.
|
||||
@@ -360,12 +371,10 @@ BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
|
||||
/// no other analyses. In particular, it does not preserve LoopSimplify
|
||||
/// (because it's complicated to handle the case where one of the edges being
|
||||
/// split is an exit of a loop with other exits).
|
||||
BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
|
||||
const char *Suffix,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
bool PreserveLCSSA = false);
|
||||
LLVM_ABI BasicBlock *SplitBlockPredecessors(
|
||||
BasicBlock *BB, ArrayRef<BasicBlock *> Preds, const char *Suffix,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr, bool PreserveLCSSA = false);
|
||||
|
||||
/// This method transforms the landing pad, OrigBB, by introducing two new basic
|
||||
/// blocks into the function. One of those new basic blocks gets the
|
||||
@@ -378,7 +387,7 @@ BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
|
||||
/// no other analyses. In particular, it does not preserve LoopSimplify
|
||||
/// (because it's complicated to handle the case where one of the edges being
|
||||
/// split is an exit of a loop with other exits).
|
||||
void SplitLandingPadPredecessors(
|
||||
LLVM_ABI void SplitLandingPadPredecessors(
|
||||
BasicBlock *OrigBB, ArrayRef<BasicBlock *> Preds, const char *Suffix,
|
||||
const char *Suffix2, SmallVectorImpl<BasicBlock *> &NewBBs,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
|
||||
@@ -388,9 +397,9 @@ void SplitLandingPadPredecessors(
|
||||
/// which ends in an unconditional branch. If the return instruction returns a
|
||||
/// value defined by a PHI, propagate the right value into the return. It
|
||||
/// returns the new return instruction in the predecessor.
|
||||
ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
|
||||
BasicBlock *Pred,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
LLVM_ABI ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
|
||||
BasicBlock *Pred,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
/// Split the containing block at the specified instruction - everything before
|
||||
/// SplitBefore stays in the old basic block, and the rest of the instructions
|
||||
@@ -413,12 +422,11 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
|
||||
/// Returns the NewBasicBlock's terminator.
|
||||
///
|
||||
/// Updates DTU and LI if given.
|
||||
Instruction *SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore,
|
||||
bool Unreachable,
|
||||
MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
LoopInfo *LI = nullptr,
|
||||
BasicBlock *ThenBlock = nullptr);
|
||||
LLVM_ABI Instruction *
|
||||
SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore,
|
||||
bool Unreachable, MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
|
||||
BasicBlock *ThenBlock = nullptr);
|
||||
|
||||
inline Instruction *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
|
||||
bool Unreachable,
|
||||
@@ -433,12 +441,11 @@ inline Instruction *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBef
|
||||
|
||||
/// Similar to SplitBlockAndInsertIfThen, but the inserted block is on the false
|
||||
/// path of the branch.
|
||||
Instruction *SplitBlockAndInsertIfElse(Value *Cond, BasicBlock::iterator SplitBefore,
|
||||
bool Unreachable,
|
||||
MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
LoopInfo *LI = nullptr,
|
||||
BasicBlock *ElseBlock = nullptr);
|
||||
LLVM_ABI Instruction *
|
||||
SplitBlockAndInsertIfElse(Value *Cond, BasicBlock::iterator SplitBefore,
|
||||
bool Unreachable, MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
|
||||
BasicBlock *ElseBlock = nullptr);
|
||||
|
||||
inline Instruction *SplitBlockAndInsertIfElse(Value *Cond, Instruction *SplitBefore,
|
||||
bool Unreachable,
|
||||
@@ -467,13 +474,10 @@ inline Instruction *SplitBlockAndInsertIfElse(Value *Cond, Instruction *SplitBef
|
||||
/// Tail
|
||||
///
|
||||
/// Updates DT if given.
|
||||
void SplitBlockAndInsertIfThenElse(Value *Cond,
|
||||
BasicBlock::iterator SplitBefore,
|
||||
Instruction **ThenTerm,
|
||||
Instruction **ElseTerm,
|
||||
MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
LoopInfo *LI = nullptr);
|
||||
LLVM_ABI void SplitBlockAndInsertIfThenElse(
|
||||
Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm,
|
||||
Instruction **ElseTerm, MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr);
|
||||
|
||||
inline void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
|
||||
Instruction **ThenTerm,
|
||||
@@ -513,15 +517,11 @@ inline void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
|
||||
/// caller must ensure that Tail is reachable from Head.
|
||||
/// Returns the newly created blocks in \p ThenBlock and \p ElseBlock.
|
||||
/// Updates DTU and LI if given.
|
||||
void SplitBlockAndInsertIfThenElse(Value *Cond,
|
||||
BasicBlock::iterator SplitBefore,
|
||||
BasicBlock **ThenBlock,
|
||||
BasicBlock **ElseBlock,
|
||||
bool UnreachableThen = false,
|
||||
bool UnreachableElse = false,
|
||||
MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
LoopInfo *LI = nullptr);
|
||||
LLVM_ABI void SplitBlockAndInsertIfThenElse(
|
||||
Value *Cond, BasicBlock::iterator SplitBefore, BasicBlock **ThenBlock,
|
||||
BasicBlock **ElseBlock, bool UnreachableThen = false,
|
||||
bool UnreachableElse = false, MDNode *BranchWeights = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr);
|
||||
|
||||
inline void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
|
||||
BasicBlock **ThenBlock,
|
||||
@@ -539,7 +539,7 @@ inline void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
|
||||
/// that \p End is assumed > 0, and thus not checked on entry) at \p
|
||||
/// SplitBefore. Returns the first insert point in the loop body, and the
|
||||
/// PHINode for the induction variable (i.e. "i" above).
|
||||
std::pair<Instruction*, Value*>
|
||||
LLVM_ABI std::pair<Instruction *, Value *>
|
||||
SplitBlockAndInsertSimpleForLoop(Value *End, BasicBlock::iterator SplitBefore);
|
||||
|
||||
/// Utility function for performing a given action on each lane of a vector
|
||||
@@ -550,7 +550,7 @@ SplitBlockAndInsertSimpleForLoop(Value *End, BasicBlock::iterator SplitBefore);
|
||||
/// IRBuilder whose insert point is correctly set for instantiating the
|
||||
/// given index, and a value which is (at runtime) the index to access.
|
||||
/// This index *may* be a constant.
|
||||
void SplitBlockAndInsertForEachLane(
|
||||
LLVM_ABI void SplitBlockAndInsertForEachLane(
|
||||
ElementCount EC, Type *IndexTy, BasicBlock::iterator InsertBefore,
|
||||
std::function<void(IRBuilderBase &, Value *)> Func);
|
||||
|
||||
@@ -562,7 +562,7 @@ void SplitBlockAndInsertForEachLane(
|
||||
/// arguments an IRBuilder whose insert point is correctly set for instantiating
|
||||
/// the given index, and a value which is (at runtime) the index to access. This
|
||||
/// index *may* be a constant.
|
||||
void SplitBlockAndInsertForEachLane(
|
||||
LLVM_ABI void SplitBlockAndInsertForEachLane(
|
||||
Value *End, BasicBlock::iterator InsertBefore,
|
||||
std::function<void(IRBuilderBase &, Value *)> Func);
|
||||
|
||||
@@ -574,8 +574,8 @@ void SplitBlockAndInsertForEachLane(
|
||||
///
|
||||
/// This does no checking to see if the true/false blocks have large or unsavory
|
||||
/// instructions in them.
|
||||
BranchInst *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
|
||||
BasicBlock *&IfFalse);
|
||||
LLVM_ABI BranchInst *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
|
||||
BasicBlock *&IfFalse);
|
||||
|
||||
// Split critical edges where the source of the edge is an indirectbr
|
||||
// instruction. This isn't always possible, but we can handle some easy cases.
|
||||
@@ -598,17 +598,18 @@ BranchInst *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
|
||||
// If BPI and BFI aren't non-null, BPI/BFI will be updated accordingly.
|
||||
// When `IgnoreBlocksWithoutPHI` is set to `true` critical edges leading to a
|
||||
// block without phi-instructions will not be split.
|
||||
bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI,
|
||||
BranchProbabilityInfo *BPI = nullptr,
|
||||
BlockFrequencyInfo *BFI = nullptr);
|
||||
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F,
|
||||
bool IgnoreBlocksWithoutPHI,
|
||||
BranchProbabilityInfo *BPI = nullptr,
|
||||
BlockFrequencyInfo *BFI = nullptr);
|
||||
|
||||
// Utility function for inverting branch condition and for swapping its
|
||||
// successors
|
||||
void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder);
|
||||
LLVM_ABI void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder);
|
||||
|
||||
// Check whether the function only has simple terminator:
|
||||
// br/brcond/unreachable/ret
|
||||
bool hasOnlySimpleTerminator(const Function &F);
|
||||
LLVM_ABI bool hasOnlySimpleTerminator(const Function &F);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H
|
||||
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Value;
|
||||
@@ -28,17 +29,22 @@ namespace llvm {
|
||||
/// If the library function is unavailable, this doesn't modify it.
|
||||
///
|
||||
/// Returns true if any attributes were set and false otherwise.
|
||||
bool inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name,
|
||||
const TargetLibraryInfo &TLI);
|
||||
bool inferNonMandatoryLibFuncAttrs(Function &F, const TargetLibraryInfo &TLI);
|
||||
LLVM_ABI bool inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name,
|
||||
const TargetLibraryInfo &TLI);
|
||||
LLVM_ABI bool inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
const TargetLibraryInfo &TLI);
|
||||
|
||||
/// Calls getOrInsertFunction() and then makes sure to add mandatory
|
||||
/// argument attributes.
|
||||
FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
|
||||
LibFunc TheLibFunc, FunctionType *T,
|
||||
AttributeList AttributeList);
|
||||
FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
|
||||
LibFunc TheLibFunc, FunctionType *T);
|
||||
LLVM_ABI FunctionCallee getOrInsertLibFunc(Module *M,
|
||||
const TargetLibraryInfo &TLI,
|
||||
LibFunc TheLibFunc,
|
||||
FunctionType *T,
|
||||
AttributeList AttributeList);
|
||||
LLVM_ABI FunctionCallee getOrInsertLibFunc(Module *M,
|
||||
const TargetLibraryInfo &TLI,
|
||||
LibFunc TheLibFunc,
|
||||
FunctionType *T);
|
||||
template <typename... ArgsTy>
|
||||
FunctionCallee getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
|
||||
LibFunc TheLibFunc, AttributeList AttributeList,
|
||||
@@ -67,219 +73,238 @@ namespace llvm {
|
||||
// function signatures; it does not apply other relevant attributes for
|
||||
// function signatures, including sign/zero-extension for arguments and return
|
||||
// values.
|
||||
void markRegisterParameterAttributes(Function *F);
|
||||
LLVM_ABI void markRegisterParameterAttributes(Function *F);
|
||||
|
||||
/// Check whether the library function is available on target and also that
|
||||
/// it in the current Module is a Function with the right type.
|
||||
bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
|
||||
LibFunc TheLibFunc);
|
||||
bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
|
||||
StringRef Name);
|
||||
LLVM_ABI bool isLibFuncEmittable(const Module *M,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc TheLibFunc);
|
||||
LLVM_ABI bool isLibFuncEmittable(const Module *M,
|
||||
const TargetLibraryInfo *TLI,
|
||||
StringRef Name);
|
||||
|
||||
/// Check whether the overloaded floating point function
|
||||
/// corresponding to \a Ty is available.
|
||||
bool hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty,
|
||||
LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn);
|
||||
LLVM_ABI bool hasFloatFn(const Module *M, const TargetLibraryInfo *TLI,
|
||||
Type *Ty, LibFunc DoubleFn, LibFunc FloatFn,
|
||||
LibFunc LongDoubleFn);
|
||||
|
||||
/// Get the name of the overloaded floating point function
|
||||
/// corresponding to \a Ty. Return the LibFunc in \a TheLibFunc.
|
||||
StringRef getFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty,
|
||||
LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn,
|
||||
LibFunc &TheLibFunc);
|
||||
LLVM_ABI StringRef getFloatFn(const Module *M, const TargetLibraryInfo *TLI,
|
||||
Type *Ty, LibFunc DoubleFn, LibFunc FloatFn,
|
||||
LibFunc LongDoubleFn, LibFunc &TheLibFunc);
|
||||
|
||||
/// Emit a call to the strlen function to the builder, for the specified
|
||||
/// pointer. Ptr is required to be some pointer type, and the return value has
|
||||
/// 'size_t' type.
|
||||
Value *emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the wcslen function to the builder, for the specified
|
||||
/// pointer. Ptr is required to be some pointer type, and the return value has
|
||||
/// 'size_t' type.
|
||||
Value *emitWcsLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitWcsLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strdup function to the builder, for the specified
|
||||
/// pointer. Ptr is required to be some pointer type, and the return value has
|
||||
/// 'i8*' type.
|
||||
Value *emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrDup(Value *Ptr, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strchr function to the builder, for the specified
|
||||
/// pointer and character. Ptr is required to be some pointer type, and the
|
||||
/// return value has 'i8*' type.
|
||||
Value *emitStrChr(Value *Ptr, char C, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrChr(Value *Ptr, char C, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strncmp function to the builder.
|
||||
Value *emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strcpy function to the builder, for the specified
|
||||
/// pointer arguments.
|
||||
Value *emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the stpcpy function to the builder, for the specified
|
||||
/// pointer arguments.
|
||||
Value *emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strncpy function to the builder, for the specified
|
||||
/// pointer arguments and length.
|
||||
Value *emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrNCpy(Value *Dst, Value *Src, Value *Len,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the stpncpy function to the builder, for the specified
|
||||
/// pointer arguments and length.
|
||||
Value *emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStpNCpy(Value *Dst, Value *Src, Value *Len,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the __memcpy_chk function to the builder. This expects that
|
||||
/// the Len and ObjSize have type 'size_t' and Dst/Src are pointers.
|
||||
Value *emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitMemCpyChk(Value *Dst, Value *Src, Value *Len,
|
||||
Value *ObjSize, IRBuilderBase &B,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the mempcpy function.
|
||||
Value *emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitMemPCpy(Value *Dst, Value *Src, Value *Len,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the memchr function. This assumes that Ptr is a pointer,
|
||||
/// Val is an 'int' value, and Len is an 'size_t' value.
|
||||
Value *emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitMemChr(Value *Ptr, Value *Val, Value *Len,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the memrchr function, analogously to emitMemChr.
|
||||
Value *emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitMemRChr(Value *Ptr, Value *Val, Value *Len,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the memcmp function.
|
||||
Value *emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the bcmp function.
|
||||
Value *emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the memccpy function.
|
||||
Value *emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the snprintf function.
|
||||
Value *emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
|
||||
ArrayRef<Value *> Args, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
|
||||
ArrayRef<Value *> Args, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the sprintf function.
|
||||
Value *emitSPrintf(Value *Dest, Value *Fmt, ArrayRef<Value *> VariadicArgs,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitSPrintf(Value *Dest, Value *Fmt,
|
||||
ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strcat function.
|
||||
Value *emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strlcpy function.
|
||||
Value *emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrLCpy(Value *Dest, Value *Src, Value *Size,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strlcat function.
|
||||
Value *emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrLCat(Value *Dest, Value *Src, Value *Size,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the strncat function.
|
||||
Value *emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitStrNCat(Value *Dest, Value *Src, Value *Size,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the vsnprintf function.
|
||||
Value *emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt,
|
||||
Value *VAList, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the vsprintf function.
|
||||
Value *emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
|
||||
IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the unary function named 'Name' (e.g. 'floor'). This
|
||||
/// function is known to take a single of type matching 'Op' and returns one
|
||||
/// value with the same type. If 'Op' is a long double, 'l' is added as the
|
||||
/// suffix of name, if 'Op' is a float, we add a 'f' suffix.
|
||||
Value *emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
|
||||
StringRef Name, IRBuilderBase &B,
|
||||
const AttributeList &Attrs);
|
||||
LLVM_ABI Value *emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
|
||||
StringRef Name, IRBuilderBase &B,
|
||||
const AttributeList &Attrs);
|
||||
|
||||
/// Emit a call to the unary function DoubleFn, FloatFn or LongDoubleFn,
|
||||
/// depending of the type of Op.
|
||||
Value *emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
|
||||
LibFunc DoubleFn, LibFunc FloatFn,
|
||||
LibFunc LongDoubleFn, IRBuilderBase &B,
|
||||
const AttributeList &Attrs);
|
||||
LLVM_ABI Value *emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
|
||||
LibFunc DoubleFn, LibFunc FloatFn,
|
||||
LibFunc LongDoubleFn, IRBuilderBase &B,
|
||||
const AttributeList &Attrs);
|
||||
|
||||
/// Emit a call to the binary function named 'Name' (e.g. 'fmin'). This
|
||||
/// function is known to take type matching 'Op1' and 'Op2' and return one
|
||||
/// value with the same type. If 'Op1/Op2' are long double, 'l' is added as
|
||||
/// the suffix of name, if 'Op1/Op2' are float, we add a 'f' suffix.
|
||||
Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2,
|
||||
const TargetLibraryInfo *TLI,
|
||||
StringRef Name, IRBuilderBase &B,
|
||||
const AttributeList &Attrs);
|
||||
LLVM_ABI Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2,
|
||||
const TargetLibraryInfo *TLI,
|
||||
StringRef Name, IRBuilderBase &B,
|
||||
const AttributeList &Attrs);
|
||||
|
||||
/// Emit a call to the binary function DoubleFn, FloatFn or LongDoubleFn,
|
||||
/// depending of the type of Op1.
|
||||
Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2,
|
||||
const TargetLibraryInfo *TLI, LibFunc DoubleFn,
|
||||
LibFunc FloatFn, LibFunc LongDoubleFn,
|
||||
IRBuilderBase &B, const AttributeList &Attrs);
|
||||
LLVM_ABI Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc DoubleFn, LibFunc FloatFn,
|
||||
LibFunc LongDoubleFn, IRBuilderBase &B,
|
||||
const AttributeList &Attrs);
|
||||
|
||||
/// Emit a call to the putchar function. This assumes that Char is an 'int'.
|
||||
Value *emitPutChar(Value *Char, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitPutChar(Value *Char, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the puts function. This assumes that Str is some pointer.
|
||||
Value *emitPutS(Value *Str, IRBuilderBase &B, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitPutS(Value *Str, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the fputc function. This assumes that Char is an 'int', and
|
||||
/// File is a pointer to FILE.
|
||||
Value *emitFPutC(Value *Char, Value *File, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitFPutC(Value *Char, Value *File, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the fputs function. Str is required to be a pointer and
|
||||
/// File is a pointer to FILE.
|
||||
Value *emitFPutS(Value *Str, Value *File, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitFPutS(Value *Str, Value *File, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the fwrite function. This assumes that Ptr is a pointer,
|
||||
/// Size is an 'size_t', and File is a pointer to FILE.
|
||||
Value *emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitFWrite(Value *Ptr, Value *Size, Value *File,
|
||||
IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the malloc function.
|
||||
Value *emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI Value *emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Emit a call to the calloc function.
|
||||
Value *emitCalloc(Value *Num, Value *Size, IRBuilderBase &B,
|
||||
const TargetLibraryInfo &TLI, unsigned AddrSpace);
|
||||
LLVM_ABI Value *emitCalloc(Value *Num, Value *Size, IRBuilderBase &B,
|
||||
const TargetLibraryInfo &TLI, unsigned AddrSpace);
|
||||
|
||||
/// Emit a call to the hot/cold operator new function.
|
||||
Value *emitHotColdNew(Value *Num, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI, LibFunc NewFunc,
|
||||
uint8_t HotCold);
|
||||
Value *emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI, LibFunc NewFunc,
|
||||
uint8_t HotCold);
|
||||
Value *emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI, LibFunc NewFunc,
|
||||
uint8_t HotCold);
|
||||
Value *emitHotColdNewAlignedNoThrow(Value *Num, Value *Align, Value *NoThrow,
|
||||
IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc NewFunc, uint8_t HotCold);
|
||||
Value *emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B,
|
||||
LLVM_ABI Value *emitHotColdNew(Value *Num, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI, LibFunc NewFunc,
|
||||
uint8_t HotCold);
|
||||
LLVM_ABI Value *emitHotColdNewNoThrow(Value *Num, Value *NoThrow,
|
||||
IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc NewFunc, uint8_t HotCold);
|
||||
LLVM_ABI Value *emitHotColdNewAligned(Value *Num, Value *Align,
|
||||
IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc NewFunc, uint8_t HotCold);
|
||||
LLVM_ABI Value *emitHotColdNewAlignedNoThrow(Value *Num, Value *Align,
|
||||
Value *NoThrow, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc NewFunc,
|
||||
uint8_t HotCold);
|
||||
LLVM_ABI Value *emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc NewFunc, uint8_t HotCold);
|
||||
LLVM_ABI Value *
|
||||
emitHotColdSizeReturningNewAligned(Value *Num, Value *Align, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc NewFunc, uint8_t HotCold);
|
||||
Value *emitHotColdSizeReturningNewAligned(Value *Num, Value *Align,
|
||||
IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI,
|
||||
LibFunc NewFunc, uint8_t HotCold);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -66,25 +67,25 @@ public:
|
||||
///}
|
||||
|
||||
/// Finalizer that will trigger actions like function removal from the CG.
|
||||
bool finalize();
|
||||
LLVM_ABI bool finalize();
|
||||
|
||||
/// Remove \p Fn from the call graph.
|
||||
void removeFunction(Function &Fn);
|
||||
LLVM_ABI void removeFunction(Function &Fn);
|
||||
|
||||
/// After an CGSCC pass changes a function in ways that affect the call
|
||||
/// graph, this method can be called to update it.
|
||||
void reanalyzeFunction(Function &Fn);
|
||||
LLVM_ABI void reanalyzeFunction(Function &Fn);
|
||||
|
||||
/// If a new function was created by outlining, this method can be called
|
||||
/// to update the call graph for the new function. Note that the old one
|
||||
/// still needs to be re-analyzed or manually updated.
|
||||
void registerOutlinedFunction(Function &OriginalFn, Function &NewFn);
|
||||
LLVM_ABI void registerOutlinedFunction(Function &OriginalFn, Function &NewFn);
|
||||
|
||||
/// Replace \p OldFn in the call graph (and SCC) with \p NewFn. The uses
|
||||
/// outside the call graph and the function \p OldFn are not modified.
|
||||
/// Note that \p OldFn is also removed from the call graph
|
||||
/// (\see removeFunction).
|
||||
void replaceFunctionWith(Function &OldFn, Function &NewFn);
|
||||
LLVM_ABI void replaceFunctionWith(Function &OldFn, Function &NewFn);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
|
||||
|
||||
#include "llvm/Analysis/CtxProfAnalysis.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
namespace llvm {
|
||||
template <typename T> class ArrayRef;
|
||||
class Constant;
|
||||
@@ -32,8 +33,8 @@ class Value;
|
||||
/// match exactly, they must at least be bitcast compatible. If \p FailureReason
|
||||
/// is non-null and the indirect call cannot be promoted, the failure reason
|
||||
/// will be stored in it.
|
||||
bool isLegalToPromote(const CallBase &CB, Function *Callee,
|
||||
const char **FailureReason = nullptr);
|
||||
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee,
|
||||
const char **FailureReason = nullptr);
|
||||
|
||||
/// Promote the given indirect call site to unconditionally call \p Callee.
|
||||
///
|
||||
@@ -42,8 +43,8 @@ bool isLegalToPromote(const CallBase &CB, Function *Callee,
|
||||
/// of the callee, bitcast instructions are inserted where appropriate. If \p
|
||||
/// RetBitCast is non-null, it will be used to store the return value bitcast,
|
||||
/// if created.
|
||||
CallBase &promoteCall(CallBase &CB, Function *Callee,
|
||||
CastInst **RetBitCast = nullptr);
|
||||
LLVM_ABI CallBase &promoteCall(CallBase &CB, Function *Callee,
|
||||
CastInst **RetBitCast = nullptr);
|
||||
|
||||
/// Promote the given indirect call site to conditionally call \p Callee. The
|
||||
/// promoted direct call instruction is predicated on `CB.getCalledOperand() ==
|
||||
@@ -54,11 +55,11 @@ CallBase &promoteCall(CallBase &CB, Function *Callee,
|
||||
/// indirect call site is promoted, placed in the "then" block, and returned. If
|
||||
/// \p BranchWeights is non-null, it will be used to set !prof metadata on the
|
||||
/// new conditional branch.
|
||||
CallBase &promoteCallWithIfThenElse(CallBase &CB, Function *Callee,
|
||||
MDNode *BranchWeights = nullptr);
|
||||
LLVM_ABI CallBase &promoteCallWithIfThenElse(CallBase &CB, Function *Callee,
|
||||
MDNode *BranchWeights = nullptr);
|
||||
|
||||
CallBase *promoteCallWithIfThenElse(CallBase &CB, Function &Callee,
|
||||
PGOContextualProfile &CtxProf);
|
||||
LLVM_ABI CallBase *promoteCallWithIfThenElse(CallBase &CB, Function &Callee,
|
||||
PGOContextualProfile &CtxProf);
|
||||
|
||||
/// This is similar to `promoteCallWithIfThenElse` except that the condition to
|
||||
/// promote a virtual call is that \p VPtr is the same as any of \p
|
||||
@@ -71,10 +72,10 @@ CallBase *promoteCallWithIfThenElse(CallBase &CB, Function &Callee,
|
||||
///
|
||||
/// TODO: sink the address-calculation instructions of indirect callee to the
|
||||
/// indirect call fallback after transformation.
|
||||
CallBase &promoteCallWithVTableCmp(CallBase &CB, Instruction *VPtr,
|
||||
Function *Callee,
|
||||
ArrayRef<Constant *> AddressPoints,
|
||||
MDNode *BranchWeights);
|
||||
LLVM_ABI CallBase &promoteCallWithVTableCmp(CallBase &CB, Instruction *VPtr,
|
||||
Function *Callee,
|
||||
ArrayRef<Constant *> AddressPoints,
|
||||
MDNode *BranchWeights);
|
||||
|
||||
/// Try to promote (devirtualize) a virtual call on an Alloca. Return true on
|
||||
/// success.
|
||||
@@ -97,7 +98,7 @@ CallBase &promoteCallWithVTableCmp(CallBase &CB, Instruction *VPtr,
|
||||
/// [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI4Impl to i8*),
|
||||
/// i8* bitcast (void (%class.Impl*)* @_ZN4Impl3RunEv to i8*)] }
|
||||
///
|
||||
bool tryPromoteCall(CallBase &CB);
|
||||
LLVM_ABI bool tryPromoteCall(CallBase &CB);
|
||||
|
||||
/// Predicate and clone the given call site.
|
||||
///
|
||||
@@ -106,7 +107,8 @@ bool tryPromoteCall(CallBase &CB);
|
||||
/// the given callee. The original call site is moved into the "else" block,
|
||||
/// and a clone of the call site is placed in the "then" block. The cloned
|
||||
/// instruction is returned.
|
||||
CallBase &versionCallSite(CallBase &CB, Value *Callee, MDNode *BranchWeights);
|
||||
LLVM_ABI CallBase &versionCallSite(CallBase &CB, Value *Callee,
|
||||
MDNode *BranchWeights);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -49,14 +50,15 @@ class ReturnInst;
|
||||
class DomTreeUpdater;
|
||||
|
||||
/// Return an exact copy of the specified module
|
||||
std::unique_ptr<Module> CloneModule(const Module &M);
|
||||
std::unique_ptr<Module> CloneModule(const Module &M, ValueToValueMapTy &VMap);
|
||||
LLVM_ABI std::unique_ptr<Module> CloneModule(const Module &M);
|
||||
LLVM_ABI std::unique_ptr<Module> CloneModule(const Module &M,
|
||||
ValueToValueMapTy &VMap);
|
||||
|
||||
/// Return a copy of the specified module. The ShouldCloneDefinition function
|
||||
/// controls whether a specific GlobalValue's definition is cloned. If the
|
||||
/// function returns false, the module copy will contain an external reference
|
||||
/// in place of the global definition.
|
||||
std::unique_ptr<Module>
|
||||
LLVM_ABI std::unique_ptr<Module>
|
||||
CloneModule(const Module &M, ValueToValueMapTy &VMap,
|
||||
function_ref<bool(const GlobalValue *)> ShouldCloneDefinition);
|
||||
|
||||
@@ -127,14 +129,14 @@ struct ClonedCodeInfo {
|
||||
/// Setting true (default) is always safe (won't produce incorrect debug info)
|
||||
/// but is sometimes unnecessary, causing extra work that could be avoided by
|
||||
/// setting the parameter to false.
|
||||
BasicBlock *CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
|
||||
const Twine &NameSuffix = "", Function *F = nullptr,
|
||||
ClonedCodeInfo *CodeInfo = nullptr,
|
||||
bool MapAtoms = true);
|
||||
LLVM_ABI BasicBlock *
|
||||
CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
|
||||
const Twine &NameSuffix = "", Function *F = nullptr,
|
||||
ClonedCodeInfo *CodeInfo = nullptr, bool MapAtoms = true);
|
||||
|
||||
/// Mark a cloned instruction as a new instance so that its source loc can
|
||||
/// be updated when remapped.
|
||||
void mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap);
|
||||
LLVM_ABI void mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap);
|
||||
|
||||
/// Return a copy of the specified function and add it to that
|
||||
/// function's module. Also, any references specified in the VMap are changed
|
||||
@@ -147,8 +149,8 @@ void mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap);
|
||||
///
|
||||
/// \pre VMap contains no non-identity GlobalValue mappings.
|
||||
///
|
||||
Function *CloneFunction(Function *F, ValueToValueMapTy &VMap,
|
||||
ClonedCodeInfo *CodeInfo = nullptr);
|
||||
LLVM_ABI Function *CloneFunction(Function *F, ValueToValueMapTy &VMap,
|
||||
ClonedCodeInfo *CodeInfo = nullptr);
|
||||
|
||||
enum class CloneFunctionChangeType {
|
||||
LocalChangesOnly,
|
||||
@@ -181,21 +183,22 @@ enum class CloneFunctionChangeType {
|
||||
/// FIXME: Consider simplifying this function by splitting out \a
|
||||
/// CloneFunctionMetadataInto() and expecting / updating callers to call it
|
||||
/// first when / how it's needed.
|
||||
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueToValueMapTy &VMap, CloneFunctionChangeType Changes,
|
||||
SmallVectorImpl<ReturnInst *> &Returns,
|
||||
const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = nullptr,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr);
|
||||
LLVM_ABI void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueToValueMapTy &VMap,
|
||||
CloneFunctionChangeType Changes,
|
||||
SmallVectorImpl<ReturnInst *> &Returns,
|
||||
const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = nullptr,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr);
|
||||
|
||||
/// Clone OldFunc's attributes into NewFunc, transforming values based on the
|
||||
/// mappings in VMap.
|
||||
void CloneFunctionAttributesInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueToValueMapTy &VMap,
|
||||
bool ModuleLevelChanges,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr);
|
||||
LLVM_ABI void
|
||||
CloneFunctionAttributesInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr);
|
||||
|
||||
/// Clone OldFunc's metadata into NewFunc.
|
||||
///
|
||||
@@ -205,28 +208,27 @@ void CloneFunctionAttributesInto(Function *NewFunc, const Function *OldFunc,
|
||||
///
|
||||
/// NOTE: This function doesn't clone !llvm.dbg.cu when cloning into a different
|
||||
/// module. Use CloneFunctionInto for that behavior.
|
||||
void CloneFunctionMetadataInto(Function &NewFunc, const Function &OldFunc,
|
||||
ValueToValueMapTy &VMap, RemapFlags RemapFlag,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr,
|
||||
const MetadataPredicate *IdentityMD = nullptr);
|
||||
LLVM_ABI void
|
||||
CloneFunctionMetadataInto(Function &NewFunc, const Function &OldFunc,
|
||||
ValueToValueMapTy &VMap, RemapFlags RemapFlag,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr,
|
||||
const MetadataPredicate *IdentityMD = nullptr);
|
||||
|
||||
/// Clone OldFunc's body into NewFunc.
|
||||
void CloneFunctionBodyInto(Function &NewFunc, const Function &OldFunc,
|
||||
ValueToValueMapTy &VMap, RemapFlags RemapFlag,
|
||||
SmallVectorImpl<ReturnInst *> &Returns,
|
||||
const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = nullptr,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr,
|
||||
const MetadataPredicate *IdentityMD = nullptr);
|
||||
LLVM_ABI void CloneFunctionBodyInto(
|
||||
Function &NewFunc, const Function &OldFunc, ValueToValueMapTy &VMap,
|
||||
RemapFlags RemapFlag, SmallVectorImpl<ReturnInst *> &Returns,
|
||||
const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = nullptr,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr,
|
||||
const MetadataPredicate *IdentityMD = nullptr);
|
||||
|
||||
void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
|
||||
const Instruction *StartingInst,
|
||||
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst *> &Returns,
|
||||
const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = nullptr);
|
||||
LLVM_ABI void CloneAndPruneIntoFromInst(
|
||||
Function *NewFunc, const Function *OldFunc, const Instruction *StartingInst,
|
||||
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst *> &Returns, const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = nullptr);
|
||||
|
||||
/// This works exactly like CloneFunctionInto,
|
||||
/// except that it does some simple constant prop and DCE on the fly. The
|
||||
@@ -239,11 +241,10 @@ void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
|
||||
/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
|
||||
/// mappings.
|
||||
///
|
||||
void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst*> &Returns,
|
||||
const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = nullptr);
|
||||
LLVM_ABI void CloneAndPruneFunctionInto(
|
||||
Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap,
|
||||
bool ModuleLevelChanges, SmallVectorImpl<ReturnInst *> &Returns,
|
||||
const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = nullptr);
|
||||
|
||||
/// This class captures the data input to the InlineFunction call, and records
|
||||
/// the auxiliary results produced by it.
|
||||
@@ -311,23 +312,23 @@ public:
|
||||
///
|
||||
/// The callee's function attributes are merged into the callers' if
|
||||
/// MergeAttributes is set to true.
|
||||
InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
|
||||
bool MergeAttributes = false,
|
||||
AAResults *CalleeAAR = nullptr,
|
||||
bool InsertLifetime = true,
|
||||
Function *ForwardVarArgsTo = nullptr,
|
||||
OptimizationRemarkEmitter *ORE = nullptr);
|
||||
LLVM_ABI InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
|
||||
bool MergeAttributes = false,
|
||||
AAResults *CalleeAAR = nullptr,
|
||||
bool InsertLifetime = true,
|
||||
Function *ForwardVarArgsTo = nullptr,
|
||||
OptimizationRemarkEmitter *ORE = nullptr);
|
||||
|
||||
/// Same as above, but it will update the contextual profile. If the contextual
|
||||
/// profile is invalid (i.e. not loaded because it is not present), it defaults
|
||||
/// to the behavior of the non-contextual profile updating variant above. This
|
||||
/// makes it easy to drop-in replace uses of the non-contextual overload.
|
||||
InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
|
||||
PGOContextualProfile &CtxProf,
|
||||
bool MergeAttributes = false,
|
||||
AAResults *CalleeAAR = nullptr,
|
||||
bool InsertLifetime = true,
|
||||
Function *ForwardVarArgsTo = nullptr);
|
||||
LLVM_ABI InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
|
||||
PGOContextualProfile &CtxProf,
|
||||
bool MergeAttributes = false,
|
||||
AAResults *CalleeAAR = nullptr,
|
||||
bool InsertLifetime = true,
|
||||
Function *ForwardVarArgsTo = nullptr);
|
||||
|
||||
/// Clones a loop \p OrigLoop. Returns the loop and the blocks in \p
|
||||
/// Blocks.
|
||||
@@ -335,15 +336,15 @@ InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
|
||||
/// Updates LoopInfo and DominatorTree assuming the loop is dominated by block
|
||||
/// \p LoopDomBB. Insert the new blocks before block specified in \p Before.
|
||||
/// Note: Only innermost loops are supported.
|
||||
Loop *cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB,
|
||||
Loop *OrigLoop, ValueToValueMapTy &VMap,
|
||||
const Twine &NameSuffix, LoopInfo *LI,
|
||||
DominatorTree *DT,
|
||||
SmallVectorImpl<BasicBlock *> &Blocks);
|
||||
LLVM_ABI Loop *cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB,
|
||||
Loop *OrigLoop, ValueToValueMapTy &VMap,
|
||||
const Twine &NameSuffix, LoopInfo *LI,
|
||||
DominatorTree *DT,
|
||||
SmallVectorImpl<BasicBlock *> &Blocks);
|
||||
|
||||
/// Remaps instructions in \p Blocks using the mapping in \p VMap.
|
||||
void remapInstructionsInBlocks(ArrayRef<BasicBlock *> Blocks,
|
||||
ValueToValueMapTy &VMap);
|
||||
LLVM_ABI void remapInstructionsInBlocks(ArrayRef<BasicBlock *> Blocks,
|
||||
ValueToValueMapTy &VMap);
|
||||
|
||||
/// Split edge between BB and PredBB and duplicate all non-Phi instructions
|
||||
/// from BB between its beginning and the StopAt instruction into the split
|
||||
@@ -351,62 +352,62 @@ void remapInstructionsInBlocks(ArrayRef<BasicBlock *> Blocks,
|
||||
/// we replace them with the uses of corresponding Phi inputs. ValueMapping
|
||||
/// is used to map the original instructions from BB to their newly-created
|
||||
/// copies. Returns the split block.
|
||||
BasicBlock *DuplicateInstructionsInSplitBetween(BasicBlock *BB,
|
||||
BasicBlock *PredBB,
|
||||
Instruction *StopAt,
|
||||
ValueToValueMapTy &ValueMapping,
|
||||
DomTreeUpdater &DTU);
|
||||
LLVM_ABI BasicBlock *DuplicateInstructionsInSplitBetween(
|
||||
BasicBlock *BB, BasicBlock *PredBB, Instruction *StopAt,
|
||||
ValueToValueMapTy &ValueMapping, DomTreeUpdater &DTU);
|
||||
|
||||
/// Updates profile information by adjusting the entry count by adding
|
||||
/// EntryDelta then scaling callsite information by the new count divided by the
|
||||
/// old count. VMap is used during inlinng to also update the new clone
|
||||
void updateProfileCallee(
|
||||
LLVM_ABI void updateProfileCallee(
|
||||
Function *Callee, int64_t EntryDelta,
|
||||
const ValueMap<const Value *, WeakTrackingVH> *VMap = nullptr);
|
||||
|
||||
/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
|
||||
/// basic blocks and extract their scope. These are candidates for duplication
|
||||
/// when cloning.
|
||||
void identifyNoAliasScopesToClone(
|
||||
ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
|
||||
LLVM_ABI void
|
||||
identifyNoAliasScopesToClone(ArrayRef<BasicBlock *> BBs,
|
||||
SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
|
||||
|
||||
/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
|
||||
/// instruction range and extract their scope. These are candidates for
|
||||
/// duplication when cloning.
|
||||
void identifyNoAliasScopesToClone(
|
||||
BasicBlock::iterator Start, BasicBlock::iterator End,
|
||||
SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
|
||||
LLVM_ABI void
|
||||
identifyNoAliasScopesToClone(BasicBlock::iterator Start,
|
||||
BasicBlock::iterator End,
|
||||
SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
|
||||
|
||||
/// Duplicate the specified list of noalias decl scopes.
|
||||
/// The 'Ext' string is added as an extension to the name.
|
||||
/// Afterwards, the ClonedScopes contains the mapping of the original scope
|
||||
/// MDNode onto the cloned scope.
|
||||
/// Be aware that the cloned scopes are still part of the original scope domain.
|
||||
void cloneNoAliasScopes(
|
||||
ArrayRef<MDNode *> NoAliasDeclScopes,
|
||||
DenseMap<MDNode *, MDNode *> &ClonedScopes,
|
||||
StringRef Ext, LLVMContext &Context);
|
||||
LLVM_ABI void cloneNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
|
||||
DenseMap<MDNode *, MDNode *> &ClonedScopes,
|
||||
StringRef Ext, LLVMContext &Context);
|
||||
|
||||
/// Adapt the metadata for the specified instruction according to the
|
||||
/// provided mapping. This is normally used after cloning an instruction, when
|
||||
/// some noalias scopes needed to be cloned.
|
||||
void adaptNoAliasScopes(
|
||||
llvm::Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
|
||||
LLVMContext &Context);
|
||||
LLVM_ABI void
|
||||
adaptNoAliasScopes(llvm::Instruction *I,
|
||||
const DenseMap<MDNode *, MDNode *> &ClonedScopes,
|
||||
LLVMContext &Context);
|
||||
|
||||
/// Clone the specified noalias decl scopes. Then adapt all instructions in the
|
||||
/// NewBlocks basicblocks to the cloned versions.
|
||||
/// 'Ext' will be added to the duplicate scope names.
|
||||
void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
|
||||
ArrayRef<BasicBlock *> NewBlocks,
|
||||
LLVMContext &Context, StringRef Ext);
|
||||
LLVM_ABI void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
|
||||
ArrayRef<BasicBlock *> NewBlocks,
|
||||
LLVMContext &Context, StringRef Ext);
|
||||
|
||||
/// Clone the specified noalias decl scopes. Then adapt all instructions in the
|
||||
/// [IStart, IEnd] (IEnd included !) range to the cloned versions. 'Ext' will be
|
||||
/// added to the duplicate scope names.
|
||||
void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
|
||||
Instruction *IStart, Instruction *IEnd,
|
||||
LLVMContext &Context, StringRef Ext);
|
||||
LLVM_ABI void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
|
||||
Instruction *IStart, Instruction *IEnd,
|
||||
LLVMContext &Context, StringRef Ext);
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_UTILS_CLONING_H
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <limits>
|
||||
|
||||
namespace llvm {
|
||||
@@ -57,7 +58,7 @@ class CodeExtractorAnalysisCache {
|
||||
void findSideEffectInfoForBlock(BasicBlock &BB);
|
||||
|
||||
public:
|
||||
CodeExtractorAnalysisCache(Function &F);
|
||||
LLVM_ABI CodeExtractorAnalysisCache(Function &F);
|
||||
|
||||
/// Get the allocas in the function at the time the analysis was created.
|
||||
/// Note that some of these allocas may no longer be present in the function,
|
||||
@@ -66,7 +67,8 @@ public:
|
||||
|
||||
/// Check whether \p BB contains an instruction thought to load from, store
|
||||
/// to, or otherwise clobber the alloca \p Addr.
|
||||
bool doesBlockContainClobberOfAddr(BasicBlock &BB, AllocaInst *Addr) const;
|
||||
LLVM_ABI bool doesBlockContainClobberOfAddr(BasicBlock &BB,
|
||||
AllocaInst *Addr) const;
|
||||
};
|
||||
|
||||
/// Utility class for extracting code into a new function.
|
||||
@@ -148,6 +150,7 @@ public:
|
||||
/// If ArgsInZeroAddressSpace param is set to true, then the aggregate
|
||||
/// param pointer of the outlined function is declared in zero address
|
||||
/// space.
|
||||
LLVM_ABI
|
||||
CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = nullptr,
|
||||
bool AggregateArgs = false, BlockFrequencyInfo *BFI = nullptr,
|
||||
BranchProbabilityInfo *BPI = nullptr,
|
||||
@@ -160,7 +163,8 @@ public:
|
||||
///
|
||||
/// Returns zero when called on a CodeExtractor instance where isEligible
|
||||
/// returns false.
|
||||
Function *extractCodeRegion(const CodeExtractorAnalysisCache &CEAC);
|
||||
LLVM_ABI Function *
|
||||
extractCodeRegion(const CodeExtractorAnalysisCache &CEAC);
|
||||
|
||||
/// Perform the extraction, returning the new function and providing an
|
||||
/// interface to see what was categorized as inputs and outputs.
|
||||
@@ -173,15 +177,15 @@ public:
|
||||
/// newly outlined function.
|
||||
/// \returns zero when called on a CodeExtractor instance where isEligible
|
||||
/// returns false.
|
||||
Function *extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
|
||||
ValueSet &Inputs, ValueSet &Outputs);
|
||||
LLVM_ABI Function *extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
|
||||
ValueSet &Inputs, ValueSet &Outputs);
|
||||
|
||||
/// Verify that assumption cache isn't stale after a region is extracted.
|
||||
/// Returns true when verifier finds errors. AssumptionCache is passed as
|
||||
/// parameter to make this function stateless.
|
||||
static bool verifyAssumptionCache(const Function &OldFunc,
|
||||
const Function &NewFunc,
|
||||
AssumptionCache *AC);
|
||||
LLVM_ABI static bool verifyAssumptionCache(const Function &OldFunc,
|
||||
const Function &NewFunc,
|
||||
AssumptionCache *AC);
|
||||
|
||||
/// Test whether this code extractor is eligible.
|
||||
///
|
||||
@@ -190,7 +194,7 @@ public:
|
||||
///
|
||||
/// Checks that varargs handling (with vastart and vaend) is only done in
|
||||
/// the outlined blocks.
|
||||
bool isEligible() const;
|
||||
LLVM_ABI bool isEligible() const;
|
||||
|
||||
/// Compute the set of input values and output values for the code.
|
||||
///
|
||||
@@ -200,15 +204,15 @@ public:
|
||||
/// a code sequence, that sequence is modified, including changing these
|
||||
/// sets, before extraction occurs. These modifications won't have any
|
||||
/// significant impact on the cost however.
|
||||
void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
|
||||
const ValueSet &Allocas,
|
||||
bool CollectGlobalInputs = false) const;
|
||||
LLVM_ABI void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
|
||||
const ValueSet &Allocas,
|
||||
bool CollectGlobalInputs = false) const;
|
||||
|
||||
/// Check if life time marker nodes can be hoisted/sunk into the outline
|
||||
/// region.
|
||||
///
|
||||
/// Returns true if it is safe to do the code motion.
|
||||
bool
|
||||
LLVM_ABI bool
|
||||
isLegalToShrinkwrapLifetimeMarkers(const CodeExtractorAnalysisCache &CEAC,
|
||||
Instruction *AllocaAddr) const;
|
||||
|
||||
@@ -220,9 +224,9 @@ public:
|
||||
/// are used by the lifetime markers are also candidates for shrink-
|
||||
/// wrapping. The instructions that need to be sunk are collected in
|
||||
/// 'Allocas'.
|
||||
void findAllocas(const CodeExtractorAnalysisCache &CEAC,
|
||||
ValueSet &SinkCands, ValueSet &HoistCands,
|
||||
BasicBlock *&ExitBlock) const;
|
||||
LLVM_ABI void findAllocas(const CodeExtractorAnalysisCache &CEAC,
|
||||
ValueSet &SinkCands, ValueSet &HoistCands,
|
||||
BasicBlock *&ExitBlock) const;
|
||||
|
||||
/// Find or create a block within the outline region for placing hoisted
|
||||
/// code.
|
||||
@@ -232,11 +236,12 @@ public:
|
||||
/// inside the region that is the predecessor of CommonExitBlock, that block
|
||||
/// will be returned. Otherwise CommonExitBlock will be split and the
|
||||
/// original block will be added to the outline region.
|
||||
BasicBlock *findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock);
|
||||
LLVM_ABI BasicBlock *
|
||||
findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock);
|
||||
|
||||
/// Exclude a value from aggregate argument passing when extracting a code
|
||||
/// region, passing it instead as a scalar.
|
||||
void excludeArgFromAggregate(Value *Arg);
|
||||
LLVM_ABI void excludeArgFromAggregate(Value *Arg);
|
||||
|
||||
private:
|
||||
struct LifetimeMarkerInfo {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_CODELAYOUT_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -40,20 +41,21 @@ struct EdgeCount {
|
||||
/// \p EdgeCounts: The execution counts of every edge (jump) in the profile. The
|
||||
/// map also defines the edges in CFG and should include 0-count edges.
|
||||
/// \returns The best block order found.
|
||||
std::vector<uint64_t> computeExtTspLayout(ArrayRef<uint64_t> NodeSizes,
|
||||
ArrayRef<uint64_t> NodeCounts,
|
||||
ArrayRef<EdgeCount> EdgeCounts);
|
||||
LLVM_ABI std::vector<uint64_t>
|
||||
computeExtTspLayout(ArrayRef<uint64_t> NodeSizes, ArrayRef<uint64_t> NodeCounts,
|
||||
ArrayRef<EdgeCount> EdgeCounts);
|
||||
|
||||
/// Estimate the "quality" of a given node order in CFG. The higher the score,
|
||||
/// the better the order is. The score is designed to reflect the locality of
|
||||
/// the given order, which is anti-correlated with the number of I-cache misses
|
||||
/// in a typical execution of the function.
|
||||
double calcExtTspScore(ArrayRef<uint64_t> Order, ArrayRef<uint64_t> NodeSizes,
|
||||
ArrayRef<EdgeCount> EdgeCounts);
|
||||
LLVM_ABI double calcExtTspScore(ArrayRef<uint64_t> Order,
|
||||
ArrayRef<uint64_t> NodeSizes,
|
||||
ArrayRef<EdgeCount> EdgeCounts);
|
||||
|
||||
/// Estimate the "quality" of the current node order in CFG.
|
||||
double calcExtTspScore(ArrayRef<uint64_t> NodeSizes,
|
||||
ArrayRef<EdgeCount> EdgeCounts);
|
||||
LLVM_ABI double calcExtTspScore(ArrayRef<uint64_t> NodeSizes,
|
||||
ArrayRef<EdgeCount> EdgeCounts);
|
||||
|
||||
/// Algorithm-specific params for Cache-Directed Sort. The values are tuned for
|
||||
/// the best performance of large-scale front-end bound binaries.
|
||||
@@ -79,12 +81,12 @@ struct CDSortConfig {
|
||||
/// map also defines the edges in CFG and should include 0-count edges.
|
||||
/// \p CallOffsets: The offsets of the calls from their source nodes.
|
||||
/// \returns The best function order found.
|
||||
std::vector<uint64_t> computeCacheDirectedLayout(
|
||||
LLVM_ABI std::vector<uint64_t> computeCacheDirectedLayout(
|
||||
ArrayRef<uint64_t> FuncSizes, ArrayRef<uint64_t> FuncCounts,
|
||||
ArrayRef<EdgeCount> CallCounts, ArrayRef<uint64_t> CallOffsets);
|
||||
|
||||
/// Apply a Cache-Directed Sort with a custom config.
|
||||
std::vector<uint64_t> computeCacheDirectedLayout(
|
||||
LLVM_ABI std::vector<uint64_t> computeCacheDirectedLayout(
|
||||
const CDSortConfig &Config, ArrayRef<uint64_t> FuncSizes,
|
||||
ArrayRef<uint64_t> FuncCounts, ArrayRef<EdgeCount> CallCounts,
|
||||
ArrayRef<uint64_t> CallOffsets);
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef LLVM_TRANSFORMS_UTILS_CODEMOVERUTILS_H
|
||||
#define LLVM_TRANSFORMS_UTILS_CODEMOVERUTILS_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BasicBlock;
|
||||
@@ -28,56 +30,61 @@ class PostDominatorTree;
|
||||
/// Return true if \p I0 and \p I1 are control flow equivalent.
|
||||
/// Two instructions are control flow equivalent if their basic blocks are
|
||||
/// control flow equivalent.
|
||||
bool isControlFlowEquivalent(const Instruction &I0, const Instruction &I1,
|
||||
const DominatorTree &DT,
|
||||
const PostDominatorTree &PDT);
|
||||
LLVM_ABI bool isControlFlowEquivalent(const Instruction &I0,
|
||||
const Instruction &I1,
|
||||
const DominatorTree &DT,
|
||||
const PostDominatorTree &PDT);
|
||||
|
||||
/// Return true if \p BB0 and \p BB1 are control flow equivalent.
|
||||
/// Two basic blocks are control flow equivalent if when one executes, the other
|
||||
/// is guaranteed to execute.
|
||||
bool isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1,
|
||||
const DominatorTree &DT,
|
||||
const PostDominatorTree &PDT);
|
||||
LLVM_ABI bool isControlFlowEquivalent(const BasicBlock &BB0,
|
||||
const BasicBlock &BB1,
|
||||
const DominatorTree &DT,
|
||||
const PostDominatorTree &PDT);
|
||||
|
||||
/// Return true if \p I can be safely moved before \p InsertPoint.
|
||||
bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
|
||||
DominatorTree &DT,
|
||||
const PostDominatorTree *PDT = nullptr,
|
||||
DependenceInfo *DI = nullptr,
|
||||
bool CheckForEntireBlock = false);
|
||||
LLVM_ABI bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
|
||||
DominatorTree &DT,
|
||||
const PostDominatorTree *PDT = nullptr,
|
||||
DependenceInfo *DI = nullptr,
|
||||
bool CheckForEntireBlock = false);
|
||||
|
||||
/// Return true if all instructions (except the terminator) in \p BB can be
|
||||
/// safely moved before \p InsertPoint.
|
||||
bool isSafeToMoveBefore(BasicBlock &BB, Instruction &InsertPoint,
|
||||
DominatorTree &DT,
|
||||
const PostDominatorTree *PDT = nullptr,
|
||||
DependenceInfo *DI = nullptr);
|
||||
LLVM_ABI bool isSafeToMoveBefore(BasicBlock &BB, Instruction &InsertPoint,
|
||||
DominatorTree &DT,
|
||||
const PostDominatorTree *PDT = nullptr,
|
||||
DependenceInfo *DI = nullptr);
|
||||
|
||||
/// Move instructions, in an order-preserving manner, from \p FromBB to the
|
||||
/// beginning of \p ToBB when proven safe.
|
||||
void moveInstructionsToTheBeginning(BasicBlock &FromBB, BasicBlock &ToBB,
|
||||
DominatorTree &DT,
|
||||
const PostDominatorTree &PDT,
|
||||
DependenceInfo &DI);
|
||||
LLVM_ABI void moveInstructionsToTheBeginning(BasicBlock &FromBB,
|
||||
BasicBlock &ToBB,
|
||||
DominatorTree &DT,
|
||||
const PostDominatorTree &PDT,
|
||||
DependenceInfo &DI);
|
||||
|
||||
/// Move instructions, in an order-preserving manner, from \p FromBB to the end
|
||||
/// of \p ToBB when proven safe.
|
||||
void moveInstructionsToTheEnd(BasicBlock &FromBB, BasicBlock &ToBB,
|
||||
DominatorTree &DT, const PostDominatorTree &PDT,
|
||||
DependenceInfo &DI);
|
||||
LLVM_ABI void moveInstructionsToTheEnd(BasicBlock &FromBB, BasicBlock &ToBB,
|
||||
DominatorTree &DT,
|
||||
const PostDominatorTree &PDT,
|
||||
DependenceInfo &DI);
|
||||
|
||||
/// In case that two BBs \p ThisBlock and \p OtherBlock are control flow
|
||||
/// equivalent but they do not strictly dominate and post-dominate each
|
||||
/// other, we determine if \p ThisBlock is reached after \p OtherBlock
|
||||
/// in the control flow.
|
||||
bool nonStrictlyPostDominate(const BasicBlock *ThisBlock,
|
||||
const BasicBlock *OtherBlock,
|
||||
const DominatorTree *DT,
|
||||
const PostDominatorTree *PDT);
|
||||
LLVM_ABI bool nonStrictlyPostDominate(const BasicBlock *ThisBlock,
|
||||
const BasicBlock *OtherBlock,
|
||||
const DominatorTree *DT,
|
||||
const PostDominatorTree *PDT);
|
||||
|
||||
// Check if I0 is reached before I1 in the control flow.
|
||||
bool isReachedBefore(const Instruction *I0, const Instruction *I1,
|
||||
const DominatorTree *DT, const PostDominatorTree *PDT);
|
||||
LLVM_ABI bool isReachedBefore(const Instruction *I0, const Instruction *I1,
|
||||
const DominatorTree *DT,
|
||||
const PostDominatorTree *PDT);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
using DebugFnMap =
|
||||
llvm::MapVector<const llvm::Function *, const llvm::DISubprogram *>;
|
||||
@@ -56,14 +57,15 @@ class DIBuilder;
|
||||
/// \param ApplyToMF A call back that will add debug information to the
|
||||
/// MachineFunction for a Function. If nullptr, then the
|
||||
/// MachineFunction (if any) will not be modified.
|
||||
bool applyDebugifyMetadata(
|
||||
Module &M, iterator_range<Module::iterator> Functions, StringRef Banner,
|
||||
std::function<bool(DIBuilder &, Function &)> ApplyToMF);
|
||||
LLVM_ABI bool
|
||||
applyDebugifyMetadata(Module &M, iterator_range<Module::iterator> Functions,
|
||||
StringRef Banner,
|
||||
std::function<bool(DIBuilder &, Function &)> ApplyToMF);
|
||||
|
||||
/// Strip out all of the metadata and debug info inserted by debugify. If no
|
||||
/// llvm.debugify module-level named metadata is present, this is a no-op.
|
||||
/// Returns true if any change was made.
|
||||
bool stripDebugifyMetadata(Module &M);
|
||||
LLVM_ABI bool stripDebugifyMetadata(Module &M);
|
||||
|
||||
/// Collect original debug information before a pass.
|
||||
///
|
||||
@@ -72,10 +74,10 @@ bool stripDebugifyMetadata(Module &M);
|
||||
/// \param DebugInfoBeforePass DI metadata before a pass.
|
||||
/// \param Banner A prefix string to add to debug/error messages.
|
||||
/// \param NameOfWrappedPass A name of a pass to add to debug/error messages.
|
||||
bool collectDebugInfoMetadata(Module &M,
|
||||
iterator_range<Module::iterator> Functions,
|
||||
DebugInfoPerPass &DebugInfoBeforePass,
|
||||
StringRef Banner, StringRef NameOfWrappedPass);
|
||||
LLVM_ABI bool
|
||||
collectDebugInfoMetadata(Module &M, iterator_range<Module::iterator> Functions,
|
||||
DebugInfoPerPass &DebugInfoBeforePass,
|
||||
StringRef Banner, StringRef NameOfWrappedPass);
|
||||
|
||||
/// Check original debug information after a pass.
|
||||
///
|
||||
@@ -84,21 +86,22 @@ bool collectDebugInfoMetadata(Module &M,
|
||||
/// \param DebugInfoBeforePass DI metadata before a pass.
|
||||
/// \param Banner A prefix string to add to debug/error messages.
|
||||
/// \param NameOfWrappedPass A name of a pass to add to debug/error messages.
|
||||
bool checkDebugInfoMetadata(Module &M,
|
||||
iterator_range<Module::iterator> Functions,
|
||||
DebugInfoPerPass &DebugInfoBeforePass,
|
||||
StringRef Banner, StringRef NameOfWrappedPass,
|
||||
StringRef OrigDIVerifyBugsReportFilePath);
|
||||
LLVM_ABI bool checkDebugInfoMetadata(Module &M,
|
||||
iterator_range<Module::iterator> Functions,
|
||||
DebugInfoPerPass &DebugInfoBeforePass,
|
||||
StringRef Banner,
|
||||
StringRef NameOfWrappedPass,
|
||||
StringRef OrigDIVerifyBugsReportFilePath);
|
||||
} // namespace llvm
|
||||
|
||||
/// Used to check whether we track synthetic or original debug info.
|
||||
enum class DebugifyMode { NoDebugify, SyntheticDebugInfo, OriginalDebugInfo };
|
||||
|
||||
llvm::ModulePass *createDebugifyModulePass(
|
||||
LLVM_ABI llvm::ModulePass *createDebugifyModulePass(
|
||||
enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
|
||||
llvm::StringRef NameOfWrappedPass = "",
|
||||
DebugInfoPerPass *DebugInfoBeforePass = nullptr);
|
||||
llvm::FunctionPass *createDebugifyFunctionPass(
|
||||
LLVM_ABI llvm::FunctionPass *createDebugifyFunctionPass(
|
||||
enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
|
||||
llvm::StringRef NameOfWrappedPass = "",
|
||||
DebugInfoPerPass *DebugInfoBeforePass = nullptr);
|
||||
@@ -115,7 +118,8 @@ public:
|
||||
: NameOfWrappedPass(NameOfWrappedPass),
|
||||
DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
|
||||
|
||||
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
|
||||
LLVM_ABI llvm::PreservedAnalyses run(llvm::Module &M,
|
||||
llvm::ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Track how much `debugify` information (in the `synthetic` mode only)
|
||||
@@ -147,14 +151,14 @@ struct DebugifyStatistics {
|
||||
/// Map pass names to a per-pass DebugifyStatistics instance.
|
||||
using DebugifyStatsMap = llvm::MapVector<llvm::StringRef, DebugifyStatistics>;
|
||||
|
||||
llvm::ModulePass *createCheckDebugifyModulePass(
|
||||
LLVM_ABI llvm::ModulePass *createCheckDebugifyModulePass(
|
||||
bool Strip = false, llvm::StringRef NameOfWrappedPass = "",
|
||||
DebugifyStatsMap *StatsMap = nullptr,
|
||||
enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
|
||||
DebugInfoPerPass *DebugInfoBeforePass = nullptr,
|
||||
llvm::StringRef OrigDIVerifyBugsReportFilePath = "");
|
||||
|
||||
llvm::FunctionPass *createCheckDebugifyFunctionPass(
|
||||
LLVM_ABI llvm::FunctionPass *createCheckDebugifyFunctionPass(
|
||||
bool Strip = false, llvm::StringRef NameOfWrappedPass = "",
|
||||
DebugifyStatsMap *StatsMap = nullptr,
|
||||
enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
|
||||
@@ -181,11 +185,12 @@ public:
|
||||
StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
|
||||
Strip(Strip) {}
|
||||
|
||||
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
|
||||
LLVM_ABI llvm::PreservedAnalyses run(llvm::Module &M,
|
||||
llvm::ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
namespace llvm {
|
||||
void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map);
|
||||
LLVM_ABI void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map);
|
||||
|
||||
class DebugifyEachInstrumentation {
|
||||
llvm::StringRef OrigDIVerifyBugsReportFilePath = "";
|
||||
@@ -194,8 +199,8 @@ class DebugifyEachInstrumentation {
|
||||
DebugifyStatsMap *DIStatsMap = nullptr;
|
||||
|
||||
public:
|
||||
void registerCallbacks(PassInstrumentationCallbacks &PIC,
|
||||
ModuleAnalysisManager &MAM);
|
||||
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC,
|
||||
ModuleAnalysisManager &MAM);
|
||||
// Used within DebugifyMode::SyntheticDebugInfo mode.
|
||||
void setDIStatsMap(DebugifyStatsMap &StatMap) { DIStatsMap = &StatMap; }
|
||||
const DebugifyStatsMap &getDebugifyStatsMap() const { return *DIStatsMap; }
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "llvm/IR/ValueMap.h"
|
||||
#include "llvm/Support/AtomicOrdering.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cstdint>
|
||||
#include <tuple>
|
||||
|
||||
@@ -97,7 +98,7 @@ public:
|
||||
: FnL(F1), FnR(F2), GlobalNumbers(GN) {}
|
||||
|
||||
/// Test whether the two functions have equivalent behaviour.
|
||||
int compare();
|
||||
LLVM_ABI int compare();
|
||||
|
||||
protected:
|
||||
/// Start the comparison.
|
||||
@@ -107,10 +108,11 @@ protected:
|
||||
}
|
||||
|
||||
/// Compares the signature and other general attributes of the two functions.
|
||||
int compareSignature() const;
|
||||
LLVM_ABI int compareSignature() const;
|
||||
|
||||
/// Test whether two basic blocks have equivalent behaviour.
|
||||
int cmpBasicBlocks(const BasicBlock *BBL, const BasicBlock *BBR) const;
|
||||
LLVM_ABI int cmpBasicBlocks(const BasicBlock *BBL,
|
||||
const BasicBlock *BBR) const;
|
||||
|
||||
/// Constants comparison.
|
||||
/// Its analog to lexicographical comparison between hypothetical numbers
|
||||
@@ -214,11 +216,11 @@ protected:
|
||||
/// look at their particular properties (bit-width for vectors, and
|
||||
/// address space for pointers).
|
||||
/// If these properties are equal - compare their contents.
|
||||
int cmpConstants(const Constant *L, const Constant *R) const;
|
||||
LLVM_ABI int cmpConstants(const Constant *L, const Constant *R) const;
|
||||
|
||||
/// Compares two global values by number. Uses the GlobalNumbersState to
|
||||
/// identify the same gobals across function calls.
|
||||
int cmpGlobalValues(GlobalValue *L, GlobalValue *R) const;
|
||||
LLVM_ABI int cmpGlobalValues(GlobalValue *L, GlobalValue *R) const;
|
||||
|
||||
/// Assign or look up previously assigned numbers for the two values, and
|
||||
/// return whether the numbers are equal. Numbers are assigned in the order
|
||||
@@ -238,7 +240,7 @@ protected:
|
||||
/// then left value is greater.
|
||||
/// In another words, we compare serial numbers, for more details
|
||||
/// see comments for sn_mapL and sn_mapR.
|
||||
int cmpValues(const Value *L, const Value *R) const;
|
||||
LLVM_ABI int cmpValues(const Value *L, const Value *R) const;
|
||||
|
||||
/// Compare two Instructions for equivalence, similar to
|
||||
/// Instruction::isSameOperationAs.
|
||||
@@ -269,8 +271,8 @@ protected:
|
||||
/// Sets \p needToCmpOperands to true if the operands of the instructions
|
||||
/// still must be compared afterwards. In this case it's already guaranteed
|
||||
/// that both instructions have the same number of operands.
|
||||
int cmpOperations(const Instruction *L, const Instruction *R,
|
||||
bool &needToCmpOperands) const;
|
||||
LLVM_ABI int cmpOperations(const Instruction *L, const Instruction *R,
|
||||
bool &needToCmpOperands) const;
|
||||
|
||||
/// cmpType - compares two types,
|
||||
/// defines total ordering among the types set.
|
||||
@@ -312,14 +314,15 @@ protected:
|
||||
/// be checked with the same way. If we get Res != 0 on some stage, return it.
|
||||
/// Otherwise return 0.
|
||||
/// 6. For all other cases put llvm_unreachable.
|
||||
int cmpTypes(Type *TyL, Type *TyR) const;
|
||||
LLVM_ABI int cmpTypes(Type *TyL, Type *TyR) const;
|
||||
|
||||
int cmpNumbers(uint64_t L, uint64_t R) const;
|
||||
int cmpAligns(Align L, Align R) const;
|
||||
int cmpAPInts(const APInt &L, const APInt &R) const;
|
||||
int cmpConstantRanges(const ConstantRange &L, const ConstantRange &R) const;
|
||||
int cmpAPFloats(const APFloat &L, const APFloat &R) const;
|
||||
int cmpMem(StringRef L, StringRef R) const;
|
||||
LLVM_ABI int cmpNumbers(uint64_t L, uint64_t R) const;
|
||||
LLVM_ABI int cmpAligns(Align L, Align R) const;
|
||||
LLVM_ABI int cmpAPInts(const APInt &L, const APInt &R) const;
|
||||
LLVM_ABI int cmpConstantRanges(const ConstantRange &L,
|
||||
const ConstantRange &R) const;
|
||||
LLVM_ABI int cmpAPFloats(const APFloat &L, const APFloat &R) const;
|
||||
LLVM_ABI int cmpMem(StringRef L, StringRef R) const;
|
||||
|
||||
// The two functions undergoing comparison.
|
||||
const Function *FnL, *FnR;
|
||||
@@ -341,7 +344,7 @@ private:
|
||||
/// 3. Pointer operand type (using cmpType method).
|
||||
/// 4. Number of operands.
|
||||
/// 5. Compare operands, using cmpValues method.
|
||||
int cmpGEPs(const GEPOperator *GEPL, const GEPOperator *GEPR) const;
|
||||
LLVM_ABI int cmpGEPs(const GEPOperator *GEPL, const GEPOperator *GEPR) const;
|
||||
int cmpGEPs(const GetElementPtrInst *GEPL,
|
||||
const GetElementPtrInst *GEPR) const {
|
||||
return cmpGEPs(cast<GEPOperator>(GEPL), cast<GEPOperator>(GEPR));
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
@@ -102,18 +103,19 @@ class FunctionImportGlobalProcessing {
|
||||
DenseSet<GlobalValue::GUID> SymbolsToMove;
|
||||
|
||||
public:
|
||||
LLVM_ABI
|
||||
FunctionImportGlobalProcessing(Module &M, const ModuleSummaryIndex &Index,
|
||||
SetVector<GlobalValue *> *GlobalsToImport,
|
||||
bool ClearDSOLocalOnDeclarations);
|
||||
void run();
|
||||
LLVM_ABI void run();
|
||||
};
|
||||
|
||||
/// Perform in-place global value handling on the given Module for
|
||||
/// exported local functions renamed and promoted for ThinLTO.
|
||||
void renameModuleForThinLTO(
|
||||
Module &M, const ModuleSummaryIndex &Index,
|
||||
bool ClearDSOLocalOnDeclarations,
|
||||
SetVector<GlobalValue *> *GlobalsToImport = nullptr);
|
||||
LLVM_ABI void
|
||||
renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index,
|
||||
bool ClearDSOLocalOnDeclarations,
|
||||
SetVector<GlobalValue *> *GlobalsToImport = nullptr);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
@@ -33,35 +34,35 @@ class CallBase;
|
||||
class Module;
|
||||
|
||||
/// Check if module has flag attached, if not add the flag.
|
||||
bool checkIfAlreadyInstrumented(Module &M, StringRef Flag);
|
||||
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag);
|
||||
|
||||
/// Instrumentation passes often insert conditional checks into entry blocks.
|
||||
/// Call this function before splitting the entry block to move instructions
|
||||
/// that must remain in the entry block up before the split point. Static
|
||||
/// allocas and llvm.localescape calls, for example, must remain in the entry
|
||||
/// block.
|
||||
BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB,
|
||||
BasicBlock::iterator IP);
|
||||
LLVM_ABI BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB,
|
||||
BasicBlock::iterator IP);
|
||||
|
||||
// Create a constant for Str so that we can pass it to the run-time lib.
|
||||
GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
|
||||
bool AllowMerging,
|
||||
Twine NamePrefix = "");
|
||||
LLVM_ABI GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
|
||||
bool AllowMerging,
|
||||
Twine NamePrefix = "");
|
||||
|
||||
// Returns F.getComdat() if it exists.
|
||||
// Otherwise creates a new comdat, sets F's comdat, and returns it.
|
||||
// Returns nullptr on failure.
|
||||
Comdat *getOrCreateFunctionComdat(Function &F, Triple &T);
|
||||
LLVM_ABI Comdat *getOrCreateFunctionComdat(Function &F, Triple &T);
|
||||
|
||||
// Place global in a large section for x86-64 ELF binaries to mitigate
|
||||
// relocation overflow pressure. This can be be used for metadata globals that
|
||||
// aren't directly accessed by code, which has no performance impact.
|
||||
void setGlobalVariableLargeSection(const Triple &TargetTriple,
|
||||
GlobalVariable &GV);
|
||||
LLVM_ABI void setGlobalVariableLargeSection(const Triple &TargetTriple,
|
||||
GlobalVariable &GV);
|
||||
|
||||
// Insert GCOV profiling instrumentation
|
||||
struct GCOVOptions {
|
||||
static GCOVOptions getDefault();
|
||||
LLVM_ABI static GCOVOptions getDefault();
|
||||
|
||||
// Specify whether to emit .gcno files.
|
||||
bool EmitNotes;
|
||||
@@ -106,9 +107,10 @@ namespace pgo {
|
||||
// If \p AttachProfToDirectCall is true, a prof metadata is attached to the
|
||||
// new direct call to contain \p Count.
|
||||
// Returns the promoted direct call instruction.
|
||||
CallBase &promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count,
|
||||
uint64_t TotalCount, bool AttachProfToDirectCall,
|
||||
OptimizationRemarkEmitter *ORE);
|
||||
LLVM_ABI CallBase &promoteIndirectCall(CallBase &CB, Function *F,
|
||||
uint64_t Count, uint64_t TotalCount,
|
||||
bool AttachProfToDirectCall,
|
||||
OptimizationRemarkEmitter *ORE);
|
||||
} // namespace pgo
|
||||
|
||||
/// Options for the frontend instrumentation based profiling pass.
|
||||
@@ -135,7 +137,7 @@ struct InstrProfOptions {
|
||||
};
|
||||
|
||||
// Create the variable for profile sampling.
|
||||
void createProfileSamplingVar(Module &M);
|
||||
LLVM_ABI void createProfileSamplingVar(Module &M);
|
||||
|
||||
// Options for sanitizer coverage instrumentation.
|
||||
struct SanitizerCoverageOptions {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#ifndef LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H
|
||||
#define LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class BinaryOperator;
|
||||
}
|
||||
@@ -29,43 +31,43 @@ namespace llvm {
|
||||
/// 32bit and 64bit scalar division.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
bool expandRemainder(BinaryOperator *Rem);
|
||||
LLVM_ABI bool expandRemainder(BinaryOperator *Rem);
|
||||
|
||||
/// Generate code to divide two integers, replacing Div with the generated
|
||||
/// code. This currently generates code similarly to compiler-rt's
|
||||
/// implementations, but future work includes generating more specialized code
|
||||
/// when more information about the operands are known. Implements both
|
||||
/// 32bit and 64bit scalar division.
|
||||
///
|
||||
/// Replace Div with generated code.
|
||||
bool expandDivision(BinaryOperator* Div);
|
||||
/// Generate code to divide two integers, replacing Div with the generated
|
||||
/// code. This currently generates code similarly to compiler-rt's
|
||||
/// implementations, but future work includes generating more specialized code
|
||||
/// when more information about the operands are known. Implements both
|
||||
/// 32bit and 64bit scalar division.
|
||||
///
|
||||
/// Replace Div with generated code.
|
||||
LLVM_ABI bool expandDivision(BinaryOperator *Div);
|
||||
|
||||
/// Generate code to calculate the remainder of two integers, replacing Rem
|
||||
/// with the generated code. Uses ExpandReminder with a 32bit Rem which
|
||||
/// makes it useful for targets with little or no support for less than
|
||||
/// 32 bit arithmetic.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
bool expandRemainderUpTo32Bits(BinaryOperator *Rem);
|
||||
/// Generate code to calculate the remainder of two integers, replacing Rem
|
||||
/// with the generated code. Uses ExpandReminder with a 32bit Rem which
|
||||
/// makes it useful for targets with little or no support for less than
|
||||
/// 32 bit arithmetic.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
LLVM_ABI bool expandRemainderUpTo32Bits(BinaryOperator *Rem);
|
||||
|
||||
/// Generate code to calculate the remainder of two integers, replacing Rem
|
||||
/// with the generated code. Uses ExpandReminder with a 64bit Rem.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
bool expandRemainderUpTo64Bits(BinaryOperator *Rem);
|
||||
/// Generate code to calculate the remainder of two integers, replacing Rem
|
||||
/// with the generated code. Uses ExpandReminder with a 64bit Rem.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
LLVM_ABI bool expandRemainderUpTo64Bits(BinaryOperator *Rem);
|
||||
|
||||
/// Generate code to divide two integers, replacing Div with the generated
|
||||
/// code. Uses ExpandDivision with a 32bit Div which makes it useful for
|
||||
/// targets with little or no support for less than 32 bit arithmetic.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
bool expandDivisionUpTo32Bits(BinaryOperator *Div);
|
||||
/// Generate code to divide two integers, replacing Div with the generated
|
||||
/// code. Uses ExpandDivision with a 32bit Div which makes it useful for
|
||||
/// targets with little or no support for less than 32 bit arithmetic.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
LLVM_ABI bool expandDivisionUpTo32Bits(BinaryOperator *Div);
|
||||
|
||||
/// Generate code to divide two integers, replacing Div with the generated
|
||||
/// code. Uses ExpandDivision with a 64bit Div.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
bool expandDivisionUpTo64Bits(BinaryOperator *Div);
|
||||
/// Generate code to divide two integers, replacing Div with the generated
|
||||
/// code. Uses ExpandDivision with a 64bit Div.
|
||||
///
|
||||
/// Replace Rem with generated code.
|
||||
LLVM_ABI bool expandDivisionUpTo64Bits(BinaryOperator *Div);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
||||
@@ -30,13 +30,14 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_LCSSA_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Converts loops into loop-closed SSA form.
|
||||
class LCSSAPass : public PassInfoMixin<LCSSAPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
|
||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||
#include <cstdint>
|
||||
@@ -60,9 +61,10 @@ class TargetTransformInfo;
|
||||
/// Also calls RecursivelyDeleteTriviallyDeadInstructions() on any branch/switch
|
||||
/// conditions and indirectbr addresses this might make dead if
|
||||
/// DeleteDeadConditions is true.
|
||||
bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB,
|
||||
bool DeleteDeadConditions = false,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Local dead code elimination.
|
||||
@@ -71,27 +73,29 @@ bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false,
|
||||
/// Return true if the result produced by the instruction is not used, and the
|
||||
/// instruction will return. Certain side-effecting instructions are also
|
||||
/// considered dead if there are no uses of the instruction.
|
||||
bool isInstructionTriviallyDead(Instruction *I,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
LLVM_ABI bool
|
||||
isInstructionTriviallyDead(Instruction *I,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
|
||||
/// Return true if the result produced by the instruction would have no side
|
||||
/// effects if it was not used. This is equivalent to checking whether
|
||||
/// isInstructionTriviallyDead would be true if the use count was 0.
|
||||
bool wouldInstructionBeTriviallyDead(const Instruction *I,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
LLVM_ABI bool
|
||||
wouldInstructionBeTriviallyDead(const Instruction *I,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
|
||||
/// Return true if the result produced by the instruction has no side effects on
|
||||
/// any paths other than where it is used. This is less conservative than
|
||||
/// wouldInstructionBeTriviallyDead which is based on the assumption
|
||||
/// that the use count will be 0. An example usage of this API is for
|
||||
/// identifying instructions that can be sunk down to use(s).
|
||||
bool wouldInstructionBeTriviallyDeadOnUnusedPaths(
|
||||
LLVM_ABI bool wouldInstructionBeTriviallyDeadOnUnusedPaths(
|
||||
Instruction *I, const TargetLibraryInfo *TLI = nullptr);
|
||||
|
||||
/// If the specified value is a trivially dead instruction, delete it.
|
||||
/// If that makes any of its operands trivially dead, delete them too,
|
||||
/// recursively. Return true if any instructions were deleted.
|
||||
bool RecursivelyDeleteTriviallyDeadInstructions(
|
||||
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(
|
||||
Value *V, const TargetLibraryInfo *TLI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
std::function<void(Value *)> AboutToDeleteCallback =
|
||||
@@ -105,7 +109,7 @@ bool RecursivelyDeleteTriviallyDeadInstructions(
|
||||
///
|
||||
/// `DeadInsts` will be used as scratch storage for this routine and will be
|
||||
/// empty afterward.
|
||||
void RecursivelyDeleteTriviallyDeadInstructions(
|
||||
LLVM_ABI void RecursivelyDeleteTriviallyDeadInstructions(
|
||||
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
|
||||
const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr,
|
||||
std::function<void(Value *)> AboutToDeleteCallback =
|
||||
@@ -115,7 +119,7 @@ void RecursivelyDeleteTriviallyDeadInstructions(
|
||||
/// instructions that are not trivially dead. These will be ignored.
|
||||
/// Returns true if any changes were made, i.e. any instructions trivially dead
|
||||
/// were found and deleted.
|
||||
bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(
|
||||
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(
|
||||
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
|
||||
const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr,
|
||||
std::function<void(Value *)> AboutToDeleteCallback =
|
||||
@@ -126,23 +130,25 @@ bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(
|
||||
/// by a trivially dead instruction, delete it. If that makes any of its
|
||||
/// operands trivially dead, delete them too, recursively. Return true if a
|
||||
/// change was made.
|
||||
bool RecursivelyDeleteDeadPHINode(PHINode *PN,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
LLVM_ABI bool
|
||||
RecursivelyDeleteDeadPHINode(PHINode *PN,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
|
||||
/// Scan the specified basic block and try to simplify any instructions in it
|
||||
/// and recursively delete dead instructions.
|
||||
///
|
||||
/// This returns true if it changed the code, note that it can delete
|
||||
/// instructions in other blocks as well in this block.
|
||||
bool SimplifyInstructionsInBlock(BasicBlock *BB,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
LLVM_ABI bool
|
||||
SimplifyInstructionsInBlock(BasicBlock *BB,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
|
||||
/// Replace all the uses of an SSA value in @llvm.dbg intrinsics with
|
||||
/// undef. This is useful for signaling that a variable, e.g. has been
|
||||
/// found dead and hence it's unavailable at a given program point.
|
||||
/// Returns true if the dbg values have been changed.
|
||||
bool replaceDbgUsesWithUndef(Instruction *I);
|
||||
LLVM_ABI bool replaceDbgUsesWithUndef(Instruction *I);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Control Flow Graph Restructuring.
|
||||
@@ -151,29 +157,31 @@ bool replaceDbgUsesWithUndef(Instruction *I);
|
||||
/// BB is a block with one predecessor and its predecessor is known to have one
|
||||
/// successor (BB!). Eliminate the edge between them, moving the instructions in
|
||||
/// the predecessor into BB. This deletes the predecessor block.
|
||||
void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, DomTreeUpdater *DTU = nullptr);
|
||||
LLVM_ABI void MergeBasicBlockIntoOnlyPred(BasicBlock *BB,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
/// BB is known to contain an unconditional branch, and contains no instructions
|
||||
/// other than PHI nodes, potential debug intrinsics and the branch. If
|
||||
/// possible, eliminate BB by rewriting all the predecessors to branch to the
|
||||
/// successor block and return true. If we can't transform, return false.
|
||||
bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
LLVM_ABI bool
|
||||
TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
/// Check for and eliminate duplicate PHI nodes in this block. This doesn't try
|
||||
/// to be clever about PHI nodes which differ only in the order of the incoming
|
||||
/// values, but instcombine orders them so it usually won't matter.
|
||||
///
|
||||
/// This overload removes the duplicate PHI nodes directly.
|
||||
bool EliminateDuplicatePHINodes(BasicBlock *BB);
|
||||
LLVM_ABI bool EliminateDuplicatePHINodes(BasicBlock *BB);
|
||||
|
||||
/// Check for and eliminate duplicate PHI nodes in this block. This doesn't try
|
||||
/// to be clever about PHI nodes which differ only in the order of the incoming
|
||||
/// values, but instcombine orders them so it usually won't matter.
|
||||
///
|
||||
/// This overload collects the PHI nodes to be removed into the ToRemove set.
|
||||
bool EliminateDuplicatePHINodes(BasicBlock *BB,
|
||||
SmallPtrSetImpl<PHINode *> &ToRemove);
|
||||
LLVM_ABI bool EliminateDuplicatePHINodes(BasicBlock *BB,
|
||||
SmallPtrSetImpl<PHINode *> &ToRemove);
|
||||
|
||||
/// This function is used to do simplification of a CFG. For example, it
|
||||
/// adjusts branches to branches to eliminate the extra hop, it eliminates
|
||||
@@ -181,38 +189,40 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB,
|
||||
/// It returns true if a modification was made, possibly deleting the basic
|
||||
/// block that was pointed to. LoopHeaders is an optional input parameter
|
||||
/// providing the set of loop headers that SimplifyCFG should not eliminate.
|
||||
extern cl::opt<bool> RequireAndPreserveDomTree;
|
||||
bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
const SimplifyCFGOptions &Options = {},
|
||||
ArrayRef<WeakVH> LoopHeaders = {});
|
||||
LLVM_ABI extern cl::opt<bool> RequireAndPreserveDomTree;
|
||||
LLVM_ABI bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
const SimplifyCFGOptions &Options = {},
|
||||
ArrayRef<WeakVH> LoopHeaders = {});
|
||||
|
||||
/// This function is used to flatten a CFG. For example, it uses parallel-and
|
||||
/// and parallel-or mode to collapse if-conditions and merge if-regions with
|
||||
/// identical statements.
|
||||
bool FlattenCFG(BasicBlock *BB, AAResults *AA = nullptr);
|
||||
LLVM_ABI bool FlattenCFG(BasicBlock *BB, AAResults *AA = nullptr);
|
||||
|
||||
/// If this basic block is ONLY a setcc and a branch, and if a predecessor
|
||||
/// branches to us and one of our successors, fold the setcc into the
|
||||
/// predecessor and use logical operations to pick the right destination.
|
||||
bool foldBranchToCommonDest(BranchInst *BI, llvm::DomTreeUpdater *DTU = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const TargetTransformInfo *TTI = nullptr,
|
||||
unsigned BonusInstThreshold = 1);
|
||||
LLVM_ABI bool foldBranchToCommonDest(BranchInst *BI,
|
||||
llvm::DomTreeUpdater *DTU = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr,
|
||||
const TargetTransformInfo *TTI = nullptr,
|
||||
unsigned BonusInstThreshold = 1);
|
||||
|
||||
/// This function takes a virtual register computed by an Instruction and
|
||||
/// replaces it with a slot in the stack frame, allocated via alloca.
|
||||
/// This allows the CFG to be changed around without fear of invalidating the
|
||||
/// SSA information for the value. It returns the pointer to the alloca inserted
|
||||
/// to create a stack slot for X.
|
||||
AllocaInst *DemoteRegToStack(Instruction &X,
|
||||
bool VolatileLoads = false,
|
||||
std::optional<BasicBlock::iterator> AllocaPoint = std::nullopt);
|
||||
LLVM_ABI AllocaInst *DemoteRegToStack(
|
||||
Instruction &X, bool VolatileLoads = false,
|
||||
std::optional<BasicBlock::iterator> AllocaPoint = std::nullopt);
|
||||
|
||||
/// This function takes a virtual register computed by a phi node and replaces
|
||||
/// it with a slot in the stack frame, allocated via alloca. The phi node is
|
||||
/// deleted and it returns the pointer to the alloca inserted.
|
||||
AllocaInst *DemotePHIToStack(PHINode *P, std::optional<BasicBlock::iterator> AllocaPoint = std::nullopt);
|
||||
LLVM_ABI AllocaInst *DemotePHIToStack(
|
||||
PHINode *P, std::optional<BasicBlock::iterator> AllocaPoint = std::nullopt);
|
||||
|
||||
/// If the specified pointer points to an object that we control, try to modify
|
||||
/// the object's alignment to PrefAlign. Returns a minimum known alignment of
|
||||
@@ -221,7 +231,8 @@ AllocaInst *DemotePHIToStack(PHINode *P, std::optional<BasicBlock::iterator> All
|
||||
/// Increating value alignment isn't often possible though. If alignment is
|
||||
/// important, a more reliable approach is to simply align all global variables
|
||||
/// and allocation instructions to their preferred alignment from the beginning.
|
||||
Align tryEnforceAlignment(Value *V, Align PrefAlign, const DataLayout &DL);
|
||||
LLVM_ABI Align tryEnforceAlignment(Value *V, Align PrefAlign,
|
||||
const DataLayout &DL);
|
||||
|
||||
/// Try to ensure that the alignment of \p V is at least \p PrefAlign bytes. If
|
||||
/// the owning object can be modified and has an alignment less than \p
|
||||
@@ -232,11 +243,11 @@ Align tryEnforceAlignment(Value *V, Align PrefAlign, const DataLayout &DL);
|
||||
/// so if alignment is important, a more reliable approach is to simply align
|
||||
/// all global variables and allocation instructions to their preferred
|
||||
/// alignment from the beginning.
|
||||
Align getOrEnforceKnownAlignment(Value *V, MaybeAlign PrefAlign,
|
||||
const DataLayout &DL,
|
||||
const Instruction *CxtI = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
LLVM_ABI Align getOrEnforceKnownAlignment(Value *V, MaybeAlign PrefAlign,
|
||||
const DataLayout &DL,
|
||||
const Instruction *CxtI = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Try to infer an alignment for the specified pointer.
|
||||
inline Align getKnownAlignment(Value *V, const DataLayout &DL,
|
||||
@@ -250,10 +261,10 @@ inline Align getKnownAlignment(Value *V, const DataLayout &DL,
|
||||
/// attributes, debug information, etc. The call is not placed in a block and it
|
||||
/// will not have a name. The invoke instruction is not removed, nor are the
|
||||
/// uses replaced by the new call.
|
||||
CallInst *createCallMatchingInvoke(InvokeInst *II);
|
||||
LLVM_ABI CallInst *createCallMatchingInvoke(InvokeInst *II);
|
||||
|
||||
/// This function converts the specified invoke into a normal call.
|
||||
CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
|
||||
LLVM_ABI CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
///===---------------------------------------------------------------------===//
|
||||
/// Dbg Intrinsic utilities
|
||||
@@ -261,70 +272,75 @@ CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
/// Creates and inserts a dbg_value record intrinsic before a store
|
||||
/// that has an associated llvm.dbg.value intrinsic.
|
||||
void InsertDebugValueAtStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
|
||||
DIBuilder &Builder);
|
||||
LLVM_ABI void InsertDebugValueAtStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
|
||||
DIBuilder &Builder);
|
||||
|
||||
/// Creates and inserts an llvm.dbg.value intrinsic before a store
|
||||
/// that has an associated llvm.dbg.value intrinsic.
|
||||
void InsertDebugValueAtStoreLoc(DbgVariableIntrinsic *DII, StoreInst *SI,
|
||||
DIBuilder &Builder);
|
||||
LLVM_ABI void InsertDebugValueAtStoreLoc(DbgVariableIntrinsic *DII,
|
||||
StoreInst *SI, DIBuilder &Builder);
|
||||
|
||||
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
|
||||
/// that has an associated llvm.dbg.declare intrinsic.
|
||||
void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
|
||||
StoreInst *SI, DIBuilder &Builder);
|
||||
void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, StoreInst *SI,
|
||||
DIBuilder &Builder);
|
||||
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
|
||||
StoreInst *SI,
|
||||
DIBuilder &Builder);
|
||||
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
|
||||
StoreInst *SI,
|
||||
DIBuilder &Builder);
|
||||
|
||||
/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
|
||||
/// that has an associated llvm.dbg.declare intrinsic.
|
||||
void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
|
||||
LoadInst *LI, DIBuilder &Builder);
|
||||
void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, LoadInst *LI,
|
||||
DIBuilder &Builder);
|
||||
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
|
||||
LoadInst *LI, DIBuilder &Builder);
|
||||
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
|
||||
LoadInst *LI, DIBuilder &Builder);
|
||||
|
||||
/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
|
||||
/// llvm.dbg.declare intrinsic.
|
||||
void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
|
||||
PHINode *LI, DIBuilder &Builder);
|
||||
void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, PHINode *LI,
|
||||
DIBuilder &Builder);
|
||||
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
|
||||
PHINode *LI, DIBuilder &Builder);
|
||||
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
|
||||
PHINode *LI, DIBuilder &Builder);
|
||||
|
||||
/// Lowers llvm.dbg.declare intrinsics into appropriate set of
|
||||
/// llvm.dbg.value intrinsics.
|
||||
bool LowerDbgDeclare(Function &F);
|
||||
LLVM_ABI bool LowerDbgDeclare(Function &F);
|
||||
|
||||
/// Propagate dbg.value intrinsics through the newly inserted PHIs.
|
||||
void insertDebugValuesForPHIs(BasicBlock *BB,
|
||||
SmallVectorImpl<PHINode *> &InsertedPHIs);
|
||||
LLVM_ABI void
|
||||
insertDebugValuesForPHIs(BasicBlock *BB,
|
||||
SmallVectorImpl<PHINode *> &InsertedPHIs);
|
||||
|
||||
/// Replaces llvm.dbg.declare instruction when the address it
|
||||
/// describes is replaced with a new value. If Deref is true, an
|
||||
/// additional DW_OP_deref is prepended to the expression. If Offset
|
||||
/// is non-zero, a constant displacement is added to the expression
|
||||
/// (between the optional Deref operations). Offset can be negative.
|
||||
bool replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder,
|
||||
uint8_t DIExprFlags, int Offset);
|
||||
LLVM_ABI bool replaceDbgDeclare(Value *Address, Value *NewAddress,
|
||||
DIBuilder &Builder, uint8_t DIExprFlags,
|
||||
int Offset);
|
||||
|
||||
/// Replaces multiple llvm.dbg.value instructions when the alloca it describes
|
||||
/// is replaced with a new value. If Offset is non-zero, a constant displacement
|
||||
/// is added to the expression (after the mandatory Deref). Offset can be
|
||||
/// negative. New llvm.dbg.value instructions are inserted at the locations of
|
||||
/// the instructions they replace.
|
||||
void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
|
||||
DIBuilder &Builder, int Offset = 0);
|
||||
LLVM_ABI void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
|
||||
DIBuilder &Builder, int Offset = 0);
|
||||
|
||||
/// Assuming the instruction \p I is going to be deleted, attempt to salvage
|
||||
/// debug users of \p I by writing the effect of \p I in a DIExpression. If it
|
||||
/// cannot be salvaged changes its debug uses to undef.
|
||||
void salvageDebugInfo(Instruction &I);
|
||||
LLVM_ABI void salvageDebugInfo(Instruction &I);
|
||||
|
||||
/// Implementation of salvageDebugInfo, applying only to instructions in
|
||||
/// \p Insns, rather than all debug users from findDbgUsers( \p I).
|
||||
/// Mark undef if salvaging cannot be completed.
|
||||
void salvageDebugInfoForDbgValues(Instruction &I,
|
||||
ArrayRef<DbgVariableIntrinsic *> Insns,
|
||||
ArrayRef<DbgVariableRecord *> DPInsns);
|
||||
LLVM_ABI void
|
||||
salvageDebugInfoForDbgValues(Instruction &I,
|
||||
ArrayRef<DbgVariableIntrinsic *> Insns,
|
||||
ArrayRef<DbgVariableRecord *> DPInsns);
|
||||
|
||||
/// Given an instruction \p I and DIExpression \p DIExpr operating on
|
||||
/// it, append the effects of \p I to the DIExpression operand list
|
||||
@@ -347,9 +363,10 @@ void salvageDebugInfoForDbgValues(Instruction &I,
|
||||
/// Return = %a
|
||||
/// Ops = llvm::dwarf::DW_OP_LLVM_arg0 llvm::dwarf::DW_OP_add
|
||||
/// AdditionalValues = %b
|
||||
Value *salvageDebugInfoImpl(Instruction &I, uint64_t CurrentLocOps,
|
||||
SmallVectorImpl<uint64_t> &Ops,
|
||||
SmallVectorImpl<Value *> &AdditionalValues);
|
||||
LLVM_ABI Value *
|
||||
salvageDebugInfoImpl(Instruction &I, uint64_t CurrentLocOps,
|
||||
SmallVectorImpl<uint64_t> &Ops,
|
||||
SmallVectorImpl<Value *> &AdditionalValues);
|
||||
|
||||
/// Point debug users of \p From to \p To or salvage them. Use this function
|
||||
/// only when replacing all uses of \p From with \p To, with a guarantee that
|
||||
@@ -365,37 +382,39 @@ Value *salvageDebugInfoImpl(Instruction &I, uint64_t CurrentLocOps,
|
||||
/// If a debug user cannot be preserved without reordering variable updates or
|
||||
/// introducing a use-before-def, it is either salvaged (\ref salvageDebugInfo)
|
||||
/// or deleted. Returns true if any debug users were updated.
|
||||
bool replaceAllDbgUsesWith(Instruction &From, Value &To, Instruction &DomPoint,
|
||||
DominatorTree &DT);
|
||||
LLVM_ABI bool replaceAllDbgUsesWith(Instruction &From, Value &To,
|
||||
Instruction &DomPoint, DominatorTree &DT);
|
||||
|
||||
/// If a terminator in an unreachable basic block has an operand of type
|
||||
/// Instruction, transform it into poison. Return true if any operands
|
||||
/// are changed to poison. Original Values prior to being changed to poison
|
||||
/// are returned in \p PoisonedValues.
|
||||
bool handleUnreachableTerminator(Instruction *I,
|
||||
SmallVectorImpl<Value *> &PoisonedValues);
|
||||
LLVM_ABI bool
|
||||
handleUnreachableTerminator(Instruction *I,
|
||||
SmallVectorImpl<Value *> &PoisonedValues);
|
||||
|
||||
/// Remove all instructions from a basic block other than its terminator
|
||||
/// and any present EH pad instructions. Returns a pair where the first element
|
||||
/// is the number of instructions (excluding debug info intrinsics) that have
|
||||
/// been removed, and the second element is the number of debug info intrinsics
|
||||
/// that have been removed.
|
||||
std::pair<unsigned, unsigned>
|
||||
LLVM_ABI std::pair<unsigned, unsigned>
|
||||
removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB);
|
||||
|
||||
/// Insert an unreachable instruction before the specified
|
||||
/// instruction, making it and the rest of the code in the block dead.
|
||||
unsigned changeToUnreachable(Instruction *I, bool PreserveLCSSA = false,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
LLVM_ABI unsigned changeToUnreachable(Instruction *I,
|
||||
bool PreserveLCSSA = false,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
|
||||
/// Convert the CallInst to InvokeInst with the specified unwind edge basic
|
||||
/// block. This also splits the basic block where CI is located, because
|
||||
/// InvokeInst is a terminator instruction. Returns the newly split basic
|
||||
/// block.
|
||||
BasicBlock *changeToInvokeAndSplitBasicBlock(CallInst *CI,
|
||||
BasicBlock *UnwindEdge,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
LLVM_ABI BasicBlock *
|
||||
changeToInvokeAndSplitBasicBlock(CallInst *CI, BasicBlock *UnwindEdge,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
/// Replace 'BB's terminator with one that does not have an unwind successor
|
||||
/// block. Rewrites `invoke` to `call`, etc. Updates any PHIs in unwind
|
||||
@@ -404,13 +423,15 @@ BasicBlock *changeToInvokeAndSplitBasicBlock(CallInst *CI,
|
||||
///
|
||||
/// \param BB Block whose terminator will be replaced. Its terminator must
|
||||
/// have an unwind successor.
|
||||
Instruction *removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU = nullptr);
|
||||
LLVM_ABI Instruction *removeUnwindEdge(BasicBlock *BB,
|
||||
DomTreeUpdater *DTU = nullptr);
|
||||
|
||||
/// Remove all blocks that can not be reached from the function's entry.
|
||||
///
|
||||
/// Returns true if any basic block was removed.
|
||||
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
LLVM_ABI bool removeUnreachableBlocks(Function &F,
|
||||
DomTreeUpdater *DTU = nullptr,
|
||||
MemorySSAUpdater *MSSAU = nullptr);
|
||||
|
||||
/// Combine the metadata of two instructions so that K can replace J. This
|
||||
/// specifically handles the case of CSE-like transformations. Some
|
||||
@@ -418,45 +439,47 @@ bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU = nullptr,
|
||||
/// K cannot be hoisted.
|
||||
///
|
||||
/// Unknown metadata is removed.
|
||||
void combineMetadataForCSE(Instruction *K, const Instruction *J,
|
||||
bool DoesKMove);
|
||||
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J,
|
||||
bool DoesKMove);
|
||||
|
||||
/// Combine metadata of two instructions, where instruction J is a memory
|
||||
/// access that has been merged into K. This will intersect alias-analysis
|
||||
/// metadata, while preserving other known metadata.
|
||||
void combineAAMetadata(Instruction *K, const Instruction *J);
|
||||
LLVM_ABI void combineAAMetadata(Instruction *K, const Instruction *J);
|
||||
|
||||
/// Copy the metadata from the source instruction to the destination (the
|
||||
/// replacement for the source instruction).
|
||||
void copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source);
|
||||
LLVM_ABI void copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source);
|
||||
|
||||
/// Patch the replacement so that it is not more restrictive than the value
|
||||
/// being replaced. It assumes that the replacement does not get moved from
|
||||
/// its original position.
|
||||
void patchReplacementInstruction(Instruction *I, Value *Repl);
|
||||
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl);
|
||||
|
||||
// Replace each use of 'From' with 'To', if that use does not belong to basic
|
||||
// block where 'From' is defined. Returns the number of replacements made.
|
||||
unsigned replaceNonLocalUsesWith(Instruction *From, Value *To);
|
||||
LLVM_ABI unsigned replaceNonLocalUsesWith(Instruction *From, Value *To);
|
||||
|
||||
/// Replace each use of 'From' with 'To' if that use is dominated by
|
||||
/// the given edge. Returns the number of replacements made.
|
||||
unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
|
||||
const BasicBlockEdge &Edge);
|
||||
LLVM_ABI unsigned replaceDominatedUsesWith(Value *From, Value *To,
|
||||
DominatorTree &DT,
|
||||
const BasicBlockEdge &Edge);
|
||||
/// Replace each use of 'From' with 'To' if that use is dominated by
|
||||
/// the end of the given BasicBlock. Returns the number of replacements made.
|
||||
unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
|
||||
const BasicBlock *BB);
|
||||
LLVM_ABI unsigned replaceDominatedUsesWith(Value *From, Value *To,
|
||||
DominatorTree &DT,
|
||||
const BasicBlock *BB);
|
||||
/// Replace each use of 'From' with 'To' if that use is dominated by
|
||||
/// the given edge and the callback ShouldReplace returns true. Returns the
|
||||
/// number of replacements made.
|
||||
unsigned replaceDominatedUsesWithIf(
|
||||
LLVM_ABI unsigned replaceDominatedUsesWithIf(
|
||||
Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge,
|
||||
function_ref<bool(const Use &U, const Value *To)> ShouldReplace);
|
||||
/// Replace each use of 'From' with 'To' if that use is dominated by
|
||||
/// the end of the given BasicBlock and the callback ShouldReplace returns true.
|
||||
/// Returns the number of replacements made.
|
||||
unsigned replaceDominatedUsesWithIf(
|
||||
LLVM_ABI unsigned replaceDominatedUsesWithIf(
|
||||
Value *From, Value *To, DominatorTree &DT, const BasicBlock *BB,
|
||||
function_ref<bool(const Use &U, const Value *To)> ShouldReplace);
|
||||
|
||||
@@ -468,39 +491,41 @@ unsigned replaceDominatedUsesWithIf(
|
||||
///
|
||||
/// Most passes can and should ignore this information, and it is only used
|
||||
/// during lowering by the GC infrastructure.
|
||||
bool callsGCLeafFunction(const CallBase *Call, const TargetLibraryInfo &TLI);
|
||||
LLVM_ABI bool callsGCLeafFunction(const CallBase *Call,
|
||||
const TargetLibraryInfo &TLI);
|
||||
|
||||
/// Copy a nonnull metadata node to a new load instruction.
|
||||
///
|
||||
/// This handles mapping it to range metadata if the new load is an integer
|
||||
/// load instead of a pointer load.
|
||||
void copyNonnullMetadata(const LoadInst &OldLI, MDNode *N, LoadInst &NewLI);
|
||||
LLVM_ABI void copyNonnullMetadata(const LoadInst &OldLI, MDNode *N,
|
||||
LoadInst &NewLI);
|
||||
|
||||
/// Copy a range metadata node to a new load instruction.
|
||||
///
|
||||
/// This handles mapping it to nonnull metadata if the new load is a pointer
|
||||
/// load instead of an integer load and the range doesn't cover null.
|
||||
void copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI, MDNode *N,
|
||||
LoadInst &NewLI);
|
||||
LLVM_ABI void copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI,
|
||||
MDNode *N, LoadInst &NewLI);
|
||||
|
||||
/// Remove the debug intrinsic instructions for the given instruction.
|
||||
void dropDebugUsers(Instruction &I);
|
||||
LLVM_ABI void dropDebugUsers(Instruction &I);
|
||||
|
||||
/// Hoist all of the instructions in the \p IfBlock to the dominant block
|
||||
/// \p DomBlock, by moving its instructions to the insertion point \p InsertPt.
|
||||
///
|
||||
/// The moved instructions receive the insertion point debug location values
|
||||
/// (DILocations) and their debug intrinsic instructions are removed.
|
||||
void hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt,
|
||||
BasicBlock *BB);
|
||||
LLVM_ABI void hoistAllInstructionsInto(BasicBlock *DomBlock,
|
||||
Instruction *InsertPt, BasicBlock *BB);
|
||||
|
||||
/// Given a constant, create a debug information expression.
|
||||
DIExpression *getExpressionForConstant(DIBuilder &DIB, const Constant &C,
|
||||
Type &Ty);
|
||||
LLVM_ABI DIExpression *getExpressionForConstant(DIBuilder &DIB,
|
||||
const Constant &C, Type &Ty);
|
||||
|
||||
/// Remap the operands of the debug records attached to \p Inst, and the
|
||||
/// operands of \p Inst itself if it's a debug intrinsic.
|
||||
void remapDebugVariable(ValueToValueMapTy &Mapping, Instruction *Inst);
|
||||
LLVM_ABI void remapDebugVariable(ValueToValueMapTy &Mapping, Instruction *Inst);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Intrinsic pattern matching
|
||||
@@ -517,9 +542,10 @@ void remapDebugVariable(ValueToValueMapTy &Mapping, Instruction *Inst);
|
||||
/// to BW / 4 nodes to be searched, so is significantly faster.
|
||||
///
|
||||
/// This function returns true on a successful match or false otherwise.
|
||||
bool recognizeBSwapOrBitReverseIdiom(
|
||||
Instruction *I, bool MatchBSwaps, bool MatchBitReversals,
|
||||
SmallVectorImpl<Instruction *> &InsertedInsts);
|
||||
LLVM_ABI bool
|
||||
recognizeBSwapOrBitReverseIdiom(Instruction *I, bool MatchBSwaps,
|
||||
bool MatchBitReversals,
|
||||
SmallVectorImpl<Instruction *> &InsertedInsts);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Sanitizer utilities
|
||||
@@ -529,8 +555,9 @@ bool recognizeBSwapOrBitReverseIdiom(
|
||||
/// and mark it with NoBuiltin if so. To be used by sanitizers that intend
|
||||
/// to intercept string functions and want to avoid converting them to target
|
||||
/// specific instructions.
|
||||
void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI,
|
||||
const TargetLibraryInfo *TLI);
|
||||
LLVM_ABI void
|
||||
maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI,
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Transform predicates
|
||||
@@ -538,15 +565,15 @@ void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI,
|
||||
|
||||
/// Given an instruction, is it legal to set operand OpIdx to a non-constant
|
||||
/// value?
|
||||
bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx);
|
||||
LLVM_ABI bool canReplaceOperandWithVariable(const Instruction *I,
|
||||
unsigned OpIdx);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Value helper functions
|
||||
//
|
||||
|
||||
/// Invert the given true/false value, possibly reusing an existing copy.
|
||||
Value *invertCondition(Value *Condition);
|
||||
|
||||
LLVM_ABI Value *invertCondition(Value *Condition);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Assorted
|
||||
@@ -554,7 +581,7 @@ Value *invertCondition(Value *Condition);
|
||||
|
||||
/// If we can infer one attribute from another on the declaration of a
|
||||
/// function, explicitly materialize the maximal set in the IR.
|
||||
bool inferAttributesFromOthers(Function &F);
|
||||
LLVM_ABI bool inferAttributesFromOthers(Function &F);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Helpers to track and update flags on instructions.
|
||||
@@ -581,10 +608,10 @@ struct OverflowTracking {
|
||||
OverflowTracking() = default;
|
||||
|
||||
/// Merge in the no-wrap flags from \p I.
|
||||
void mergeFlags(Instruction &I);
|
||||
LLVM_ABI void mergeFlags(Instruction &I);
|
||||
|
||||
/// Apply the no-wrap flags to \p I if applicable.
|
||||
void applyFlags(Instruction &I);
|
||||
LLVM_ABI void applyFlags(Instruction &I);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#ifndef LLVM_TRANSFORMS_UTILS_LOOPROTATIONUTILS_H
|
||||
#define LLVM_TRANSFORMS_UTILS_LOOPROTATIONUTILS_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AssumptionCache;
|
||||
@@ -30,11 +32,12 @@ class TargetTransformInfo;
|
||||
/// header. If the loop header's size exceeds the threshold, the loop rotation
|
||||
/// will give up. The flag IsUtilMode controls the heuristic used in the
|
||||
/// LoopRotation. If it is true, the profitability heuristic will be ignored.
|
||||
bool LoopRotation(Loop *L, LoopInfo *LI, const TargetTransformInfo *TTI,
|
||||
AssumptionCache *AC, DominatorTree *DT, ScalarEvolution *SE,
|
||||
MemorySSAUpdater *MSSAU, const SimplifyQuery &SQ,
|
||||
bool RotationOnly, unsigned Threshold, bool IsUtilMode,
|
||||
bool PrepareForLTO = false);
|
||||
LLVM_ABI bool LoopRotation(Loop *L, LoopInfo *LI,
|
||||
const TargetTransformInfo *TTI, AssumptionCache *AC,
|
||||
DominatorTree *DT, ScalarEvolution *SE,
|
||||
MemorySSAUpdater *MSSAU, const SimplifyQuery &SQ,
|
||||
bool RotationOnly, unsigned Threshold,
|
||||
bool IsUtilMode, bool PrepareForLTO = false);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_LOOPSIMPLIFY_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -52,7 +53,7 @@ class ScalarEvolution;
|
||||
/// This pass is responsible for loop canonicalization.
|
||||
class LoopSimplifyPass : public PassInfoMixin<LoopSimplifyPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Simplify each loop in a loop nest recursively.
|
||||
@@ -61,9 +62,9 @@ public:
|
||||
/// it into a simplified loop nest with preheaders and single backedges. It will
|
||||
/// update \c DominatorTree, \c LoopInfo, \c ScalarEvolution and \c MemorySSA
|
||||
/// analyses if they're non-null, and LCSSA if \c PreserveLCSSA is true.
|
||||
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE,
|
||||
AssumptionCache *AC, MemorySSAUpdater *MSSAU,
|
||||
bool PreserveLCSSA);
|
||||
LLVM_ABI bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
ScalarEvolution *SE, AssumptionCache *AC,
|
||||
MemorySSAUpdater *MSSAU, bool PreserveLCSSA);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "llvm/Analysis/LoopAccessAnalysis.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/VectorBuilder.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -52,16 +53,19 @@ typedef std::pair<const RuntimeCheckingPtrGroup *,
|
||||
template <typename T, unsigned N> class SmallSetVector;
|
||||
template <typename T, unsigned N> class SmallPriorityWorklist;
|
||||
|
||||
BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
MemorySSAUpdater *MSSAU, bool PreserveLCSSA);
|
||||
LLVM_ABI BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT,
|
||||
LoopInfo *LI,
|
||||
MemorySSAUpdater *MSSAU,
|
||||
bool PreserveLCSSA);
|
||||
|
||||
/// Ensure that all exit blocks of the loop are dedicated exits.
|
||||
///
|
||||
/// For any loop exit block with non-loop predecessors, we split the loop
|
||||
/// predecessors to use a dedicated loop exit block. We update the dominator
|
||||
/// tree and loop info if provided, and will preserve LCSSA if requested.
|
||||
bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
MemorySSAUpdater *MSSAU, bool PreserveLCSSA);
|
||||
LLVM_ABI bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
MemorySSAUpdater *MSSAU,
|
||||
bool PreserveLCSSA);
|
||||
|
||||
/// Ensures LCSSA form for every instruction from the Worklist in the scope of
|
||||
/// innermost containing loop.
|
||||
@@ -81,11 +85,12 @@ bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
///
|
||||
/// If \p InsertedPHIs is not nullptr, inserted phis will be added to this
|
||||
/// vector.
|
||||
bool formLCSSAForInstructions(
|
||||
SmallVectorImpl<Instruction *> &Worklist, const DominatorTree &DT,
|
||||
const LoopInfo &LI, ScalarEvolution *SE,
|
||||
SmallVectorImpl<PHINode *> *PHIsToRemove = nullptr,
|
||||
SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
|
||||
LLVM_ABI bool
|
||||
formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
||||
const DominatorTree &DT, const LoopInfo &LI,
|
||||
ScalarEvolution *SE,
|
||||
SmallVectorImpl<PHINode *> *PHIsToRemove = nullptr,
|
||||
SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
|
||||
|
||||
/// Put loop into LCSSA form.
|
||||
///
|
||||
@@ -99,8 +104,8 @@ bool formLCSSAForInstructions(
|
||||
/// If ScalarEvolution is passed in, it will be preserved.
|
||||
///
|
||||
/// Returns true if any modifications are made to the loop.
|
||||
bool formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
|
||||
ScalarEvolution *SE);
|
||||
LLVM_ABI bool formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
|
||||
ScalarEvolution *SE);
|
||||
|
||||
/// Put a loop nest into LCSSA form.
|
||||
///
|
||||
@@ -111,8 +116,8 @@ bool formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
|
||||
/// If ScalarEvolution is passed in, it will be preserved.
|
||||
///
|
||||
/// Returns true if any modifications are made to the loop.
|
||||
bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
|
||||
ScalarEvolution *SE);
|
||||
LLVM_ABI bool formLCSSARecursively(Loop &L, const DominatorTree &DT,
|
||||
const LoopInfo *LI, ScalarEvolution *SE);
|
||||
|
||||
/// Flags controlling how much is checked when sinking or hoisting
|
||||
/// instructions. The number of memory access in the loop (and whether there
|
||||
@@ -120,11 +125,11 @@ bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
|
||||
class SinkAndHoistLICMFlags {
|
||||
public:
|
||||
// Explicitly set limits.
|
||||
SinkAndHoistLICMFlags(unsigned LicmMssaOptCap,
|
||||
unsigned LicmMssaNoAccForPromotionCap, bool IsSink,
|
||||
Loop &L, MemorySSA &MSSA);
|
||||
LLVM_ABI SinkAndHoistLICMFlags(unsigned LicmMssaOptCap,
|
||||
unsigned LicmMssaNoAccForPromotionCap,
|
||||
bool IsSink, Loop &L, MemorySSA &MSSA);
|
||||
// Use default limits.
|
||||
SinkAndHoistLICMFlags(bool IsSink, Loop &L, MemorySSA &MSSA);
|
||||
LLVM_ABI SinkAndHoistLICMFlags(bool IsSink, Loop &L, MemorySSA &MSSA);
|
||||
|
||||
void setIsSink(bool B) { IsSink = B; }
|
||||
bool getIsSink() { return IsSink; }
|
||||
@@ -150,19 +155,21 @@ protected:
|
||||
/// arguments. Diagnostics is emitted via \p ORE. It returns changed status.
|
||||
/// \p CurLoop is a loop to do sinking on. \p OutermostLoop is used only when
|
||||
/// this function is called by \p sinkRegionForLoopNest.
|
||||
bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
|
||||
TargetLibraryInfo *, TargetTransformInfo *, Loop *CurLoop,
|
||||
MemorySSAUpdater &, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *,
|
||||
Loop *OutermostLoop = nullptr);
|
||||
LLVM_ABI bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *,
|
||||
DominatorTree *, TargetLibraryInfo *,
|
||||
TargetTransformInfo *, Loop *CurLoop,
|
||||
MemorySSAUpdater &, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *,
|
||||
Loop *OutermostLoop = nullptr);
|
||||
|
||||
/// Call sinkRegion on loops contained within the specified loop
|
||||
/// in order from innermost to outermost.
|
||||
bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *,
|
||||
DominatorTree *, TargetLibraryInfo *,
|
||||
TargetTransformInfo *, Loop *, MemorySSAUpdater &,
|
||||
ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &,
|
||||
OptimizationRemarkEmitter *);
|
||||
LLVM_ABI bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *,
|
||||
DominatorTree *, TargetLibraryInfo *,
|
||||
TargetTransformInfo *, Loop *,
|
||||
MemorySSAUpdater &, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &,
|
||||
OptimizationRemarkEmitter *);
|
||||
|
||||
/// Walk the specified region of the CFG (defined by all blocks
|
||||
/// dominated by the specified block, and that are in the current loop) in depth
|
||||
@@ -174,16 +181,17 @@ bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *,
|
||||
/// Diagnostics is emitted via \p ORE. It returns changed status.
|
||||
/// \p AllowSpeculation is whether values should be hoisted even if they are not
|
||||
/// guaranteed to execute in the loop, but are safe to speculatively execute.
|
||||
bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
|
||||
AssumptionCache *, TargetLibraryInfo *, Loop *,
|
||||
MemorySSAUpdater &, ScalarEvolution *, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *, bool,
|
||||
bool AllowSpeculation);
|
||||
LLVM_ABI bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *,
|
||||
DominatorTree *, AssumptionCache *,
|
||||
TargetLibraryInfo *, Loop *, MemorySSAUpdater &,
|
||||
ScalarEvolution *, ICFLoopSafetyInfo *,
|
||||
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *,
|
||||
bool, bool AllowSpeculation);
|
||||
|
||||
/// Return true if the induction variable \p IV in a Loop whose latch is
|
||||
/// \p LatchBlock would become dead if the exit test \p Cond were removed.
|
||||
/// Conservatively returns false if analysis is insufficient.
|
||||
bool isAlmostDeadIV(PHINode *IV, BasicBlock *LatchBlock, Value *Cond);
|
||||
LLVM_ABI bool isAlmostDeadIV(PHINode *IV, BasicBlock *LatchBlock, Value *Cond);
|
||||
|
||||
/// This function deletes dead loops. The caller of this function needs to
|
||||
/// guarantee that the loop is infact dead.
|
||||
@@ -196,14 +204,14 @@ bool isAlmostDeadIV(PHINode *IV, BasicBlock *LatchBlock, Value *Cond);
|
||||
/// and \p MSSA if pointers to those are provided.
|
||||
/// It also updates the loop PM if an updater struct is provided.
|
||||
|
||||
void deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
|
||||
LoopInfo *LI, MemorySSA *MSSA = nullptr);
|
||||
LLVM_ABI void deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
|
||||
LoopInfo *LI, MemorySSA *MSSA = nullptr);
|
||||
|
||||
/// Remove the backedge of the specified loop. Handles loop nests and general
|
||||
/// loop structures subject to the precondition that the loop has no parent
|
||||
/// loop and has a single latch block. Preserves all listed analyses.
|
||||
void breakLoopBackedge(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
|
||||
LoopInfo &LI, MemorySSA *MSSA);
|
||||
LLVM_ABI void breakLoopBackedge(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
|
||||
LoopInfo &LI, MemorySSA *MSSA);
|
||||
|
||||
/// Try to promote memory values to scalars by sinking stores out of
|
||||
/// the loop and moving loads to before the loop. We do this by looping over
|
||||
@@ -215,7 +223,7 @@ void breakLoopBackedge(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
|
||||
/// Diagnostics is emitted via \p ORE. It returns changed status.
|
||||
/// \p AllowSpeculation is whether values should be hoisted even if they are not
|
||||
/// guaranteed to execute in the loop, but are safe to speculatively execute.
|
||||
bool promoteLoopAccessesToScalars(
|
||||
LLVM_ABI bool promoteLoopAccessesToScalars(
|
||||
const SmallSetVector<Value *, 8> &, SmallVectorImpl<BasicBlock *> &,
|
||||
SmallVectorImpl<BasicBlock::iterator> &, SmallVectorImpl<MemoryAccess *> &,
|
||||
PredIteratorCache &, LoopInfo *, DominatorTree *, AssumptionCache *AC,
|
||||
@@ -225,17 +233,17 @@ bool promoteLoopAccessesToScalars(
|
||||
|
||||
/// Does a BFS from a given node to all of its children inside a given loop.
|
||||
/// The returned vector of basic blocks includes the starting point.
|
||||
SmallVector<BasicBlock *, 16>
|
||||
LLVM_ABI SmallVector<BasicBlock *, 16>
|
||||
collectChildrenInLoop(DominatorTree *DT, DomTreeNode *N, const Loop *CurLoop);
|
||||
|
||||
/// Returns the instructions that use values defined in the loop.
|
||||
SmallVector<Instruction *, 8> findDefsUsedOutsideOfLoop(Loop *L);
|
||||
LLVM_ABI SmallVector<Instruction *, 8> findDefsUsedOutsideOfLoop(Loop *L);
|
||||
|
||||
/// Find a combination of metadata ("llvm.loop.vectorize.width" and
|
||||
/// "llvm.loop.vectorize.scalable.enable") for a loop and use it to construct a
|
||||
/// ElementCount. If the metadata "llvm.loop.vectorize.width" cannot be found
|
||||
/// then std::nullopt is returned.
|
||||
std::optional<ElementCount>
|
||||
LLVM_ABI std::optional<ElementCount>
|
||||
getOptionalElementCountLoopAttribute(const Loop *TheLoop);
|
||||
|
||||
/// Create a new loop identifier for a loop created from a loop transformation.
|
||||
@@ -262,16 +270,16 @@ getOptionalElementCountLoopAttribute(const Loop *TheLoop);
|
||||
/// @p OrigLoopID: The original identifier can be reused.
|
||||
/// nullptr : The new loop has no attributes.
|
||||
/// MDNode* : A new unique loop identifier.
|
||||
std::optional<MDNode *>
|
||||
LLVM_ABI std::optional<MDNode *>
|
||||
makeFollowupLoopID(MDNode *OrigLoopID, ArrayRef<StringRef> FollowupAttrs,
|
||||
const char *InheritOptionsAttrsPrefix = "",
|
||||
bool AlwaysNew = false);
|
||||
|
||||
/// Look for the loop attribute that disables all transformation heuristic.
|
||||
bool hasDisableAllTransformsHint(const Loop *L);
|
||||
LLVM_ABI bool hasDisableAllTransformsHint(const Loop *L);
|
||||
|
||||
/// Look for the loop attribute that disables the LICM transformation heuristics.
|
||||
bool hasDisableLICMTransformsHint(const Loop *L);
|
||||
LLVM_ABI bool hasDisableLICMTransformsHint(const Loop *L);
|
||||
|
||||
/// The mode sets how eager a transformation should be applied.
|
||||
enum TransformationMode {
|
||||
@@ -302,25 +310,25 @@ enum TransformationMode {
|
||||
|
||||
/// @{
|
||||
/// Get the mode for LLVM's supported loop transformations.
|
||||
TransformationMode hasUnrollTransformation(const Loop *L);
|
||||
TransformationMode hasUnrollAndJamTransformation(const Loop *L);
|
||||
TransformationMode hasVectorizeTransformation(const Loop *L);
|
||||
TransformationMode hasDistributeTransformation(const Loop *L);
|
||||
TransformationMode hasLICMVersioningTransformation(const Loop *L);
|
||||
LLVM_ABI TransformationMode hasUnrollTransformation(const Loop *L);
|
||||
LLVM_ABI TransformationMode hasUnrollAndJamTransformation(const Loop *L);
|
||||
LLVM_ABI TransformationMode hasVectorizeTransformation(const Loop *L);
|
||||
LLVM_ABI TransformationMode hasDistributeTransformation(const Loop *L);
|
||||
LLVM_ABI TransformationMode hasLICMVersioningTransformation(const Loop *L);
|
||||
/// @}
|
||||
|
||||
/// Set input string into loop metadata by keeping other values intact.
|
||||
/// If the string is already in loop metadata update value if it is
|
||||
/// different.
|
||||
void addStringMetadataToLoop(Loop *TheLoop, const char *MDString,
|
||||
unsigned V = 0);
|
||||
LLVM_ABI void addStringMetadataToLoop(Loop *TheLoop, const char *MDString,
|
||||
unsigned V = 0);
|
||||
|
||||
/// Returns a loop's estimated trip count based on branch weight metadata.
|
||||
/// In addition if \p EstimatedLoopInvocationWeight is not null it is
|
||||
/// initialized with weight of loop's latch leading to the exit.
|
||||
/// Returns a valid positive trip count, saturated at UINT_MAX, or std::nullopt
|
||||
/// when a meaningful estimate cannot be made.
|
||||
std::optional<unsigned>
|
||||
LLVM_ABI std::optional<unsigned>
|
||||
getLoopEstimatedTripCount(Loop *L,
|
||||
unsigned *EstimatedLoopInvocationWeight = nullptr);
|
||||
|
||||
@@ -329,20 +337,20 @@ getLoopEstimatedTripCount(Loop *L,
|
||||
/// through latch. Returns true if metadata is successfully updated, false
|
||||
/// otherwise. Note that loop must have a latch block which controls loop exit
|
||||
/// in order to succeed.
|
||||
bool setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount,
|
||||
unsigned EstimatedLoopInvocationWeight);
|
||||
LLVM_ABI bool setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount,
|
||||
unsigned EstimatedLoopInvocationWeight);
|
||||
|
||||
/// Check inner loop (L) backedge count is known to be invariant on all
|
||||
/// iterations of its outer loop. If the loop has no parent, this is trivially
|
||||
/// true.
|
||||
bool hasIterationCountInvariantInParent(Loop *L, ScalarEvolution &SE);
|
||||
LLVM_ABI bool hasIterationCountInvariantInParent(Loop *L, ScalarEvolution &SE);
|
||||
|
||||
/// Helper to consistently add the set of standard passes to a loop pass's \c
|
||||
/// AnalysisUsage.
|
||||
///
|
||||
/// All loop passes should call this as part of implementing their \c
|
||||
/// getAnalysisUsage.
|
||||
void getLoopAnalysisUsage(AnalysisUsage &AU);
|
||||
LLVM_ABI void getLoopAnalysisUsage(AnalysisUsage &AU);
|
||||
|
||||
/// Returns true if is legal to hoist or sink this instruction disregarding the
|
||||
/// possible introduction of faults. Reasoning about potential faulting
|
||||
@@ -353,84 +361,89 @@ void getLoopAnalysisUsage(AnalysisUsage &AU);
|
||||
/// to assess the legality of duplicating atomic loads. Generally, this is
|
||||
/// true when moving out of loop and not true when moving into loops.
|
||||
/// If \p ORE is set use it to emit optimization remarks.
|
||||
bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
|
||||
Loop *CurLoop, MemorySSAUpdater &MSSAU,
|
||||
bool TargetExecutesOncePerLoop,
|
||||
SinkAndHoistLICMFlags &LICMFlags,
|
||||
OptimizationRemarkEmitter *ORE = nullptr);
|
||||
LLVM_ABI bool canSinkOrHoistInst(Instruction &I, AAResults *AA,
|
||||
DominatorTree *DT, Loop *CurLoop,
|
||||
MemorySSAUpdater &MSSAU,
|
||||
bool TargetExecutesOncePerLoop,
|
||||
SinkAndHoistLICMFlags &LICMFlags,
|
||||
OptimizationRemarkEmitter *ORE = nullptr);
|
||||
|
||||
/// Returns the llvm.vector.reduce intrinsic that corresponds to the recurrence
|
||||
/// kind.
|
||||
constexpr Intrinsic::ID getReductionIntrinsicID(RecurKind RK);
|
||||
LLVM_ABI constexpr Intrinsic::ID getReductionIntrinsicID(RecurKind RK);
|
||||
|
||||
/// Returns the arithmetic instruction opcode used when expanding a reduction.
|
||||
unsigned getArithmeticReductionInstruction(Intrinsic::ID RdxID);
|
||||
LLVM_ABI unsigned getArithmeticReductionInstruction(Intrinsic::ID RdxID);
|
||||
/// Returns the reduction intrinsic id corresponding to the binary operation.
|
||||
Intrinsic::ID getReductionForBinop(Instruction::BinaryOps Opc);
|
||||
LLVM_ABI Intrinsic::ID getReductionForBinop(Instruction::BinaryOps Opc);
|
||||
|
||||
/// Returns the min/max intrinsic used when expanding a min/max reduction.
|
||||
Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID);
|
||||
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID);
|
||||
|
||||
/// Returns the min/max intrinsic used when expanding a min/max reduction.
|
||||
Intrinsic::ID getMinMaxReductionIntrinsicOp(RecurKind RK);
|
||||
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(RecurKind RK);
|
||||
|
||||
/// Returns the recurence kind used when expanding a min/max reduction.
|
||||
RecurKind getMinMaxReductionRecurKind(Intrinsic::ID RdxID);
|
||||
LLVM_ABI RecurKind getMinMaxReductionRecurKind(Intrinsic::ID RdxID);
|
||||
|
||||
/// Returns the comparison predicate used when expanding a min/max reduction.
|
||||
CmpInst::Predicate getMinMaxReductionPredicate(RecurKind RK);
|
||||
LLVM_ABI CmpInst::Predicate getMinMaxReductionPredicate(RecurKind RK);
|
||||
|
||||
/// Given information about an @llvm.vector.reduce.* intrinsic, return
|
||||
/// the identity value for the reduction.
|
||||
Value *getReductionIdentity(Intrinsic::ID RdxID, Type *Ty, FastMathFlags FMF);
|
||||
LLVM_ABI Value *getReductionIdentity(Intrinsic::ID RdxID, Type *Ty,
|
||||
FastMathFlags FMF);
|
||||
|
||||
/// Given information about an recurrence kind, return the identity
|
||||
/// for the @llvm.vector.reduce.* used to generate it.
|
||||
Value *getRecurrenceIdentity(RecurKind K, Type *Tp, FastMathFlags FMF);
|
||||
LLVM_ABI Value *getRecurrenceIdentity(RecurKind K, Type *Tp, FastMathFlags FMF);
|
||||
|
||||
/// Returns a Min/Max operation corresponding to MinMaxRecurrenceKind.
|
||||
/// The Builder's fast-math-flags must be set to propagate the expected values.
|
||||
Value *createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
|
||||
Value *Right);
|
||||
LLVM_ABI Value *createMinMaxOp(IRBuilderBase &Builder, RecurKind RK,
|
||||
Value *Left, Value *Right);
|
||||
|
||||
/// Generates an ordered vector reduction using extracts to reduce the value.
|
||||
Value *getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src,
|
||||
unsigned Op, RecurKind MinMaxKind = RecurKind::None);
|
||||
LLVM_ABI Value *getOrderedReduction(IRBuilderBase &Builder, Value *Acc,
|
||||
Value *Src, unsigned Op,
|
||||
RecurKind MinMaxKind = RecurKind::None);
|
||||
|
||||
/// Generates a vector reduction using shufflevectors to reduce the value.
|
||||
/// Fast-math-flags are propagated using the IRBuilder's setting.
|
||||
Value *getShuffleReduction(IRBuilderBase &Builder, Value *Src, unsigned Op,
|
||||
TargetTransformInfo::ReductionShuffle RS,
|
||||
RecurKind MinMaxKind = RecurKind::None);
|
||||
LLVM_ABI Value *getShuffleReduction(IRBuilderBase &Builder, Value *Src,
|
||||
unsigned Op,
|
||||
TargetTransformInfo::ReductionShuffle RS,
|
||||
RecurKind MinMaxKind = RecurKind::None);
|
||||
|
||||
/// Create a reduction of the given vector. The reduction operation
|
||||
/// is described by the \p Opcode parameter. min/max reductions require
|
||||
/// additional information supplied in \p RdxKind.
|
||||
/// Fast-math-flags are propagated using the IRBuilder's setting.
|
||||
Value *createSimpleReduction(IRBuilderBase &B, Value *Src,
|
||||
RecurKind RdxKind);
|
||||
LLVM_ABI Value *createSimpleReduction(IRBuilderBase &B, Value *Src,
|
||||
RecurKind RdxKind);
|
||||
/// Overloaded function to generate vector-predication intrinsics for
|
||||
/// reduction.
|
||||
Value *createSimpleReduction(VectorBuilder &VB, Value *Src, RecurKind RdxKind);
|
||||
LLVM_ABI Value *createSimpleReduction(VectorBuilder &VB, Value *Src,
|
||||
RecurKind RdxKind);
|
||||
|
||||
/// Create a reduction of the given vector \p Src for a reduction of kind
|
||||
/// RecurKind::AnyOf. The start value of the reduction is \p InitVal.
|
||||
Value *createAnyOfReduction(IRBuilderBase &B, Value *Src, Value *InitVal,
|
||||
PHINode *OrigPhi);
|
||||
LLVM_ABI Value *createAnyOfReduction(IRBuilderBase &B, Value *Src,
|
||||
Value *InitVal, PHINode *OrigPhi);
|
||||
|
||||
/// Create a reduction of the given vector \p Src for a reduction of the
|
||||
/// kind RecurKind::FindLastIV.
|
||||
Value *createFindLastIVReduction(IRBuilderBase &B, Value *Src, Value *Start,
|
||||
Value *Sentinel);
|
||||
LLVM_ABI Value *createFindLastIVReduction(IRBuilderBase &B, Value *Src,
|
||||
Value *Start, Value *Sentinel);
|
||||
|
||||
/// Create an ordered reduction intrinsic using the given recurrence
|
||||
/// kind \p RdxKind.
|
||||
Value *createOrderedReduction(IRBuilderBase &B, RecurKind RdxKind, Value *Src,
|
||||
Value *Start);
|
||||
LLVM_ABI Value *createOrderedReduction(IRBuilderBase &B, RecurKind RdxKind,
|
||||
Value *Src, Value *Start);
|
||||
/// Overloaded function to generate vector-predication intrinsics for ordered
|
||||
/// reduction.
|
||||
Value *createOrderedReduction(VectorBuilder &VB, RecurKind RdxKind, Value *Src,
|
||||
Value *Start);
|
||||
LLVM_ABI Value *createOrderedReduction(VectorBuilder &VB, RecurKind RdxKind,
|
||||
Value *Src, Value *Start);
|
||||
|
||||
/// Get the intersection (logical and) of all of the potential IR flags
|
||||
/// of each scalar operation (VL) that will be converted into a vector (I).
|
||||
@@ -438,33 +451,36 @@ Value *createOrderedReduction(VectorBuilder &VB, RecurKind RdxKind, Value *Src,
|
||||
/// when intersecting.
|
||||
/// Flag set: NSW, NUW (if IncludeWrapFlags is true), exact, and all of
|
||||
/// fast-math.
|
||||
void propagateIRFlags(Value *I, ArrayRef<Value *> VL, Value *OpValue = nullptr,
|
||||
bool IncludeWrapFlags = true);
|
||||
LLVM_ABI void propagateIRFlags(Value *I, ArrayRef<Value *> VL,
|
||||
Value *OpValue = nullptr,
|
||||
bool IncludeWrapFlags = true);
|
||||
|
||||
/// Returns true if we can prove that \p S is defined and always negative in
|
||||
/// loop \p L.
|
||||
bool isKnownNegativeInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE);
|
||||
LLVM_ABI bool isKnownNegativeInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE);
|
||||
|
||||
/// Returns true if we can prove that \p S is defined and always non-negative in
|
||||
/// loop \p L.
|
||||
bool isKnownNonNegativeInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE);
|
||||
LLVM_ABI bool isKnownNonNegativeInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE);
|
||||
/// Returns true if we can prove that \p S is defined and always positive in
|
||||
/// loop \p L.
|
||||
bool isKnownPositiveInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE);
|
||||
LLVM_ABI bool isKnownPositiveInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE);
|
||||
|
||||
/// Returns true if we can prove that \p S is defined and always non-positive in
|
||||
/// loop \p L.
|
||||
bool isKnownNonPositiveInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE);
|
||||
LLVM_ABI bool isKnownNonPositiveInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE);
|
||||
|
||||
/// Returns true if \p S is defined and never is equal to signed/unsigned max.
|
||||
bool cannotBeMaxInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,
|
||||
bool Signed);
|
||||
LLVM_ABI bool cannotBeMaxInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE, bool Signed);
|
||||
|
||||
/// Returns true if \p S is defined and never is equal to signed/unsigned min.
|
||||
bool cannotBeMinInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,
|
||||
bool Signed);
|
||||
LLVM_ABI bool cannotBeMinInLoop(const SCEV *S, const Loop *L,
|
||||
ScalarEvolution &SE, bool Signed);
|
||||
|
||||
enum ReplaceExitVal {
|
||||
NeverRepl,
|
||||
@@ -479,11 +495,12 @@ enum ReplaceExitVal {
|
||||
/// outside of the loop that use the final values of the current expressions.
|
||||
/// Return the number of loop exit values that have been replaced, and the
|
||||
/// corresponding phi node will be added to DeadInsts.
|
||||
int rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
|
||||
ScalarEvolution *SE, const TargetTransformInfo *TTI,
|
||||
SCEVExpander &Rewriter, DominatorTree *DT,
|
||||
ReplaceExitVal ReplaceExitValue,
|
||||
SmallVector<WeakTrackingVH, 16> &DeadInsts);
|
||||
LLVM_ABI int rewriteLoopExitValues(Loop *L, LoopInfo *LI,
|
||||
TargetLibraryInfo *TLI, ScalarEvolution *SE,
|
||||
const TargetTransformInfo *TTI,
|
||||
SCEVExpander &Rewriter, DominatorTree *DT,
|
||||
ReplaceExitVal ReplaceExitValue,
|
||||
SmallVector<WeakTrackingVH, 16> &DeadInsts);
|
||||
|
||||
/// Set weights for \p UnrolledLoop and \p RemainderLoop based on weights for
|
||||
/// \p OrigLoop and the following distribution of \p OrigLoop iteration among \p
|
||||
@@ -499,8 +516,8 @@ int rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
|
||||
///
|
||||
/// This utility may be useful for such optimizations as unroller and
|
||||
/// vectorizer as it's typical transformation for them.
|
||||
void setProfileInfoAfterUnrolling(Loop *OrigLoop, Loop *UnrolledLoop,
|
||||
Loop *RemainderLoop, uint64_t UF);
|
||||
LLVM_ABI void setProfileInfoAfterUnrolling(Loop *OrigLoop, Loop *UnrolledLoop,
|
||||
Loop *RemainderLoop, uint64_t UF);
|
||||
|
||||
/// Utility that implements appending of loops onto a worklist given a range.
|
||||
/// We want to process loops in postorder, but the worklist is a LIFO data
|
||||
@@ -508,7 +525,8 @@ void setProfileInfoAfterUnrolling(Loop *OrigLoop, Loop *UnrolledLoop,
|
||||
/// For trees, a preorder traversal is a viable reverse postorder, so we
|
||||
/// actually append using a preorder walk algorithm.
|
||||
template <typename RangeT>
|
||||
void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist<Loop *, 4> &);
|
||||
LLVM_TEMPLATE_ABI void
|
||||
appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist<Loop *, 4> &);
|
||||
/// Utility that implements appending of loops onto a worklist given a range.
|
||||
/// It has the same behavior as appendLoopsToWorklist, but assumes the range of
|
||||
/// loops has already been reversed, so it processes loops in the given order.
|
||||
@@ -516,6 +534,14 @@ template <typename RangeT>
|
||||
void appendReversedLoopsToWorklist(RangeT &&,
|
||||
SmallPriorityWorklist<Loop *, 4> &);
|
||||
|
||||
extern template LLVM_TEMPLATE_ABI void
|
||||
llvm::appendLoopsToWorklist<ArrayRef<Loop *> &>(
|
||||
ArrayRef<Loop *> &Loops, SmallPriorityWorklist<Loop *, 4> &Worklist);
|
||||
|
||||
extern template LLVM_TEMPLATE_ABI void
|
||||
llvm::appendLoopsToWorklist<Loop &>(Loop &L,
|
||||
SmallPriorityWorklist<Loop *, 4> &Worklist);
|
||||
|
||||
/// Utility that implements appending of loops onto a worklist given LoopInfo.
|
||||
/// Calls the templated utility taking a Range of loops, handing it the Loops
|
||||
/// in LoopInfo, iterated in reverse. This is because the loops are stored in
|
||||
@@ -525,21 +551,22 @@ void appendReversedLoopsToWorklist(RangeT &&,
|
||||
/// loop nest into the next. Calls appendReversedLoopsToWorklist with the
|
||||
/// already reversed loops in LI.
|
||||
/// FIXME: Consider changing the order in LoopInfo.
|
||||
void appendLoopsToWorklist(LoopInfo &, SmallPriorityWorklist<Loop *, 4> &);
|
||||
LLVM_ABI void appendLoopsToWorklist(LoopInfo &,
|
||||
SmallPriorityWorklist<Loop *, 4> &);
|
||||
|
||||
/// Recursively clone the specified loop and all of its children,
|
||||
/// mapping the blocks with the specified map.
|
||||
Loop *cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
|
||||
LoopInfo *LI, LPPassManager *LPM);
|
||||
LLVM_ABI Loop *cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, LoopInfo *LI,
|
||||
LPPassManager *LPM);
|
||||
|
||||
/// Add code that checks at runtime if the accessed arrays in \p PointerChecks
|
||||
/// overlap. Returns the final comparator value or NULL if no check is needed.
|
||||
Value *
|
||||
LLVM_ABI Value *
|
||||
addRuntimeChecks(Instruction *Loc, Loop *TheLoop,
|
||||
const SmallVectorImpl<RuntimePointerCheck> &PointerChecks,
|
||||
SCEVExpander &Expander, bool HoistRuntimeChecks = false);
|
||||
|
||||
Value *addDiffRuntimeChecks(
|
||||
LLVM_ABI Value *addDiffRuntimeChecks(
|
||||
Instruction *Loc, ArrayRef<PointerDiffInfo> Checks, SCEVExpander &Expander,
|
||||
function_ref<Value *(IRBuilderBase &, unsigned)> GetVF, unsigned IC);
|
||||
|
||||
@@ -572,10 +599,9 @@ struct IVConditionInfo {
|
||||
/// If the branch condition of the header is partially invariant, return a pair
|
||||
/// containing the instructions to duplicate and a boolean Constant to update
|
||||
/// the condition in the loops created for the true or false successors.
|
||||
std::optional<IVConditionInfo> hasPartialIVCondition(const Loop &L,
|
||||
unsigned MSSAThreshold,
|
||||
const MemorySSA &MSSA,
|
||||
AAResults &AA);
|
||||
LLVM_ABI std::optional<IVConditionInfo>
|
||||
hasPartialIVCondition(const Loop &L, unsigned MSSAThreshold,
|
||||
const MemorySSA &MSSA, AAResults &AA);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef LLVM_TRANSFORMS_UTILS_LOWERMEMINTRINSICS_H
|
||||
#define LLVM_TRANSFORMS_UTILS_LOWERMEMINTRINSICS_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
@@ -33,7 +34,7 @@ struct Align;
|
||||
|
||||
/// Emit a loop implementing the semantics of llvm.memcpy where the size is not
|
||||
/// a compile-time constant. Loop will be insterted at \p InsertBefore.
|
||||
void createMemCpyLoopUnknownSize(
|
||||
LLVM_ABI void createMemCpyLoopUnknownSize(
|
||||
Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr, Value *CopyLen,
|
||||
Align SrcAlign, Align DestAlign, bool SrcIsVolatile, bool DstIsVolatile,
|
||||
bool CanOverlap, const TargetTransformInfo &TTI,
|
||||
@@ -41,30 +42,32 @@ void createMemCpyLoopUnknownSize(
|
||||
|
||||
/// Emit a loop implementing the semantics of an llvm.memcpy whose size is a
|
||||
/// compile time constant. Loop is inserted at \p InsertBefore.
|
||||
void createMemCpyLoopKnownSize(
|
||||
LLVM_ABI void createMemCpyLoopKnownSize(
|
||||
Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr,
|
||||
ConstantInt *CopyLen, Align SrcAlign, Align DestAlign, bool SrcIsVolatile,
|
||||
bool DstIsVolatile, bool CanOverlap, const TargetTransformInfo &TTI,
|
||||
std::optional<uint32_t> AtomicCpySize = std::nullopt);
|
||||
|
||||
/// Expand \p MemCpy as a loop. \p MemCpy is not deleted.
|
||||
void expandMemCpyAsLoop(MemCpyInst *MemCpy, const TargetTransformInfo &TTI,
|
||||
ScalarEvolution *SE = nullptr);
|
||||
LLVM_ABI void expandMemCpyAsLoop(MemCpyInst *MemCpy,
|
||||
const TargetTransformInfo &TTI,
|
||||
ScalarEvolution *SE = nullptr);
|
||||
|
||||
/// Expand \p MemMove as a loop. \p MemMove is not deleted. Returns true if the
|
||||
/// memmove was lowered.
|
||||
bool expandMemMoveAsLoop(MemMoveInst *MemMove, const TargetTransformInfo &TTI);
|
||||
LLVM_ABI bool expandMemMoveAsLoop(MemMoveInst *MemMove,
|
||||
const TargetTransformInfo &TTI);
|
||||
|
||||
/// Expand \p MemSet as a loop. \p MemSet is not deleted.
|
||||
void expandMemSetAsLoop(MemSetInst *MemSet);
|
||||
LLVM_ABI void expandMemSetAsLoop(MemSetInst *MemSet);
|
||||
|
||||
/// Expand \p MemSetPattern as a loop. \p MemSet is not deleted.
|
||||
void expandMemSetPatternAsLoop(MemSetPatternInst *MemSet);
|
||||
LLVM_ABI void expandMemSetPatternAsLoop(MemSetPatternInst *MemSet);
|
||||
|
||||
/// Expand \p AtomicMemCpy as a loop. \p AtomicMemCpy is not deleted.
|
||||
void expandAtomicMemCpyAsLoop(AnyMemCpyInst *AtomicMemCpy,
|
||||
const TargetTransformInfo &TTI,
|
||||
ScalarEvolution *SE);
|
||||
LLVM_ABI void expandAtomicMemCpyAsLoop(AnyMemCpyInst *AtomicMemCpy,
|
||||
const TargetTransformInfo &TTI,
|
||||
ScalarEvolution *SE);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/GlobalIFunc.h"
|
||||
#include "llvm/Support/Alignment.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/MemoryBufferRef.h"
|
||||
#include <utility> // for std::pair
|
||||
|
||||
@@ -38,41 +39,44 @@ class Type;
|
||||
/// This wraps the function in the appropriate structure and stores it along
|
||||
/// side other global constructors. For details see
|
||||
/// https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable
|
||||
void appendToGlobalCtors(Module &M, Function *F, int Priority,
|
||||
Constant *Data = nullptr);
|
||||
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority,
|
||||
Constant *Data = nullptr);
|
||||
|
||||
/// Same as appendToGlobalCtors(), but for global dtors.
|
||||
void appendToGlobalDtors(Module &M, Function *F, int Priority,
|
||||
Constant *Data = nullptr);
|
||||
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority,
|
||||
Constant *Data = nullptr);
|
||||
|
||||
/// Apply 'Fn' to the list of global ctors of module M and replace contructor
|
||||
/// record with the one returned by `Fn`. If `nullptr` was returned, the
|
||||
/// corresponding constructor will be removed from the array. For details see
|
||||
/// https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable
|
||||
using GlobalCtorTransformFn = llvm::function_ref<Constant *(Constant *)>;
|
||||
void transformGlobalCtors(Module &M, const GlobalCtorTransformFn &Fn);
|
||||
void transformGlobalDtors(Module &M, const GlobalCtorTransformFn &Fn);
|
||||
LLVM_ABI void transformGlobalCtors(Module &M, const GlobalCtorTransformFn &Fn);
|
||||
LLVM_ABI void transformGlobalDtors(Module &M, const GlobalCtorTransformFn &Fn);
|
||||
|
||||
/// Sets the KCFI type for the function. Used for compiler-generated functions
|
||||
/// that are indirectly called in instrumented code.
|
||||
void setKCFIType(Module &M, Function &F, StringRef MangledType);
|
||||
LLVM_ABI void setKCFIType(Module &M, Function &F, StringRef MangledType);
|
||||
|
||||
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes,
|
||||
bool Weak = false);
|
||||
LLVM_ABI FunctionCallee
|
||||
declareSanitizerInitFunction(Module &M, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, bool Weak = false);
|
||||
|
||||
/// Creates sanitizer constructor function.
|
||||
/// \return Returns pointer to constructor.
|
||||
Function *createSanitizerCtor(Module &M, StringRef CtorName);
|
||||
LLVM_ABI Function *createSanitizerCtor(Module &M, StringRef CtorName);
|
||||
|
||||
/// Creates sanitizer constructor function, and calls sanitizer's init
|
||||
/// function from it.
|
||||
/// \return Returns pair of pointers to constructor, and init functions
|
||||
/// respectively.
|
||||
std::pair<Function *, FunctionCallee> createSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
StringRef VersionCheckName = StringRef(), bool Weak = false);
|
||||
LLVM_ABI std::pair<Function *, FunctionCallee>
|
||||
createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName,
|
||||
StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes,
|
||||
ArrayRef<Value *> InitArgs,
|
||||
StringRef VersionCheckName = StringRef(),
|
||||
bool Weak = false);
|
||||
|
||||
/// Creates sanitizer constructor function lazily. If a constructor and init
|
||||
/// function already exist, this function returns it. Otherwise it calls \c
|
||||
@@ -81,7 +85,8 @@ std::pair<Function *, FunctionCallee> createSanitizerCtorAndInitFunctions(
|
||||
///
|
||||
/// \return Returns pair of pointers to constructor, and init functions
|
||||
/// respectively.
|
||||
std::pair<Function *, FunctionCallee> getOrCreateSanitizerCtorAndInitFunctions(
|
||||
LLVM_ABI std::pair<Function *, FunctionCallee>
|
||||
getOrCreateSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback,
|
||||
@@ -89,19 +94,19 @@ std::pair<Function *, FunctionCallee> getOrCreateSanitizerCtorAndInitFunctions(
|
||||
|
||||
/// Rename all the anon globals in the module using a hash computed from
|
||||
/// the list of public globals in the module.
|
||||
bool nameUnamedGlobals(Module &M);
|
||||
LLVM_ABI bool nameUnamedGlobals(Module &M);
|
||||
|
||||
/// Adds global values to the llvm.used list.
|
||||
void appendToUsed(Module &M, ArrayRef<GlobalValue *> Values);
|
||||
LLVM_ABI void appendToUsed(Module &M, ArrayRef<GlobalValue *> Values);
|
||||
|
||||
/// Adds global values to the llvm.compiler.used list.
|
||||
void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values);
|
||||
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values);
|
||||
|
||||
/// Removes global values from the llvm.used and llvm.compiler.used arrays. \p
|
||||
/// ShouldRemove should return true for any initializer field that should not be
|
||||
/// included in the replacement global.
|
||||
void removeFromUsedLists(Module &M,
|
||||
function_ref<bool(Constant *)> ShouldRemove);
|
||||
LLVM_ABI void removeFromUsedLists(Module &M,
|
||||
function_ref<bool(Constant *)> ShouldRemove);
|
||||
|
||||
/// Filter out potentially dead comdat functions where other entries keep the
|
||||
/// entire comdat group alive.
|
||||
@@ -116,8 +121,8 @@ void removeFromUsedLists(Module &M,
|
||||
/// After this routine finishes, the only remaining `Function`s in \p
|
||||
/// DeadComdatFunctions are those where every member of the comdat is listed
|
||||
/// and thus removing them is safe (provided *all* are removed).
|
||||
void filterDeadComdatFunctions(
|
||||
SmallVectorImpl<Function *> &DeadComdatFunctions);
|
||||
LLVM_ABI void
|
||||
filterDeadComdatFunctions(SmallVectorImpl<Function *> &DeadComdatFunctions);
|
||||
|
||||
/// Produce a unique identifier for this module by taking the MD5 sum of
|
||||
/// the names of the module's strong external symbols that are not comdat
|
||||
@@ -129,13 +134,14 @@ void filterDeadComdatFunctions(
|
||||
/// If the module has no strong external symbols (such a module may still have a
|
||||
/// semantic effect if it performs global initialization), we cannot produce a
|
||||
/// unique identifier for this module, so we return the empty string.
|
||||
std::string getUniqueModuleId(Module *M);
|
||||
LLVM_ABI std::string getUniqueModuleId(Module *M);
|
||||
|
||||
/// Embed the memory buffer \p Buf into the module \p M as a global using the
|
||||
/// specified section name. Also provide a metadata entry to identify it in the
|
||||
/// module using the same section name.
|
||||
void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName,
|
||||
Align Alignment = Align(1));
|
||||
LLVM_ABI void embedBufferInModule(Module &M, MemoryBufferRef Buf,
|
||||
StringRef SectionName,
|
||||
Align Alignment = Align(1));
|
||||
|
||||
/// Lower all calls to ifuncs by replacing uses with indirect calls loaded out
|
||||
/// of a global table initialized in a global constructor. This will introduce
|
||||
@@ -149,8 +155,9 @@ void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName,
|
||||
///
|
||||
/// The processed ifuncs without remaining users will be removed from the
|
||||
/// module.
|
||||
bool lowerGlobalIFuncUsersAsGlobalCtor(
|
||||
Module &M, ArrayRef<GlobalIFunc *> IFuncsToLower = {});
|
||||
LLVM_ABI bool
|
||||
lowerGlobalIFuncUsersAsGlobalCtor(Module &M,
|
||||
ArrayRef<GlobalIFunc *> IFuncsToLower = {});
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -102,7 +103,7 @@ public:
|
||||
}
|
||||
|
||||
/// Fetch condition in the form of PredicateConstraint, if possible.
|
||||
std::optional<PredicateConstraint> getConstraint() const;
|
||||
LLVM_ABI std::optional<PredicateConstraint> getConstraint() const;
|
||||
|
||||
protected:
|
||||
PredicateBase(PredicateType PT, Value *Op, Value *Condition)
|
||||
@@ -176,13 +177,13 @@ public:
|
||||
/// accesses.
|
||||
class PredicateInfo {
|
||||
public:
|
||||
PredicateInfo(Function &, DominatorTree &, AssumptionCache &);
|
||||
~PredicateInfo();
|
||||
LLVM_ABI PredicateInfo(Function &, DominatorTree &, AssumptionCache &);
|
||||
LLVM_ABI ~PredicateInfo();
|
||||
|
||||
void verifyPredicateInfo() const;
|
||||
LLVM_ABI void verifyPredicateInfo() const;
|
||||
|
||||
void dump() const;
|
||||
void print(raw_ostream &) const;
|
||||
LLVM_ABI void dump() const;
|
||||
LLVM_ABI void print(raw_ostream &) const;
|
||||
|
||||
const PredicateBase *getPredicateInfoFor(const Value *V) const {
|
||||
return PredicateMap.lookup(V);
|
||||
@@ -214,13 +215,13 @@ class PredicateInfoPrinterPass
|
||||
|
||||
public:
|
||||
explicit PredicateInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
/// Verifier pass for \c PredicateInfo.
|
||||
struct PredicateInfoVerifierPass : PassInfoMixin<PredicateInfoVerifierPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
static bool isRequired() { return true; }
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class AssumptionCache;
|
||||
/// (transitively) using this alloca. This also enforces that there is only
|
||||
/// ever one layer of bitcasts or GEPs between the alloca and the lifetime
|
||||
/// markers.
|
||||
bool isAllocaPromotable(const AllocaInst *AI);
|
||||
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI);
|
||||
|
||||
/// Promote the specified list of alloca instructions into scalar
|
||||
/// registers, inserting PHI nodes as appropriate.
|
||||
@@ -36,8 +36,8 @@ bool isAllocaPromotable(const AllocaInst *AI);
|
||||
/// does not modify the CFG of the function at all. All allocas must be from
|
||||
/// the same function.
|
||||
///
|
||||
void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
|
||||
AssumptionCache *AC = nullptr);
|
||||
LLVM_ABI void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
|
||||
AssumptionCache *AC = nullptr);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/DomTreeUpdater.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/PredicateInfo.h"
|
||||
#include <vector>
|
||||
|
||||
@@ -66,149 +67,155 @@ class SCCPSolver {
|
||||
std::unique_ptr<SCCPInstVisitor> Visitor;
|
||||
|
||||
public:
|
||||
LLVM_ABI
|
||||
SCCPSolver(const DataLayout &DL,
|
||||
std::function<const TargetLibraryInfo &(Function &)> GetTLI,
|
||||
LLVMContext &Ctx);
|
||||
|
||||
~SCCPSolver();
|
||||
LLVM_ABI ~SCCPSolver();
|
||||
|
||||
void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC);
|
||||
LLVM_ABI void addPredicateInfo(Function &F, DominatorTree &DT,
|
||||
AssumptionCache &AC);
|
||||
|
||||
/// markBlockExecutable - This method can be used by clients to mark all of
|
||||
/// the blocks that are known to be intrinsically live in the processed unit.
|
||||
/// This returns true if the block was not considered live before.
|
||||
bool markBlockExecutable(BasicBlock *BB);
|
||||
LLVM_ABI bool markBlockExecutable(BasicBlock *BB);
|
||||
|
||||
const PredicateBase *getPredicateInfoFor(Instruction *I);
|
||||
LLVM_ABI const PredicateBase *getPredicateInfoFor(Instruction *I);
|
||||
|
||||
/// trackValueOfGlobalVariable - Clients can use this method to
|
||||
/// inform the SCCPSolver that it should track loads and stores to the
|
||||
/// specified global variable if it can. This is only legal to call if
|
||||
/// performing Interprocedural SCCP.
|
||||
void trackValueOfGlobalVariable(GlobalVariable *GV);
|
||||
LLVM_ABI void trackValueOfGlobalVariable(GlobalVariable *GV);
|
||||
|
||||
/// addTrackedFunction - If the SCCP solver is supposed to track calls into
|
||||
/// and out of the specified function (which cannot have its address taken),
|
||||
/// this method must be called.
|
||||
void addTrackedFunction(Function *F);
|
||||
LLVM_ABI void addTrackedFunction(Function *F);
|
||||
|
||||
/// Add function to the list of functions whose return cannot be modified.
|
||||
void addToMustPreserveReturnsInFunctions(Function *F);
|
||||
LLVM_ABI void addToMustPreserveReturnsInFunctions(Function *F);
|
||||
|
||||
/// Returns true if the return of the given function cannot be modified.
|
||||
bool mustPreserveReturn(Function *F);
|
||||
LLVM_ABI bool mustPreserveReturn(Function *F);
|
||||
|
||||
void addArgumentTrackedFunction(Function *F);
|
||||
LLVM_ABI void addArgumentTrackedFunction(Function *F);
|
||||
|
||||
/// Returns true if the given function is in the solver's set of
|
||||
/// argument-tracked functions.
|
||||
bool isArgumentTrackedFunction(Function *F);
|
||||
LLVM_ABI bool isArgumentTrackedFunction(Function *F);
|
||||
|
||||
const SmallPtrSetImpl<Function *> &getArgumentTrackedFunctions() const;
|
||||
LLVM_ABI const SmallPtrSetImpl<Function *> &
|
||||
getArgumentTrackedFunctions() const;
|
||||
|
||||
/// Solve - Solve for constants and executable blocks.
|
||||
void solve();
|
||||
LLVM_ABI void solve();
|
||||
|
||||
/// resolvedUndefsIn - While solving the dataflow for a function, we assume
|
||||
/// that branches on undef values cannot reach any of their successors.
|
||||
/// However, this is not a safe assumption. After we solve dataflow, this
|
||||
/// method should be use to handle this. If this returns true, the solver
|
||||
/// should be rerun.
|
||||
bool resolvedUndefsIn(Function &F);
|
||||
LLVM_ABI bool resolvedUndefsIn(Function &F);
|
||||
|
||||
void solveWhileResolvedUndefsIn(Module &M);
|
||||
LLVM_ABI void solveWhileResolvedUndefsIn(Module &M);
|
||||
|
||||
void solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList);
|
||||
LLVM_ABI void
|
||||
solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList);
|
||||
|
||||
void solveWhileResolvedUndefs();
|
||||
LLVM_ABI void solveWhileResolvedUndefs();
|
||||
|
||||
bool isBlockExecutable(BasicBlock *BB) const;
|
||||
LLVM_ABI bool isBlockExecutable(BasicBlock *BB) const;
|
||||
|
||||
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
|
||||
// block to the 'To' basic block is currently feasible.
|
||||
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
|
||||
LLVM_ABI bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
|
||||
|
||||
std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const;
|
||||
LLVM_ABI std::vector<ValueLatticeElement>
|
||||
getStructLatticeValueFor(Value *V) const;
|
||||
|
||||
void removeLatticeValueFor(Value *V);
|
||||
LLVM_ABI void removeLatticeValueFor(Value *V);
|
||||
|
||||
/// Invalidate the Lattice Value of \p Call and its users after specializing
|
||||
/// the call. Then recompute it.
|
||||
void resetLatticeValueFor(CallBase *Call);
|
||||
LLVM_ABI void resetLatticeValueFor(CallBase *Call);
|
||||
|
||||
const ValueLatticeElement &getLatticeValueFor(Value *V) const;
|
||||
LLVM_ABI const ValueLatticeElement &getLatticeValueFor(Value *V) const;
|
||||
|
||||
/// getTrackedRetVals - Get the inferred return value map.
|
||||
const MapVector<Function *, ValueLatticeElement> &getTrackedRetVals() const;
|
||||
LLVM_ABI const MapVector<Function *, ValueLatticeElement> &
|
||||
getTrackedRetVals() const;
|
||||
|
||||
/// getTrackedGlobals - Get and return the set of inferred initializers for
|
||||
/// global variables.
|
||||
const DenseMap<GlobalVariable *, ValueLatticeElement> &
|
||||
LLVM_ABI const DenseMap<GlobalVariable *, ValueLatticeElement> &
|
||||
getTrackedGlobals() const;
|
||||
|
||||
/// getMRVFunctionsTracked - Get the set of functions which return multiple
|
||||
/// values tracked by the pass.
|
||||
const SmallPtrSet<Function *, 16> &getMRVFunctionsTracked() const;
|
||||
LLVM_ABI const SmallPtrSet<Function *, 16> &getMRVFunctionsTracked() const;
|
||||
|
||||
/// markOverdefined - Mark the specified value overdefined. This
|
||||
/// works with both scalars and structs.
|
||||
void markOverdefined(Value *V);
|
||||
LLVM_ABI void markOverdefined(Value *V);
|
||||
|
||||
/// trackValueOfArgument - Mark the specified argument overdefined unless it
|
||||
/// have range attribute. This works with both scalars and structs.
|
||||
void trackValueOfArgument(Argument *V);
|
||||
LLVM_ABI void trackValueOfArgument(Argument *V);
|
||||
|
||||
// isStructLatticeConstant - Return true if all the lattice values
|
||||
// corresponding to elements of the structure are constants,
|
||||
// false otherwise.
|
||||
bool isStructLatticeConstant(Function *F, StructType *STy);
|
||||
LLVM_ABI bool isStructLatticeConstant(Function *F, StructType *STy);
|
||||
|
||||
/// Helper to return a Constant if \p LV is either a constant or a constant
|
||||
/// range with a single element.
|
||||
Constant *getConstant(const ValueLatticeElement &LV, Type *Ty) const;
|
||||
LLVM_ABI Constant *getConstant(const ValueLatticeElement &LV, Type *Ty) const;
|
||||
|
||||
/// Return either a Constant or nullptr for a given Value.
|
||||
Constant *getConstantOrNull(Value *V) const;
|
||||
LLVM_ABI Constant *getConstantOrNull(Value *V) const;
|
||||
|
||||
/// Set the Lattice Value for the arguments of a specialization \p F.
|
||||
/// If an argument is Constant then its lattice value is marked with the
|
||||
/// corresponding actual argument in \p Args. Otherwise, its lattice value
|
||||
/// is inherited (copied) from the corresponding formal argument in \p Args.
|
||||
void setLatticeValueForSpecializationArguments(Function *F,
|
||||
const SmallVectorImpl<ArgInfo> &Args);
|
||||
LLVM_ABI void setLatticeValueForSpecializationArguments(
|
||||
Function *F, const SmallVectorImpl<ArgInfo> &Args);
|
||||
|
||||
/// Mark all of the blocks in function \p F non-executable. Clients can used
|
||||
/// this method to erase a function from the module (e.g., if it has been
|
||||
/// completely specialized and is no longer needed).
|
||||
void markFunctionUnreachable(Function *F);
|
||||
LLVM_ABI void markFunctionUnreachable(Function *F);
|
||||
|
||||
void visit(Instruction *I);
|
||||
void visitCall(CallInst &I);
|
||||
LLVM_ABI void visit(Instruction *I);
|
||||
LLVM_ABI void visitCall(CallInst &I);
|
||||
|
||||
bool simplifyInstsInBlock(BasicBlock &BB,
|
||||
SmallPtrSetImpl<Value *> &InsertedValues,
|
||||
Statistic &InstRemovedStat,
|
||||
Statistic &InstReplacedStat);
|
||||
LLVM_ABI bool simplifyInstsInBlock(BasicBlock &BB,
|
||||
SmallPtrSetImpl<Value *> &InsertedValues,
|
||||
Statistic &InstRemovedStat,
|
||||
Statistic &InstReplacedStat);
|
||||
|
||||
bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU,
|
||||
BasicBlock *&NewUnreachableBB) const;
|
||||
LLVM_ABI bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU,
|
||||
BasicBlock *&NewUnreachableBB) const;
|
||||
|
||||
void inferReturnAttributes() const;
|
||||
void inferArgAttributes() const;
|
||||
LLVM_ABI void inferReturnAttributes() const;
|
||||
LLVM_ABI void inferArgAttributes() const;
|
||||
|
||||
bool tryToReplaceWithConstant(Value *V);
|
||||
LLVM_ABI bool tryToReplaceWithConstant(Value *V);
|
||||
|
||||
// Helper to check if \p LV is either a constant or a constant
|
||||
// range with a single element. This should cover exactly the same cases as
|
||||
// the old ValueLatticeElement::isConstant() and is intended to be used in the
|
||||
// transition to ValueLatticeElement.
|
||||
static bool isConstant(const ValueLatticeElement &LV);
|
||||
LLVM_ABI static bool isConstant(const ValueLatticeElement &LV);
|
||||
|
||||
// Helper to check if \p LV is either overdefined or a constant range with
|
||||
// more than a single element. This should cover exactly the same cases as the
|
||||
// old ValueLatticeElement::isOverdefined() and is intended to be used in the
|
||||
// transition to ValueLatticeElement.
|
||||
static bool isOverdefined(const ValueLatticeElement &LV);
|
||||
LLVM_ABI static bool isOverdefined(const ValueLatticeElement &LV);
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/PredIteratorCache.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -58,15 +59,15 @@ public:
|
||||
/// Add a new variable to the SSA rewriter. This needs to be called before
|
||||
/// AddAvailableValue or AddUse calls. The return value is the variable ID,
|
||||
/// which needs to be passed to AddAvailableValue and AddUse.
|
||||
unsigned AddVariable(StringRef Name, Type *Ty);
|
||||
LLVM_ABI unsigned AddVariable(StringRef Name, Type *Ty);
|
||||
|
||||
/// Indicate that a rewritten value is available in the specified block with
|
||||
/// the specified value.
|
||||
void AddAvailableValue(unsigned Var, BasicBlock *BB, Value *V);
|
||||
LLVM_ABI void AddAvailableValue(unsigned Var, BasicBlock *BB, Value *V);
|
||||
|
||||
/// Record a use of the symbolic value. This use will be updated with a
|
||||
/// rewritten value when RewriteAllUses is called.
|
||||
void AddUse(unsigned Var, Use *U);
|
||||
LLVM_ABI void AddUse(unsigned Var, Use *U);
|
||||
|
||||
/// Perform all the necessary updates, including new PHI-nodes insertion and
|
||||
/// the requested uses update.
|
||||
@@ -75,8 +76,9 @@ public:
|
||||
/// locations for new phi-nodes insertions. If a nonnull pointer to a vector
|
||||
/// InsertedPHIs is passed, all the new phi-nodes will be added to this
|
||||
/// vector.
|
||||
void RewriteAllUses(DominatorTree *DT,
|
||||
SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
|
||||
LLVM_ABI void
|
||||
RewriteAllUses(DominatorTree *DT,
|
||||
SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_SANITIZERSTATS_H
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -30,14 +31,14 @@ enum SanitizerStatKind {
|
||||
};
|
||||
|
||||
struct SanitizerStatReport {
|
||||
SanitizerStatReport(Module *M);
|
||||
LLVM_ABI SanitizerStatReport(Module *M);
|
||||
|
||||
/// Generates code into B that increments a location-specific counter tagged
|
||||
/// with the given sanitizer kind SK.
|
||||
void create(IRBuilder<> &B, SanitizerStatKind SK);
|
||||
LLVM_ABI void create(IRBuilder<> &B, SanitizerStatKind SK);
|
||||
|
||||
/// Finalize module stats array and add global constructor to register it.
|
||||
void finish();
|
||||
LLVM_ABI void finish();
|
||||
|
||||
private:
|
||||
Module *M;
|
||||
|
||||
@@ -23,10 +23,11 @@
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/InstructionCost.h"
|
||||
|
||||
namespace llvm {
|
||||
extern cl::opt<unsigned> SCEVCheapExpansionBudget;
|
||||
LLVM_ABI extern cl::opt<unsigned> SCEVCheapExpansionBudget;
|
||||
|
||||
/// struct for holding enough information to help calculate the cost of the
|
||||
/// given SCEV when expanded into IR.
|
||||
@@ -50,8 +51,8 @@ struct PoisonFlags {
|
||||
unsigned SameSign : 1;
|
||||
GEPNoWrapFlags GEPNW;
|
||||
|
||||
PoisonFlags(const Instruction *I);
|
||||
void apply(Instruction *I);
|
||||
LLVM_ABI PoisonFlags(const Instruction *I);
|
||||
LLVM_ABI void apply(Instruction *I);
|
||||
};
|
||||
|
||||
/// This class uses information about analyze scalars to rewrite expressions
|
||||
@@ -271,8 +272,8 @@ public:
|
||||
}
|
||||
|
||||
/// Return the induction variable increment's IV operand.
|
||||
Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
|
||||
bool allowScale);
|
||||
LLVM_ABI Instruction *
|
||||
getIVIncOperand(Instruction *IncV, Instruction *InsertPos, bool allowScale);
|
||||
|
||||
/// Utility for hoisting \p IncV (with all subexpressions requried for its
|
||||
/// computation) before \p InsertPos. If \p RecomputePoisonFlags is set, drops
|
||||
@@ -280,36 +281,40 @@ public:
|
||||
/// re-infer them in the new location. It should be used when we are going to
|
||||
/// introduce a new use in the new position that didn't exist before, and may
|
||||
/// trigger new UB in case of poison.
|
||||
bool hoistIVInc(Instruction *IncV, Instruction *InsertPos,
|
||||
bool RecomputePoisonFlags = false);
|
||||
LLVM_ABI bool hoistIVInc(Instruction *IncV, Instruction *InsertPos,
|
||||
bool RecomputePoisonFlags = false);
|
||||
|
||||
/// Return true if both increments directly increment the corresponding IV PHI
|
||||
/// nodes and have the same opcode. It is not safe to re-use the flags from
|
||||
/// the original increment, if it is more complex and SCEV expansion may have
|
||||
/// yielded a more simplified wider increment.
|
||||
static bool canReuseFlagsFromOriginalIVInc(PHINode *OrigPhi, PHINode *WidePhi,
|
||||
Instruction *OrigInc,
|
||||
Instruction *WideInc);
|
||||
LLVM_ABI static bool canReuseFlagsFromOriginalIVInc(PHINode *OrigPhi,
|
||||
PHINode *WidePhi,
|
||||
Instruction *OrigInc,
|
||||
Instruction *WideInc);
|
||||
|
||||
/// replace congruent phis with their most canonical representative. Return
|
||||
/// the number of phis eliminated.
|
||||
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
||||
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
|
||||
const TargetTransformInfo *TTI = nullptr);
|
||||
LLVM_ABI unsigned
|
||||
replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
||||
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
|
||||
const TargetTransformInfo *TTI = nullptr);
|
||||
|
||||
/// Return true if the given expression is safe to expand in the sense that
|
||||
/// all materialized values are safe to speculate anywhere their operands are
|
||||
/// defined, and the expander is capable of expanding the expression.
|
||||
bool isSafeToExpand(const SCEV *S) const;
|
||||
LLVM_ABI bool isSafeToExpand(const SCEV *S) const;
|
||||
|
||||
/// Return true if the given expression is safe to expand in the sense that
|
||||
/// all materialized values are defined and safe to speculate at the specified
|
||||
/// location and their operands are defined at this location.
|
||||
bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint) const;
|
||||
LLVM_ABI bool isSafeToExpandAt(const SCEV *S,
|
||||
const Instruction *InsertionPoint) const;
|
||||
|
||||
/// Insert code to directly compute the specified SCEV expression into the
|
||||
/// program. The code is inserted into the specified block.
|
||||
Value *expandCodeFor(const SCEV *SH, Type *Ty, BasicBlock::iterator I);
|
||||
LLVM_ABI Value *expandCodeFor(const SCEV *SH, Type *Ty,
|
||||
BasicBlock::iterator I);
|
||||
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I) {
|
||||
return expandCodeFor(SH, Ty, I->getIterator());
|
||||
}
|
||||
@@ -318,29 +323,32 @@ public:
|
||||
/// program. The code is inserted into the SCEVExpander's current
|
||||
/// insertion point. If a type is specified, the result will be expanded to
|
||||
/// have that type, with a cast if necessary.
|
||||
Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr);
|
||||
LLVM_ABI Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr);
|
||||
|
||||
/// Generates a code sequence that evaluates this predicate. The inserted
|
||||
/// instructions will be at position \p Loc. The result will be of type i1
|
||||
/// and will have a value of 0 when the predicate is false and 1 otherwise.
|
||||
Value *expandCodeForPredicate(const SCEVPredicate *Pred, Instruction *Loc);
|
||||
LLVM_ABI Value *expandCodeForPredicate(const SCEVPredicate *Pred,
|
||||
Instruction *Loc);
|
||||
|
||||
/// A specialized variant of expandCodeForPredicate, handling the case when
|
||||
/// we are expanding code for a SCEVComparePredicate.
|
||||
Value *expandComparePredicate(const SCEVComparePredicate *Pred,
|
||||
Instruction *Loc);
|
||||
LLVM_ABI Value *expandComparePredicate(const SCEVComparePredicate *Pred,
|
||||
Instruction *Loc);
|
||||
|
||||
/// Generates code that evaluates if the \p AR expression will overflow.
|
||||
Value *generateOverflowCheck(const SCEVAddRecExpr *AR, Instruction *Loc,
|
||||
bool Signed);
|
||||
LLVM_ABI Value *generateOverflowCheck(const SCEVAddRecExpr *AR,
|
||||
Instruction *Loc, bool Signed);
|
||||
|
||||
/// A specialized variant of expandCodeForPredicate, handling the case when
|
||||
/// we are expanding code for a SCEVWrapPredicate.
|
||||
Value *expandWrapPredicate(const SCEVWrapPredicate *P, Instruction *Loc);
|
||||
LLVM_ABI Value *expandWrapPredicate(const SCEVWrapPredicate *P,
|
||||
Instruction *Loc);
|
||||
|
||||
/// A specialized variant of expandCodeForPredicate, handling the case when
|
||||
/// we are expanding code for a SCEVUnionPredicate.
|
||||
Value *expandUnionPredicate(const SCEVUnionPredicate *Pred, Instruction *Loc);
|
||||
LLVM_ABI Value *expandUnionPredicate(const SCEVUnionPredicate *Pred,
|
||||
Instruction *Loc);
|
||||
|
||||
/// Set the current IV increment loop and position.
|
||||
void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
|
||||
@@ -417,24 +425,24 @@ public:
|
||||
///
|
||||
/// Note that this function does not perform an exhaustive search. I.e if it
|
||||
/// didn't find any value it does not mean that there is no such value.
|
||||
bool hasRelatedExistingExpansion(const SCEV *S, const Instruction *At,
|
||||
Loop *L);
|
||||
LLVM_ABI bool hasRelatedExistingExpansion(const SCEV *S,
|
||||
const Instruction *At, Loop *L);
|
||||
|
||||
/// Returns a suitable insert point after \p I, that dominates \p
|
||||
/// MustDominate. Skips instructions inserted by the expander.
|
||||
BasicBlock::iterator findInsertPointAfter(Instruction *I,
|
||||
Instruction *MustDominate) const;
|
||||
LLVM_ABI BasicBlock::iterator
|
||||
findInsertPointAfter(Instruction *I, Instruction *MustDominate) const;
|
||||
|
||||
private:
|
||||
LLVMContext &getContext() const { return SE.getContext(); }
|
||||
|
||||
/// Recursive helper function for isHighCostExpansion.
|
||||
bool isHighCostExpansionHelper(const SCEVOperand &WorkItem, Loop *L,
|
||||
const Instruction &At, InstructionCost &Cost,
|
||||
unsigned Budget,
|
||||
const TargetTransformInfo &TTI,
|
||||
SmallPtrSetImpl<const SCEV *> &Processed,
|
||||
SmallVectorImpl<SCEVOperand> &Worklist);
|
||||
LLVM_ABI bool
|
||||
isHighCostExpansionHelper(const SCEVOperand &WorkItem, Loop *L,
|
||||
const Instruction &At, InstructionCost &Cost,
|
||||
unsigned Budget, const TargetTransformInfo &TTI,
|
||||
SmallPtrSetImpl<const SCEV *> &Processed,
|
||||
SmallVectorImpl<SCEVOperand> &Worklist);
|
||||
|
||||
/// Insert the specified binary operator, doing a small amount of work to
|
||||
/// avoid inserting an obviously redundant operation, and hoisting to an
|
||||
@@ -466,7 +474,7 @@ private:
|
||||
const SCEV *S, const Instruction *InsertPt,
|
||||
SmallVectorImpl<Instruction *> &DropPoisonGeneratingInsts);
|
||||
|
||||
Value *expand(const SCEV *S);
|
||||
LLVM_ABI Value *expand(const SCEV *S);
|
||||
Value *expand(const SCEV *S, BasicBlock::iterator I) {
|
||||
setInsertPoint(I);
|
||||
return expand(S);
|
||||
@@ -514,7 +522,7 @@ private:
|
||||
|
||||
Value *visitUnknown(const SCEVUnknown *S) { return S->getValue(); }
|
||||
|
||||
void rememberInstruction(Value *I);
|
||||
LLVM_ABI void rememberInstruction(Value *I);
|
||||
|
||||
void rememberFlags(Instruction *I);
|
||||
|
||||
@@ -561,7 +569,7 @@ public:
|
||||
/// Indicate that the result of the expansion is used.
|
||||
void markResultUsed() { ResultUsed = true; }
|
||||
|
||||
void cleanup();
|
||||
LLVM_ABI void cleanup();
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
|
||||
@@ -15,17 +15,18 @@
|
||||
|
||||
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
extern cl::opt<bool> EnablePGSO;
|
||||
extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
|
||||
extern cl::opt<bool> PGSOColdCodeOnly;
|
||||
extern cl::opt<bool> PGSOColdCodeOnlyForInstrPGO;
|
||||
extern cl::opt<bool> PGSOColdCodeOnlyForSamplePGO;
|
||||
extern cl::opt<bool> PGSOColdCodeOnlyForPartialSamplePGO;
|
||||
extern cl::opt<bool> ForcePGSO;
|
||||
extern cl::opt<int> PgsoCutoffInstrProf;
|
||||
extern cl::opt<int> PgsoCutoffSampleProf;
|
||||
LLVM_ABI extern cl::opt<bool> EnablePGSO;
|
||||
LLVM_ABI extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
|
||||
LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnly;
|
||||
LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnlyForInstrPGO;
|
||||
LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnlyForSamplePGO;
|
||||
LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnlyForPartialSamplePGO;
|
||||
LLVM_ABI extern cl::opt<bool> ForcePGSO;
|
||||
LLVM_ABI extern cl::opt<int> PgsoCutoffInstrProf;
|
||||
LLVM_ABI extern cl::opt<int> PgsoCutoffSampleProf;
|
||||
|
||||
class BasicBlock;
|
||||
class BlockFrequencyInfo;
|
||||
@@ -90,15 +91,17 @@ bool shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq,
|
||||
|
||||
/// Returns true if function \p F is suggested to be size-optimized based on the
|
||||
/// profile.
|
||||
bool shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI,
|
||||
BlockFrequencyInfo *BFI,
|
||||
PGSOQueryType QueryType = PGSOQueryType::Other);
|
||||
LLVM_ABI bool
|
||||
shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI,
|
||||
BlockFrequencyInfo *BFI,
|
||||
PGSOQueryType QueryType = PGSOQueryType::Other);
|
||||
|
||||
/// Returns true if basic block \p BB is suggested to be size-optimized based on
|
||||
/// the profile.
|
||||
bool shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI,
|
||||
BlockFrequencyInfo *BFI,
|
||||
PGSOQueryType QueryType = PGSOQueryType::Other);
|
||||
LLVM_ABI bool
|
||||
shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI,
|
||||
BlockFrequencyInfo *BFI,
|
||||
PGSOQueryType QueryType = PGSOQueryType::Other);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_SPLITMODULE_H
|
||||
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
@@ -35,10 +36,10 @@ class Module;
|
||||
/// module.
|
||||
/// - Internal symbols defined in module-level inline asm should be visible to
|
||||
/// each partition.
|
||||
void SplitModule(
|
||||
Module &M, unsigned N,
|
||||
function_ref<void(std::unique_ptr<Module> MPart)> ModuleCallback,
|
||||
bool PreserveLocals = false, bool RoundRobin = false);
|
||||
LLVM_ABI void
|
||||
SplitModule(Module &M, unsigned N,
|
||||
function_ref<void(std::unique_ptr<Module> MPart)> ModuleCallback,
|
||||
bool PreserveLocals = false, bool RoundRobin = false);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -92,7 +93,8 @@ using RewriteDescriptorList = std::list<std::unique_ptr<RewriteDescriptor>>;
|
||||
|
||||
class RewriteMapParser {
|
||||
public:
|
||||
bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors);
|
||||
LLVM_ABI bool parse(const std::string &MapFile,
|
||||
RewriteDescriptorList *Descriptors);
|
||||
|
||||
private:
|
||||
bool parse(std::unique_ptr<MemoryBuffer> &MapFile, RewriteDescriptorList *DL);
|
||||
@@ -121,13 +123,13 @@ public:
|
||||
Descriptors.splice(Descriptors.begin(), DL);
|
||||
}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
// Glue for old PM
|
||||
bool runImpl(Module &M);
|
||||
LLVM_ABI bool runImpl(Module &M);
|
||||
|
||||
private:
|
||||
void loadAndParseMapFiles();
|
||||
LLVM_ABI void loadAndParseMapFiles();
|
||||
|
||||
SymbolRewriter::RewriteDescriptorList Descriptors;
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/InstructionCost.h"
|
||||
|
||||
namespace llvm {
|
||||
@@ -48,9 +49,10 @@ const char *const LLVMLoopUnrollFollowupRemainder =
|
||||
"llvm.loop.unroll.followup_remainder";
|
||||
/// @}
|
||||
|
||||
const Loop* addClonedBlockToLoopInfo(BasicBlock *OriginalBB,
|
||||
BasicBlock *ClonedBB, LoopInfo *LI,
|
||||
NewLoopsMap &NewLoops);
|
||||
LLVM_ABI const Loop *addClonedBlockToLoopInfo(BasicBlock *OriginalBB,
|
||||
BasicBlock *ClonedBB,
|
||||
LoopInfo *LI,
|
||||
NewLoopsMap &NewLoops);
|
||||
|
||||
/// Represents the result of a \c UnrollLoop invocation.
|
||||
enum class LoopUnrollResult {
|
||||
@@ -79,15 +81,16 @@ struct UnrollLoopOptions {
|
||||
bool RuntimeUnrollMultiExit = false;
|
||||
};
|
||||
|
||||
LoopUnrollResult UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
|
||||
ScalarEvolution *SE, DominatorTree *DT,
|
||||
AssumptionCache *AC,
|
||||
const llvm::TargetTransformInfo *TTI,
|
||||
OptimizationRemarkEmitter *ORE, bool PreserveLCSSA,
|
||||
Loop **RemainderLoop = nullptr,
|
||||
AAResults *AA = nullptr);
|
||||
LLVM_ABI LoopUnrollResult UnrollLoop(Loop *L, UnrollLoopOptions ULO,
|
||||
LoopInfo *LI, ScalarEvolution *SE,
|
||||
DominatorTree *DT, AssumptionCache *AC,
|
||||
const llvm::TargetTransformInfo *TTI,
|
||||
OptimizationRemarkEmitter *ORE,
|
||||
bool PreserveLCSSA,
|
||||
Loop **RemainderLoop = nullptr,
|
||||
AAResults *AA = nullptr);
|
||||
|
||||
bool UnrollRuntimeLoopRemainder(
|
||||
LLVM_ABI bool UnrollRuntimeLoopRemainder(
|
||||
Loop *L, unsigned Count, bool AllowExpensiveTripCount,
|
||||
bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV,
|
||||
LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
|
||||
@@ -95,26 +98,25 @@ bool UnrollRuntimeLoopRemainder(
|
||||
unsigned SCEVExpansionBudget, bool RuntimeUnrollMultiExit,
|
||||
Loop **ResultLoop = nullptr);
|
||||
|
||||
LoopUnrollResult UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
|
||||
unsigned TripMultiple, bool UnrollRemainder,
|
||||
LoopInfo *LI, ScalarEvolution *SE,
|
||||
DominatorTree *DT, AssumptionCache *AC,
|
||||
const TargetTransformInfo *TTI,
|
||||
OptimizationRemarkEmitter *ORE,
|
||||
Loop **EpilogueLoop = nullptr);
|
||||
LLVM_ABI LoopUnrollResult UnrollAndJamLoop(
|
||||
Loop *L, unsigned Count, unsigned TripCount, unsigned TripMultiple,
|
||||
bool UnrollRemainder, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT,
|
||||
AssumptionCache *AC, const TargetTransformInfo *TTI,
|
||||
OptimizationRemarkEmitter *ORE, Loop **EpilogueLoop = nullptr);
|
||||
|
||||
bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT,
|
||||
DependenceInfo &DI, LoopInfo &LI);
|
||||
LLVM_ABI bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE,
|
||||
DominatorTree &DT, DependenceInfo &DI,
|
||||
LoopInfo &LI);
|
||||
|
||||
void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI,
|
||||
ScalarEvolution *SE, DominatorTree *DT,
|
||||
AssumptionCache *AC,
|
||||
const TargetTransformInfo *TTI,
|
||||
AAResults *AA = nullptr);
|
||||
LLVM_ABI void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI,
|
||||
ScalarEvolution *SE, DominatorTree *DT,
|
||||
AssumptionCache *AC,
|
||||
const TargetTransformInfo *TTI,
|
||||
AAResults *AA = nullptr);
|
||||
|
||||
MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
|
||||
LLVM_ABI MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
|
||||
|
||||
TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(
|
||||
LLVM_ABI TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(
|
||||
Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI,
|
||||
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
|
||||
llvm::OptimizationRemarkEmitter &ORE, int OptLevel,
|
||||
@@ -136,32 +138,30 @@ public:
|
||||
ConvergenceKind Convergence;
|
||||
bool ConvergenceAllowsRuntime;
|
||||
|
||||
UnrollCostEstimator(const Loop *L, const TargetTransformInfo &TTI,
|
||||
const SmallPtrSetImpl<const Value *> &EphValues,
|
||||
unsigned BEInsns);
|
||||
LLVM_ABI UnrollCostEstimator(const Loop *L, const TargetTransformInfo &TTI,
|
||||
const SmallPtrSetImpl<const Value *> &EphValues,
|
||||
unsigned BEInsns);
|
||||
|
||||
/// Whether it is legal to unroll this loop.
|
||||
bool canUnroll() const;
|
||||
LLVM_ABI bool canUnroll() const;
|
||||
|
||||
uint64_t getRolledLoopSize() const { return LoopSize.getValue(); }
|
||||
|
||||
/// Returns loop size estimation for unrolled loop, given the unrolling
|
||||
/// configuration specified by UP.
|
||||
uint64_t
|
||||
LLVM_ABI uint64_t
|
||||
getUnrolledLoopSize(const TargetTransformInfo::UnrollingPreferences &UP,
|
||||
unsigned CountOverwrite = 0) const;
|
||||
};
|
||||
|
||||
bool computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
|
||||
DominatorTree &DT, LoopInfo *LI, AssumptionCache *AC,
|
||||
ScalarEvolution &SE,
|
||||
const SmallPtrSetImpl<const Value *> &EphValues,
|
||||
OptimizationRemarkEmitter *ORE, unsigned TripCount,
|
||||
unsigned MaxTripCount, bool MaxOrZero,
|
||||
unsigned TripMultiple, const UnrollCostEstimator &UCE,
|
||||
TargetTransformInfo::UnrollingPreferences &UP,
|
||||
TargetTransformInfo::PeelingPreferences &PP,
|
||||
bool &UseUpperBound);
|
||||
LLVM_ABI bool computeUnrollCount(
|
||||
Loop *L, const TargetTransformInfo &TTI, DominatorTree &DT, LoopInfo *LI,
|
||||
AssumptionCache *AC, ScalarEvolution &SE,
|
||||
const SmallPtrSetImpl<const Value *> &EphValues,
|
||||
OptimizationRemarkEmitter *ORE, unsigned TripCount, unsigned MaxTripCount,
|
||||
bool MaxOrZero, unsigned TripMultiple, const UnrollCostEstimator &UCE,
|
||||
TargetTransformInfo::UnrollingPreferences &UP,
|
||||
TargetTransformInfo::PeelingPreferences &PP, bool &UseUpperBound);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "llvm/ADT/simple_ilist.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/IR/ValueMap.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -41,7 +42,7 @@ using MetadataPredicate = std::function<bool(const Metadata *)>;
|
||||
|
||||
/// This is a class that can be implemented by clients to remap types when
|
||||
/// cloning constants and instructions.
|
||||
class ValueMapTypeRemapper {
|
||||
class LLVM_ABI ValueMapTypeRemapper {
|
||||
virtual void anchor(); // Out of line method.
|
||||
|
||||
public:
|
||||
@@ -54,7 +55,7 @@ public:
|
||||
|
||||
/// This is a class that can be implemented by clients to materialize Values on
|
||||
/// demand.
|
||||
class ValueMaterializer {
|
||||
class LLVM_ABI ValueMaterializer {
|
||||
virtual void anchor(); // Out of line method.
|
||||
|
||||
protected:
|
||||
@@ -163,21 +164,21 @@ class ValueMapper {
|
||||
void *pImpl;
|
||||
|
||||
public:
|
||||
ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr,
|
||||
const MetadataPredicate *IdentityMD = nullptr);
|
||||
LLVM_ABI ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
|
||||
ValueMapTypeRemapper *TypeMapper = nullptr,
|
||||
ValueMaterializer *Materializer = nullptr,
|
||||
const MetadataPredicate *IdentityMD = nullptr);
|
||||
ValueMapper(ValueMapper &&) = delete;
|
||||
ValueMapper(const ValueMapper &) = delete;
|
||||
ValueMapper &operator=(ValueMapper &&) = delete;
|
||||
ValueMapper &operator=(const ValueMapper &) = delete;
|
||||
~ValueMapper();
|
||||
LLVM_ABI ~ValueMapper();
|
||||
|
||||
/// Register an alternate mapping context.
|
||||
///
|
||||
/// Returns a MappingContextID that can be used with the various schedule*()
|
||||
/// API to switch in a different value map on-the-fly.
|
||||
unsigned
|
||||
LLVM_ABI unsigned
|
||||
registerAlternateMappingContext(ValueToValueMapTy &VM,
|
||||
ValueMaterializer *Materializer = nullptr);
|
||||
|
||||
@@ -185,31 +186,34 @@ public:
|
||||
///
|
||||
/// \note Like the top-level mapping functions, \a addFlags() must be called
|
||||
/// at the top level, not during a callback in a \a ValueMaterializer.
|
||||
void addFlags(RemapFlags Flags);
|
||||
LLVM_ABI void addFlags(RemapFlags Flags);
|
||||
|
||||
Metadata *mapMetadata(const Metadata &MD);
|
||||
MDNode *mapMDNode(const MDNode &N);
|
||||
LLVM_ABI Metadata *mapMetadata(const Metadata &MD);
|
||||
LLVM_ABI MDNode *mapMDNode(const MDNode &N);
|
||||
|
||||
Value *mapValue(const Value &V);
|
||||
Constant *mapConstant(const Constant &C);
|
||||
LLVM_ABI Value *mapValue(const Value &V);
|
||||
LLVM_ABI Constant *mapConstant(const Constant &C);
|
||||
|
||||
void remapInstruction(Instruction &I);
|
||||
void remapDbgRecord(Module *M, DbgRecord &V);
|
||||
void remapDbgRecordRange(Module *M, iterator_range<DbgRecordIterator> Range);
|
||||
void remapFunction(Function &F);
|
||||
void remapGlobalObjectMetadata(GlobalObject &GO);
|
||||
LLVM_ABI void remapInstruction(Instruction &I);
|
||||
LLVM_ABI void remapDbgRecord(Module *M, DbgRecord &V);
|
||||
LLVM_ABI void remapDbgRecordRange(Module *M,
|
||||
iterator_range<DbgRecordIterator> Range);
|
||||
LLVM_ABI void remapFunction(Function &F);
|
||||
LLVM_ABI void remapGlobalObjectMetadata(GlobalObject &GO);
|
||||
|
||||
void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
|
||||
unsigned MappingContextID = 0);
|
||||
void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
|
||||
bool IsOldCtorDtor,
|
||||
ArrayRef<Constant *> NewMembers,
|
||||
unsigned MappingContextID = 0);
|
||||
void scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee,
|
||||
unsigned MappingContextID = 0);
|
||||
void scheduleMapGlobalIFunc(GlobalIFunc &GI, Constant &Resolver,
|
||||
unsigned MappingContextID = 0);
|
||||
void scheduleRemapFunction(Function &F, unsigned MappingContextID = 0);
|
||||
LLVM_ABI void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
|
||||
unsigned MappingContextID = 0);
|
||||
LLVM_ABI void scheduleMapAppendingVariable(GlobalVariable &GV,
|
||||
Constant *InitPrefix,
|
||||
bool IsOldCtorDtor,
|
||||
ArrayRef<Constant *> NewMembers,
|
||||
unsigned MappingContextID = 0);
|
||||
LLVM_ABI void scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee,
|
||||
unsigned MappingContextID = 0);
|
||||
LLVM_ABI void scheduleMapGlobalIFunc(GlobalIFunc &GI, Constant &Resolver,
|
||||
unsigned MappingContextID = 0);
|
||||
LLVM_ABI void scheduleRemapFunction(Function &F,
|
||||
unsigned MappingContextID = 0);
|
||||
};
|
||||
|
||||
/// Look up or compute a value in the value map.
|
||||
@@ -295,7 +299,7 @@ inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
|
||||
/// instruction's atom group number if it has been mapped (e.g. with
|
||||
/// llvm::mapAtomInstance), which is necessary to distinguish source code
|
||||
/// atoms on duplicated code paths.
|
||||
void RemapSourceAtom(Instruction *I, ValueToValueMapTy &VM);
|
||||
LLVM_ABI void RemapSourceAtom(Instruction *I, ValueToValueMapTy &VM);
|
||||
|
||||
/// Remap the Values used in the DbgRecord \a DR using the value map \a
|
||||
/// VM.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define LLVM_TRANSFORMS_VECTORIZE_LOADSTOREVECTORIZER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class Pass;
|
||||
@@ -17,12 +18,11 @@ class Function;
|
||||
|
||||
class LoadStoreVectorizerPass : public PassInfoMixin<LoadStoreVectorizerPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Create a legacy pass manager instance of the LoadStoreVectorizer pass
|
||||
Pass *createLoadStoreVectorizerPass();
|
||||
|
||||
LLVM_ABI Pass *createLoadStoreVectorizerPass();
|
||||
}
|
||||
|
||||
#endif /* LLVM_TRANSFORMS_VECTORIZE_LOADSTOREVECTORIZER_H */
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Utils/ExtraPassManager.h"
|
||||
#include <functional>
|
||||
|
||||
@@ -78,8 +79,8 @@ class ScalarEvolution;
|
||||
class TargetLibraryInfo;
|
||||
class TargetTransformInfo;
|
||||
|
||||
extern cl::opt<bool> EnableLoopInterleaving;
|
||||
extern cl::opt<bool> EnableLoopVectorization;
|
||||
LLVM_ABI extern cl::opt<bool> EnableLoopInterleaving;
|
||||
LLVM_ABI extern cl::opt<bool> EnableLoopVectorization;
|
||||
|
||||
struct LoopVectorizeOptions {
|
||||
/// If false, consider all loops for interleaving.
|
||||
@@ -138,7 +139,7 @@ private:
|
||||
bool VectorizeOnlyWhenForced;
|
||||
|
||||
public:
|
||||
LoopVectorizePass(LoopVectorizeOptions Opts = {});
|
||||
LLVM_ABI LoopVectorizePass(LoopVectorizeOptions Opts = {});
|
||||
|
||||
ScalarEvolution *SE;
|
||||
LoopInfo *LI;
|
||||
@@ -152,22 +153,23 @@ public:
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
ProfileSummaryInfo *PSI;
|
||||
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
void printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI void
|
||||
printPipeline(raw_ostream &OS,
|
||||
function_ref<StringRef(StringRef)> MapClassName2PassName);
|
||||
|
||||
// Shim for old PM.
|
||||
LoopVectorizeResult runImpl(Function &F);
|
||||
LLVM_ABI LoopVectorizeResult runImpl(Function &F);
|
||||
|
||||
bool processLoop(Loop *L);
|
||||
LLVM_ABI bool processLoop(Loop *L);
|
||||
};
|
||||
|
||||
/// Reports a vectorization failure: print \p DebugMsg for debugging
|
||||
/// purposes along with the corresponding optimization remark \p RemarkName.
|
||||
/// If \p I is passed, it is an instruction that prevents vectorization.
|
||||
/// Otherwise, the loop \p TheLoop is used for the location of the remark.
|
||||
void reportVectorizationFailure(const StringRef DebugMsg,
|
||||
const StringRef OREMsg, const StringRef ORETag,
|
||||
LLVM_ABI void reportVectorizationFailure(
|
||||
const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag,
|
||||
OptimizationRemarkEmitter *ORE, Loop *TheLoop, Instruction *I = nullptr);
|
||||
|
||||
/// Same as above, but the debug message and optimization remark are identical
|
||||
@@ -184,7 +186,7 @@ inline void reportVectorizationFailure(const StringRef DebugMsg,
|
||||
struct ShouldRunExtraVectorPasses
|
||||
: public ShouldRunExtraPasses<ShouldRunExtraVectorPasses>,
|
||||
public AnalysisInfoMixin<ShouldRunExtraVectorPasses> {
|
||||
static AnalysisKey Key;
|
||||
LLVM_ABI static AnalysisKey Key;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/SandboxIR/Instruction.h"
|
||||
#include "llvm/SandboxIR/IntrinsicInst.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
|
||||
|
||||
namespace llvm::sandboxir {
|
||||
@@ -45,6 +46,9 @@ class DGNode;
|
||||
class MemDGNode;
|
||||
class DependencyGraph;
|
||||
|
||||
// Defined in Transforms/Vectorize/SandboxVectorizer/Interval.cpp
|
||||
extern template class LLVM_TEMPLATE_ABI Interval<MemDGNode>;
|
||||
|
||||
/// Iterate over both def-use and mem dependencies.
|
||||
class PredIterator {
|
||||
User::op_iterator OpIt;
|
||||
@@ -65,9 +69,9 @@ class PredIterator {
|
||||
|
||||
/// Skip iterators that don't point instructions or are outside \p DAG,
|
||||
/// starting from \p OpIt and ending before \p OpItE.n
|
||||
static User::op_iterator skipBadIt(User::op_iterator OpIt,
|
||||
User::op_iterator OpItE,
|
||||
const DependencyGraph &DAG);
|
||||
LLVM_ABI static User::op_iterator skipBadIt(User::op_iterator OpIt,
|
||||
User::op_iterator OpItE,
|
||||
const DependencyGraph &DAG);
|
||||
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
@@ -75,20 +79,20 @@ public:
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
value_type operator*();
|
||||
PredIterator &operator++();
|
||||
LLVM_ABI value_type operator*();
|
||||
LLVM_ABI PredIterator &operator++();
|
||||
PredIterator operator++(int) {
|
||||
auto Copy = *this;
|
||||
++(*this);
|
||||
return Copy;
|
||||
}
|
||||
bool operator==(const PredIterator &Other) const;
|
||||
LLVM_ABI bool operator==(const PredIterator &Other) const;
|
||||
bool operator!=(const PredIterator &Other) const { return !(*this == Other); }
|
||||
};
|
||||
|
||||
/// A DependencyGraph Node that points to an Instruction and contains memory
|
||||
/// dependency edges.
|
||||
class DGNode {
|
||||
class LLVM_ABI DGNode {
|
||||
protected:
|
||||
Instruction *I;
|
||||
// TODO: Use a PointerIntPair for SubclassID and I.
|
||||
@@ -310,17 +314,17 @@ class MemDGNodeIntervalBuilder {
|
||||
public:
|
||||
/// Scans the instruction chain in \p Intvl top-down, returning the top-most
|
||||
/// MemDGNode, or nullptr.
|
||||
static MemDGNode *getTopMemDGNode(const Interval<Instruction> &Intvl,
|
||||
const DependencyGraph &DAG);
|
||||
LLVM_ABI static MemDGNode *getTopMemDGNode(const Interval<Instruction> &Intvl,
|
||||
const DependencyGraph &DAG);
|
||||
/// Scans the instruction chain in \p Intvl bottom-up, returning the
|
||||
/// bottom-most MemDGNode, or nullptr.
|
||||
static MemDGNode *getBotMemDGNode(const Interval<Instruction> &Intvl,
|
||||
const DependencyGraph &DAG);
|
||||
LLVM_ABI static MemDGNode *getBotMemDGNode(const Interval<Instruction> &Intvl,
|
||||
const DependencyGraph &DAG);
|
||||
/// Given \p Instrs it finds their closest mem nodes in the interval and
|
||||
/// returns the corresponding mem range. Note: BotN (or its neighboring mem
|
||||
/// node) is included in the range.
|
||||
static Interval<MemDGNode> make(const Interval<Instruction> &Instrs,
|
||||
DependencyGraph &DAG);
|
||||
LLVM_ABI static Interval<MemDGNode> make(const Interval<Instruction> &Instrs,
|
||||
DependencyGraph &DAG);
|
||||
static Interval<MemDGNode> makeEmpty() { return {}; }
|
||||
};
|
||||
|
||||
@@ -383,15 +387,15 @@ private:
|
||||
MemDGNode *SkipN = nullptr) const;
|
||||
|
||||
/// Called by the callbacks when a new instruction \p I has been created.
|
||||
void notifyCreateInstr(Instruction *I);
|
||||
LLVM_ABI void notifyCreateInstr(Instruction *I);
|
||||
/// Called by the callbacks when instruction \p I is about to get
|
||||
/// deleted.
|
||||
void notifyEraseInstr(Instruction *I);
|
||||
LLVM_ABI void notifyEraseInstr(Instruction *I);
|
||||
/// Called by the callbacks when instruction \p I is about to be moved to
|
||||
/// \p To.
|
||||
void notifyMoveInstr(Instruction *I, const BBIterator &To);
|
||||
LLVM_ABI void notifyMoveInstr(Instruction *I, const BBIterator &To);
|
||||
/// Called by the callbacks when \p U's source is about to be set to \p NewSrc
|
||||
void notifySetUse(const Use &U, Value *NewSrc);
|
||||
LLVM_ABI void notifySetUse(const Use &U, Value *NewSrc);
|
||||
|
||||
public:
|
||||
/// This constructor also registers callbacks.
|
||||
@@ -441,7 +445,7 @@ public:
|
||||
}
|
||||
/// Build/extend the dependency graph such that it includes \p Instrs. Returns
|
||||
/// the range of instructions added to the DAG.
|
||||
Interval<Instruction> extend(ArrayRef<Instruction *> Instrs);
|
||||
LLVM_ABI Interval<Instruction> extend(ArrayRef<Instruction *> Instrs);
|
||||
/// \Returns the range of instructions included in the DAG.
|
||||
Interval<Instruction> getInterval() const { return DAGInterval; }
|
||||
void clear() {
|
||||
@@ -460,7 +464,6 @@ public:
|
||||
LLVM_DUMP_METHOD void dump() const;
|
||||
#endif // NDEBUG
|
||||
};
|
||||
|
||||
} // namespace llvm::sandboxir
|
||||
|
||||
#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/SandboxIR/Instruction.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
@@ -235,6 +236,9 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
// Defined in Transforms/Vectorize/SandboxVectorizer/Interval.cpp
|
||||
extern template class LLVM_TEMPLATE_ABI Interval<Instruction>;
|
||||
|
||||
} // namespace llvm::sandboxir
|
||||
|
||||
#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
|
||||
#include "llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h"
|
||||
@@ -347,13 +348,13 @@ public:
|
||||
/// \Returns a LegalityResult object owned by LegalityAnalysis.
|
||||
/// \p SkipScheduling skips the scheduler check and is only meant for testing.
|
||||
// TODO: Try to remove the SkipScheduling argument by refactoring the tests.
|
||||
const LegalityResult &canVectorize(ArrayRef<Value *> Bndl,
|
||||
bool SkipScheduling = false);
|
||||
LLVM_ABI const LegalityResult &canVectorize(ArrayRef<Value *> Bndl,
|
||||
bool SkipScheduling = false);
|
||||
/// \Returns a Pack with reason 'ForcePackForDebugging'.
|
||||
const LegalityResult &getForcedPackForDebugging() {
|
||||
return createLegalityResult<Pack>(ResultReason::ForcePackForDebugging);
|
||||
}
|
||||
void clear();
|
||||
LLVM_ABI void clear();
|
||||
};
|
||||
|
||||
} // namespace llvm::sandboxir
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZER_H
|
||||
#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZER_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <memory>
|
||||
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
@@ -49,11 +50,11 @@ public:
|
||||
// Vectorizer component can't find the vtable for classes like
|
||||
// sandboxir::Pass. This way we don't have to make LLVMPasses add a direct
|
||||
// dependency on SandboxIR.
|
||||
SandboxVectorizerPass();
|
||||
SandboxVectorizerPass(SandboxVectorizerPass &&);
|
||||
~SandboxVectorizerPass();
|
||||
LLVM_ABI SandboxVectorizerPass();
|
||||
LLVM_ABI SandboxVectorizerPass(SandboxVectorizerPass &&);
|
||||
LLVM_ABI ~SandboxVectorizerPass();
|
||||
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
|
||||
|
||||
#include "llvm/SandboxIR/Instruction.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h"
|
||||
#include <queue>
|
||||
|
||||
@@ -143,11 +144,11 @@ public:
|
||||
const_iterator begin() const { return Nodes.begin(); }
|
||||
const_iterator end() const { return Nodes.end(); }
|
||||
/// \Returns the bundle node that comes before the others in program order.
|
||||
DGNode *getTop() const;
|
||||
LLVM_ABI DGNode *getTop() const;
|
||||
/// \Returns the bundle node that comes after the others in program order.
|
||||
DGNode *getBot() const;
|
||||
LLVM_ABI DGNode *getBot() const;
|
||||
/// Move all bundle instructions to \p Where back-to-back.
|
||||
void cluster(BasicBlock::iterator Where);
|
||||
LLVM_ABI void cluster(BasicBlock::iterator Where);
|
||||
/// \Returns true if all nodes in the bundle are ready.
|
||||
bool ready() const {
|
||||
return all_of(Nodes, [](const auto *N) { return N->ready(); });
|
||||
@@ -182,7 +183,7 @@ class Scheduler {
|
||||
/// Called by Sandbox IR's callback system, after \p I has been created.
|
||||
/// NOTE: This should run after DAG's callback has run.
|
||||
// TODO: Perhaps call DAG's notify function from within this one?
|
||||
void notifyCreateInstr(Instruction *I);
|
||||
LLVM_ABI void notifyCreateInstr(Instruction *I);
|
||||
|
||||
/// \Returns a scheduling bundle containing \p Instrs.
|
||||
SchedBundle *createBundle(ArrayRef<Instruction *> Instrs);
|
||||
@@ -206,7 +207,8 @@ class Scheduler {
|
||||
/// were in the same SchedBundle.
|
||||
};
|
||||
/// \Returns whether none/some/all of \p Instrs have been scheduled.
|
||||
BndlSchedState getBndlSchedState(ArrayRef<Instruction *> Instrs) const;
|
||||
LLVM_ABI BndlSchedState
|
||||
getBndlSchedState(ArrayRef<Instruction *> Instrs) const;
|
||||
/// Destroy the top-most part of the schedule that includes \p Instrs.
|
||||
void trimSchedule(ArrayRef<Instruction *> Instrs);
|
||||
/// Disable copies.
|
||||
@@ -229,7 +231,7 @@ public:
|
||||
/// dependencies among \p Instrs. This function may involve scheduling
|
||||
/// intermediate instructions or canceling and re-scheduling if needed.
|
||||
/// \Returns true on success, false otherwise.
|
||||
bool trySchedule(ArrayRef<Instruction *> Instrs);
|
||||
LLVM_ABI bool trySchedule(ArrayRef<Instruction *> Instrs);
|
||||
/// Clear the scheduler's state, including the DAG.
|
||||
void clear() {
|
||||
Bndls.clear();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user