[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:
Andrew Rogers
2025-06-10 08:10:17 -07:00
committed by GitHub
parent 3cb104e98b
commit b2584e0b17
110 changed files with 2084 additions and 1743 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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; }

View File

@@ -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

View File

@@ -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);

View File

@@ -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; }
};

View File

@@ -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 {

View File

@@ -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

View File

@@ -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;

View File

@@ -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; }
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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.

View File

@@ -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

View File

@@ -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);
};

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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 &);
};
}

View File

@@ -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

View File

@@ -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; }
};

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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; }
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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; }
};

View File

@@ -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);

View File

@@ -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:

View File

@@ -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; }
};

View File

@@ -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

View File

@@ -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; }
};

View File

@@ -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:

View File

@@ -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:

View File

@@ -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; }
};

View File

@@ -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; }
};

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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,

View File

@@ -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 &);
};
}

View File

@@ -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 &);
};
}

View File

@@ -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

View File

@@ -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());
}

View File

@@ -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);
};
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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

View File

@@ -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; }

View File

@@ -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));

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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; }
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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.

View File

@@ -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 */

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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