[flang-commits] [clang] [flang] [lld] [llvm] [polly] [Option] Make Passes, Scalar, Instrumentation, and CGData options per-context (PR #232599)
Fangrui Song via flang-commits
flang-commits at lists.llvm.org
Fri Oct 16 10:51:32 PDT 2026
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/232599
>From 4568fe7f4d0d330a00014c42e304f9ea2a3af4d6 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 15 Oct 2026 08:40:57 -0700
Subject: [PATCH] [Option] Make Passes, Scalar, Instrumentation, and CGData
options per-context
Follow-up to #232365: drop `perContext = false` from PassesOptions,
ScalarOptions, InstrumentationOptions, and CGDataOptions.
* IR passes read their LLVMContext's options in run(). Legacy passes
that chose analyses from an option now always require them
(ConstantHoisting, StructurizeCFG, GVN).
* Pass parameters that an option overrides are combined in run(), so
-print-pipeline-passes no longer folds such options (e.g.
-bonus-inst-threshold) into the printed parameters.
* PipelineTuningOptions carries the library options to PassBuilder,
which falls back to the TargetMachine's. opt, clang, flang, and Polly
pass their module's.
* The CodeGenData singleton is configured by its first caller. lld and
llvm-cgdata pass an empty context.
* GCOVOptions::getDefault is removed.
LLM-aided
---
clang/lib/CodeGen/BackendUtil.cpp | 48 ++++----
flang/lib/Frontend/FrontendActions.cpp | 6 +-
lld/MachO/Driver.cpp | 3 +-
llvm/include/llvm/CGData/CodeGenData.h | 49 +++++---
llvm/include/llvm/CGData/CodeGenDataReader.h | 13 ++-
llvm/include/llvm/CGData/StableFunctionMap.h | 7 +-
.../llvm/CGData/StableFunctionMapRecord.h | 5 +-
.../llvm/Frontend/Driver/CodeGenOptions.h | 6 +-
llvm/include/llvm/Passes/PassBuilder.h | 25 +++-
.../llvm/Passes/StandardInstrumentations.h | 31 +++--
.../Instrumentation/AddressSanitizerCommon.h | 3 +-
.../Instrumentation/ControlHeightReduction.h | 8 +-
.../Transforms/Instrumentation/GCOVProfiler.h | 5 +-
.../Instrumentation/InstrProfiling.h | 6 +-
.../Instrumentation/LowerAllowCheckPass.h | 7 +-
.../Instrumentation/MemorySanitizer.h | 6 +
.../Instrumentation/PGOCtxProfLowering.h | 6 +-
.../Instrumentation/PGOInstrumentation.h | 6 +-
.../llvm/Transforms/Scalar/ConstantHoisting.h | 2 +
llvm/include/llvm/Transforms/Scalar/LICM.h | 28 +++--
.../llvm/Transforms/Scalar/LoopUnrollPass.h | 10 +-
.../llvm/Transforms/Scalar/Reassociate.h | 1 +
.../Transforms/Scalar/SpeculativeExecution.h | 3 +
.../llvm/Transforms/Utils/Instrumentation.h | 2 -
llvm/lib/CGData/CGDataOptions.td | 2 +-
llvm/lib/CGData/CodeGenData.cpp | 29 +++--
llvm/lib/CGData/CodeGenDataReader.cpp | 18 +--
llvm/lib/CGData/StableFunctionMap.cpp | 10 +-
llvm/lib/CodeGen/GlobalMergeFunctions.cpp | 12 +-
llvm/lib/CodeGen/MachineOutliner.cpp | 12 +-
llvm/lib/Frontend/Driver/CodeGenOptions.cpp | 7 +-
llvm/lib/LTO/LTO.cpp | 5 +-
llvm/lib/Passes/PassBuilder.cpp | 17 ++-
llvm/lib/Passes/PassBuilderPipelines.cpp | 24 ++--
llvm/lib/Passes/PassesOptions.td | 2 +-
llvm/lib/Passes/RunCodeGen.cpp | 7 +-
llvm/lib/Passes/StandardInstrumentations.cpp | 82 +++++++-------
llvm/lib/Target/AMDGPU/AMDGPUSwLowerLDS.cpp | 4 +-
llvm/lib/Target/X86/X86MCInstLower.cpp | 3 +-
.../Instrumentation/AddressSanitizer.cpp | 11 +-
.../Transforms/Instrumentation/AllocToken.cpp | 4 +-
.../Instrumentation/BoundsChecking.cpp | 15 +--
.../ControlHeightReduction.cpp | 42 ++++---
.../Instrumentation/DataFlowSanitizer.cpp | 5 +-
.../Instrumentation/GCOVProfiling.cpp | 9 +-
.../Instrumentation/HWAddressSanitizer.cpp | 3 +-
.../Instrumentation/IndirectCallPromotion.cpp | 3 +-
.../Instrumentation/InstrProfiling.cpp | 16 ++-
.../Instrumentation/InstrumentationOptions.td | 2 +-
.../Instrumentation/LowerAllowCheckPass.cpp | 9 +-
.../MemProfInstrumentation.cpp | 7 +-
.../Transforms/Instrumentation/MemProfUse.cpp | 9 +-
.../Instrumentation/MemorySanitizer.cpp | 51 ++++++---
.../NumericalStabilitySanitizer.cpp | 4 +-
.../Instrumentation/PGOCtxProfLowering.cpp | 10 +-
.../Instrumentation/PGOInstrumentation.cpp | 44 ++++---
.../Instrumentation/PGOMemOPSizeOpt.cpp | 5 +-
.../SanitizerBinaryMetadata.cpp | 5 +-
.../Instrumentation/SanitizerCoverage.cpp | 3 +-
.../Instrumentation/ThreadSanitizer.cpp | 3 +-
.../Instrumentation/TypeSanitizer.cpp | 3 +-
.../Instrumentation/ValueProfilePlugins.inc | 6 +-
llvm/lib/Transforms/Scalar/ADCE.cpp | 12 +-
.../Transforms/Scalar/CallSiteSplitting.cpp | 15 ++-
.../Transforms/Scalar/ConstantHoisting.cpp | 17 +--
.../Scalar/ConstraintElimination.cpp | 3 +-
.../Transforms/Scalar/DFAJumpThreading.cpp | 12 +-
.../Scalar/DeadStoreElimination.cpp | 3 +-
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 29 +++--
llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp | 13 ++-
llvm/lib/Transforms/Scalar/Float2Int.cpp | 3 +-
llvm/lib/Transforms/Scalar/GVN.cpp | 82 +++++++-------
llvm/lib/Transforms/Scalar/GVNHoist.cpp | 10 +-
llvm/lib/Transforms/Scalar/GuardWidening.cpp | 28 +++--
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 3 +-
.../Scalar/InductiveRangeCheckElimination.cpp | 3 +-
.../Transforms/Scalar/JumpTableToSwitch.cpp | 8 +-
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 2 +-
llvm/lib/Transforms/Scalar/LICM.cpp | 78 ++++++-------
.../Transforms/Scalar/LoopDataPrefetch.cpp | 16 ++-
llvm/lib/Transforms/Scalar/LoopDeletion.cpp | 6 +-
llvm/lib/Transforms/Scalar/LoopDistribute.cpp | 3 +-
llvm/lib/Transforms/Scalar/LoopFlatten.cpp | 8 +-
llvm/lib/Transforms/Scalar/LoopFuse.cpp | 4 +-
.../Transforms/Scalar/LoopIdiomRecognize.cpp | 14 ++-
.../lib/Transforms/Scalar/LoopInterchange.cpp | 12 +-
.../Transforms/Scalar/LoopLoadElimination.cpp | 3 +-
.../lib/Transforms/Scalar/LoopPredication.cpp | 12 +-
llvm/lib/Transforms/Scalar/LoopRotation.cpp | 3 +-
.../lib/Transforms/Scalar/LoopSimplifyCFG.cpp | 9 +-
llvm/lib/Transforms/Scalar/LoopSink.cpp | 3 +-
.../Transforms/Scalar/LoopStrengthReduce.cpp | 3 +-
.../Scalar/LoopUnrollAndJamPass.cpp | 3 +-
llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp | 22 +++-
.../Transforms/Scalar/LoopVersioningLICM.cpp | 5 +-
.../Scalar/LowerExpectIntrinsic.cpp | 30 ++---
.../Scalar/LowerMatrixIntrinsics.cpp | 107 +++++++++---------
llvm/lib/Transforms/Scalar/NewGVN.cpp | 14 +--
.../lib/Transforms/Scalar/PlaceSafepoints.cpp | 13 ++-
llvm/lib/Transforms/Scalar/Reassociate.cpp | 6 +-
.../Scalar/RewriteStatepointsForGC.cpp | 3 +-
llvm/lib/Transforms/Scalar/SROA.cpp | 2 +-
llvm/lib/Transforms/Scalar/ScalarOptions.td | 2 +-
.../Scalar/SeparateConstOffsetFromGEP.cpp | 3 +-
.../Transforms/Scalar/SimpleLoopUnswitch.cpp | 3 +-
.../lib/Transforms/Scalar/SimplifyCFGPass.cpp | 23 ++--
.../Scalar/SpeculativeExecution.cpp | 18 ++-
.../Scalar/StraightLineStrengthReduce.cpp | 18 ++-
llvm/lib/Transforms/Scalar/StructurizeCFG.cpp | 39 +++----
.../Scalar/TailRecursionElimination.cpp | 3 +-
llvm/tools/llvm-cgdata/llvm-cgdata.cpp | 9 +-
llvm/tools/opt/NewPMDriver.cpp | 2 +-
.../CGData/StableFunctionMapTest.cpp | 7 +-
polly/lib/Support/RegisterPasses.cpp | 43 ++++---
polly/lib/Transform/ScopInliner.cpp | 2 +-
115 files changed, 955 insertions(+), 628 deletions(-)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 77c53c612df8f1..1ffcf7d7f6b0a7 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -144,10 +144,13 @@ extern llvm::cl::opt<bool> ClSanitizeGuardChecks;
}
// Path and name of file used for profile generation
-static std::string getProfileGenName(const CodeGenOptions &CodeGenOpts) {
- std::string FileName = CodeGenOpts.InstrProfileOutput.empty()
- ? llvm::driver::getDefaultProfileGenName()
- : CodeGenOpts.InstrProfileOutput;
+static std::string
+getProfileGenName(const cl::LibraryOptionsContext &LibraryOptions,
+ const CodeGenOptions &CodeGenOpts) {
+ std::string FileName =
+ CodeGenOpts.InstrProfileOutput.empty()
+ ? llvm::driver::getDefaultProfileGenName(LibraryOptions)
+ : CodeGenOpts.InstrProfileOutput;
if (CodeGenOpts.ContinuousProfileSync)
FileName = "%c" + FileName;
return FileName;
@@ -529,8 +532,8 @@ getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts) {
if (CodeGenOpts.CoverageNotesFile.empty() &&
CodeGenOpts.CoverageDataFile.empty())
return std::nullopt;
- // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
- // LLVM's -default-gcov-version flag is set to something invalid.
+ // Not using GCOVProfilerPass's default options allows us to avoid exiting
+ // if LLVM's -default-gcov-version flag is set to something invalid.
GCOVOptions Options;
Options.EmitNotes = !CodeGenOpts.CoverageNotesFile.empty();
Options.EmitData = !CodeGenOpts.CoverageDataFile.empty();
@@ -773,7 +776,8 @@ static void addSanitizers(const Triple &TargetTriple,
}
}
-void addLowerAllowCheckPass(const CodeGenOptions &CodeGenOpts,
+void addLowerAllowCheckPass(const cl::LibraryOptionsContext &LibraryOptions,
+ const CodeGenOptions &CodeGenOpts,
const LangOptions &LangOpts, PassBuilder &PB) {
// SanitizeSkipHotCutoffs: doubles with range [0, 1]
// Opts.cutoffs: unsigned ints with range [0, 1000000]
@@ -788,8 +792,9 @@ void addLowerAllowCheckPass(const CodeGenOptions &CodeGenOpts,
SanitizerKind::KernelMemory | SanitizerKind::HWAddress |
SanitizerKind::KernelHWAddress);
- // TODO: remove IsRequested()
- if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value() ||
+ // TODO: remove isRequested()
+ if (LowerAllowCheckPass::isRequested(LibraryOptions) ||
+ ScaledCutoffs.has_value() ||
CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.has_value() ||
LowerAllowSanitize) {
// We want to call it after inline, which is about OptimizerEarlyEPCallback.
@@ -798,7 +803,7 @@ void addLowerAllowCheckPass(const CodeGenOptions &CodeGenOpts,
ModulePassManager &MPM, OptimizationLevel Level,
ThinOrFullLTOPhase Phase) {
LowerAllowCheckPass::Options Opts;
- // TODO: after removing IsRequested(), make this unconditional
+ // TODO: after removing isRequested(), make this unconditional
if (ScaledCutoffs.has_value())
Opts.cutoffs = ScaledCutoffs.value();
Opts.runtime_check = AllowRuntimeCheckSkipHotCutoff;
@@ -843,11 +848,13 @@ static void addAMDGCNSPIRVSizeOptimizationPasses(ModulePassManager &MPM) {
void EmitAssemblyHelper::RunOptimizationPipeline(
BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS, BackendConsumer *BC) {
+ const cl::LibraryOptionsContext &LibraryOptions =
+ TheModule->getContext().getLibraryOptions();
std::optional<PGOOptions> PGOOpt;
if (CodeGenOpts.hasProfileIRInstr())
// -fprofile-generate.
- PGOOpt = PGOOptions(getProfileGenName(CodeGenOpts), "", "",
+ PGOOpt = PGOOptions(getProfileGenName(LibraryOptions, CodeGenOpts), "", "",
CodeGenOpts.MemoryProfileUsePath, PGOOptions::IRInstr,
PGOOptions::NoCSAction, ClPGOColdFuncAttr,
CodeGenOpts.DebugInfoForProfiling,
@@ -894,18 +901,18 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
PGOOpt->Action != PGOOptions::SampleUse &&
"Cannot run CSProfileGen pass with ProfileGen or SampleUse "
" pass");
- PGOOpt->CSProfileGenFile = getProfileGenName(CodeGenOpts);
+ PGOOpt->CSProfileGenFile = getProfileGenName(LibraryOptions, CodeGenOpts);
PGOOpt->CSAction = PGOOptions::CSIRInstr;
} else
- PGOOpt = PGOOptions("", getProfileGenName(CodeGenOpts), "",
- /*MemoryProfile=*/"", PGOOptions::NoAction,
- PGOOptions::CSIRInstr, ClPGOColdFuncAttr,
- CodeGenOpts.DebugInfoForProfiling);
+ PGOOpt = PGOOptions(
+ "", getProfileGenName(LibraryOptions, CodeGenOpts), "",
+ /*MemoryProfile=*/"", PGOOptions::NoAction, PGOOptions::CSIRInstr,
+ ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
}
if (TM)
TM->setPGOOption(PGOOpt);
- PipelineTuningOptions PTO;
+ PipelineTuningOptions PTO(&LibraryOptions);
PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
PTO.LoopInterchange = CodeGenOpts.InterchangeLoops;
PTO.LoopFusion = CodeGenOpts.FuseLoops;
@@ -1086,7 +1093,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
// Most sanitizers only run during PreLink stage.
addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB);
addKCFIPass(TargetTriple, LangOpts, PB);
- addLowerAllowCheckPass(CodeGenOpts, LangOpts, PB);
+ addLowerAllowCheckPass(LibraryOptions, CodeGenOpts, LangOpts, PB);
PB.registerPipelineStartEPCallback(
[&](ModulePassManager &MPM, OptimizationLevel Level) {
@@ -1378,6 +1385,9 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
Conf.OptLevel = CGOpts.OptimizationLevel;
initTargetOptions(CI, Diags, Conf.Options);
Conf.SampleProfile = std::move(SampleProfile);
+ const cl::LibraryOptionsContext &LibraryOptions =
+ M->getContext().getLibraryOptions();
+ Conf.PTO = PipelineTuningOptions(&LibraryOptions);
Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops;
Conf.PTO.LoopFusion = CGOpts.FuseLoops;
@@ -1393,7 +1403,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
// Context sensitive profile.
if (CGOpts.hasProfileCSIRInstr()) {
Conf.RunCSIRInstr = true;
- Conf.CSIRProfile = getProfileGenName(CGOpts);
+ Conf.CSIRProfile = getProfileGenName(LibraryOptions, CGOpts);
} else if (CGOpts.hasProfileCSIRUse()) {
Conf.RunCSIRInstr = false;
Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index b8b8b426dfe86d..21170893e6e898 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -974,14 +974,16 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
// Create the pass manager builder.
llvm::PassInstrumentationCallbacks pic;
- llvm::PipelineTuningOptions pto;
+ const llvm::cl::LibraryOptionsContext &libraryOptions =
+ llvmModule->getContext().getLibraryOptions();
+ llvm::PipelineTuningOptions pto(&libraryOptions);
std::optional<llvm::PGOOptions> pgoOpt;
if (opts.hasProfileIRInstr()) {
// -fprofile-generate.
pgoOpt = llvm::PGOOptions(
opts.InstrProfileOutput.empty()
- ? llvm::driver::getDefaultProfileGenName()
+ ? llvm::driver::getDefaultProfileGenName(libraryOptions)
: opts.InstrProfileOutput,
"", "", opts.MemoryProfileUsePath, llvm::PGOOptions::IRInstr,
llvm::PGOOptions::NoCSAction, llvm::PGOOptions::ColdFuncOpt::Default,
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 0dfced91c511dd..5f2c541bdd2fd9 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -45,6 +45,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/LibraryOptionsContext.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
@@ -1562,7 +1563,7 @@ static void codegenDataGenerate() {
}
}
- globalMergeRecord.finalize();
+ globalMergeRecord.finalize(cl::LibraryOptionsContext());
CodeGenDataWriter Writer;
if (!globalOutlineRecord.empty())
diff --git a/llvm/include/llvm/CGData/CodeGenData.h b/llvm/include/llvm/CGData/CodeGenData.h
index cd1d849fdc1551..c1919428fa1d07 100644
--- a/llvm/include/llvm/CGData/CodeGenData.h
+++ b/llvm/include/llvm/CGData/CodeGenData.h
@@ -30,6 +30,10 @@
namespace llvm {
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
+
enum CGDataSectKind {
#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind,
#include "llvm/CGData/CodeGenData.inc"
@@ -131,7 +135,9 @@ class CodeGenData {
public:
~CodeGenData() = default;
- LLVM_ABI static CodeGenData &getInstance();
+ /// The first call's \p LibraryOptions configure the singleton.
+ LLVM_ABI static CodeGenData &
+ getInstance(const cl::LibraryOptionsContext &LibraryOptions);
/// Returns true if we have a valid outlined hash tree.
bool hasOutlinedHashTree() {
@@ -169,32 +175,42 @@ class CodeGenData {
namespace cgdata {
-inline bool hasOutlinedHashTree() {
- return CodeGenData::getInstance().hasOutlinedHashTree();
+inline bool
+hasOutlinedHashTree(const cl::LibraryOptionsContext &LibraryOptions) {
+ return CodeGenData::getInstance(LibraryOptions).hasOutlinedHashTree();
}
-inline bool hasStableFunctionMap() {
- return CodeGenData::getInstance().hasStableFunctionMap();
+inline bool
+hasStableFunctionMap(const cl::LibraryOptionsContext &LibraryOptions) {
+ return CodeGenData::getInstance(LibraryOptions).hasStableFunctionMap();
}
-inline const OutlinedHashTree *getOutlinedHashTree() {
- return CodeGenData::getInstance().getOutlinedHashTree();
+inline const OutlinedHashTree *
+getOutlinedHashTree(const cl::LibraryOptionsContext &LibraryOptions) {
+ return CodeGenData::getInstance(LibraryOptions).getOutlinedHashTree();
}
-inline const StableFunctionMap *getStableFunctionMap() {
- return CodeGenData::getInstance().getStableFunctionMap();
+inline const StableFunctionMap *
+getStableFunctionMap(const cl::LibraryOptionsContext &LibraryOptions) {
+ return CodeGenData::getInstance(LibraryOptions).getStableFunctionMap();
}
-inline bool emitCGData() { return CodeGenData::getInstance().emitCGData(); }
+inline bool emitCGData(const cl::LibraryOptionsContext &LibraryOptions) {
+ return CodeGenData::getInstance(LibraryOptions).emitCGData();
+}
inline void
-publishOutlinedHashTree(std::unique_ptr<OutlinedHashTree> HashTree) {
- CodeGenData::getInstance().publishOutlinedHashTree(std::move(HashTree));
+publishOutlinedHashTree(const cl::LibraryOptionsContext &LibraryOptions,
+ std::unique_ptr<OutlinedHashTree> HashTree) {
+ CodeGenData::getInstance(LibraryOptions)
+ .publishOutlinedHashTree(std::move(HashTree));
}
inline void
-publishStableFunctionMap(std::unique_ptr<StableFunctionMap> FunctionMap) {
- CodeGenData::getInstance().publishStableFunctionMap(std::move(FunctionMap));
+publishStableFunctionMap(const cl::LibraryOptionsContext &LibraryOptions,
+ std::unique_ptr<StableFunctionMap> FunctionMap) {
+ CodeGenData::getInstance(LibraryOptions)
+ .publishStableFunctionMap(std::move(FunctionMap));
}
struct StreamCacheData {
@@ -244,7 +260,7 @@ struct StreamCacheData {
/// Returns whether ThinLTO runs two rounds of code generation
/// (-codegen-data-thinlto-two-rounds).
-LLVM_ABI bool thinLTOTwoRounds();
+LLVM_ABI bool thinLTOTwoRounds(const cl::LibraryOptionsContext &LibraryOptions);
/// Save \p TheModule before the first codegen round.
/// \p Task represents the partition number in the parallel code generation
@@ -267,7 +283,8 @@ loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task,
/// first codegen round.
/// \return the combined hash of the merged codegen data.
LLVM_ABI Expected<stable_hash>
-mergeCodeGenData(ArrayRef<StringRef> ObjectFiles);
+mergeCodeGenData(const cl::LibraryOptionsContext &LibraryOptions,
+ ArrayRef<StringRef> ObjectFiles);
LLVM_ABI void warn(Error E, StringRef Whence = "");
LLVM_ABI void warn(Twine Message, StringRef Whence = "", StringRef Hint = "");
diff --git a/llvm/include/llvm/CGData/CodeGenDataReader.h b/llvm/include/llvm/CGData/CodeGenDataReader.h
index 94f7af2de17012..0b827cd97c08b5 100644
--- a/llvm/include/llvm/CGData/CodeGenDataReader.h
+++ b/llvm/include/llvm/CGData/CodeGenDataReader.h
@@ -52,12 +52,14 @@ class CodeGenDataReader {
/// codegen data file path and file system. \p LazyLoading defers
/// deserializing the stable function map of indexed codegen data.
LLVM_ABI static Expected<std::unique_ptr<CodeGenDataReader>>
- create(const Twine &Path, vfs::FileSystem &FS, bool LazyLoading = false);
+ create(const cl::LibraryOptionsContext &LibraryOptions, const Twine &Path,
+ vfs::FileSystem &FS, bool LazyLoading = false);
/// Factory method to create an appropriately typed reader for the given
/// memory buffer.
LLVM_ABI static Expected<std::unique_ptr<CodeGenDataReader>>
- create(std::unique_ptr<MemoryBuffer> Buffer, bool LazyLoading = false);
+ create(const cl::LibraryOptionsContext &LibraryOptions,
+ std::unique_ptr<MemoryBuffer> Buffer, bool LazyLoading = false);
/// Extract the cgdata embedded in sections from the given object file and
/// merge them into the GlobalOutlineRecord. This is a static helper that
@@ -101,6 +103,7 @@ class CodeGenDataReader {
};
class LLVM_ABI IndexedCodeGenDataReader : public CodeGenDataReader {
+ bool ReadStableFunctionMapNames;
/// The codegen data file contents.
std::unique_ptr<MemoryBuffer> DataBuffer;
/// The header
@@ -108,9 +111,11 @@ class LLVM_ABI IndexedCodeGenDataReader : public CodeGenDataReader {
bool LazyLoading;
public:
- IndexedCodeGenDataReader(std::unique_ptr<MemoryBuffer> DataBuffer,
+ IndexedCodeGenDataReader(bool ReadStableFunctionMapNames,
+ std::unique_ptr<MemoryBuffer> DataBuffer,
bool LazyLoading = false)
- : DataBuffer(std::move(DataBuffer)), LazyLoading(LazyLoading) {}
+ : ReadStableFunctionMapNames(ReadStableFunctionMapNames),
+ DataBuffer(std::move(DataBuffer)), LazyLoading(LazyLoading) {}
IndexedCodeGenDataReader(const IndexedCodeGenDataReader &) = delete;
IndexedCodeGenDataReader &
operator=(const IndexedCodeGenDataReader &) = delete;
diff --git a/llvm/include/llvm/CGData/StableFunctionMap.h b/llvm/include/llvm/CGData/StableFunctionMap.h
index 909d0e1debe7e6..b9be47177c9a31 100644
--- a/llvm/include/llvm/CGData/StableFunctionMap.h
+++ b/llvm/include/llvm/CGData/StableFunctionMap.h
@@ -26,6 +26,10 @@
namespace llvm {
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
+
using IndexPairHash = std::pair<IndexPair, stable_hash>;
using IndexOperandHashVecType = SmallVector<IndexPairHash>;
@@ -153,7 +157,8 @@ struct StableFunctionMap {
LLVM_ABI size_t size(SizeType Type = UniqueHashCount) const;
/// Finalize the stable function map by trimming content.
- LLVM_ABI void finalize(bool SkipTrim = false);
+ LLVM_ABI void finalize(const cl::LibraryOptionsContext &LibraryOptions,
+ bool SkipTrim = false);
private:
/// Insert a `StableFunctionEntry` into the function map directly. This
diff --git a/llvm/include/llvm/CGData/StableFunctionMapRecord.h b/llvm/include/llvm/CGData/StableFunctionMapRecord.h
index 2d8b573a3cb467..24e7ef1af2ea81 100644
--- a/llvm/include/llvm/CGData/StableFunctionMapRecord.h
+++ b/llvm/include/llvm/CGData/StableFunctionMapRecord.h
@@ -87,7 +87,10 @@ struct StableFunctionMapRecord {
LLVM_ABI void deserializeYAML(yaml::Input &YIS);
/// Finalize the stable function map by trimming content.
- void finalize(bool SkipTrim = false) { FunctionMap->finalize(SkipTrim); }
+ void finalize(const cl::LibraryOptionsContext &LibraryOptions,
+ bool SkipTrim = false) {
+ FunctionMap->finalize(LibraryOptions, SkipTrim);
+ }
/// Merge the stable function map into this one.
void merge(const StableFunctionMapRecord &Other) {
diff --git a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
index 77ab477986d31c..3d292139cb7d06 100644
--- a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
+++ b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
@@ -20,6 +20,9 @@ namespace llvm {
class Triple;
class TargetLibraryInfoImpl;
enum class VectorLibrary;
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
} // namespace llvm
namespace llvm::driver {
@@ -67,7 +70,8 @@ enum ProfileInstrKind {
};
// Default filename used for profile generation.
-LLVM_ABI std::string getDefaultProfileGenName();
+LLVM_ABI std::string
+getDefaultProfileGenName(const cl::LibraryOptionsContext &LibraryOptions);
} // end namespace llvm::driver
#endif
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 502dfd93842bea..2dd74624b424e3 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -37,13 +37,24 @@ class AAManager;
class TargetMachine;
class ModuleSummaryIndex;
struct PassesOptions;
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
/// Tunable parameters for passes in the default pipelines.
class PipelineTuningOptions {
public:
- /// Constructor sets pipeline tuning defaults based on cl::opts. Each option
- /// can be set in the PassBuilder when using a LLVM as a library.
- LLVM_ABI PipelineTuningOptions();
+ /// Constructor sets pipeline tuning defaults based on the global values of
+ /// the library options. Each option can be set in the PassBuilder when using
+ /// a LLVM as a library.
+ PipelineTuningOptions() : PipelineTuningOptions(nullptr) {}
+
+ /// Reads the defaults from \p LibraryOptions, or their global values if
+ /// null.
+ LLVM_ABI explicit PipelineTuningOptions(
+ const cl::LibraryOptionsContext *LibraryOptions);
+
+ const cl::LibraryOptionsContext *LibraryOptions;
/// Tuning option to set loop interleaving on/off, set based on opt level.
bool LoopInterleaving;
@@ -118,6 +129,7 @@ enum class PrintPipelinePassesFormat {
/// of the built-in passes, and those may reference these members during
/// construction.
class PassBuilder {
+ const cl::LibraryOptionsContext *LibraryOptions;
const PassesOptions &Opts;
TargetMachine *TM;
PipelineTuningOptions PTO;
@@ -674,6 +686,13 @@ class PassBuilder {
return PIC;
}
+ /// Returns the library options the pipelines read: the
+ /// PipelineTuningOptions', else the TargetMachine's, else null for the global
+ /// values.
+ const cl::LibraryOptionsContext *getLibraryOptions() const {
+ return LibraryOptions;
+ }
+
/// Returns the virtual file system.
IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystemPtr() const {
return FS;
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index d485ea78f462a1..1c378941cc1259 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -43,6 +43,7 @@ class Function;
class MachineFunction;
class PassInstrumentationCallbacks;
struct ExtendedIRContext;
+struct PassesOptions;
/// Instrumentation to print IR before/after passes.
///
@@ -50,6 +51,7 @@ struct ExtendedIRContext;
/// (typically Loop or SCC).
class PrintIRInstrumentation {
public:
+ explicit PrintIRInstrumentation(const PassesOptions &Opts) : Opts(Opts) {}
LLVM_ABI ~PrintIRInstrumentation();
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC,
@@ -98,6 +100,7 @@ class PrintIRInstrumentation {
unsigned PassNumber,
IRDumpFileSuffixType SuffixType);
+ const PassesOptions &Opts;
PassInstrumentationCallbacks *PIC;
/// Stack of Pass Run descriptions, enough to print the IR unit after a given
/// pass.
@@ -121,10 +124,12 @@ class OptNoneInstrumentation {
};
class OptPassGateInstrumentation {
+ const PassesOptions &Opts;
LLVMContext &Context;
bool HasWrittenIR = false;
public:
- OptPassGateInstrumentation(LLVMContext &Context) : Context(Context) {}
+ OptPassGateInstrumentation(const PassesOptions &Opts, LLVMContext &Context)
+ : Opts(Opts), Context(Context) {}
LLVM_ABI bool shouldRun(StringRef PassName, IRUnitRef IR);
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC,
ExtendedIRContext *IRContext = nullptr);
@@ -161,6 +166,9 @@ class PrintPassInstrumentation {
class PreservedCFGCheckerInstrumentation {
public:
+ explicit PreservedCFGCheckerInstrumentation(const PassesOptions &Opts)
+ : Opts(Opts) {}
+
// Keeps sticky poisoned flag for the given basic block once it has been
// deleted or RAUWed.
struct BBGuard final : public CallbackVH {
@@ -206,6 +214,9 @@ class PreservedCFGCheckerInstrumentation {
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC,
ModuleAnalysisManager &MAM);
+
+private:
+ const PassesOptions &Opts;
};
class ExtendedIRTraits {
@@ -336,12 +347,14 @@ class LLVM_ABI TextChangeReporter : public ChangeReporter<IRUnitT> {
// included in this representation but it is massaged before reporting.
class LLVM_ABI IRChangedPrinter : public TextChangeReporter<std::string> {
public:
- IRChangedPrinter(bool VerboseMode)
- : TextChangeReporter<std::string>(VerboseMode) {}
+ IRChangedPrinter(const PassesOptions &Opts, bool VerboseMode)
+ : TextChangeReporter<std::string>(VerboseMode), Opts(Opts) {}
~IRChangedPrinter() override;
void registerCallbacks(PassInstrumentationCallbacks &PIC);
protected:
+ const PassesOptions &Opts;
+
// Called before and after a pass to get the representation of the IR.
void generateIRRepresentation(IRUnitRef IR, StringRef PassID,
std::string &Output) override;
@@ -353,7 +366,8 @@ class LLVM_ABI IRChangedPrinter : public TextChangeReporter<std::string> {
class LLVM_ABI IRChangedTester : public IRChangedPrinter {
public:
- IRChangedTester() : IRChangedPrinter(true) {}
+ explicit IRChangedTester(const PassesOptions &Opts)
+ : IRChangedPrinter(Opts, true) {}
~IRChangedTester() override;
void registerCallbacks(PassInstrumentationCallbacks &PIC);
@@ -590,7 +604,7 @@ class DCData {
// dot control flow graphs with changed instructions shown in colour.
class LLVM_ABI DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
public:
- DotCfgChangeReporter(bool Verbose);
+ DotCfgChangeReporter(const PassesOptions &Opts, bool Verbose);
~DotCfgChangeReporter() override;
void registerCallbacks(PassInstrumentationCallbacks &PIC);
@@ -626,6 +640,7 @@ class LLVM_ABI DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
const FuncDataT<DCData> &Before,
const FuncDataT<DCData> &After);
+ const PassesOptions &Opts;
unsigned N = 0;
// -dot-cfg-dir with ~ expanded, made absolute.
std::string OutputDir;
@@ -635,13 +650,14 @@ class LLVM_ABI DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
// Print IR on crash.
class PrintCrashIRInstrumentation {
public:
- PrintCrashIRInstrumentation()
- : SavedIR("*** Dump of IR Before Last Pass Unknown ***") {}
+ explicit PrintCrashIRInstrumentation(const PassesOptions &Opts)
+ : Opts(Opts), SavedIR("*** Dump of IR Before Last Pass Unknown ***") {}
LLVM_ABI ~PrintCrashIRInstrumentation();
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC);
LLVM_ABI void reportCrashIR();
protected:
+ const PassesOptions &Opts;
std::string SavedIR;
private:
@@ -654,6 +670,7 @@ class PrintCrashIRInstrumentation {
/// This class provides an interface to register all the standard pass
/// instrumentations and manages their state (if any).
class StandardInstrumentations {
+ const PassesOptions &Opts;
PrintIRInstrumentation PrintIR;
PrintPassInstrumentation PrintPass;
TimePassesHandler TimePasses;
diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
index f8635154e486b1..839ef752aec3b0 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
@@ -24,7 +24,8 @@
namespace llvm {
// Get AddressSanitizer parameters.
-LLVM_ABI void getAddressSanitizerParams(const Triple &TargetTriple,
+LLVM_ABI void getAddressSanitizerParams(const LLVMContext &Ctx,
+ const Triple &TargetTriple,
int LongSize, bool IsKasan,
uint64_t *ShadowBase, int *MappingScale,
bool *OrShadowOffset);
diff --git a/llvm/include/llvm/Transforms/Instrumentation/ControlHeightReduction.h b/llvm/include/llvm/Transforms/Instrumentation/ControlHeightReduction.h
index b3bda90550037a..716a50afbe598b 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/ControlHeightReduction.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/ControlHeightReduction.h
@@ -14,15 +14,21 @@
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_CONTROLHEIGHTREDUCTION_H
#define LLVM_TRANSFORMS_INSTRUMENTATION_CONTROLHEIGHTREDUCTION_H
+#include "llvm/ADT/StringSet.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+struct InstrumentationOptions;
+
class ControlHeightReductionPass
: public OptionalPassInfoMixin<ControlHeightReductionPass> {
public:
- LLVM_ABI ControlHeightReductionPass();
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+
+private:
+ const InstrumentationOptions *ParsedOpts = nullptr;
+ StringSet<> CHRModules, CHRFunctions;
};
} // end namespace llvm
diff --git a/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h b/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h
index 4d1688cc1676f1..2a76433f438e8b 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h
@@ -16,19 +16,20 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Transforms/Utils/Instrumentation.h"
+#include <optional>
namespace llvm {
/// The gcov-style instrumentation pass
class GCOVProfilerPass : public OptionalPassInfoMixin<GCOVProfilerPass> {
public:
GCOVProfilerPass(
- const GCOVOptions &Options = GCOVOptions::getDefault(),
+ std::optional<GCOVOptions> Options = std::nullopt,
IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem())
: GCOVOpts(Options), VFS(std::move(VFS)) {}
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
private:
- GCOVOptions GCOVOpts;
+ std::optional<GCOVOptions> GCOVOpts;
IntrusiveRefCntPtr<vfs::FileSystem> VFS;
};
diff --git a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
index 9d4c40b25cd19a..c3d9f406d1776c 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
@@ -20,6 +20,9 @@
namespace llvm {
class TargetLibraryInfo;
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
/// Instrumentation based profiling lowering pass. This pass lowers
/// the profile instrumented code generated by FE or the IR based
/// instrumentation pass.
@@ -38,7 +41,8 @@ class InstrProfilingLoweringPass
};
/// Return true if -profile-correlate is set.
-LLVM_ABI bool isProfileCorrelationEnabled();
+LLVM_ABI bool
+isProfileCorrelationEnabled(const cl::LibraryOptionsContext &LibraryOptions);
} // end namespace llvm
#endif // LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H
diff --git a/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h b/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h
index cf5fe6d2ab5067..62a58fc6490833 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h
@@ -21,6 +21,10 @@
namespace llvm {
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
+
// This pass is responsible for removing optional traps, like llvm.ubsantrap
// from the hot code.
class LowerAllowCheckPass : public RequiredPassInfoMixin<LowerAllowCheckPass> {
@@ -34,7 +38,8 @@ class LowerAllowCheckPass : public RequiredPassInfoMixin<LowerAllowCheckPass> {
: Opts(std::move(Opts)) {};
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- LLVM_ABI static bool IsRequested();
+ LLVM_ABI static bool
+ isRequested(const cl::LibraryOptionsContext &LibraryOptions);
LLVM_ABI void
printPipeline(raw_ostream &OS,
function_ref<StringRef(StringRef)> MapClassName2PassName);
diff --git a/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h
index b42f2e21aa52f4..33713f7aec2d05 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Compiler.h"
+#include <optional>
namespace llvm {
class Module;
@@ -32,6 +33,11 @@ struct MemorySanitizerOptions {
int TrackOrigins;
bool Recover;
bool EagerChecks;
+ // msan<...> parameters, which override the -msan-* options.
+ std::optional<bool> KernelParam;
+ std::optional<int> TrackOriginsParam;
+ std::optional<bool> RecoverParam;
+ std::optional<bool> EagerChecksParam;
};
/// A module pass for msan instrumentation.
diff --git a/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h b/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
index 930c8bf9d96463..1d4c21d91a9b1f 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
@@ -15,13 +15,17 @@
#include "llvm/IR/PassManager.h"
namespace llvm {
class Type;
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
class PGOCtxProfLoweringPass
: public OptionalPassInfoMixin<PGOCtxProfLoweringPass> {
public:
explicit PGOCtxProfLoweringPass() = default;
// True if contextual instrumentation is enabled.
- LLVM_ABI static bool isCtxIRPGOInstrEnabled();
+ LLVM_ABI static bool
+ isCtxIRPGOInstrEnabled(const cl::LibraryOptionsContext *LibraryOptions);
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
};
diff --git a/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h b/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h
index 8f5c9d57d02d9d..af2e5373f1d6de 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h
@@ -111,8 +111,10 @@ LLVM_ABI void setProfMetadata(Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
LLVM_ABI void setIrrLoopHeaderMetadata(Module *M, Instruction *TI,
uint64_t Count);
-/// Return the value of -pgo-instrument-cold-function-only.
-LLVM_ABI bool isPGOInstrumentColdFunctionOnly();
+/// Return the value of -pgo-instrument-cold-function-only in LibraryOptions, or
+/// its global value if null.
+LLVM_ABI bool isPGOInstrumentColdFunctionOnly(
+ const cl::LibraryOptionsContext *LibraryOptions);
} // end namespace llvm
diff --git a/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h b/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
index 7a872ef1021b2c..f1ed7c6b042924 100644
--- a/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
+++ b/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
@@ -59,6 +59,7 @@ class Function;
class GlobalVariable;
class Instruction;
class ProfileSummaryInfo;
+struct ScalarOptions;
class TargetTransformInfo;
class TargetTransformInfo;
@@ -145,6 +146,7 @@ class ConstantHoistingPass
using ConstPtrUnionType = PointerUnion<ConstantInt *, ConstantExpr *>;
using ConstCandMapType = DenseMap<ConstPtrUnionType, unsigned>;
+ const ScalarOptions *Opts = nullptr;
const TargetTransformInfo *TTI;
DominatorTree *DT;
BlockFrequencyInfo *BFI;
diff --git a/llvm/include/llvm/Transforms/Scalar/LICM.h b/llvm/include/llvm/Transforms/Scalar/LICM.h
index 4cabf02cb3b154..7eb460e7b33599 100644
--- a/llvm/include/llvm/Transforms/Scalar/LICM.h
+++ b/llvm/include/llvm/Transforms/Scalar/LICM.h
@@ -34,27 +34,33 @@
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/PassManager.h"
+#include <optional>
namespace llvm {
class LPMUpdater;
class Loop;
class LoopNest;
-
-/// Returns -licm-mssa-optimization-cap.
-LLVM_ABI unsigned getLicmMssaOptCap();
-/// Returns -licm-mssa-max-acc-promotion.
-LLVM_ABI unsigned getLicmMssaNoAccForPromotionCap();
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
+
+/// Returns -licm-mssa-optimization-cap of LibraryOptions, or its global value
+/// if null.
+LLVM_ABI unsigned
+getLicmMssaOptCap(const cl::LibraryOptionsContext *LibraryOptions);
+/// Returns -licm-mssa-max-acc-promotion of LibraryOptions, or its global value
+/// if null.
+LLVM_ABI unsigned getLicmMssaNoAccForPromotionCap(
+ const cl::LibraryOptionsContext *LibraryOptions);
struct LICMOptions {
- unsigned MssaOptCap;
- unsigned MssaNoAccForPromotionCap;
+ // Unset means the -licm-mssa-* value of the loop's LLVMContext.
+ std::optional<unsigned> MssaOptCap;
+ std::optional<unsigned> MssaNoAccForPromotionCap;
bool AllowSpeculation;
- LICMOptions()
- : MssaOptCap(getLicmMssaOptCap()),
- MssaNoAccForPromotionCap(getLicmMssaNoAccForPromotionCap()),
- AllowSpeculation(true) {}
+ LICMOptions() : AllowSpeculation(true) {}
LICMOptions(unsigned MssaOptCap, unsigned MssaNoAccForPromotionCap,
bool AllowSpeculation)
diff --git a/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h b/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h
index 9d2b221b9ad73f..7955d8f79dc5c0 100644
--- a/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h
+++ b/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h
@@ -15,8 +15,14 @@
namespace llvm {
-/// Returns -forget-scev-loop-unroll.
-LLVM_ABI bool getForgetSCEVInLoopUnroll();
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
+
+/// Returns -forget-scev-loop-unroll of LibraryOptions, or its global value if
+/// null.
+LLVM_ABI bool
+getForgetSCEVInLoopUnroll(const cl::LibraryOptionsContext *LibraryOptions);
class Function;
class Loop;
diff --git a/llvm/include/llvm/Transforms/Scalar/Reassociate.h b/llvm/include/llvm/Transforms/Scalar/Reassociate.h
index a261d0b9baf026..db6c34fc6571bb 100644
--- a/llvm/include/llvm/Transforms/Scalar/Reassociate.h
+++ b/llvm/include/llvm/Transforms/Scalar/Reassociate.h
@@ -97,6 +97,7 @@ class ReassociatePass : public OptionalPassInfoMixin<ReassociatePass> {
bool MadeChange;
UniformityInfo *UA = nullptr;
+ bool UseCSELocal = false;
public:
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
diff --git a/llvm/include/llvm/Transforms/Scalar/SpeculativeExecution.h b/llvm/include/llvm/Transforms/Scalar/SpeculativeExecution.h
index b0e2bff1e6c646..753e5c7a423d7d 100644
--- a/llvm/include/llvm/Transforms/Scalar/SpeculativeExecution.h
+++ b/llvm/include/llvm/Transforms/Scalar/SpeculativeExecution.h
@@ -66,6 +66,7 @@
namespace llvm {
class BasicBlock;
+struct ScalarOptions;
class TargetTransformInfo;
class SpeculativeExecutionPass
@@ -86,6 +87,8 @@ class SpeculativeExecutionPass
bool runOnBasicBlock(BasicBlock &B);
bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);
+ const ScalarOptions *Opts = nullptr;
+
// If true, this pass is a nop unless the target architecture has branch
// divergence.
const bool OnlyIfDivergentTarget = false;
diff --git a/llvm/include/llvm/Transforms/Utils/Instrumentation.h b/llvm/include/llvm/Transforms/Utils/Instrumentation.h
index 8405245b2bc0ac..9945ef5665e9be 100644
--- a/llvm/include/llvm/Transforms/Utils/Instrumentation.h
+++ b/llvm/include/llvm/Transforms/Utils/Instrumentation.h
@@ -62,8 +62,6 @@ LLVM_ABI void setGlobalVariableLargeSection(const Triple &TargetTriple,
// Insert GCOV profiling instrumentation
struct GCOVOptions {
- LLVM_ABI static GCOVOptions getDefault();
-
// Specify whether to emit .gcno files.
bool EmitNotes;
diff --git a/llvm/lib/CGData/CGDataOptions.td b/llvm/lib/CGData/CGDataOptions.td
index 0e4cbdcc005bac..025e91f5bca236 100644
--- a/llvm/lib/CGData/CGDataOptions.td
+++ b/llvm/lib/CGData/CGDataOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def CGDataOptions : OptionsStruct<perContext = false>;
+def CGDataOptions : OptionsStruct;
defm : BoolField<"codegen-data-generate", "false",
"Emit CodeGen Data into custom sections">;
diff --git a/llvm/lib/CGData/CodeGenData.cpp b/llvm/lib/CGData/CodeGenData.cpp
index d27ac5a589fea5..aab15ae700c104 100644
--- a/llvm/lib/CGData/CodeGenData.cpp
+++ b/llvm/lib/CGData/CodeGenData.cpp
@@ -108,8 +108,9 @@ const char *CodeGenDataSectNamePrefix[] = {
} // namespace
-bool llvm::cgdata::thinLTOTwoRounds() {
- return CGDataOptions::Global.codegen_data_thinlto_two_rounds;
+bool llvm::cgdata::thinLTOTwoRounds(
+ const cl::LibraryOptionsContext &LibraryOptions) {
+ return LibraryOptions.get<CGDataOptions>().codegen_data_thinlto_two_rounds;
}
namespace llvm {
@@ -133,11 +134,12 @@ std::string getCodeGenDataSectionName(CGDataSectKind CGSK,
std::unique_ptr<CodeGenData> CodeGenData::Instance = nullptr;
std::once_flag CodeGenData::OnceFlag;
-CodeGenData &CodeGenData::getInstance() {
- std::call_once(CodeGenData::OnceFlag, []() {
+CodeGenData &
+CodeGenData::getInstance(const cl::LibraryOptionsContext &LibraryOptions) {
+ std::call_once(CodeGenData::OnceFlag, [&LibraryOptions]() {
Instance = std::unique_ptr<CodeGenData>(new CodeGenData());
- const CGDataOptions &Opts = CGDataOptions::Global;
+ const CGDataOptions &Opts = LibraryOptions.get<CGDataOptions>();
if (Opts.codegen_data_generate || Opts.codegen_data_thinlto_two_rounds)
Instance->EmitCGData = true;
else if (!Opts.codegen_data_use_path.empty()) {
@@ -146,9 +148,9 @@ CodeGenData &CodeGenData::getInstance() {
// Instead, just emit an warning message and fall back as if no CGData
// were available.
auto FS = vfs::getRealFileSystem();
- auto ReaderOrErr =
- CodeGenDataReader::create(Opts.codegen_data_use_path, *FS,
- Opts.indexed_codegen_data_lazy_loading);
+ auto ReaderOrErr = CodeGenDataReader::create(
+ LibraryOptions, Opts.codegen_data_use_path, *FS,
+ Opts.indexed_codegen_data_lazy_loading);
if (Error E = ReaderOrErr.takeError()) {
warn(std::move(E), Opts.codegen_data_use_path);
return;
@@ -250,7 +252,9 @@ std::unique_ptr<Module> loadModuleForTwoRounds(BitcodeModule &OrigModule,
return std::move(*RestoredModule);
}
-Expected<stable_hash> mergeCodeGenData(ArrayRef<StringRef> ObjFiles) {
+Expected<stable_hash>
+mergeCodeGenData(const cl::LibraryOptionsContext &LibraryOptions,
+ ArrayRef<StringRef> ObjFiles) {
OutlinedHashTreeRecord GlobalOutlineRecord;
StableFunctionMapRecord GlobalStableFunctionMapRecord;
stable_hash CombinedHash = 0;
@@ -271,13 +275,14 @@ Expected<stable_hash> mergeCodeGenData(ArrayRef<StringRef> ObjFiles) {
return E;
}
- GlobalStableFunctionMapRecord.finalize();
+ GlobalStableFunctionMapRecord.finalize(LibraryOptions);
if (!GlobalOutlineRecord.empty())
- cgdata::publishOutlinedHashTree(std::move(GlobalOutlineRecord.HashTree));
+ cgdata::publishOutlinedHashTree(LibraryOptions,
+ std::move(GlobalOutlineRecord.HashTree));
if (!GlobalStableFunctionMapRecord.empty())
cgdata::publishStableFunctionMap(
- std::move(GlobalStableFunctionMapRecord.FunctionMap));
+ LibraryOptions, std::move(GlobalStableFunctionMapRecord.FunctionMap));
return CombinedHash;
}
diff --git a/llvm/lib/CGData/CodeGenDataReader.cpp b/llvm/lib/CGData/CodeGenDataReader.cpp
index 5e6fb34dce21b4..46f4e863264433 100644
--- a/llvm/lib/CGData/CodeGenDataReader.cpp
+++ b/llvm/lib/CGData/CodeGenDataReader.cpp
@@ -110,8 +110,7 @@ Error IndexedCodeGenDataReader::read() {
const unsigned char *Ptr = Start + Header.StableFunctionMapOffset;
if (Ptr >= End)
return error(cgdata_error::eof);
- FunctionMapRecord.setReadStableFunctionMapNames(
- CGDataOptions::Global.indexed_codegen_data_read_function_map_names);
+ FunctionMapRecord.setReadStableFunctionMapNames(ReadStableFunctionMapNames);
if (LazyLoading)
FunctionMapRecord.lazyDeserialize(std::move(SharedDataBuffer),
Header.StableFunctionMapOffset);
@@ -123,17 +122,20 @@ Error IndexedCodeGenDataReader::read() {
}
Expected<std::unique_ptr<CodeGenDataReader>>
-CodeGenDataReader::create(const Twine &Path, vfs::FileSystem &FS,
+CodeGenDataReader::create(const cl::LibraryOptionsContext &LibraryOptions,
+ const Twine &Path, vfs::FileSystem &FS,
bool LazyLoading) {
// Set up the buffer to read.
auto BufferOrError = setupMemoryBuffer(Path, FS);
if (Error E = BufferOrError.takeError())
return std::move(E);
- return CodeGenDataReader::create(std::move(BufferOrError.get()), LazyLoading);
+ return CodeGenDataReader::create(LibraryOptions,
+ std::move(BufferOrError.get()), LazyLoading);
}
Expected<std::unique_ptr<CodeGenDataReader>>
-CodeGenDataReader::create(std::unique_ptr<MemoryBuffer> Buffer,
+CodeGenDataReader::create(const cl::LibraryOptionsContext &LibraryOptions,
+ std::unique_ptr<MemoryBuffer> Buffer,
bool LazyLoading) {
if (Buffer->getBufferSize() == 0)
return make_error<CGDataError>(cgdata_error::empty_cgdata);
@@ -141,8 +143,10 @@ CodeGenDataReader::create(std::unique_ptr<MemoryBuffer> Buffer,
std::unique_ptr<CodeGenDataReader> Reader;
// Create the reader.
if (IndexedCodeGenDataReader::hasFormat(*Buffer))
- Reader = std::make_unique<IndexedCodeGenDataReader>(std::move(Buffer),
- LazyLoading);
+ Reader = std::make_unique<IndexedCodeGenDataReader>(
+ LibraryOptions.get<CGDataOptions>()
+ .indexed_codegen_data_read_function_map_names,
+ std::move(Buffer), LazyLoading);
else if (TextCodeGenDataReader::hasFormat(*Buffer))
Reader = std::make_unique<TextCodeGenDataReader>(std::move(Buffer));
else
diff --git a/llvm/lib/CGData/StableFunctionMap.cpp b/llvm/lib/CGData/StableFunctionMap.cpp
index b8b8cfd1286ae1..4b3a82c87f164e 100644
--- a/llvm/lib/CGData/StableFunctionMap.cpp
+++ b/llvm/lib/CGData/StableFunctionMap.cpp
@@ -161,8 +161,8 @@ removeIdenticalIndexPair(StableFunctionMap::StableFunctionEntries &SFS) {
SF->IndexOperandHashMap->erase(Pair);
}
-static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS) {
- const CGDataOptions &Opts = CGDataOptions::Global;
+static bool isProfitable(const CGDataOptions &Opts,
+ const StableFunctionMap::StableFunctionEntries &SFS) {
unsigned StableFunctionCount = SFS.size();
if (StableFunctionCount < Opts.global_merging_min_merges)
return false;
@@ -203,7 +203,9 @@ static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS) {
return Result;
}
-void StableFunctionMap::finalize(bool SkipTrim) {
+void StableFunctionMap::finalize(
+ const cl::LibraryOptionsContext &LibraryOptions, bool SkipTrim) {
+ const CGDataOptions &Opts = LibraryOptions.get<CGDataOptions>();
deserializeLazyLoadingEntries();
SmallVector<HashFuncsMapType::iterator> ToDelete;
for (auto It = HashToFuncs.begin(); It != HashToFuncs.end(); ++It) {
@@ -252,7 +254,7 @@ void StableFunctionMap::finalize(bool SkipTrim) {
// stable functions.
removeIdenticalIndexPair(SFS);
- if (!isProfitable(SFS))
+ if (!isProfitable(Opts, SFS))
ToDelete.push_back(It);
}
for (auto It : ToDelete)
diff --git a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
index e13d7b47600fde..1b9cf2d528a0ec 100644
--- a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
+++ b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
@@ -535,9 +535,11 @@ void GlobalMergeFunc::initializeMergerMode(const Module &M) {
if (Index && !Index->hasExportedFunctions(M))
return;
- if (cgdata::emitCGData())
+ const cl::LibraryOptionsContext &LibraryOptions =
+ M.getContext().getLibraryOptions();
+ if (cgdata::emitCGData(LibraryOptions))
MergerMode = HashFunctionMode::BuildingHashFuncion;
- else if (cgdata::hasStableFunctionMap())
+ else if (cgdata::hasStableFunctionMap(LibraryOptions))
MergerMode = HashFunctionMode::UsingHashFunction;
}
@@ -566,18 +568,20 @@ void GlobalMergeFunc::emitFunctionMap(Module &M) {
bool GlobalMergeFunc::run(Module &M) {
initializeMergerMode(M);
+ const cl::LibraryOptionsContext &LibraryOptions =
+ M.getContext().getLibraryOptions();
const StableFunctionMap *FuncMap;
if (MergerMode == HashFunctionMode::UsingHashFunction) {
// Use the prior CG data to optimistically create global merge candidates.
- FuncMap = cgdata::getStableFunctionMap();
+ FuncMap = cgdata::getStableFunctionMap(LibraryOptions);
} else {
analyze(M);
// Emit the local function map to the custom section, __llvm_merge before
// finalizing it.
if (MergerMode == HashFunctionMode::BuildingHashFuncion)
emitFunctionMap(M);
- LocalFunctionMap->finalize();
+ LocalFunctionMap->finalize(LibraryOptions);
FuncMap = LocalFunctionMap.get();
}
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 540c9c8b018da1..5251ee13683b23 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -683,8 +683,10 @@ static SmallVector<MatchedEntry> getMatchedEntries(InstructionMapper &Mapper) {
auto Size = UnsignedVec.size();
// Get the global outlined hash tree built from the previous run.
- assert(cgdata::hasOutlinedHashTree());
- const auto *RootNode = cgdata::getOutlinedHashTree()->getRoot();
+ const cl::LibraryOptionsContext &LibraryOptions =
+ Mapper.MMI.getModule()->getContext().getLibraryOptions();
+ assert(cgdata::hasOutlinedHashTree(LibraryOptions));
+ const auto *RootNode = cgdata::getOutlinedHashTree(LibraryOptions)->getRoot();
auto getValidInstr = [&](unsigned Index) -> const MachineInstr * {
if (UnsignedVec[Index] >= Mapper.LegalInstrNumber)
@@ -1537,12 +1539,14 @@ void MachineOutliner::initializeOutlinerMode(const Module &M) {
// hash tree to the custom section, `__llvm_outline`.
// When the outlined hash tree is available from the previous codegen data,
// we want to read it to optimistically create global outlining candidates.
- if (cgdata::emitCGData()) {
+ const cl::LibraryOptionsContext &LibraryOptions =
+ M.getContext().getLibraryOptions();
+ if (cgdata::emitCGData(LibraryOptions)) {
OutlinerMode = CGDataMode::Write;
// Create a local outlined hash tree to be published.
LocalHashTree = std::make_unique<OutlinedHashTree>();
// We don't need to read the outlined hash tree from the previous codegen
- } else if (cgdata::hasOutlinedHashTree())
+ } else if (cgdata::hasOutlinedHashTree(LibraryOptions))
OutlinerMode = CGDataMode::Read;
}
diff --git a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
index e4d5317d68fc85..e893c15d76147f 100644
--- a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
+++ b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
@@ -45,8 +45,9 @@ TargetLibraryInfoImpl *createTLII(const llvm::Triple &TargetTriple,
TargetTriple, convertDriverVectorLibraryToVectorLibrary(Veclib));
}
-std::string getDefaultProfileGenName() {
- return isProfileCorrelationEnabled() ? "default_%m.proflite"
- : "default_%m.profraw";
+std::string
+getDefaultProfileGenName(const cl::LibraryOptionsContext &LibraryOptions) {
+ return isProfileCorrelationEnabled(LibraryOptions) ? "default_%m.proflite"
+ : "default_%m.profraw";
}
} // namespace llvm::driver
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 50232bf87d257d..e92c33a15e88aa 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -2296,7 +2296,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
return BackendProcess->wait();
};
- if (!cgdata::thinLTOTwoRounds()) {
+ if (!cgdata::thinLTOTwoRounds(RegularLTO.Ctx.getLibraryOptions())) {
std::unique_ptr<ThinBackendProc> BackendProc =
ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
AddStream, Cache, BitcodeLibFuncs);
@@ -2327,7 +2327,8 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
return E;
LLVM_DEBUG(dbgs() << "[TwoRounds] Merging codegen data\n");
- auto CombinedHashOrErr = cgdata::mergeCodeGenData(*CG.getResult());
+ auto CombinedHashOrErr = cgdata::mergeCodeGenData(
+ RegularLTO.Ctx.getLibraryOptions(), *CG.getResult());
if (Error E = CombinedHashOrErr.takeError())
return E;
auto CombinedHash = *CombinedHashOrErr;
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 96d18057a594d4..6eb5281513d125 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -570,8 +570,11 @@ PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
std::optional<PGOOptions> PGOOpt,
PassInstrumentationCallbacks *PIC,
IntrusiveRefCntPtr<vfs::FileSystem> FS)
- : Opts(PassesOptions::Global), TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC),
- FS(std::move(FS)) {
+ : LibraryOptions(PTO.LibraryOptions ? PTO.LibraryOptions
+ : TM ? TM->Options.MCOptions.LibraryOptions
+ : nullptr),
+ Opts(cl::LibraryOptionsContext::get<PassesOptions>(LibraryOptions)),
+ TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
if (TM)
TM->registerPassBuilderCallbacks(*this);
if (PIC) {
@@ -1162,19 +1165,21 @@ Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
std::tie(ParamName, Params) = Params.split(';');
if (ParamName == "recover") {
- Result.Recover = true;
+ Result.RecoverParam = true;
} else if (ParamName == "kernel") {
- Result.Kernel = true;
+ Result.KernelParam = true;
} else if (ParamName.consume_front("track-origins=")) {
- if (ParamName.getAsInteger(0, Result.TrackOrigins))
+ int TrackOrigins;
+ if (ParamName.getAsInteger(0, TrackOrigins))
return make_error<StringError>(
formatv("invalid argument to MemorySanitizer pass track-origins "
"parameter: '{}'",
ParamName)
.str(),
inconvertibleErrorCode());
+ Result.TrackOriginsParam = TrackOrigins;
} else if (ParamName == "eager-checks") {
- Result.EagerChecks = true;
+ Result.EagerChecksParam = true;
} else {
return make_error<StringError>(
formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 348f52fbe933f8..125c8e442f27b6 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -167,17 +167,21 @@ extern cl::opt<std::string> UseCtxProfile;
extern cl::opt<bool> EnableMemProfContextDisambiguation;
} // namespace llvm
-PipelineTuningOptions::PipelineTuningOptions() {
- const PassesOptions &Opts = PassesOptions::Global;
+PipelineTuningOptions::PipelineTuningOptions(
+ const cl::LibraryOptionsContext *LibraryOptions)
+ : LibraryOptions(LibraryOptions) {
+ const PassesOptions &Opts =
+ cl::LibraryOptionsContext::get<PassesOptions>(LibraryOptions);
LoopInterleaving = true;
LoopVectorization = true;
SLPVectorization = false;
LoopUnrolling = true;
LoopInterchange = Opts.enable_loopinterchange;
LoopFusion = false;
- ForgetAllSCEVInLoopUnroll = getForgetSCEVInLoopUnroll();
- LicmMssaOptCap = getLicmMssaOptCap();
- LicmMssaNoAccForPromotionCap = getLicmMssaNoAccForPromotionCap();
+ ForgetAllSCEVInLoopUnroll = getForgetSCEVInLoopUnroll(LibraryOptions);
+ LicmMssaOptCap = getLicmMssaOptCap(LibraryOptions);
+ LicmMssaNoAccForPromotionCap =
+ getLicmMssaNoAccForPromotionCap(LibraryOptions);
CallGraphProfile = true;
UnifiedLTO = false;
MergeFunctions = Opts.enable_merge_functions;
@@ -1127,7 +1131,8 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
const bool IsPreLink = !isThinLTOPostLink(Phase);
// Enable contextual profiling instrumentation.
const bool IsCtxProfGen =
- IsPreLink && PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled();
+ IsPreLink &&
+ PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(LibraryOptions);
const bool IsPGOPreLink = !IsCtxProfGen && PGOOpt && IsPreLink;
const bool IsPGOInstrGen =
IsPGOPreLink && PGOOpt->Action == PGOOptions::IRInstr;
@@ -1136,17 +1141,18 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
const bool IsMemprofUse = IsPGOPreLink && !PGOOpt->MemoryProfile.empty();
// We don't want to mix pgo ctx gen and pgo gen; we also don't currently
// enable ctx profiling from the frontend.
- assert(!(IsPGOInstrGen && PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled()) &&
+ assert(!(IsPGOInstrGen &&
+ PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(LibraryOptions)) &&
"Enabling both instrumented PGO and contextual instrumentation is not "
"supported.");
const bool IsCtxProfUse = !UseCtxProfile.empty() && isThinLTOPreLink(Phase);
assert((Opts.instrument_cold_function_only_path.empty() ||
- isPGOInstrumentColdFunctionOnly()) &&
+ isPGOInstrumentColdFunctionOnly(LibraryOptions)) &&
"--instrument-cold-function-only-path is provided but "
"--pgo-instrument-cold-function-only is not enabled");
const bool IsColdFuncOnlyInstrGen =
- isPGOInstrumentColdFunctionOnly() && IsPGOPreLink &&
+ isPGOInstrumentColdFunctionOnly(LibraryOptions) && IsPGOPreLink &&
!Opts.instrument_cold_function_only_path.empty();
if (IsPGOInstrGen || IsPGOInstrUse || IsMemprofUse || IsCtxProfGen ||
diff --git a/llvm/lib/Passes/PassesOptions.td b/llvm/lib/Passes/PassesOptions.td
index 8789b2a243dd8c..4398d5c06bff2b 100644
--- a/llvm/lib/Passes/PassesOptions.td
+++ b/llvm/lib/Passes/PassesOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def PassesOptions : OptionsStruct<perContext = false>;
+def PassesOptions : OptionsStruct;
// PassBuilder.cpp
defm : FlagOrEnumField<"print-pipeline-passes",
diff --git a/llvm/lib/Passes/RunCodeGen.cpp b/llvm/lib/Passes/RunCodeGen.cpp
index 611b5963af3f37..7514d6cbb9aca0 100644
--- a/llvm/lib/Passes/RunCodeGen.cpp
+++ b/llvm/lib/Passes/RunCodeGen.cpp
@@ -67,7 +67,7 @@ static Error runCodeGenPipelineNewPM(TargetMachine &TM, Module &M,
Opt.DisableVerify = DisableVerify;
MachineModuleInfo MMI(&TM);
PassInstrumentationCallbacks PIC;
- PipelineTuningOptions PTOptions;
+ PipelineTuningOptions PTOptions(&M.getContext().getLibraryOptions());
TargetMachine *TMPointer = &TM;
PassBuilder PB(TMPointer, PTOptions, std::nullopt, &PIC, VFS);
PB.registerModuleAnalyses(MAM);
@@ -95,8 +95,9 @@ Error llvm::runCodeGenPipeline(TargetMachine &TM, Module &M,
CodeGenFileType CGFT, bool DisableVerify,
bool DisableSimplifyLibCalls,
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
- if (valueOr(PassesOptions::Global.force_new_pm_codegen,
- TM.shouldDefaultToNewPM())) {
+ const PassesOptions &Opts =
+ M.getContext().getLibraryOptions().get<PassesOptions>();
+ if (valueOr(Opts.force_new_pm_codegen, TM.shouldDefaultToNewPM())) {
return runCodeGenPipelineNewPM(TM, M, OS, DwoOS, CGFT, DisableVerify, VFS);
}
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 974412960083d3..c86a7cc02fb68a 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -454,7 +454,7 @@ void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name,
const std::string &Before,
const std::string &After, IRUnitRef) {
// Report the IR before the changes when requested.
- if (PassesOptions::Global.print_before_changed)
+ if (Opts.print_before_changed)
Out << "*** IR Dump Before " << PassID << " on " << Name << " ***\n"
<< Before;
@@ -471,12 +471,11 @@ void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name,
IRChangedTester::~IRChangedTester() = default;
void IRChangedTester::registerCallbacks(PassInstrumentationCallbacks &PIC) {
- if (PassesOptions::Global.exec_on_ir_change != "")
+ if (Opts.exec_on_ir_change != "")
TextChangeReporter<std::string>::registerRequiredCallbacks(PIC);
}
void IRChangedTester::handleIR(const std::string &S, StringRef PassID) {
- const PassesOptions &Opts = PassesOptions::Global;
// Store the body into a temporary file
static SmallVector<int> FD{-1};
SmallVector<StringRef> SR{S};
@@ -748,7 +747,6 @@ StringRef PrintIRInstrumentation::getFileSuffix(IRDumpFileSuffixType Type) {
std::string PrintIRInstrumentation::fetchDumpFilename(
StringRef PassName, StringRef IRFileDisplayName, unsigned PassNumber,
IRDumpFileSuffixType SuffixType) {
- const PassesOptions &Opts = PassesOptions::Global;
assert(!Opts.ir_dump_directory.empty() &&
"The flag -ir-dump-directory must be passed to dump IR to files");
@@ -833,7 +831,7 @@ void PrintIRInstrumentation::printBeforePass(StringRef PassID, IRUnitRef IR) {
unwrapAndPrint(Stream, IR);
};
- if (!PassesOptions::Global.ir_dump_directory.empty()) {
+ if (!Opts.ir_dump_directory.empty()) {
std::string DumpIRFilename =
fetchDumpFilename(PassID, getIRFileDisplayName(IR), CurrentPassNumber,
IRDumpFileSuffixType::Before);
@@ -868,7 +866,7 @@ void PrintIRInstrumentation::printAfterPass(StringRef PassID, IRUnitRef IR) {
unwrapAndPrint(Stream, IR);
};
- if (!PassesOptions::Global.ir_dump_directory.empty()) {
+ if (!Opts.ir_dump_directory.empty()) {
std::string DumpIRFilename =
fetchDumpFilename(PassID, getIRFileDisplayName(IR), CurrentPassNumber,
IRDumpFileSuffixType::After);
@@ -906,7 +904,7 @@ void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
printIR(Stream, M);
};
- if (!PassesOptions::Global.ir_dump_directory.empty()) {
+ if (!Opts.ir_dump_directory.empty()) {
std::string DumpIRFilename =
fetchDumpFilename(PassID, IRFileDisplayName, PassNumber,
IRDumpFileSuffixType::Invalidated);
@@ -946,7 +944,7 @@ bool PrintIRInstrumentation::shouldPrintAfterCurrentPassNumber() {
}
bool PrintIRInstrumentation::shouldPrintPassNumbers() {
- return PassesOptions::Global.print_pass_numbers;
+ return Opts.print_pass_numbers;
}
bool PrintIRInstrumentation::shouldPrintBeforeSomePassNumber() {
@@ -1007,7 +1005,6 @@ bool OptNoneInstrumentation::shouldRun(StringRef PassID, IRUnitRef IR) {
}
bool OptPassGateInstrumentation::shouldRun(StringRef PassName, IRUnitRef IR) {
- const PassesOptions &Opts = PassesOptions::Global;
if (isIgnored(PassName))
return true;
@@ -1320,8 +1317,7 @@ void PreservedCFGCheckerInstrumentation::registerCallbacks(
#else
constexpr bool VerifyByDefault = false;
#endif
- if (!valueOr(PassesOptions::Global.verify_analysis_invalidation,
- VerifyByDefault))
+ if (!valueOr(Opts.verify_analysis_invalidation, VerifyByDefault))
return;
bool Registered = false;
@@ -1760,11 +1756,11 @@ class DotCfgDiffNode {
// Create a node in Dot difference graph \p G representing the basic block
// represented by \p BD with colour \p Colour (where it exists).
- DotCfgDiffNode(DotCfgDiff &G, unsigned N, const BlockDataT<DCData> &BD,
- StringRef Colour)
- : Graph(G), N(N), Data{&BD, nullptr}, Colour(Colour) {}
+ DotCfgDiffNode(const PassesOptions &Opts, DotCfgDiff &G, unsigned N,
+ const BlockDataT<DCData> &BD, StringRef Colour)
+ : Opts(Opts), Graph(G), N(N), Data{&BD, nullptr}, Colour(Colour) {}
DotCfgDiffNode(const DotCfgDiffNode &DN)
- : Graph(DN.Graph), N(DN.N), Data{DN.Data[0], DN.Data[1]},
+ : Opts(DN.Opts), Graph(DN.Graph), N(DN.N), Data{DN.Data[0], DN.Data[1]},
Colour(DN.Colour), EdgesMap(DN.EdgesMap), Children(DN.Children),
Edges(DN.Edges) {}
@@ -1782,13 +1778,12 @@ class DotCfgDiffNode {
void setCommon(const BlockDataT<DCData> &Other) {
assert(!Data[1] && "Expected only one block datum");
Data[1] = &Other;
- Colour = PassesOptions::Global.dot_cfg_common_color;
+ Colour = Opts.dot_cfg_common_color;
}
// Add an edge to \p E of colour {\p Value, \p Colour}.
void addEdge(unsigned E, StringRef Value, StringRef Colour) {
// This is a new edge or it is an edge being made common.
- assert((EdgesMap.count(E) == 0 ||
- Colour == PassesOptions::Global.dot_cfg_common_color) &&
+ assert((EdgesMap.count(E) == 0 || Colour == Opts.dot_cfg_common_color) &&
"Unexpected edge count and color.");
EdgesMap[E] = {Value.str(), Colour};
}
@@ -1808,6 +1803,7 @@ class DotCfgDiffNode {
std::map<const unsigned, unsigned> &NodeMap) const;
protected:
+ const PassesOptions &Opts;
DotCfgDiff &Graph;
const unsigned N;
const BlockDataT<DCData> *Data[2];
@@ -1824,8 +1820,8 @@ class DotCfgDiff {
// entry node for the function. \p Before and \p After are the before
// after versions of the function, respectively. \p Dir is the directory
// in which to store the results.
- DotCfgDiff(StringRef Title, const FuncDataT<DCData> &Before,
- const FuncDataT<DCData> &After);
+ DotCfgDiff(const PassesOptions &Opts, StringRef Title,
+ const FuncDataT<DCData> &Before, const FuncDataT<DCData> &After);
DotCfgDiff(const DotCfgDiff &) = delete;
DotCfgDiff &operator=(const DotCfgDiff &) = delete;
@@ -1859,10 +1855,11 @@ class DotCfgDiff {
void createNode(StringRef Label, const BlockDataT<DCData> &BD, StringRef C) {
unsigned Pos = Nodes.size();
- Nodes.emplace_back(*this, Pos, BD, C);
+ Nodes.emplace_back(Opts, *this, Pos, BD, C);
NodePosition.insert({Label, Pos});
}
+ const PassesOptions &Opts;
// TODO Nodes should probably be a StringMap<DotCfgDiffNode> after the
// display graph is separated out, which would remove the need for
// NodePosition.
@@ -1874,7 +1871,6 @@ class DotCfgDiff {
};
std::string DotCfgDiffNode::getBodyContent() const {
- const PassesOptions &Opts = PassesOptions::Global;
if (Colour == Opts.dot_cfg_common_color) {
assert(Data[1] && "Expected Data[1] to be set.");
@@ -1949,10 +1945,10 @@ std::string DotCfgDiff::colourize(std::string S, StringRef Colour) const {
return "<FONT COLOR=\"" + Colour.str() + "\">" + S + "</FONT>";
}
-DotCfgDiff::DotCfgDiff(StringRef Title, const FuncDataT<DCData> &Before,
+DotCfgDiff::DotCfgDiff(const PassesOptions &Opts, StringRef Title,
+ const FuncDataT<DCData> &Before,
const FuncDataT<DCData> &After)
- : GraphName(Title.str()) {
- const PassesOptions &Opts = PassesOptions::Global;
+ : Opts(Opts), GraphName(Title.str()) {
StringMap<StringRef> EdgesMap;
// Handle each basic block in the before IR.
@@ -2189,8 +2185,9 @@ DCData::DCData(const MachineBasicBlock &B) {
addSuccessorLabel(Succ->getName().str(), "");
}
-DotCfgChangeReporter::DotCfgChangeReporter(bool Verbose)
- : ChangeReporter<IRDataT<DCData>>(Verbose) {}
+DotCfgChangeReporter::DotCfgChangeReporter(const PassesOptions &Opts,
+ bool Verbose)
+ : ChangeReporter<IRDataT<DCData>>(Verbose), Opts(Opts) {}
void DotCfgChangeReporter::handleFunctionCompare(
StringRef Name, StringRef Prefix, StringRef PassID, StringRef Divider,
@@ -2218,7 +2215,7 @@ void DotCfgChangeReporter::handleFunctionCompare(
Text = formatv("{0}.{1}{2}{3}{4}", Number, Prefix, makeHTMLReady(PassID),
Divider, Name);
- DotCfgDiff Diff(Text, Before, After);
+ DotCfgDiff Diff(Opts, Text, Before, After);
std::string EntryBlockName = After.getEntryBlockName();
// Use the before entry block if the after entry block was removed.
if (EntryBlockName == "")
@@ -2236,7 +2233,6 @@ void DotCfgChangeReporter::handleFunctionCompare(
std::string DotCfgChangeReporter::genHTML(StringRef Text, StringRef DotFile,
StringRef PDFFileName) const {
- const PassesOptions &Opts = PassesOptions::Global;
SmallString<20> PDFFile = formatv("{0}/{1}", OutputDir, PDFFileName);
// Create the PDF file.
static ErrorOr<std::string> DotExe =
@@ -2403,7 +2399,7 @@ void DotCfgChangeReporter::registerCallbacks(
if (PrintChanged == ChangePrinter::DotCfgVerbose ||
PrintChanged == ChangePrinter::DotCfgQuiet) {
SmallString<128> Dir;
- sys::fs::expand_tilde(PassesOptions::Global.dot_cfg_dir, Dir);
+ sys::fs::expand_tilde(Opts.dot_cfg_dir, Dir);
sys::fs::make_absolute(Dir);
assert(!Dir.empty() && "expected output dir to be non-empty");
OutputDir = Dir.str();
@@ -2418,23 +2414,22 @@ void DotCfgChangeReporter::registerCallbacks(
StandardInstrumentations::StandardInstrumentations(
LLVMContext &Context, bool DebugLogging, bool VerifyEach,
PrintPassOptions PrintPassOpts)
- : PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging),
- OptPassGate(Context),
- PrintChangedIR(PrintChanged == ChangePrinter::Verbose),
+ : Opts(Context.getLibraryOptions().get<PassesOptions>()), PrintIR(Opts),
+ PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging),
+ OptPassGate(Opts, Context), PreservedCFGChecker(Opts),
+ PrintChangedIR(Opts, PrintChanged == ChangePrinter::Verbose),
PrintChangedDiff(PrintChanged == ChangePrinter::DiffVerbose ||
PrintChanged == ChangePrinter::ColourDiffVerbose,
PrintChanged == ChangePrinter::ColourDiffVerbose ||
PrintChanged == ChangePrinter::ColourDiffQuiet),
- WebsiteChangeReporter(PrintChanged == ChangePrinter::DotCfgVerbose),
- Verify(DebugLogging),
- DroppedStatsIR(PassesOptions::Global.dropped_variable_stats),
- VerifyEach(VerifyEach) {}
+ WebsiteChangeReporter(Opts, PrintChanged == ChangePrinter::DotCfgVerbose),
+ PrintCrashIR(Opts), ChangeTester(Opts), Verify(DebugLogging),
+ DroppedStatsIR(Opts.dropped_variable_stats), VerifyEach(VerifyEach) {}
PrintCrashIRInstrumentation *PrintCrashIRInstrumentation::CrashReporter =
nullptr;
void PrintCrashIRInstrumentation::reportCrashIR() {
- const PassesOptions &Opts = PassesOptions::Global;
if (!Opts.print_on_crash_path.empty()) {
std::error_code EC;
raw_fd_ostream Out(Opts.print_on_crash_path, EC);
@@ -2452,8 +2447,8 @@ void PrintCrashIRInstrumentation::SignalHandler(void *) {
if (!CrashReporter)
return;
- assert((PassesOptions::Global.print_on_crash ||
- !PassesOptions::Global.print_on_crash_path.empty()) &&
+ assert((CrashReporter->Opts.print_on_crash ||
+ !CrashReporter->Opts.print_on_crash_path.empty()) &&
"Did not expect to get here without option set.");
CrashReporter->reportCrashIR();
}
@@ -2462,15 +2457,14 @@ PrintCrashIRInstrumentation::~PrintCrashIRInstrumentation() {
if (!CrashReporter)
return;
- assert((PassesOptions::Global.print_on_crash ||
- !PassesOptions::Global.print_on_crash_path.empty()) &&
+ assert((CrashReporter->Opts.print_on_crash ||
+ !CrashReporter->Opts.print_on_crash_path.empty()) &&
"Did not expect to get here without option set.");
CrashReporter = nullptr;
}
void PrintCrashIRInstrumentation::registerCallbacks(
PassInstrumentationCallbacks &PIC) {
- const PassesOptions &Opts = PassesOptions::Global;
if ((!Opts.print_on_crash && Opts.print_on_crash_path.empty()) ||
CrashReporter)
return;
@@ -2496,7 +2490,7 @@ void PrintCrashIRInstrumentation::registerCallbacks(
void StandardInstrumentations::registerCallbacks(
PassInstrumentationCallbacks &PIC, ModuleAnalysisManager *MAM,
ExtendedIRContext *IRContext) {
- if (PassesOptions::Global.instnamer_after_each_pass)
+ if (Opts.instnamer_after_each_pass)
InstructionNamerPass::registerCallbacks(PIC, InstNamerNextID);
PrintIR.registerCallbacks(PIC, IRContext);
PrintPass.registerCallbacks(PIC, IRContext);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSwLowerLDS.cpp b/llvm/lib/Target/AMDGPU/AMDGPUSwLowerLDS.cpp
index 65e808fba74681..e639ffa23954b4 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSwLowerLDS.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSwLowerLDS.cpp
@@ -1206,8 +1206,8 @@ void AMDGPUSwLowerLDS::initAsanInfo() {
uint64_t Offset;
int Scale;
bool OrShadowOffset;
- llvm::getAddressSanitizerParams(M.getTargetTriple(), LongSize, false, &Offset,
- &Scale, &OrShadowOffset);
+ llvm::getAddressSanitizerParams(M.getContext(), M.getTargetTriple(), LongSize,
+ false, &Offset, &Scale, &OrShadowOffset);
AsanInfo.Scale = Scale;
AsanInfo.Offset = Offset;
}
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index b18329082cfdb1..7a71b2746e7980 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -951,7 +951,8 @@ void X86AsmPrinter::LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
uint64_t ShadowBase;
int MappingScale;
bool OrShadowOffset;
- getAddressSanitizerParams(TM.getTargetTriple(), 64, AccessInfo.CompileKernel,
+ getAddressSanitizerParams(MF->getFunction().getContext(),
+ TM.getTargetTriple(), 64, AccessInfo.CompileKernel,
&ShadowBase, &MappingScale, &OrShadowOffset);
StringRef Name = AccessInfo.IsWrite ? "store" : "load";
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 8de58841938a87..70841c8324aa3f 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -350,11 +350,13 @@ static ShadowMapping getShadowMapping(const InstrumentationOptions &Opts,
return Mapping;
}
-void llvm::getAddressSanitizerParams(const Triple &TargetTriple, int LongSize,
+void llvm::getAddressSanitizerParams(const LLVMContext &Ctx,
+ const Triple &TargetTriple, int LongSize,
bool IsKasan, uint64_t *ShadowBase,
int *MappingScale, bool *OrShadowOffset) {
- auto Mapping = getShadowMapping(InstrumentationOptions::Global, TargetTriple,
- LongSize, IsKasan);
+ auto Mapping =
+ getShadowMapping(Ctx.getLibraryOptions().get<InstrumentationOptions>(),
+ TargetTriple, LongSize, IsKasan);
*ShadowBase = Mapping.Offset;
*MappingScale = Mapping.Scale;
*OrShadowOffset = Mapping.OrShadowOffset;
@@ -1057,7 +1059,8 @@ PreservedAnalyses AddressSanitizerPass::run(Module &M,
if (checkIfAlreadyInstrumented(M, "nosanitize_address"))
return PreservedAnalyses::all();
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
ModuleAddressSanitizer ModuleSanitizer(Opts, M, Options.InsertVersionCheck,
Options.CompileKernel, Options.Recover,
UseGlobalGC, UseOdrIndicator,
diff --git a/llvm/lib/Transforms/Instrumentation/AllocToken.cpp b/llvm/lib/Transforms/Instrumentation/AllocToken.cpp
index 753f665e148f85..70a5fea9652a11 100644
--- a/llvm/lib/Transforms/Instrumentation/AllocToken.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AllocToken.cpp
@@ -578,7 +578,9 @@ AllocTokenPass::AllocTokenPass(AllocTokenOptions Opts)
: Options(std::move(Opts)) {}
PreservedAnalyses AllocTokenPass::run(Module &M, ModuleAnalysisManager &MAM) {
- AllocToken Pass(InstrumentationOptions::Global, Options, M, MAM);
+ const InstrumentationOptions &CLOpts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ AllocToken Pass(CLOpts, Options, M, MAM);
bool Modified = false;
for (Function &F : M) {
diff --git a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
index 814500214c9cf2..b1c3d642ce9ba8 100644
--- a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
+++ b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
@@ -195,7 +195,8 @@ getRuntimeCallName(const BoundsCheckingPass::Options::Runtime &Opts) {
static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
ScalarEvolution &SE,
- const BoundsCheckingPass::Options &Opts) {
+ const BoundsCheckingPass::Options &Opts,
+ bool SingleTrap) {
if (F.hasFnAttribute(Attribute::NoSanitizeBounds))
return false;
@@ -248,8 +249,8 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
// flags, this will either create a single block for the entire function or
// will create a fresh block every time it is called.
BasicBlock *ReuseTrapBB = nullptr;
- auto GetTrapBB = [&ReuseTrapBB, &Opts, &Name](BuilderTy &IRB,
- BasicBlock *Cont) {
+ auto GetTrapBB = [&ReuseTrapBB, &Opts, &Name, SingleTrap](BuilderTy &IRB,
+ BasicBlock *Cont) {
Function *Fn = IRB.GetInsertBlock()->getParent();
auto DebugLoc = IRB.getCurrentDebugLocation();
IRBuilder<>::InsertPointGuard Guard(IRB);
@@ -283,9 +284,7 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
// local-bounds. Make sure to change that too.
if (Opts.Rt && Opts.Rt->HandlerPreserveAllRegs && MayReturn)
TrapCall->setCallingConv(CallingConv::PreserveAll);
- if (!MayReturn &&
- InstrumentationOptions::Global.bounds_checking_single_trap &&
- !DebugTrapBB)
+ if (!MayReturn && SingleTrap && !DebugTrapBB)
ReuseTrapBB = TrapBB;
return TrapBB;
@@ -304,7 +303,9 @@ PreservedAnalyses BoundsCheckingPass::run(Function &F, FunctionAnalysisManager &
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
- if (!addBoundsChecking(F, TLI, SE, Opts))
+ const InstrumentationOptions &CLOpts =
+ F.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ if (!addBoundsChecking(F, TLI, SE, Opts, CLOpts.bounds_checking_single_trap))
return PreservedAnalyses::all();
return PreservedAnalyses::none();
diff --git a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
index d4e6a6936bbcc8..145f4c77632f20 100644
--- a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
+++ b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
@@ -48,11 +48,9 @@ using namespace llvm;
#define CHR_DEBUG(X) LLVM_DEBUG(X)
-static StringSet<> CHRModules;
-static StringSet<> CHRFunctions;
-
-static void parseCHRFilterFiles() {
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+static void parseCHRFilterFiles(const InstrumentationOptions &Opts,
+ StringSet<> &CHRModules,
+ StringSet<> &CHRFunctions) {
if (!Opts.chr_module_list.empty()) {
auto FileOrErr = MemoryBuffer::getFile(Opts.chr_module_list);
if (!FileOrErr) {
@@ -262,11 +260,12 @@ class CHRScope {
class CHR {
public:
- CHR(const InstrumentationOptions &Opts, Function &Fin,
- BlockFrequencyInfo &BFIin, DominatorTree &DTin, ProfileSummaryInfo &PSIin,
- RegionInfo &RIin, OptimizationRemarkEmitter &OREin)
- : Opts(Opts), F(Fin), BFI(BFIin), DT(DTin), PSI(PSIin), RI(RIin),
- ORE(OREin) {}
+ CHR(const InstrumentationOptions &Opts, const StringSet<> &CHRModules,
+ const StringSet<> &CHRFunctions, Function &Fin, BlockFrequencyInfo &BFIin,
+ DominatorTree &DTin, ProfileSummaryInfo &PSIin, RegionInfo &RIin,
+ OptimizationRemarkEmitter &OREin)
+ : Opts(Opts), CHRModules(CHRModules), CHRFunctions(CHRFunctions), F(Fin),
+ BFI(BFIin), DT(DTin), PSI(PSIin), RI(RIin), ORE(OREin) {}
~CHR() {
for (CHRScope *Scope : Scopes) {
@@ -347,6 +346,8 @@ class CHR {
}
const InstrumentationOptions &Opts;
+ const StringSet<> &CHRModules;
+ const StringSet<> &CHRFunctions;
Function &F;
BlockFrequencyInfo &BFI;
DominatorTree &DT;
@@ -387,7 +388,9 @@ raw_ostream &operator<<(raw_ostream &OS, const CHRScope &Scope) {
return OS;
}
-static bool shouldApply(const InstrumentationOptions &Opts, Function &F,
+static bool shouldApply(const InstrumentationOptions &Opts,
+ const StringSet<> &CHRModules,
+ const StringSet<> &CHRFunctions, Function &F,
ProfileSummaryInfo &PSI) {
if (Opts.disable_chr)
return false;
@@ -2006,7 +2009,7 @@ void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
}
bool CHR::run() {
- if (!shouldApply(Opts, F, PSI))
+ if (!shouldApply(Opts, CHRModules, CHRFunctions, F, PSI))
return false;
CHR_DEBUG(dumpIR(F, "before", nullptr));
@@ -2082,10 +2085,6 @@ bool CHR::run() {
return Changed;
}
-ControlHeightReductionPass::ControlHeightReductionPass() {
- parseCHRFilterFiles();
-}
-
PreservedAnalyses ControlHeightReductionPass::run(
Function &F,
FunctionAnalysisManager &FAM) {
@@ -2099,8 +2098,17 @@ PreservedAnalyses ControlHeightReductionPass::run(
auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
auto &RI = FAM.getResult<RegionInfoAnalysis>(F);
auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
+ const InstrumentationOptions &Opts =
+ F.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ if (&Opts != ParsedOpts &&
+ (!Opts.chr_module_list.empty() || !Opts.chr_function_list.empty())) {
+ CHRModules.clear();
+ CHRFunctions.clear();
+ parseCHRFilterFiles(Opts, CHRModules, CHRFunctions);
+ ParsedOpts = &Opts;
+ }
bool Changed =
- CHR(InstrumentationOptions::Global, F, BFI, DT, PSI, RI, ORE).run();
+ CHR(Opts, CHRModules, CHRFunctions, F, BFI, DT, PSI, RI, ORE).run();
if (!Changed)
return PreservedAnalyses::all();
return PreservedAnalyses::none();
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index e16431a3168865..72ebfa0f3a8ce0 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -3428,8 +3428,9 @@ PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
return FAM.getResult<TargetLibraryAnalysis>(F);
};
- if (!DataFlowSanitizer(InstrumentationOptions::Global, ABIListFiles, FS)
- .runImpl(M, GetTLI))
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ if (!DataFlowSanitizer(Opts, ABIListFiles, FS).runImpl(M, GetTLI))
return PreservedAnalyses::all();
PreservedAnalyses PA = PreservedAnalyses::none();
diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index e3c1602fe7419b..44990595c6e9a4 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -66,12 +66,11 @@ static unsigned wordsOfString(StringRef s) {
return (s.size() / 4) + 2;
}
-GCOVOptions GCOVOptions::getDefault() {
+static GCOVOptions getDefaultOptions(const InstrumentationOptions &Opts) {
GCOVOptions Options;
Options.EmitNotes = true;
Options.EmitData = true;
Options.NoRedZone = false;
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
Options.Atomic = Opts.gcov_atomic_counter;
if (Opts.default_gcov_version.size() != 4) {
@@ -87,8 +86,6 @@ class GCOVFunction;
class GCOVProfiler {
public:
- GCOVProfiler()
- : GCOVProfiler(GCOVOptions::getDefault(), *vfs::getRealFileSystem()) {}
GCOVProfiler(const GCOVOptions &Opts, vfs::FileSystem &VFS)
: Options(Opts), VFS(VFS) {}
bool
@@ -554,7 +551,9 @@ bool GCOVProfiler::runOnModule(
PreservedAnalyses GCOVProfilerPass::run(Module &M,
ModuleAnalysisManager &AM) {
- GCOVProfiler Profiler(GCOVOpts, *VFS);
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ GCOVProfiler Profiler(GCOVOpts ? *GCOVOpts : getDefaultOptions(Opts), *VFS);
FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index ea31e08a4661a0..0097f333c2ef63 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -351,7 +351,8 @@ PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
return PreservedAnalyses::all();
const StackSafetyGlobalInfo *SSI = nullptr;
const Triple &TargetTriple = M.getTargetTriple();
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
if (shouldUseStackSafetyAnalysis(Opts, TargetTriple,
Options.DisableOptimization))
SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
diff --git a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
index 365bac5a0a7f26..8a547b8647c929 100644
--- a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
+++ b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
@@ -1017,7 +1017,8 @@ PreservedAnalyses PGOIndirectCallPromotion::run(Module &M,
ModuleAnalysisManager &MAM) {
ProfileSummaryInfo *PSI = &MAM.getResult<ProfileSummaryAnalysis>(M);
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
if (!promoteIndirectCalls(Opts, M, PSI, InLTO | Opts.icp_lto,
SamplePGO | Opts.icp_samplepgo, MAM))
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 6a7bda565ef212..828e8e987662f1 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -76,8 +76,10 @@ namespace llvm {
extern cl::opt<bool> EnableVTableValueProfiling;
} // namespace llvm
-bool llvm::isProfileCorrelationEnabled() {
- return InstrumentationOptions::Global.profile_correlate.has_value();
+bool llvm::isProfileCorrelationEnabled(
+ const cl::LibraryOptionsContext &LibraryOptions) {
+ return LibraryOptions.get<InstrumentationOptions>()
+ .profile_correlate.has_value();
}
namespace {
@@ -639,8 +641,9 @@ PreservedAnalyses InstrProfilingLoweringPass::run(Module &M,
auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
return FAM.getResult<TargetLibraryAnalysis>(F);
};
- InstrLowerer Lowerer(InstrumentationOptions::Global, M, Options, GetTLI,
- IsCS);
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ InstrLowerer Lowerer(Opts, M, Options, GetTLI, IsCS);
if (!Lowerer.lower())
return PreservedAnalyses::all();
@@ -2441,8 +2444,9 @@ void createProfileSamplingVar(Module &M) {
const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_SAMPLING_VAR));
IntegerType *SamplingVarTy;
Constant *ValueZero;
- if (getSampledInstrumentationConfig(InstrumentationOptions::Global)
- .UseShort) {
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ if (getSampledInstrumentationConfig(Opts).UseShort) {
SamplingVarTy = Type::getInt16Ty(M.getContext());
ValueZero = Constant::getIntegerValue(SamplingVarTy, APInt(16, 0));
} else {
diff --git a/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td b/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td
index a430c79f325758..44a2c46ed3ec43 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td
+++ b/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def InstrumentationOptions : OptionsStruct<perContext = false>;
+def InstrumentationOptions : OptionsStruct;
// AddressSanitizer.cpp
defm : BoolField<"asan-always-slow-path", "false",
diff --git a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp
index d1b6451c3376df..fd969cf4968131 100644
--- a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp
+++ b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp
@@ -67,7 +67,8 @@ static void emitRemark(IntrinsicInst *II, OptimizationRemarkEmitter &ORE,
static bool lowerAllowChecks(Function &F, FunctionAnalysisManager &AM,
const LowerAllowCheckPass::Options &Opts) {
- const InstrumentationOptions &CLOpts = InstrumentationOptions::Global;
+ const InstrumentationOptions &CLOpts =
+ F.getContext().getLibraryOptions().get<InstrumentationOptions>();
// Lazy analysis getters.
auto GetBFI = [&AM, &F, BFI = (BlockFrequencyInfo *)nullptr]() mutable
-> const BlockFrequencyInfo & {
@@ -194,8 +195,10 @@ PreservedAnalyses LowerAllowCheckPass::run(Function &F,
: PreservedAnalyses::all();
}
-bool LowerAllowCheckPass::IsRequested() {
- const InstrumentationOptions &CLOpts = InstrumentationOptions::Global;
+bool LowerAllowCheckPass::isRequested(
+ const cl::LibraryOptionsContext &LibraryOptions) {
+ const InstrumentationOptions &CLOpts =
+ LibraryOptions.get<InstrumentationOptions>();
return CLOpts.lower_allow_check_random_rate ||
CLOpts.lower_allow_check_percentile_cutoff_hot;
}
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/MemProfInstrumentation.cpp
index 96e3a97bbe1ac2..cfd8f8cc93adab 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfInstrumentation.cpp
@@ -172,7 +172,8 @@ MemProfilerPass::MemProfilerPass() = default;
PreservedAnalyses MemProfilerPass::run(Function &F,
AnalysisManager<Function> &AM) {
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ F.getContext().getLibraryOptions().get<InstrumentationOptions>();
assert((!Opts.memprof_histogram ||
Opts.memprof_mapping_granularity == DefaultMemGranularity) &&
"Memprof with histogram only supports default mapping granularity");
@@ -188,7 +189,9 @@ ModuleMemProfilerPass::ModuleMemProfilerPass() = default;
PreservedAnalyses ModuleMemProfilerPass::run(Module &M,
AnalysisManager<Module> &AM) {
- ModuleMemProfiler Profiler(InstrumentationOptions::Global, M);
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ ModuleMemProfiler Profiler(Opts, M);
if (Profiler.instrumentModule(M))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
index bbab620269eba1..382222904bb367 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
@@ -242,6 +242,8 @@ struct AllocMatchInfo {
DenseMap<uint64_t, SmallVector<CallEdgeTy, 0>>
memprof::extractCallsFromIR(Module &M, const TargetLibraryInfo &TLI,
function_ref<bool(uint64_t)> IsPresentInProfile) {
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
DenseMap<uint64_t, SmallVector<CallEdgeTy, 0>> Calls;
for (Function &F : M) {
@@ -262,8 +264,8 @@ memprof::extractCallsFromIR(Module &M, const TargetLibraryInfo &TLI,
StringRef CalleeName = CalledFunction->getName();
// True if we are calling a heap allocation function that supports
// hot/cold variants.
- bool IsAlloc = isAllocationWithHotColdVariant(
- InstrumentationOptions::Global, CalledFunction, TLI);
+ bool IsAlloc =
+ isAllocationWithHotColdVariant(Opts, CalledFunction, TLI);
// True for the first iteration below, indicating that we are looking at
// a leaf node.
bool IsLeaf = true;
@@ -836,7 +838,8 @@ MemProfUsePass::MemProfUsePass(std::string MemoryProfileFile,
}
PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) {
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
// Return immediately if the module doesn't contain any function or global
// variables.
if (M.empty() && M.globals().empty())
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 2e31d692599cf1..a6d4086fb924e7 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -592,13 +592,33 @@ void insertModuleCtor(const InstrumentationOptions &Opts, Module &M) {
} // end anonymous namespace
-MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K,
- bool EC) {
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
- Kernel = valueOr(Opts.msan_kernel, K);
- TrackOrigins = Opts.msan_track_origins.value_or(Kernel ? 2 : TO);
- Recover = valueOr(Opts.msan_keep_going, Kernel || R);
- EagerChecks = valueOr(Opts.msan_eager_checks, EC);
+MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K, bool EC)
+ : Kernel(K), TrackOrigins(TO), Recover(R), EagerChecks(EC) {}
+
+static MemorySanitizerOptions applyParams(MemorySanitizerOptions O) {
+ O.Kernel = O.KernelParam.value_or(O.Kernel);
+ O.TrackOrigins = O.TrackOriginsParam.value_or(O.TrackOrigins);
+ O.Recover = O.RecoverParam.value_or(O.Recover);
+ O.EagerChecks = O.EagerChecksParam.value_or(O.EagerChecks);
+ return O;
+}
+
+static MemorySanitizerOptions applyKernelDefaults(MemorySanitizerOptions O) {
+ if (O.Kernel) {
+ O.TrackOrigins = 2;
+ O.Recover = true;
+ }
+ return O;
+}
+
+static MemorySanitizerOptions resolveOptions(const InstrumentationOptions &Opts,
+ MemorySanitizerOptions O) {
+ O.Kernel = valueOr(Opts.msan_kernel, O.Kernel);
+ O = applyKernelDefaults(O);
+ O.TrackOrigins = Opts.msan_track_origins.value_or(O.TrackOrigins);
+ O.Recover = valueOr(Opts.msan_keep_going, O.Recover);
+ O.EagerChecks = valueOr(Opts.msan_eager_checks, O.EagerChecks);
+ return applyParams(O);
}
PreservedAnalyses MemorySanitizerPass::run(Module &M,
@@ -606,9 +626,11 @@ PreservedAnalyses MemorySanitizerPass::run(Module &M,
// Return early if nosanitize_memory module flag is present for the module.
if (checkIfAlreadyInstrumented(M, "nosanitize_memory"))
return PreservedAnalyses::all();
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ MemorySanitizerOptions MSanOpts = resolveOptions(Opts, Options);
bool Modified = false;
- if (!Options.Kernel) {
+ if (!MSanOpts.Kernel) {
insertModuleCtor(Opts, M);
Modified = true;
}
@@ -617,7 +639,7 @@ PreservedAnalyses MemorySanitizerPass::run(Module &M,
for (Function &F : M) {
if (F.empty())
continue;
- MemorySanitizer Msan(Opts, *F.getParent(), Options);
+ MemorySanitizer Msan(Opts, *F.getParent(), MSanOpts);
Modified |=
Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
}
@@ -638,13 +660,14 @@ void MemorySanitizerPass::printPipeline(
static_cast<PassInfoMixin<MemorySanitizerPass> *>(this)->printPipeline(
OS, MapClassName2PassName);
OS << '<';
- if (Options.Recover)
+ MemorySanitizerOptions O = applyParams(applyKernelDefaults(Options));
+ if (O.Recover)
OS << "recover;";
- if (Options.Kernel)
+ if (O.Kernel)
OS << "kernel;";
- if (Options.EagerChecks)
+ if (O.EagerChecks)
OS << "eager-checks;";
- OS << "track-origins=" << Options.TrackOrigins;
+ OS << "track-origins=" << O.TrackOrigins;
OS << '>';
}
diff --git a/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
index 61bdaf1f3e3d95..7af39681306e9d 100644
--- a/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp
@@ -569,7 +569,9 @@ NumericalStabilitySanitizerPass::run(Module &M, ModuleAnalysisManager &MAM) {
// time. Hook them into the global ctors list in that case:
[&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); });
- NumericalStabilitySanitizer Nsan(InstrumentationOptions::Global, M);
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ NumericalStabilitySanitizer Nsan(Opts, M);
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
for (Function &F : M)
Nsan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
diff --git a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
index bc75f34e3d8351..5a35c34bc3b29d 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
@@ -30,8 +30,10 @@ using namespace llvm;
#define DEBUG_TYPE "ctx-instr-lower"
-bool PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled() {
- return !InstrumentationOptions::Global.profile_context_root.empty();
+bool PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(
+ const cl::LibraryOptionsContext *LibraryOptions) {
+ return !cl::LibraryOptionsContext::get<InstrumentationOptions>(LibraryOptions)
+ .profile_context_root.empty();
}
// the names of symbols we expect in compiler-rt. Using a namespace for
@@ -153,9 +155,11 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
I32Ty, /*NumCallsites*/
});
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
// Define a global for each entrypoint. We'll reuse the entrypoint's name
// as prefix. We assume the entrypoint names to be unique.
- for (StringRef Fname : InstrumentationOptions::Global.profile_context_root) {
+ for (StringRef Fname : Opts.profile_context_root) {
if (const auto *F = M.getFunction(Fname)) {
if (F->isDeclaration())
continue;
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index a3c0c1687ffdc6..2406dfa58b2d14 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -184,8 +184,10 @@ extern cl::opt<bool> EnableVTableValueProfiling;
extern cl::opt<bool> EnableVTableProfileUse;
} // namespace llvm
-bool llvm::isPGOInstrumentColdFunctionOnly() {
- return InstrumentationOptions::Global.pgo_instrument_cold_function_only;
+bool llvm::isPGOInstrumentColdFunctionOnly(
+ const cl::LibraryOptionsContext *LibraryOptions) {
+ return cl::LibraryOptionsContext::get<InstrumentationOptions>(LibraryOptions)
+ .pgo_instrument_cold_function_only;
}
namespace {
@@ -1890,11 +1892,12 @@ static bool instrumentAllFunctions(
PreservedAnalyses
PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &MAM) {
createProfileFileNameVar(M, CSInstrName);
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
// The variable in a comdat may be discarded by LTO. Ensure the declaration
// will be retained.
appendToCompilerUsed(
- M, createIRLevelProfileFlagVar(InstrumentationOptions::Global, M,
- PGOInstrumentationType::CSFDO));
+ M, createIRLevelProfileFlagVar(Opts, M, PGOInstrumentationType::CSFDO));
if (ProfileSampling)
createProfileSamplingVar(M);
PreservedAnalyses PA;
@@ -1919,9 +1922,10 @@ PreservedAnalyses PGOInstrumentationGen::run(Module &M,
return &FAM.getResult<LoopAnalysis>(F);
};
- if (!instrumentAllFunctions(InstrumentationOptions::Global, M, LookupTLI,
- LookupBPI, LookupBFI, LookupLI,
- InstrumentationType))
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ if (!instrumentAllFunctions(Opts, M, LookupTLI, LookupBPI, LookupBFI,
+ LookupLI, InstrumentationType))
return PreservedAnalyses::all();
return PreservedAnalyses::none();
@@ -2255,11 +2259,6 @@ PGOInstrumentationUse::PGOInstrumentationUse(
: ProfileFileName(std::move(Filename)),
ProfileRemappingFileName(std::move(RemappingFilename)), IsCS(IsCS),
FS(std::move(VFS)) {
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
- if (!Opts.pgo_test_profile_file.empty())
- ProfileFileName = Opts.pgo_test_profile_file;
- if (!Opts.pgo_test_profile_remapping_file.empty())
- ProfileRemappingFileName = Opts.pgo_test_profile_remapping_file;
if (!FS)
FS = vfs::getRealFileSystem();
}
@@ -2282,9 +2281,16 @@ PreservedAnalyses PGOInstrumentationUse::run(Module &M,
};
auto *PSI = &MAM.getResult<ProfileSummaryAnalysis>(M);
- if (!annotateAllFunctions(InstrumentationOptions::Global, M, ProfileFileName,
- ProfileRemappingFileName, *FS, LookupTLI, LookupBPI,
- LookupBFI, LookupLI, PSI, IsCS))
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ StringRef ProfileFile = ProfileFileName;
+ if (!Opts.pgo_test_profile_file.empty())
+ ProfileFile = Opts.pgo_test_profile_file;
+ StringRef RemappingFile = ProfileRemappingFileName;
+ if (!Opts.pgo_test_profile_remapping_file.empty())
+ RemappingFile = Opts.pgo_test_profile_remapping_file;
+ if (!annotateAllFunctions(Opts, M, ProfileFile, RemappingFile, *FS, LookupTLI,
+ LookupBPI, LookupBFI, LookupLI, PSI, IsCS))
return PreservedAnalyses::all();
return PreservedAnalyses::none();
@@ -2312,7 +2318,9 @@ void llvm::setProfMetadata(Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
setBranchWeights(*TI, Weights, /*IsExpected=*/false);
- if (InstrumentationOptions::Global.pgo_emit_branch_prob) {
+ const InstrumentationOptions &Opts =
+ TI->getContext().getLibraryOptions().get<InstrumentationOptions>();
+ if (Opts.pgo_emit_branch_prob) {
std::string BrCondStr = getBranchCondString(TI);
if (BrCondStr.empty())
return;
@@ -2391,7 +2399,9 @@ template <> struct DOTGraphTraits<PGOUseFunc *> : DefaultDOTGraphTraits {
else
OS << "Unknown\\l";
- if (!InstrumentationOptions::Global.pgo_instr_select)
+ const InstrumentationOptions &Opts =
+ Node->getContext().getLibraryOptions().get<InstrumentationOptions>();
+ if (!Opts.pgo_instr_select)
return Result;
for (const Instruction &I : *Node) {
diff --git a/llvm/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp b/llvm/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp
index 290aa53e51204d..d53541595818bf 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp
@@ -422,8 +422,9 @@ PreservedAnalyses PGOMemOPSizeOpt::run(Function &F,
auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
- bool Changed =
- pgoMemOPSizeOptImpl(InstrumentationOptions::Global, F, BFI, ORE, DT, TLI);
+ const InstrumentationOptions &Opts =
+ F.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ bool Changed = pgoMemOPSizeOptImpl(Opts, F, BFI, ORE, DT, TLI);
if (!Changed)
return PreservedAnalyses::all();
auto PA = PreservedAnalyses();
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
index 3f788df6ea7bba..9cbb3264ad4a8c 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
@@ -481,8 +481,9 @@ SanitizerBinaryMetadataPass::run(Module &M, AnalysisManager<Module> &AM) {
return PreservedAnalyses::all();
}
- SanitizerBinaryMetadata Pass(InstrumentationOptions::Global, M, Options,
- std::move(Ignorelist));
+ const InstrumentationOptions &CLOpts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
+ SanitizerBinaryMetadata Pass(CLOpts, M, Options, std::move(Ignorelist));
if (Pass.run())
return PreservedAnalyses::none();
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index f3436f5c9b0fe3..bace11901dcf0d 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -265,7 +265,8 @@ PreservedAnalyses SanitizerCoveragePass::run(Module &M,
auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree & {
return FAM.getResult<PostDominatorTreeAnalysis>(F);
};
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
ModuleSanitizerCoverage ModuleSancov(Opts, M, DTCallback, PDTCallback,
overrideFromCL(Opts, Options),
Allowlist.get(), Blocklist.get());
diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
index 216fb3b5eb9fe7..59e03878428e3d 100644
--- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -153,7 +153,8 @@ void insertModuleCtor(Module &M) {
PreservedAnalyses ThreadSanitizerPass::run(Function &F,
FunctionAnalysisManager &FAM) {
- ThreadSanitizer TSan(InstrumentationOptions::Global);
+ ThreadSanitizer TSan(
+ F.getContext().getLibraryOptions().get<InstrumentationOptions>());
if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index e2d9cc4450ff66..1ef88566dd260d 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -964,7 +964,8 @@ PreservedAnalyses TypeSanitizerPass::run(Module &M,
kTysanInitName, /*InitArgTypes=*/{},
/*InitArgs=*/{});
- const InstrumentationOptions &Opts = InstrumentationOptions::Global;
+ const InstrumentationOptions &Opts =
+ M.getContext().getLibraryOptions().get<InstrumentationOptions>();
TypeSanitizer TySan(Opts, M);
TySan.instrumentGlobals(M);
appendToGlobalCtors(M, TysanCtorFunction, 0);
diff --git a/llvm/lib/Transforms/Instrumentation/ValueProfilePlugins.inc b/llvm/lib/Transforms/Instrumentation/ValueProfilePlugins.inc
index 24fe43e67910ff..c052ee69912f34 100644
--- a/llvm/lib/Transforms/Instrumentation/ValueProfilePlugins.inc
+++ b/llvm/lib/Transforms/Instrumentation/ValueProfilePlugins.inc
@@ -24,6 +24,7 @@ using CandidateInfo = ValueProfileCollector::CandidateInfo;
///--------------------------- MemIntrinsicPlugin ------------------------------
class MemIntrinsicPlugin : public InstVisitor<MemIntrinsicPlugin> {
+ const InstrumentationOptions &Opts;
Function &F;
TargetLibraryInfo &TLI;
std::vector<CandidateInfo> *Candidates;
@@ -32,7 +33,8 @@ public:
static constexpr InstrProfValueKind Kind = IPVK_MemOPSize;
MemIntrinsicPlugin(Function &Fn, TargetLibraryInfo &TLI)
- : F(Fn), TLI(TLI), Candidates(nullptr) {}
+ : Opts(Fn.getContext().getLibraryOptions().get<InstrumentationOptions>()),
+ F(Fn), TLI(TLI), Candidates(nullptr) {}
void run(std::vector<CandidateInfo> &Cs) {
Candidates = &Cs;
@@ -50,7 +52,7 @@ public:
Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst});
}
void visitCallInst(CallInst &CI) {
- if (!InstrumentationOptions::Global.pgo_memop_optimize_memcmp_bcmp)
+ if (!Opts.pgo_memop_optimize_memcmp_bcmp)
return;
auto *F = CI.getCalledFunction();
if (!F)
diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp
index 2e71d080687826..ca55c0cdb8576f 100644
--- a/llvm/lib/Transforms/Scalar/ADCE.cpp
+++ b/llvm/lib/Transforms/Scalar/ADCE.cpp
@@ -163,9 +163,9 @@ class AggressiveDeadCodeElimination {
void makeUnconditional(BasicBlock *BB, BasicBlock *Target);
public:
- AggressiveDeadCodeElimination(Function &F, DominatorTree *DT,
- PostDominatorTree &PDT)
- : Opts(ScalarOptions::Global), F(F), DT(DT), PDT(PDT) {}
+ AggressiveDeadCodeElimination(const ScalarOptions &Opts, Function &F,
+ DominatorTree *DT, PostDominatorTree &PDT)
+ : Opts(Opts), F(F), DT(DT), PDT(PDT) {}
ADCEChanged performDeadCodeElimination();
};
@@ -588,8 +588,10 @@ PreservedAnalyses ADCEPass::run(Function &F, FunctionAnalysisManager &FAM) {
// to update analysis if it is already available.
auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
auto &PDT = FAM.getResult<PostDominatorTreeAnalysis>(F);
- ADCEChanged Changed =
- AggressiveDeadCodeElimination(F, DT, PDT).performDeadCodeElimination();
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ ADCEChanged Changed = AggressiveDeadCodeElimination(Opts, F, DT, PDT)
+ .performDeadCodeElimination();
if (!Changed.ChangedAnything)
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp
index d7c201c5753b35..ab4d0a079cab33 100644
--- a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp
+++ b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp
@@ -172,7 +172,8 @@ static SmallVector<BasicBlock *, 2> getTwoPredecessors(BasicBlock *BB) {
return Preds;
}
-static bool canSplitCallSite(CallBase &CB, TargetTransformInfo &TTI) {
+static bool canSplitCallSite(const ScalarOptions &Opts, CallBase &CB,
+ TargetTransformInfo &TTI) {
if (CB.isConvergent() || CB.cannotDuplicate())
return false;
@@ -202,7 +203,7 @@ static bool canSplitCallSite(CallBase &CB, TargetTransformInfo &TTI) {
llvm::make_range(CallSiteBB->begin(), CB.getIterator())) {
Cost += TTI.getInstructionCost(&InstBeforeCall,
TargetTransformInfo::TCK_CodeSize);
- if (Cost >= ScalarOptions::Global.callsite_splitting_duplication_threshold)
+ if (Cost >= Opts.callsite_splitting_duplication_threshold)
return false;
}
@@ -475,10 +476,10 @@ static PredsWithCondsTy shouldSplitOnPredicatedArgument(CallBase &CB,
return PredsCS;
}
-static bool tryToSplitCallSite(CallBase &CB, TargetTransformInfo &TTI,
- DomTreeUpdater &DTU) {
+static bool tryToSplitCallSite(const ScalarOptions &Opts, CallBase &CB,
+ TargetTransformInfo &TTI, DomTreeUpdater &DTU) {
// Check if we can split the call site.
- if (!CB.arg_size() || !canSplitCallSite(CB, TTI))
+ if (!CB.arg_size() || !canSplitCallSite(Opts, CB, TTI))
return false;
auto PredsWithConds = shouldSplitOnPredicatedArgument(CB, DTU);
@@ -494,6 +495,8 @@ static bool tryToSplitCallSite(CallBase &CB, TargetTransformInfo &TTI,
static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI,
TargetTransformInfo &TTI, DominatorTree &DT) {
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
DomTreeUpdater DTU(&DT, DomTreeUpdater::UpdateStrategy::Lazy);
bool Changed = false;
for (BasicBlock &BB : llvm::make_early_inc_range(F)) {
@@ -516,7 +519,7 @@ static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI,
// Check if such path is possible before attempting the splitting.
bool IsMustTail = CB->isMustTailCall();
- Changed |= tryToSplitCallSite(*CB, TTI, DTU);
+ Changed |= tryToSplitCallSite(Opts, *CB, TTI, DTU);
// There're no interesting instructions after this. The call site
// itself might have been erased on splitting.
diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
index 03a79ac734f719..723a301215937a 100644
--- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
@@ -92,8 +92,7 @@ class ConstantHoistingLegacyPass : public FunctionPass {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
- if (ScalarOptions::Global.consthoist_with_block_frequency)
- AU.addRequired<BlockFrequencyInfoWrapperPass>();
+ AU.addRequired<BlockFrequencyInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<ProfileSummaryInfoWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
@@ -128,10 +127,12 @@ bool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) {
LLVM_DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n");
LLVM_DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n');
+ const ScalarOptions &Opts =
+ Fn.getContext().getLibraryOptions().get<ScalarOptions>();
bool MadeChange =
Impl.runImpl(Fn, getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn),
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
- ScalarOptions::Global.consthoist_with_block_frequency
+ Opts.consthoist_with_block_frequency
? &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI()
: nullptr,
Fn.getEntryBlock(),
@@ -463,7 +464,7 @@ void ConstantHoistingPass::collectConstantCandidates(
// Visit constant expressions that have constant integers.
if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) {
// Handle constant gep expressions.
- if (ScalarOptions::Global.consthoist_gep && isa<GEPOperator>(ConstExpr))
+ if (Opts->consthoist_gep && isa<GEPOperator>(ConstExpr))
collectConstantCandidates(ConstCandMap, Inst, Idx, ConstExpr);
// Only visit constant cast expressions.
@@ -846,8 +847,7 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {
// If only few constants depend on this IP of base, skip rebasing,
// assuming the base and the rebased have the same materialization cost.
- if (ToBeRebased.size() <
- ScalarOptions::Global.consthoist_min_num_to_rebase) {
+ if (ToBeRebased.size() < Opts->consthoist_min_num_to_rebase) {
NotRebasedNum += ToBeRebased.size();
continue;
}
@@ -912,6 +912,7 @@ void ConstantHoistingPass::deleteDeadCastInst() const {
bool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI,
DominatorTree &DT, BlockFrequencyInfo *BFI,
BasicBlock &Entry, ProfileSummaryInfo *PSI) {
+ this->Opts = &Fn.getContext().getLibraryOptions().get<ScalarOptions>();
this->TTI = &TTI;
this->DT = &DT;
this->BFI = BFI;
@@ -955,7 +956,9 @@ PreservedAnalyses ConstantHoistingPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
- auto BFI = ScalarOptions::Global.consthoist_with_block_frequency
+ const ScalarOptions &CLOpts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ auto BFI = CLOpts.consthoist_with_block_frequency
? &AM.getResult<BlockFrequencyAnalysis>(F)
: nullptr;
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 51c118e995096f..be051f7a404643 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -2393,7 +2393,8 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
ScalarEvolution *SE,
OptimizationRemarkEmitter &ORE,
TargetLibraryInfo &TLI) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool Changed = false;
DT.updateDFSNumbers();
SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
diff --git a/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp b/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp
index ac8dfc8f3867ca..cc2f92520223d5 100644
--- a/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp
@@ -108,10 +108,10 @@ class SelectInstToUnfold {
class DFAJumpThreading {
public:
- DFAJumpThreading(AssumptionCache *AC, DomTreeUpdater *DTU, LoopInfo *LI,
- TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE)
- : Opts(ScalarOptions::Global), AC(AC), DTU(DTU), LI(LI), TTI(TTI),
- ORE(ORE) {}
+ DFAJumpThreading(const ScalarOptions &Opts, AssumptionCache *AC,
+ DomTreeUpdater *DTU, LoopInfo *LI, TargetTransformInfo *TTI,
+ OptimizationRemarkEmitter *ORE)
+ : Opts(Opts), AC(AC), DTU(DTU), LI(LI), TTI(TTI), ORE(ORE) {}
bool run(Function &F);
bool LoopInfoBroken;
@@ -1530,7 +1530,9 @@ PreservedAnalyses DFAJumpThreadingPass::run(Function &F,
OptimizationRemarkEmitter ORE(&F);
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
- DFAJumpThreading ThreadImpl(&AC, &DTU, &LI, &TTI, &ORE);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ DFAJumpThreading ThreadImpl(Opts, &AC, &DTU, &LI, &TTI, &ORE);
if (!ThreadImpl.run(F))
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 1266fd0708bfe4..4e74bb5a5f9c01 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -2719,7 +2719,8 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA,
DominatorTree &DT, PostDominatorTree &PDT,
const TargetLibraryInfo &TLI,
const CycleInfo &CI) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool MadeChange = false;
DSEState State(Opts, F, AA, MSSA, DT, PDT, TLI, CI);
// For each store:
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index ccd923cf7cc792..e085316cb4d439 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -269,13 +269,18 @@ static unsigned getHashValueImpl(SimpleValue Val) {
hash_combine_range(Inst->operand_values()));
}
+#ifndef NDEBUG
+// -earlycse-debug-hash of the function being processed, bound once per run.
+static LLVM_THREAD_LOCAL bool DebugHash;
+#endif
+
unsigned DenseMapInfo<SimpleValue>::getHashValue(SimpleValue Val) {
#ifndef NDEBUG
// If -earlycse-debug-hash was specified, return a constant -- this
// will force all hashing to collide, so we'll exhaustively search
// the table for a match, and the assertion in isEqual will fire if
// there's a bug causing equal keys to hash differently.
- if (ScalarOptions::Global.earlycse_debug_hash)
+ if (DebugHash)
return 0;
#endif
return getHashValueImpl(Val);
@@ -499,6 +504,7 @@ namespace {
/// expected that a later pass of GVN will catch the interesting/hard cases.
class EarlyCSE {
public:
+ const ScalarOptions &Opts;
const TargetLibraryInfo &TLI;
const TargetTransformInfo &TTI;
DominatorTree &DT;
@@ -589,11 +595,11 @@ class EarlyCSE {
unsigned CurrentGeneration = 0;
/// Set up the EarlyCSE runner for a particular function.
- EarlyCSE(const DataLayout &DL, const TargetLibraryInfo &TLI,
- const TargetTransformInfo &TTI, DominatorTree &DT,
- AssumptionCache &AC, MemorySSA *MSSA)
- : TLI(TLI), TTI(TTI), DT(DT), AC(AC), SQ(DL, &TLI, &DT, &AC), MSSA(MSSA),
- MSSAUpdater(std::make_unique<MemorySSAUpdater>(MSSA)) {}
+ EarlyCSE(const ScalarOptions &Opts, const DataLayout &DL,
+ const TargetLibraryInfo &TLI, const TargetTransformInfo &TTI,
+ DominatorTree &DT, AssumptionCache &AC, MemorySSA *MSSA)
+ : Opts(Opts), TLI(TLI), TTI(TTI), DT(DT), AC(AC), SQ(DL, &TLI, &DT, &AC),
+ MSSA(MSSA), MSSAUpdater(std::make_unique<MemorySSAUpdater>(MSSA)) {}
bool run();
@@ -1019,7 +1025,7 @@ bool EarlyCSE::isSameMemGeneration(unsigned EarlierGeneration,
// EarlierInst and LaterInst and neither can any other write that potentially
// clobbers LaterInst.
MemoryAccess *LaterDef;
- if (ClobberCounter < ScalarOptions::Global.earlycse_mssa_optimization_cap) {
+ if (ClobberCounter < Opts.earlycse_mssa_optimization_cap) {
LaterDef = MSSA->getWalker()->getClobberingMemoryAccess(LaterInst);
ClobberCounter++;
} else
@@ -1682,6 +1688,9 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
}
bool EarlyCSE::run() {
+#ifndef NDEBUG
+ DebugHash = Opts.earlycse_debug_hash;
+#endif
// Note, deque is being used here because there is significant performance
// gains over vector when the container becomes very large due to the
// specific access patterns. For more information see the mailing list
@@ -1741,7 +1750,8 @@ PreservedAnalyses EarlyCSEPass::run(Function &F,
auto *MSSA =
UseMemorySSA ? &AM.getResult<MemorySSAAnalysis>(F).getMSSA() : nullptr;
- EarlyCSE CSE(F.getDataLayout(), TLI, TTI, DT, AC, MSSA);
+ EarlyCSE CSE(F.getContext().getLibraryOptions().get<ScalarOptions>(),
+ F.getDataLayout(), TLI, TTI, DT, AC, MSSA);
if (!CSE.run())
return PreservedAnalyses::all();
@@ -1795,7 +1805,8 @@ class EarlyCSELegacyCommonPass : public FunctionPass {
auto *MSSA =
UseMemorySSA ? &getAnalysis<MemorySSAWrapperPass>().getMSSA() : nullptr;
- EarlyCSE CSE(F.getDataLayout(), TLI, TTI, DT, AC, MSSA);
+ EarlyCSE CSE(F.getContext().getLibraryOptions().get<ScalarOptions>(),
+ F.getDataLayout(), TLI, TTI, DT, AC, MSSA);
return CSE.run();
}
diff --git a/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp b/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp
index a22a2e5e62f089..bd111ebc09c847 100644
--- a/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp
+++ b/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp
@@ -961,11 +961,10 @@ Value *MemCmpExpansion::getMemCmpExpansion() {
/// %loadbb3
/// %phi.res = phi i32 [ %48, %loadbb3 ], [ %11, %res_block ]
/// ret i32 %phi.res
-static bool expandMemCmp(CallInst *CI, const TargetTransformInfo *TTI,
- const DataLayout *DL, ProfileSummaryInfo *PSI,
- BlockFrequencyInfo *BFI, DomTreeUpdater *DTU,
- const bool IsBCmp) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+static bool expandMemCmp(const ScalarOptions &Opts, CallInst *CI,
+ const TargetTransformInfo *TTI, const DataLayout *DL,
+ ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
+ DomTreeUpdater *DTU, const bool IsBCmp) {
NumMemCmpCalls++;
// Early exit from expansion if -Oz.
@@ -1064,9 +1063,11 @@ static PreservedAnalyses runImpl(Function &F, const TargetLibraryInfo *TLI,
}
}
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool MadeChanges = false;
for (const auto &[CI, Func] : MemCmpCalls) {
- if (expandMemCmp(CI, TTI, &DL, PSI, BFI, DTU ? &*DTU : nullptr,
+ if (expandMemCmp(Opts, CI, TTI, &DL, PSI, BFI, DTU ? &*DTU : nullptr,
Func == LibFunc_bcmp))
MadeChanges = true;
}
diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp
index b8509db5934c62..acb828c0030a7d 100644
--- a/llvm/lib/Transforms/Scalar/Float2Int.cpp
+++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp
@@ -484,8 +484,9 @@ bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) {
ConvertedInsts.clear();
Roots.clear();
- MaxIntegerBW = ScalarOptions::Global.float2int_max_integer_bw;
Ctx = &F.getParent()->getContext();
+ MaxIntegerBW =
+ Ctx->getLibraryOptions().get<ScalarOptions>().float2int_max_integer_bw;
findRoots(F, DT);
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 113b3abf484cde..4b63a50713baa8 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -240,15 +240,14 @@ class GVNLegacyPass;
/// FIXME: We should have a good summary of the GVN algorithm implemented by
/// this particular pass here.
class llvm::GVNPassImpl {
- const ScalarOptions &Opts;
+ const ScalarOptions *Opts = nullptr;
llvm::GVNOptions Options;
public:
struct AvailableValue;
struct AvailableValueInBlock;
- GVNPassImpl(llvm::GVNOptions Options = {})
- : Opts(ScalarOptions::Global), Options(Options) {}
+ GVNPassImpl(llvm::GVNOptions Options = {}) : Options(Options) {}
/// This removes the specified instruction from
/// our various maps and marks it for deletion.
@@ -1127,20 +1126,20 @@ void GVNLeaderMap::erase(uint32_t N, Instruction *I, const BasicBlock *BB) {
//===----------------------------------------------------------------------===//
bool GVNPassImpl::isScalarPREEnabled() const {
- return Options.AllowScalarPRE.value_or(Opts.enable_scalar_pre);
+ return Options.AllowScalarPRE.value_or(Opts->enable_scalar_pre);
}
bool GVNPassImpl::isLoadPREEnabled() const {
- return Options.AllowLoadPRE.value_or(Opts.enable_load_pre);
+ return Options.AllowLoadPRE.value_or(Opts->enable_load_pre);
}
bool GVNPassImpl::isLoadInLoopPREEnabled() const {
- return Options.AllowLoadInLoopPRE.value_or(Opts.enable_load_in_loop_pre);
+ return Options.AllowLoadInLoopPRE.value_or(Opts->enable_load_in_loop_pre);
}
bool GVNPassImpl::isLoadPRESplitBackedgeEnabled() const {
return Options.AllowLoadPRESplitBackedge.value_or(
- Opts.enable_split_backedge_in_load_pre);
+ Opts->enable_split_backedge_in_load_pre);
}
bool GVNPassImpl::isMemDepEnabled() const {
@@ -1149,11 +1148,11 @@ bool GVNPassImpl::isMemDepEnabled() const {
// overrides default independently, so honor MemorySSA winning here too.
if (isMemorySSAEnabled())
return Options.AllowMemDep.value_or(false);
- return Options.AllowMemDep.value_or(valueOr(Opts.enable_gvn_memdep, true));
+ return Options.AllowMemDep.value_or(valueOr(Opts->enable_gvn_memdep, true));
}
bool GVNPassImpl::isMemorySSAEnabled() const {
- return Options.AllowMemorySSA.value_or(Opts.enable_gvn_memoryssa);
+ return Options.AllowMemorySSA.value_or(Opts->enable_gvn_memoryssa);
}
GVNPass::GVNPass(GVNOptions Options)
@@ -1170,6 +1169,7 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
// significant! Re-ordering these variables will cause GVN when run alone to
// be less effective! We should fix memdep and basic-aa to not exhibit this
// behavior, but until then don't change the order here.
+ Impl->Opts = &F.getContext().getLibraryOptions().get<ScalarOptions>();
auto &AC = AM.getResult<AssumptionAnalysis>(F);
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
@@ -1627,11 +1627,11 @@ GVNPassImpl::analyzeSelectAvailability(LoadInst *Load, SelectInst *Sel,
// loaded values only if both sides have a dominating, non-clobbered value of
// the right type in the extended basic block ending at From.
auto Loc = MemoryLocation::get(Load);
- Value *V1 = findDominatingValue(Opts, Loc.getWithNewPtr(TrueAddr),
+ Value *V1 = findDominatingValue(*Opts, Loc.getWithNewPtr(TrueAddr),
Load->getType(), From, getAliasAnalysis());
if (!V1)
return std::nullopt;
- Value *V2 = findDominatingValue(Opts, Loc.getWithNewPtr(FalseAddr),
+ Value *V2 = findDominatingValue(*Opts, Loc.getWithNewPtr(FalseAddr),
Load->getType(), From, getAliasAnalysis());
if (!V2)
return std::nullopt;
@@ -1869,7 +1869,7 @@ LoadInst *GVNPassImpl::findLoadToHoistIntoPred(BasicBlock *Pred,
if (!SuccBB->getSinglePredecessor())
return nullptr;
- unsigned int NumInsts = Opts.gvn_max_num_insns;
+ unsigned int NumInsts = Opts->gvn_max_num_insns;
for (Instruction &Inst : *SuccBB) {
if (isa<PseudoProbeInst>(Inst))
continue;
@@ -2080,7 +2080,7 @@ bool GVNPassImpl::performLoadPRE(LoadInst *Load,
return false;
}
- if (isValueFullyAvailableInBlock(Opts, Pred, FullyAvailableBlocks)) {
+ if (isValueFullyAvailableInBlock(*Opts, Pred, FullyAvailableBlocks)) {
continue;
}
@@ -2361,7 +2361,7 @@ bool GVNPassImpl::processNonLocalLoad(LoadInst *Load) {
// dependencies, this load isn't worth worrying about. Optimizing
// it will be too expensive.
unsigned NumDeps = Deps.size();
- if (NumDeps > Opts.gvn_max_num_deps)
+ if (NumDeps > Opts->gvn_max_num_deps)
return false;
SmallVector<ReachingMemVal, 64> MemVals;
@@ -2653,7 +2653,7 @@ std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::scanMemoryAccessesUsers(
for (MemoryAccess *MA : ClobbersList) {
unsigned Scanned = 0;
for (User *U : MA->users()) {
- if (++Scanned >= Opts.gvn_scan_users_limit)
+ if (++Scanned >= Opts->gvn_scan_users_limit)
return ReachingMemVal::getUnknown(BB, Loc.Ptr);
auto *UseOrDef = dyn_cast<MemoryUseOrDef>(U);
@@ -2745,7 +2745,7 @@ std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::accessMayModifyLocation(
// the latter unchanged.
if (auto *SI = dyn_cast<StoreInst>(ClobberI))
if (isStorePreservingMemoryLocation(SI, Loc, LoadAlign, AA,
- Opts.gvn_max_num_insns))
+ Opts->gvn_max_num_insns))
return std::nullopt;
if (AR == AliasResult::MayAlias ||
@@ -2979,7 +2979,7 @@ bool GVNPassImpl::findReachingValuesForLoad(
auto Worklist = InitialWorklist;
while (!Worklist.empty()) {
// Match MemDep's cutoff for expensive non-local queries.
- if (Blocks.size() > Opts.gvn_max_num_reaching_blocks)
+ if (Blocks.size() > Opts->gvn_max_num_reaching_blocks)
return false;
auto *BB = Worklist.pop_back_val();
DependencyBlockInfo &Info = Blocks.find(BB)->second;
@@ -3832,8 +3832,8 @@ bool GVNPassImpl::run(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
// lets MemorySSA win for the common single-flag case, but an explicit
// request for both via -enable-gvn-{memdep,memoryssa} is a contradiction we
// reject rather than resolve arbitrarily.
- if (Opts.enable_gvn_memdep == BoolOrDefault::True &&
- Opts.enable_gvn_memoryssa)
+ if (Opts->enable_gvn_memdep == BoolOrDefault::True &&
+ Opts->enable_gvn_memoryssa)
report_fatal_error("GVN: -enable-gvn-memdep and -enable-gvn-memoryssa are "
"mutually exclusive",
/*gen_crash_diag=*/false);
@@ -4377,15 +4377,8 @@ class GVNLegacyPass : public FunctionPass {
public:
static char ID; // Pass identification, replacement for typeid.
- explicit GVNLegacyPass(
- bool MemDepAnalysis = valueOr(ScalarOptions::Global.enable_gvn_memdep,
- true),
- bool MemSSAAnalysis = ScalarOptions::Global.enable_gvn_memoryssa,
- bool ScalarPRE = true)
- : FunctionPass(ID), Impl(GVNOptions()
- .setMemDep(MemDepAnalysis)
- .setMemorySSA(MemSSAAnalysis)
- .setScalarPRE(ScalarPRE)) {
+ explicit GVNLegacyPass(bool ScalarPRE = true)
+ : FunctionPass(ID), Impl(GVNOptions().setScalarPRE(ScalarPRE)) {
initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry());
}
@@ -4393,21 +4386,27 @@ class GVNLegacyPass : public FunctionPass {
if (skipFunction(F))
return false;
- auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
- if (Impl.isMemorySSAEnabled() && !MSSAWP)
- MSSAWP = &getAnalysis<MemorySSAWrapperPass>();
+ Impl.Opts = &F.getContext().getLibraryOptions().get<ScalarOptions>();
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
+ MemorySSA *MSSA = nullptr;
+ std::unique_ptr<MemorySSA> LocalMSSA;
+ if (auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>()) {
+ MSSA = &MSSAWP->getMSSA();
+ } else if (Impl.isMemorySSAEnabled()) {
+ // getAnalysisUsage cannot read the context's -enable-gvn-memoryssa.
+ LocalMSSA = std::make_unique<MemorySSA>(F, &AA, &DT);
+ MSSA = LocalMSSA.get();
+ }
return Impl.run(
- F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
- getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
- getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F),
- getAnalysis<AAResultsWrapperPass>().getAAResults(),
+ F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F), DT,
+ getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F), AA,
Impl.isMemDepEnabled()
? &getAnalysis<MemoryDependenceWrapperPass>().getMemDep()
: nullptr,
getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
- &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(),
- MSSAWP ? &MSSAWP->getMSSA() : nullptr);
+ &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(), MSSA);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -4415,8 +4414,7 @@ class GVNLegacyPass : public FunctionPass {
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<LoopInfoWrapperPass>();
- if (Impl.isMemDepEnabled())
- AU.addRequired<MemoryDependenceWrapperPass>();
+ AU.addRequired<MemoryDependenceWrapperPass>();
AU.addRequired<AAResultsWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
@@ -4424,8 +4422,6 @@ class GVNLegacyPass : public FunctionPass {
AU.addPreserved<LoopInfoWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
AU.addPreserved<MemorySSAWrapperPass>();
- if (Impl.isMemorySSAEnabled())
- AU.addRequired<MemorySSAWrapperPass>();
}
private:
@@ -4448,7 +4444,5 @@ INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false
// The public interface to this file...
FunctionPass *llvm::createGVNPass() { return new GVNLegacyPass(); }
FunctionPass *llvm::createGVNPass(bool ScalarPRE) {
- const ScalarOptions &Opts = ScalarOptions::Global;
- return new GVNLegacyPass(valueOr(Opts.enable_gvn_memdep, true),
- Opts.enable_gvn_memoryssa, ScalarPRE);
+ return new GVNLegacyPass(ScalarPRE);
}
diff --git a/llvm/lib/Transforms/Scalar/GVNHoist.cpp b/llvm/lib/Transforms/Scalar/GVNHoist.cpp
index 86fe5177a0fba9..200ef27cf8af04 100644
--- a/llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ b/llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -222,9 +222,9 @@ class CallInfo {
// cases reduce critical path (by exposing more ILP).
class GVNHoist {
public:
- GVNHoist(DominatorTree *DT, PostDominatorTree *PDT, AliasAnalysis *AA,
- MemorySSA *MSSA)
- : Opts(ScalarOptions::Global), DT(DT), PDT(PDT), AA(AA), MSSA(MSSA),
+ GVNHoist(const ScalarOptions &Opts, DominatorTree *DT, PostDominatorTree *PDT,
+ AliasAnalysis *AA, MemorySSA *MSSA)
+ : Opts(Opts), DT(DT), PDT(PDT), AA(AA), MSSA(MSSA),
MSSAUpdater(std::make_unique<MemorySSAUpdater>(MSSA)) {
MSSA->ensureOptimizedUses();
}
@@ -1187,7 +1187,9 @@ PreservedAnalyses GVNHoistPass::run(Function &F, FunctionAnalysisManager &AM) {
PostDominatorTree &PDT = AM.getResult<PostDominatorTreeAnalysis>(F);
AliasAnalysis &AA = AM.getResult<AAManager>(F);
MemorySSA &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
- GVNHoist G(&DT, &PDT, &AA, &MSSA);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ GVNHoist G(Opts, &DT, &PDT, &AA, &MSSA);
if (!G.run(F))
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
index 3675f3d24d5313..0b236424e7580a 100644
--- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp
+++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
@@ -125,6 +125,7 @@ findInsertionPointForWideCondition(Instruction *WCOrGuard) {
namespace {
class GuardWideningImpl {
+ const ScalarOptions &Opts;
DominatorTree &DT;
PostDominatorTree *PDT;
LoopInfo &LI;
@@ -312,11 +313,12 @@ class GuardWideningImpl {
}
public:
- explicit GuardWideningImpl(DominatorTree &DT, PostDominatorTree *PDT,
- LoopInfo &LI, AssumptionCache &AC,
- MemorySSAUpdater *MSSAU, DomTreeNode *Root,
+ explicit GuardWideningImpl(const ScalarOptions &Opts, DominatorTree &DT,
+ PostDominatorTree *PDT, LoopInfo &LI,
+ AssumptionCache &AC, MemorySSAUpdater *MSSAU,
+ DomTreeNode *Root,
std::function<bool(BasicBlock *)> BlockFilter)
- : DT(DT), PDT(PDT), LI(LI), AC(AC), MSSAU(MSSAU), Root(Root),
+ : Opts(Opts), DT(DT), PDT(PDT), LI(LI), AC(AC), MSSAU(MSSAU), Root(Root),
BlockFilter(BlockFilter) {}
/// The entry point for this pass.
@@ -324,11 +326,11 @@ class GuardWideningImpl {
};
} // namespace
-static bool isSupportedGuardInstruction(const Instruction *Insn) {
+static bool isSupportedGuardInstruction(const ScalarOptions &Opts,
+ const Instruction *Insn) {
if (isGuard(Insn))
return true;
- if (ScalarOptions::Global.guard_widening_widen_branch_guards &&
- isGuardAsWidenableBranch(Insn))
+ if (Opts.guard_widening_widen_branch_guards && isGuardAsWidenableBranch(Insn))
return true;
return false;
}
@@ -345,7 +347,7 @@ bool GuardWideningImpl::run() {
auto &CurrentList = GuardsInBlock[BB];
for (auto &I : *BB)
- if (isSupportedGuardInstruction(&I))
+ if (isSupportedGuardInstruction(Opts, &I))
CurrentList.push_back(cast<Instruction>(&I));
for (auto *II : CurrentList)
@@ -356,7 +358,7 @@ bool GuardWideningImpl::run() {
for (auto *I : EliminatedGuardsAndBranches)
if (!WidenedGuards.count(I)) {
assert(isa<ConstantInt>(getCondition(I)) && "Should be!");
- if (isSupportedGuardInstruction(I))
+ if (isSupportedGuardInstruction(Opts, I))
eliminateGuard(I, MSSAU);
else {
assert(isa<CondBrInst>(I) &&
@@ -990,7 +992,9 @@ PreservedAnalyses GuardWideningPass::run(Function &F,
std::unique_ptr<MemorySSAUpdater> MSSAU;
if (MSSAA)
MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAA->getMSSA());
- if (!GuardWideningImpl(DT, &PDT, LI, AC, MSSAU ? MSSAU.get() : nullptr,
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ if (!GuardWideningImpl(Opts, DT, &PDT, LI, AC, MSSAU ? MSSAU.get() : nullptr,
DT.getRootNode(), [](BasicBlock *) { return true; })
.run())
return PreservedAnalyses::all();
@@ -1013,7 +1017,9 @@ PreservedAnalyses GuardWideningPass::run(Loop &L, LoopAnalysisManager &AM,
std::unique_ptr<MemorySSAUpdater> MSSAU;
if (AR.MSSA)
MSSAU = std::make_unique<MemorySSAUpdater>(AR.MSSA);
- if (!GuardWideningImpl(AR.DT, nullptr, AR.LI, AR.AC,
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
+ if (!GuardWideningImpl(Opts, AR.DT, nullptr, AR.LI, AR.AC,
MSSAU ? MSSAU.get() : nullptr, AR.DT.getNode(RootBB),
BlockFilter)
.run())
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index 267eabedce27f0..55045ada06c10e 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -2183,7 +2183,8 @@ PreservedAnalyses IndVarSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,
LPMUpdater &) {
Function *F = L.getHeader()->getParent();
const DataLayout &DL = F->getDataLayout();
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F->getContext().getLibraryOptions().get<ScalarOptions>();
IndVarSimplify IVS(Opts, &AR.LI, &AR.SE, &AR.DT, DL, &AR.TLI, &AR.TTI,
AR.MSSA, WidenIndVars && Opts.indvars_widen_indvars);
diff --git a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
index 2e75ed6c9e2334..b700a73c60b521 100644
--- a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
@@ -861,7 +861,8 @@ IntersectUnsignedRange(ScalarEvolution &SE,
}
PreservedAnalyses IRCEPass::run(Function &F, FunctionAnalysisManager &AM) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
// There are no loops in the function. Return before computing other expensive
diff --git a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
index 1b659df769b58b..f10bdb8381ae19 100644
--- a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
@@ -38,10 +38,10 @@ struct JumpTableTy {
};
} // anonymous namespace
-static std::optional<JumpTableTy> parseJumpTable(GetElementPtrInst *GEP,
+static std::optional<JumpTableTy> parseJumpTable(const ScalarOptions &Opts,
+ GetElementPtrInst *GEP,
PointerType *PtrTy,
FunctionType *CallFTy) {
- const ScalarOptions &Opts = ScalarOptions::Global;
Constant *Ptr = dyn_cast<Constant>(GEP->getPointerOperand());
if (!Ptr)
return std::nullopt;
@@ -194,6 +194,8 @@ PreservedAnalyses JumpTableToSwitchPass::run(Function &F,
DominatorTree *DT = AM.getCachedResult<DominatorTreeAnalysis>(F);
PostDominatorTree *PDT = AM.getCachedResult<PostDominatorTreeAnalysis>(F);
DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool Changed = false;
auto FuncToGuid = [&](const Function &Fct) {
if (const auto MaybeGUID = Fct.getGUIDIfAssigned(); MaybeGUID)
@@ -221,7 +223,7 @@ PreservedAnalyses JumpTableToSwitchPass::run(Function &F,
auto *PtrTy = dyn_cast<PointerType>(L->getType());
assert(PtrTy && "call operand must be a pointer");
std::optional<JumpTableTy> JumpTable =
- parseJumpTable(GEP, PtrTy, Call->getFunctionType());
+ parseJumpTable(Opts, GEP, PtrTy, Call->getFunctionType());
if (!JumpTable)
continue;
SplittedOutTail =
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index ee12796d988842..21e9ddf33f5206 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -268,7 +268,7 @@ bool JumpThreadingPass::runImpl(Function &F_, FunctionAnalysisManager *FAM_,
BlockFrequencyInfo *BFI_,
BranchProbabilityInfo *BPI_) {
LLVM_DEBUG(dbgs() << "Jump threading on function '" << F_.getName() << "'\n");
- Opts = &ScalarOptions::Global;
+ Opts = &F_.getContext().getLibraryOptions().get<ScalarOptions>();
F = &F_;
FAM = FAM_;
TLI = TLI_;
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index a72aabfc3e1e0e..04c048a94bf9bb 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -116,12 +116,16 @@ STATISTIC(NumIntAssociationsHoisted,
STATISTIC(NumBOAssociationsHoisted, "Number of invariant BinaryOp expressions "
"reassociated and hoisted out of the loop");
-unsigned llvm::getLicmMssaOptCap() {
- return ScalarOptions::Global.licm_mssa_optimization_cap;
+unsigned
+llvm::getLicmMssaOptCap(const cl::LibraryOptionsContext *LibraryOptions) {
+ return cl::LibraryOptionsContext::get<ScalarOptions>(LibraryOptions)
+ .licm_mssa_optimization_cap;
}
-unsigned llvm::getLicmMssaNoAccForPromotionCap() {
- return ScalarOptions::Global.licm_mssa_max_acc_promotion;
+unsigned llvm::getLicmMssaNoAccForPromotionCap(
+ const cl::LibraryOptionsContext *LibraryOptions) {
+ return cl::LibraryOptionsContext::get<ScalarOptions>(LibraryOptions)
+ .licm_mssa_max_acc_promotion;
}
static bool inSubLoop(BasicBlock *BB, Loop *CurLoop, LoopInfo *LI);
@@ -151,7 +155,7 @@ static bool pointerInvalidatedByLoop(MemorySSA *MSSA, MemoryUse *MU,
static bool pointerInvalidatedByBlock(BasicBlock &BB, MemorySSA &MSSA,
MemoryUse &MU);
/// Aggregates various functions for hoisting computations out of loop.
-static bool hoistArithmetics(Instruction &I, Loop &L,
+static bool hoistArithmetics(const ScalarOptions &Opts, Instruction &I, Loop &L,
ICFLoopSafetyInfo &SafetyInfo,
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
DominatorTree *DT);
@@ -180,6 +184,10 @@ static SmallVector<PointersAndHasReadsOutsideSet, 0> collectPromotionCandidates(
ICFLoopSafetyInfo *SafetyInfo,
const SmallPtrSetImpl<const MDNode *> &LoopLocalAliasScopes, Loop *L);
+static const ScalarOptions &getScalarOptions(const Loop &L) {
+ return L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
+}
+
namespace {
struct LoopInvariantCodeMotion {
bool runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI, DominatorTree *DT,
@@ -187,14 +195,15 @@ struct LoopInvariantCodeMotion {
TargetTransformInfo *TTI, ScalarEvolution *SE, MemorySSA *MSSA,
OptimizationRemarkEmitter *ORE, bool LoopNestMode = false);
- LoopInvariantCodeMotion(unsigned LicmMssaOptCap,
- unsigned LicmMssaNoAccForPromotionCap,
- bool LicmAllowSpeculation)
- : LicmMssaOptCap(LicmMssaOptCap),
- LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap),
- LicmAllowSpeculation(LicmAllowSpeculation) {}
+ LoopInvariantCodeMotion(const ScalarOptions &Opts, const LICMOptions &LO)
+ : Opts(Opts),
+ LicmMssaOptCap(LO.MssaOptCap.value_or(Opts.licm_mssa_optimization_cap)),
+ LicmMssaNoAccForPromotionCap(LO.MssaNoAccForPromotionCap.value_or(
+ Opts.licm_mssa_max_acc_promotion)),
+ LicmAllowSpeculation(LO.AllowSpeculation) {}
private:
+ const ScalarOptions &Opts;
unsigned LicmMssaOptCap;
unsigned LicmMssaNoAccForPromotionCap;
bool LicmAllowSpeculation;
@@ -202,13 +211,7 @@ struct LoopInvariantCodeMotion {
struct LegacyLICMPass : public LoopPass {
static char ID; // Pass identification, replacement for typeid
- LegacyLICMPass(unsigned LicmMssaOptCap =
- ScalarOptions::Global.licm_mssa_optimization_cap,
- unsigned LicmMssaNoAccForPromotionCap =
- ScalarOptions::Global.licm_mssa_max_acc_promotion,
- bool LicmAllowSpeculation = true)
- : LoopPass(ID), LICM(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
- LicmAllowSpeculation) {
+ LegacyLICMPass() : LoopPass(ID) {
initializeLegacyLICMPassPass(*PassRegistry::getPassRegistry());
}
@@ -227,6 +230,9 @@ struct LegacyLICMPass : public LoopPass {
// pass. Function analyses need to be preserved across loop transformations
// but ORE cannot be preserved (see comment before the pass definition).
OptimizationRemarkEmitter ORE(L->getHeader()->getParent());
+ const ScalarOptions &Opts =
+ F->getContext().getLibraryOptions().get<ScalarOptions>();
+ LoopInvariantCodeMotion LICM(Opts, LICMOptions());
return LICM.runOnLoop(
L, &getAnalysis<AAResultsWrapperPass>().getAAResults(),
&getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
@@ -253,9 +259,6 @@ struct LegacyLICMPass : public LoopPass {
AU.addPreserved<LazyBlockFrequencyInfoPass>();
AU.addPreserved<LazyBranchProbabilityInfoPass>();
}
-
-private:
- LoopInvariantCodeMotion LICM;
};
} // namespace
@@ -269,8 +272,7 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
// but ORE cannot be preserved (see comment before the pass definition).
OptimizationRemarkEmitter ORE(L.getHeader()->getParent());
- LoopInvariantCodeMotion LICM(Opts.MssaOptCap, Opts.MssaNoAccForPromotionCap,
- Opts.AllowSpeculation);
+ LoopInvariantCodeMotion LICM(getScalarOptions(L), Opts);
if (!LICM.runOnLoop(&L, &AR.AA, &AR.LI, &AR.DT, &AR.AC, &AR.TLI, &AR.TTI,
&AR.SE, AR.MSSA, &ORE))
return PreservedAnalyses::all();
@@ -302,10 +304,9 @@ PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM,
// but ORE cannot be preserved (see comment before the pass definition).
OptimizationRemarkEmitter ORE(LN.getParent());
- LoopInvariantCodeMotion LICM(Opts.MssaOptCap, Opts.MssaNoAccForPromotionCap,
- Opts.AllowSpeculation);
-
Loop &OutermostLoop = LN.getOutermostLoop();
+ LoopInvariantCodeMotion LICM(getScalarOptions(OutermostLoop), Opts);
+
bool Changed = LICM.runOnLoop(&OutermostLoop, &AR.AA, &AR.LI, &AR.DT, &AR.AC,
&AR.TLI, &AR.TTI, &AR.SE, AR.MSSA, &ORE, true);
@@ -346,8 +347,8 @@ Pass *llvm::createLICMPass() { return new LegacyLICMPass(); }
llvm::SinkAndHoistLICMFlags::SinkAndHoistLICMFlags(bool IsSink, Loop &L,
MemorySSA &MSSA)
- : SinkAndHoistLICMFlags(ScalarOptions::Global.licm_mssa_optimization_cap,
- ScalarOptions::Global.licm_mssa_max_acc_promotion,
+ : SinkAndHoistLICMFlags(getScalarOptions(L).licm_mssa_optimization_cap,
+ getScalarOptions(L).licm_mssa_max_acc_promotion,
IsSink, L, MSSA) {}
llvm::SinkAndHoistLICMFlags::SinkAndHoistLICMFlags(
@@ -454,9 +455,8 @@ bool LoopInvariantCodeMotion::runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI,
// make sure we catch that. An additional load may be generated in the
// preheader for SSA updater, so also avoid sinking when no preheader
// is available.
- if (!ScalarOptions::Global.disable_licm_promotion && Preheader &&
- L->hasDedicatedExits() && !Flags.tooManyMemoryAccesses() &&
- !HasCoroSuspendInst) {
+ if (!Opts.disable_licm_promotion && Preheader && L->hasDedicatedExits() &&
+ !Flags.tooManyMemoryAccesses() && !HasCoroSuspendInst) {
// Figure out the loop exits and their insertion points
SmallVector<BasicBlock *, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
@@ -639,6 +639,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
CurLoop != nullptr && SafetyInfo != nullptr &&
"Unexpected input to hoistRegion.");
+ const ScalarOptions &Opts = getScalarOptions(*CurLoop);
LoopBlocksRPO Worklist(CurLoop);
Worklist.perform(LI);
bool Changed = false;
@@ -716,7 +717,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
// Try to reassociate instructions so that part of computations can be
// done out of loop.
- if (hoistArithmetics(I, *CurLoop, *SafetyInfo, MSSAU, AC, DT)) {
+ if (hoistArithmetics(Opts, I, *CurLoop, *SafetyInfo, MSSAU, AC, DT)) {
Changed = true;
continue;
}
@@ -837,12 +838,14 @@ static bool isLoadInvariantInLoop(LoadInst *LI, DominatorTree *DT,
if (isa<Constant>(Addr))
return false;
+ const ScalarOptions &Opts =
+ LI->getContext().getLibraryOptions().get<ScalarOptions>();
unsigned UsesVisited = 0;
// Traverse all uses of the load operand value, to see if invariant.start is
// one of the uses, and whether it dominates the load instruction.
for (auto *U : Addr->users()) {
// Avoid traversing for Load operand with high number of users.
- if (++UsesVisited > ScalarOptions::Global.licm_max_num_uses_traversed)
+ if (++UsesVisited > Opts.licm_max_num_uses_traversed)
return false;
IntrinsicInst *II = dyn_cast<IntrinsicInst>(U);
// If there are escaping uses of invariant.start instruction, the load maybe
@@ -2584,11 +2587,10 @@ static bool isReassociableOp(Instruction *I, unsigned IntOpcode,
/// ((A1 * C * B1) + (A2 * C * B2) + ...) and hoist the (A1 * C), (A2 * C), ...
/// invariant expressions. This functions returns true only if any hoisting has
/// actually occurred.
-static bool hoistMulAddAssociation(Instruction &I, Loop &L,
- ICFLoopSafetyInfo &SafetyInfo,
+static bool hoistMulAddAssociation(const ScalarOptions &Opts, Instruction &I,
+ Loop &L, ICFLoopSafetyInfo &SafetyInfo,
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
DominatorTree *DT) {
- const ScalarOptions &Opts = ScalarOptions::Global;
if (!isReassociableOp(&I, Instruction::Mul, Instruction::FMul))
return false;
Value *VariantOp = I.getOperand(0);
@@ -2854,7 +2856,7 @@ static bool hoistSubAddAssociation(Instruction &I, Loop &L,
return true;
}
-static bool hoistArithmetics(Instruction &I, Loop &L,
+static bool hoistArithmetics(const ScalarOptions &Opts, Instruction &I, Loop &L,
ICFLoopSafetyInfo &SafetyInfo,
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
DominatorTree *DT) {
@@ -2882,7 +2884,7 @@ static bool hoistArithmetics(Instruction &I, Loop &L,
}
bool IsInt = I.getType()->isIntOrIntVectorTy();
- if (hoistMulAddAssociation(I, L, SafetyInfo, MSSAU, AC, DT)) {
+ if (hoistMulAddAssociation(Opts, I, L, SafetyInfo, MSSAU, AC, DT)) {
++NumHoisted;
if (IsInt)
++NumIntAssociationsHoisted;
diff --git a/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp b/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp
index ed0ab6be395a47..490190b2fa71dc 100644
--- a/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp
@@ -41,11 +41,11 @@ namespace {
/// Loop prefetch implementation class.
class LoopDataPrefetch {
public:
- LoopDataPrefetch(AssumptionCache *AC, DominatorTree *DT, LoopInfo *LI,
- ScalarEvolution *SE, const TargetTransformInfo *TTI,
+ LoopDataPrefetch(const ScalarOptions &Opts, AssumptionCache *AC,
+ DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE,
+ const TargetTransformInfo *TTI,
OptimizationRemarkEmitter *ORE)
- : Opts(ScalarOptions::Global), AC(AC), DT(DT), LI(LI), SE(SE), TTI(TTI),
- ORE(ORE) {}
+ : Opts(Opts), AC(AC), DT(DT), LI(LI), SE(SE), TTI(TTI), ORE(ORE) {}
bool run();
@@ -159,7 +159,9 @@ PreservedAnalyses LoopDataPrefetchPass::run(Function &F,
&AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
const TargetTransformInfo *TTI = &AM.getResult<TargetIRAnalysis>(F);
- LoopDataPrefetch LDP(AC, DT, LI, SE, TTI, ORE);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ LoopDataPrefetch LDP(Opts, AC, DT, LI, SE, TTI, ORE);
bool Changed = LDP.run();
if (Changed) {
@@ -186,7 +188,9 @@ bool LoopDataPrefetchLegacyPass::runOnFunction(Function &F) {
const TargetTransformInfo *TTI =
&getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- LoopDataPrefetch LDP(AC, DT, LI, SE, TTI, ORE);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ LoopDataPrefetch LDP(Opts, AC, DT, LI, SE, TTI, ORE);
return LDP.run();
}
diff --git a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
index 2dc696edc5accd..ce121bd6ef708b 100644
--- a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -212,7 +212,11 @@ getValueOnFirstIteration(Value *V, DenseMap<Value *, Value *> &FirstIterValue,
static bool canProveExitOnFirstIteration(Loop *L, DominatorTree &DT,
LoopInfo &LI) {
// Disabled by option.
- if (!ScalarOptions::Global.loop_deletion_enable_symbolic_execution)
+ if (!L->getHeader()
+ ->getContext()
+ .getLibraryOptions()
+ .get<ScalarOptions>()
+ .loop_deletion_enable_symbolic_execution)
return false;
BasicBlock *Predecessor = L->getLoopPredecessor();
diff --git a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
index 0044174efcb664..317d70f7a0a6dc 100644
--- a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
@@ -958,7 +958,8 @@ static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
Worklist.push_back(L);
// Now walk the identified inner loops.
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool Changed = false;
for (Loop *L : Worklist) {
LoopDistributeForLoop LDL(Opts, L, &F, LI, DT, SE, LAIs, ORE);
diff --git a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
index f1fe6f5d4d87f8..89ceabbbf06603 100644
--- a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
@@ -131,8 +131,8 @@ struct FlattenInfo {
Value *NewTripCount = nullptr; // The tripcount of the flattened loop.
- FlattenInfo(Loop *OL, Loop *IL)
- : Opts(ScalarOptions::Global), OuterLoop(OL), InnerLoop(IL) {}
+ FlattenInfo(const ScalarOptions &Opts, Loop *OL, Loop *IL)
+ : Opts(Opts), OuterLoop(OL), InnerLoop(IL) {}
bool isNarrowInductionPhi(PHINode *Phi) {
// This can't be the narrow phi if we haven't widened the IV first.
@@ -994,11 +994,13 @@ PreservedAnalyses LoopFlattenPass::run(LoopNest &LN, LoopAnalysisManager &LAM,
// regardless of whether anything ends up being flattened.
LoopAccessInfoManager LAIM(AR.SE, AR.AA, AR.DT, AR.LI, &AR.TTI, nullptr,
&AR.AC);
+ const ScalarOptions &Opts =
+ LN.getParent()->getContext().getLibraryOptions().get<ScalarOptions>();
for (Loop *InnerLoop : LN.getLoops()) {
auto *OuterLoop = InnerLoop->getParentLoop();
if (!OuterLoop)
continue;
- FlattenInfo FI(OuterLoop, InnerLoop);
+ FlattenInfo FI(Opts, OuterLoop, InnerLoop);
Changed |=
FlattenLoopPair(FI, &AR.DT, &AR.LI, &AR.SE, &AR.AC, &AR.TTI, &U,
MSSAU ? &*MSSAU : nullptr, LAIM.getInfo(*OuterLoop));
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index b9e65fb0ed5209..464a8e933f4311 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -2053,7 +2053,9 @@ PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) {
if (Changed)
PDT.recalculate(F);
- LoopFuser LF(ScalarOptions::Global, LI, DT, DI, AA, SE, PDT, ORE, AC, TTI);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ LoopFuser LF(Opts, LI, DT, DI, AA, SE, PDT, ORE, AC, TTI);
Changed |= LF.fuseLoops(F);
if (!Changed)
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index a188c33528e5e9..f3ad76afabd1aa 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -176,14 +176,14 @@ class LoopIdiomRecognize {
std::unique_ptr<MemorySSAUpdater> MSSAU;
public:
- explicit LoopIdiomRecognize(AliasAnalysis *AA, DominatorTree *DT,
- LoopInfo *LI, ScalarEvolution *SE,
- TargetLibraryInfo *TLI,
+ explicit LoopIdiomRecognize(const ScalarOptions &Opts, AliasAnalysis *AA,
+ DominatorTree *DT, LoopInfo *LI,
+ ScalarEvolution *SE, TargetLibraryInfo *TLI,
const TargetTransformInfo *TTI, MemorySSA *MSSA,
const DataLayout *DL,
OptimizationRemarkEmitter &ORE)
- : Opts(ScalarOptions::Global), AA(AA), DT(DT), LI(LI), SE(SE), TLI(TLI),
- TTI(TTI), DL(DL), ORE(ORE) {
+ : Opts(Opts), AA(AA), DT(DT), LI(LI), SE(SE), TLI(TLI), TTI(TTI), DL(DL),
+ ORE(ORE) {
if (MSSA)
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
}
@@ -297,7 +297,9 @@ PreservedAnalyses LoopIdiomRecognizePass::run(Loop &L, LoopAnalysisManager &AM,
// but ORE cannot be preserved (see comment before the pass definition).
OptimizationRemarkEmitter ORE(L.getHeader()->getParent());
- LoopIdiomRecognize LIR(&AR.AA, &AR.DT, &AR.LI, &AR.SE, &AR.TLI, &AR.TTI,
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
+ LoopIdiomRecognize LIR(Opts, &AR.AA, &AR.DT, &AR.LI, &AR.SE, &AR.TLI, &AR.TTI,
AR.MSSA, DL, ORE);
if (!LIR.runOnLoop(&L))
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 53196b5b579e17..1d384f40607f62 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -635,11 +635,11 @@ struct LoopInterchange {
/// Interface to emit optimization remarks.
OptimizationRemarkEmitter *ORE;
- LoopInterchange(ScalarEvolution *SE, LoopInfo *LI, DependenceInfo *DI,
- DominatorTree *DT, LoopStandardAnalysisResults *AR,
+ LoopInterchange(const ScalarOptions &Opts, ScalarEvolution *SE, LoopInfo *LI,
+ DependenceInfo *DI, DominatorTree *DT,
+ LoopStandardAnalysisResults *AR,
OptimizationRemarkEmitter *ORE)
- : Opts(ScalarOptions::Global), SE(SE), LI(LI), DI(DI), DT(DT), AR(AR),
- ORE(ORE) {}
+ : Opts(Opts), SE(SE), LI(LI), DI(DI), DT(DT), AR(AR), ORE(ORE) {}
bool run(Loop *L) {
if (L->getParentLoop())
@@ -2711,7 +2711,9 @@ PreservedAnalyses LoopInterchangePass::run(LoopNest &LN,
});
DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
- if (!LoopInterchange(&AR.SE, &AR.LI, &DI, &AR.DT, &AR, &ORE).run(LN))
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ if (!LoopInterchange(Opts, &AR.SE, &AR.LI, &DI, &AR.DT, &AR, &ORE).run(LN))
return PreservedAnalyses::all();
U.markLoopNestChanged(true);
return getLoopPassPreservedAnalyses();
diff --git a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
index 9925b59f26950d..04d924e0e4c013 100644
--- a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
@@ -482,7 +482,8 @@ class LoadEliminationForLoop {
/// Top-level driver for each loop: find store->load forwarding
/// candidates, add run-time checks and perform transformation.
bool processLoop() {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L->getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
LLVM_DEBUG(dbgs() << "\nIn \"" << L->getHeader()->getParent()->getName()
<< "\" checking " << *L << "\n");
diff --git a/llvm/lib/Transforms/Scalar/LoopPredication.cpp b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
index 467592ac88d0fe..7250a1d22cd827 100644
--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
@@ -290,10 +290,10 @@ class LoopPredication {
bool predicateLoopExits(Loop *L, SCEVExpander &Rewriter);
public:
- LoopPredication(AliasAnalysis *AA, DominatorTree *DT, ScalarEvolution *SE,
- LoopInfo *LI, MemorySSAUpdater *MSSAU)
- : Opts(ScalarOptions::Global), AA(AA), DT(DT), SE(SE), LI(LI),
- MSSAU(MSSAU) {};
+ LoopPredication(const ScalarOptions &Opts, AliasAnalysis *AA,
+ DominatorTree *DT, ScalarEvolution *SE, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU)
+ : Opts(Opts), AA(AA), DT(DT), SE(SE), LI(LI), MSSAU(MSSAU) {};
bool runOnLoop(Loop *L);
};
@@ -305,7 +305,9 @@ PreservedAnalyses LoopPredicationPass::run(Loop &L, LoopAnalysisManager &AM,
std::unique_ptr<MemorySSAUpdater> MSSAU;
if (AR.MSSA)
MSSAU = std::make_unique<MemorySSAUpdater>(AR.MSSA);
- LoopPredication LP(&AR.AA, &AR.DT, &AR.SE, &AR.LI,
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
+ LoopPredication LP(Opts, &AR.AA, &AR.DT, &AR.SE, &AR.LI,
MSSAU ? MSSAU.get() : nullptr);
if (!LP.runOnLoop(&L))
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Scalar/LoopRotation.cpp b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
index 1255a2d3349494..bd8b01d5205500 100644
--- a/llvm/lib/Transforms/Scalar/LoopRotation.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
@@ -56,7 +56,8 @@ void LoopRotatePass::printPipeline(
PreservedAnalyses LoopRotatePass::run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR,
LPMUpdater &) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
// Vectorization requires loop-rotation. Use default threshold for loops the
// user explicitly marked for vectorization, even when header duplication is
// disabled.
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
index a2ff998864456c..b04a3d6c628540 100644
--- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
@@ -664,11 +664,12 @@ class ConstantTerminatorFoldingImpl {
/// Turn branches and switches with known constant conditions into unconditional
/// branches.
-static bool constantFoldTerminators(Loop &L, DominatorTree &DT, LoopInfo &LI,
+static bool constantFoldTerminators(const ScalarOptions &Opts, Loop &L,
+ DominatorTree &DT, LoopInfo &LI,
ScalarEvolution &SE,
MemorySSAUpdater *MSSAU,
bool &IsLoopDeleted) {
- if (!ScalarOptions::Global.enable_loop_simplifycfg_term_folding)
+ if (!Opts.enable_loop_simplifycfg_term_folding)
return false;
// To keep things simple, only process loops with single latch. We
@@ -720,10 +721,12 @@ static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT,
static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI,
ScalarEvolution &SE, MemorySSAUpdater *MSSAU,
bool &IsLoopDeleted) {
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
bool Changed = false;
// Constant-fold terminators with known constant conditions.
- Changed |= constantFoldTerminators(L, DT, LI, SE, MSSAU, IsLoopDeleted);
+ Changed |= constantFoldTerminators(Opts, L, DT, LI, SE, MSSAU, IsLoopDeleted);
if (IsLoopDeleted)
return true;
diff --git a/llvm/lib/Transforms/Scalar/LoopSink.cpp b/llvm/lib/Transforms/Scalar/LoopSink.cpp
index add4f804b3abb9..68c0d87f88e084 100644
--- a/llvm/lib/Transforms/Scalar/LoopSink.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopSink.cpp
@@ -295,7 +295,8 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
BlockFrequencyInfo &BFI,
MemorySSA &MSSA,
ScalarEvolution *SE) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
BasicBlock *Preheader = L.getLoopPreheader();
assert(Preheader && "Expected loop to have preheader");
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 6073a177babafd..912fb890491bb2 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -7131,7 +7131,8 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
const TargetTransformInfo &TTI,
AssumptionCache &AC, TargetLibraryInfo &TLI,
MemorySSA *MSSA, bool PreserveLCSSA) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L->getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
// Debug preservation - before we start removing anything identify which DVI
// meet the salvageable criteria and store their DIExpression and SCEVs.
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
index 87b038f55c7d84..2fa73c1b45a2a8 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
@@ -248,7 +248,8 @@ tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
ScalarEvolution &SE, const TargetTransformInfo &TTI,
AssumptionCache &AC, DependenceInfo &DI,
OptimizationRemarkEmitter &ORE, int OptLevel) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L->getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
TargetTransformInfo::UnrollingPreferences UP = gatherUnrollingPreferences(
L, SE, TTI, nullptr, nullptr, ORE, OptLevel, std::nullopt, std::nullopt,
std::nullopt, std::nullopt, std::nullopt);
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
index be62b15186b145..983befea300a86 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -74,8 +74,10 @@ using namespace llvm;
#define DEBUG_TYPE "loop-unroll"
-bool llvm::getForgetSCEVInLoopUnroll() {
- return ScalarOptions::Global.forget_scev_loop_unroll;
+bool llvm::getForgetSCEVInLoopUnroll(
+ const cl::LibraryOptionsContext *LibraryOptions) {
+ return cl::LibraryOptionsContext::get<ScalarOptions>(LibraryOptions)
+ .forget_scev_loop_unroll;
}
/// A magic value for use with the Threshold parameter to indicate
@@ -92,7 +94,8 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
std::optional<unsigned> UserThreshold, std::optional<bool> UserAllowPartial,
std::optional<bool> UserRuntime, std::optional<bool> UserUpperBound,
std::optional<unsigned> UserFullUnrollMaxCount) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L->getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
TargetTransformInfo::UnrollingPreferences UP;
// Set up the defaults
@@ -684,7 +687,11 @@ static unsigned unrollCountPragmaValue(const Loop *L) {
}
UnrollPragmaInfo::UnrollPragmaInfo(const Loop *L)
- : UserUnrollCount(ScalarOptions::Global.unroll_count.has_value()),
+ : UserUnrollCount(L->getHeader()
+ ->getContext()
+ .getLibraryOptions()
+ .get<ScalarOptions>()
+ .unroll_count.has_value()),
PragmaFullUnroll(hasUnrollFullPragma(L)),
PragmaCount(unrollCountPragmaValue(L)),
PragmaEnableUnroll(hasUnrollEnablePragma(L)),
@@ -920,7 +927,8 @@ unsigned llvm::computeUnrollCount(
const unsigned TripMultiple, const UnrollCostEstimator &UCE,
TargetTransformInfo::UnrollingPreferences &UP,
TargetTransformInfo::PeelingPreferences &PP) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L->getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
unsigned LoopSize = UCE.getRolledLoopSize();
@@ -1544,6 +1552,8 @@ PreservedAnalyses LoopFullUnrollPass::run(Loop &L, LoopAnalysisManager &AM,
// pass. Function analyses need to be preserved across loop transformations
// but ORE cannot be preserved (see comment before the pass definition).
OptimizationRemarkEmitter ORE(L.getHeader()->getParent());
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
// Keep track of the previous loop structure so we can identify new loops
// created by unrolling.
@@ -1613,7 +1623,7 @@ PreservedAnalyses LoopFullUnrollPass::run(Loop &L, LoopAnalysisManager &AM,
Updater.markLoopAsDeleted(L, LoopName);
} else {
// We can only walk child loops if the current loop remained valid.
- if (ScalarOptions::Global.unroll_revisit_child_loops) {
+ if (Opts.unroll_revisit_child_loops) {
// Walk *all* of the child loops.
SmallVector<Loop *, 4> ChildLoops(L.begin(), L.end());
Updater.addChildLoops(ChildLoops);
diff --git a/llvm/lib/Transforms/Scalar/LoopVersioningLICM.cpp b/llvm/lib/Transforms/Scalar/LoopVersioningLICM.cpp
index 04d174b80e2605..7dee72e8a581a3 100644
--- a/llvm/lib/Transforms/Scalar/LoopVersioningLICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopVersioningLICM.cpp
@@ -545,8 +545,9 @@ PreservedAnalyses LoopVersioningLICMPass::run(Loop &L, LoopAnalysisManager &AM,
OptimizationRemarkEmitter ORE(F);
LoopAccessInfoManager LAIs(*SE, *AA, *DT, LAR.LI, nullptr, nullptr, &LAR.AC);
- if (!LoopVersioningLICM(ScalarOptions::Global, AA, SE, &ORE, LAIs, LAR.LI, &L)
- .run(DT))
+ const ScalarOptions &Opts =
+ F->getContext().getLibraryOptions().get<ScalarOptions>();
+ if (!LoopVersioningLICM(Opts, AA, SE, &ORE, LAIs, LAR.LI, &L).run(DT))
return PreservedAnalyses::all();
return getLoopPassPreservedAnalyses();
}
diff --git a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
index d81404dda3b2c5..8470e4ea15fb63 100644
--- a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
+++ b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
@@ -41,9 +41,10 @@ STATISTIC(ExpectIntrinsicsHandled,
// programmers may be using __builtin_expect() / llvm.expect to annotate that a
// branch is likely or unlikely to be taken.
-static std::tuple<uint32_t, uint32_t>
-getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+static std::tuple<uint32_t, uint32_t> getBranchWeight(const ScalarOptions &Opts,
+ Intrinsic::ID IntrinsicID,
+ CallInst *CI,
+ int BranchCount) {
if (IntrinsicID == Intrinsic::expect) {
// __builtin_expect
return std::make_tuple(Opts.likely_branch_weight,
@@ -63,7 +64,7 @@ getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount) {
}
}
-static bool handleSwitchExpect(SwitchInst &SI) {
+static bool handleSwitchExpect(const ScalarOptions &Opts, SwitchInst &SI) {
CallInst *CI = dyn_cast<CallInst>(SI.getCondition());
if (!CI)
return false;
@@ -82,7 +83,7 @@ static bool handleSwitchExpect(SwitchInst &SI) {
unsigned n = SI.getNumCases(); // +1 for default case.
uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
- getBranchWeight(Fn->getIntrinsicID(), CI, n + 1);
+ getBranchWeight(Opts, Fn->getIntrinsicID(), CI, n + 1);
SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeightVal);
@@ -103,7 +104,7 @@ static bool handleSwitchExpect(SwitchInst &SI) {
/// with the expected value of phi def, then the corresponding incoming
/// edge of the phi is unlikely to be taken. Using that information,
/// the branch probability info for the originating branch can be inferred.
-static void handlePhiDef(CallInst *Expect) {
+static void handlePhiDef(const ScalarOptions &Opts, CallInst *Expect) {
Value &Arg = *Expect->getArgOperand(0);
ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(Expect->getArgOperand(1));
if (!ExpectedValue)
@@ -241,7 +242,7 @@ static void handlePhiDef(CallInst *Expect) {
};
uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = getBranchWeight(
- Expect->getCalledFunction()->getIntrinsicID(), Expect, 2);
+ Opts, Expect->getCalledFunction()->getIntrinsicID(), Expect, 2);
if (!ExpectedValueIsLikely)
std::swap(LikelyBranchWeightVal, UnlikelyBranchWeightVal);
@@ -259,7 +260,8 @@ static void handlePhiDef(CallInst *Expect) {
}
// Handle both CondBrInst and SelectInst.
-template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
+template <class BrSelInst>
+static bool handleBrSelExpect(const ScalarOptions &Opts, BrSelInst &BSI) {
// Handle non-optimized IR code like:
// %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1)
@@ -314,7 +316,7 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
- getBranchWeight(Fn->getIntrinsicID(), CI, 2);
+ getBranchWeight(Opts, Fn->getIntrinsicID(), CI, 2);
SmallVector<uint32_t, 4> ExpectedWeights;
if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==
@@ -341,15 +343,17 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
}
static bool lowerExpectIntrinsic(Function &F) {
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool Changed = false;
for (BasicBlock &BB : F) {
// Create "block_weights" metadata.
if (CondBrInst *BI = dyn_cast<CondBrInst>(BB.getTerminator())) {
- if (handleBrSelExpect<CondBrInst>(*BI))
+ if (handleBrSelExpect<CondBrInst>(Opts, *BI))
ExpectIntrinsicsHandled++;
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB.getTerminator())) {
- if (handleSwitchExpect(*SI))
+ if (handleSwitchExpect(Opts, *SI))
ExpectIntrinsicsHandled++;
}
@@ -360,7 +364,7 @@ static bool lowerExpectIntrinsic(Function &F) {
CallInst *CI = dyn_cast<CallInst>(&Inst);
if (!CI) {
if (SelectInst *SI = dyn_cast<SelectInst>(&Inst)) {
- if (handleBrSelExpect(*SI))
+ if (handleBrSelExpect(Opts, *SI))
ExpectIntrinsicsHandled++;
}
continue;
@@ -372,7 +376,7 @@ static bool lowerExpectIntrinsic(Function &F) {
// Before erasing the llvm.expect, walk backward to find
// phi that define llvm.expect's first arg, and
// infer branch probability:
- handlePhiDef(CI);
+ handlePhiDef(Opts, CI);
Value *Exp = CI->getArgOperand(0);
CI->replaceAllUsesWith(Exp);
CI->eraseFromParent();
diff --git a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
index 44af9c7dbc9761..485eae8e5273a6 100644
--- a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
+++ b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
@@ -160,12 +160,8 @@ struct ShapeInfo {
unsigned NumRows;
unsigned NumColumns;
- bool IsColumnMajor;
-
ShapeInfo(unsigned NumRows = 0, unsigned NumColumns = 0)
- : NumRows(NumRows), NumColumns(NumColumns),
- IsColumnMajor(ScalarOptions::Global.matrix_default_layout ==
- MatrixLayoutTy::ColumnMajor) {}
+ : NumRows(NumRows), NumColumns(NumColumns) {}
ShapeInfo(Value *NumRows, Value *NumColumns)
: ShapeInfo(cast<ConstantInt>(NumRows)->getZExtValue(),
@@ -183,18 +179,6 @@ struct ShapeInfo {
return NumRows != 0;
}
- unsigned getStride() const {
- if (IsColumnMajor)
- return NumRows;
- return NumColumns;
- }
-
- unsigned getNumVectors() const {
- if (IsColumnMajor)
- return NumColumns;
- return NumRows;
- }
-
/// Returns the transposed shape.
ShapeInfo t() const { return ShapeInfo(NumColumns, NumRows); }
@@ -384,13 +368,16 @@ class LowerMatrixIntrinsics {
OpInfoTy OpInfo;
- bool IsColumnMajor = ScalarOptions::Global.matrix_default_layout ==
- MatrixLayoutTy::ColumnMajor;
+ bool IsColumnMajor = true;
public:
MatrixTy() = default;
- MatrixTy(ArrayRef<Value *> Vectors) : Vectors(Vectors) {}
- MatrixTy(unsigned NumRows, unsigned NumColumns, Type *EltTy) {
+ explicit MatrixTy(bool IsColumnMajor) : IsColumnMajor(IsColumnMajor) {}
+ MatrixTy(bool IsColumnMajor, ArrayRef<Value *> Vectors)
+ : Vectors(Vectors), IsColumnMajor(IsColumnMajor) {}
+ MatrixTy(bool IsColumnMajor, unsigned NumRows, unsigned NumColumns,
+ Type *EltTy)
+ : IsColumnMajor(IsColumnMajor) {
unsigned D = isColumnMajor() ? NumColumns : NumRows;
for (unsigned J = 0; J < D; ++J)
@@ -550,11 +537,22 @@ class LowerMatrixIntrinsics {
return FMF;
}
+ bool isColumnMajor() const {
+ return Opts.matrix_default_layout == MatrixLayoutTy::ColumnMajor;
+ }
+
+ unsigned getStride(const ShapeInfo &SI) const {
+ return isColumnMajor() ? SI.NumRows : SI.NumColumns;
+ }
+
+ unsigned getNumVectors(const ShapeInfo &SI) const {
+ return isColumnMajor() ? SI.NumColumns : SI.NumRows;
+ }
+
public:
- LowerMatrixIntrinsics(Function &F, TargetTransformInfo &TTI,
- FunctionAnalysisManager *AM)
- : Opts(ScalarOptions::Global), Func(F), DL(F.getDataLayout()), TTI(TTI),
- AM(AM) {}
+ LowerMatrixIntrinsics(const ScalarOptions &Opts, Function &F,
+ TargetTransformInfo &TTI, FunctionAnalysisManager *AM)
+ : Opts(Opts), Func(F), DL(F.getDataLayout()), TTI(TTI), AM(AM) {}
unsigned getNumOps(Type *VT) {
assert(isa<FixedVectorType>(VT) && "Expected vector type");
@@ -623,9 +621,9 @@ class LowerMatrixIntrinsics {
// Otherwise split MatrixVal.
SmallVector<Value *, 16> SplitVecs;
for (unsigned MaskStart = 0; MaskStart < VType->getNumElements();
- MaskStart += SI.getStride()) {
+ MaskStart += getStride(SI)) {
Value *V = Builder.CreateShuffleVector(
- MatrixVal, createSequentialMask(MaskStart, SI.getStride(), 0),
+ MatrixVal, createSequentialMask(MaskStart, getStride(SI), 0),
"split");
SplitVecs.push_back(V);
}
@@ -655,7 +653,7 @@ class LowerMatrixIntrinsics {
}
}
- return {SplitVecs};
+ return {isColumnMajor(), SplitVecs};
}
/// If \p V already has a known shape return false. Otherwise set the shape
@@ -1150,7 +1148,7 @@ class LowerMatrixIntrinsics {
const ShapeInfo &SI = ShapeMap.at(Inst);
auto *EltTy = cast<FixedVectorType>(PHI->getType())->getElementType();
- MatrixTy PhiM(SI.NumRows, SI.NumColumns, EltTy);
+ MatrixTy PhiM(isColumnMajor(), SI.NumRows, SI.NumColumns, EltTy);
IRBuilder<> Builder(Inst);
for (unsigned VI = 0, VE = PhiM.getNumVectors(); VI != VE; ++VI)
@@ -1247,7 +1245,7 @@ class LowerMatrixIntrinsics {
return LowerColumnMajorStore(Inst, Builder);
case Intrinsic::abs:
case Intrinsic::fabs: {
- MatrixTy Result;
+ MatrixTy Result(isColumnMajor());
MatrixTy M = getMatrix(Inst->getOperand(0), SI, Builder);
Builder.setFastMathFlags(getFastMathFlags(Inst));
@@ -1320,14 +1318,14 @@ class LowerMatrixIntrinsics {
bool IsVolatile, ShapeInfo Shape, IRBuilder<> &Builder) {
auto *VType = cast<FixedVectorType>(Ty);
Type *EltTy = VType->getElementType();
- Type *VecTy = FixedVectorType::get(EltTy, Shape.getStride());
+ Type *VecTy = FixedVectorType::get(EltTy, getStride(Shape));
Value *EltPtr = Ptr;
- MatrixTy Result;
+ MatrixTy Result(isColumnMajor());
Stride = castToIndexType(Ptr, Stride, Builder);
- for (unsigned I = 0, E = Shape.getNumVectors(); I < E; ++I) {
+ for (unsigned I = 0, E = getNumVectors(Shape); I < E; ++I) {
Value *GEP = computeVectorAddr(
EltPtr, Builder.getIntN(Stride->getType()->getScalarSizeInBits(), I),
- Stride, Shape.getStride(), EltTy, Builder);
+ Stride, getStride(Shape), EltTy, Builder);
Value *Vector = Builder.CreateAlignedLoad(
VecTy, GEP, getAlignForIndex(I, Stride, EltTy, MAlign),
IsVolatile, "col.load");
@@ -1345,14 +1343,14 @@ class LowerMatrixIntrinsics {
ShapeInfo ResultShape, Type *EltTy,
IRBuilder<> &Builder) {
Value *Offset = Builder.CreateAdd(
- Builder.CreateMul(J, getIndex(MatrixPtr, MatrixShape.getStride())), I);
+ Builder.CreateMul(J, getIndex(MatrixPtr, getStride(MatrixShape))), I);
Value *TileStart = Builder.CreateInBoundsGEP(EltTy, MatrixPtr, Offset);
auto *TileTy = FixedVectorType::get(EltTy, ResultShape.NumRows *
ResultShape.NumColumns);
return loadMatrix(TileTy, TileStart, Align,
- getIndex(MatrixPtr, MatrixShape.getStride()), IsVolatile,
+ getIndex(MatrixPtr, getStride(MatrixShape)), IsVolatile,
ResultShape, Builder);
}
@@ -1383,14 +1381,14 @@ class LowerMatrixIntrinsics {
MaybeAlign MAlign, bool IsVolatile, ShapeInfo MatrixShape,
Value *I, Value *J, Type *EltTy, IRBuilder<> &Builder) {
Value *Offset = Builder.CreateAdd(
- Builder.CreateMul(J, getIndex(MatrixPtr, MatrixShape.getStride())), I);
+ Builder.CreateMul(J, getIndex(MatrixPtr, getStride(MatrixShape))), I);
Value *TileStart = Builder.CreateInBoundsGEP(EltTy, MatrixPtr, Offset);
auto *TileTy = FixedVectorType::get(EltTy, StoreVal.getNumRows() *
StoreVal.getNumColumns());
storeMatrix(TileTy, StoreVal, TileStart, MAlign,
- getIndex(MatrixPtr, MatrixShape.getStride()), IsVolatile,
+ getIndex(MatrixPtr, getStride(MatrixShape)), IsVolatile,
Builder);
}
@@ -1414,8 +1412,9 @@ class LowerMatrixIntrinsics {
MAlign),
IsVolatile);
}
- return MatrixTy().addNumStores(getNumOps(StoreVal.getVectorTy()) *
- StoreVal.getNumVectors());
+ return MatrixTy(isColumnMajor())
+ .addNumStores(getNumOps(StoreVal.getVectorTy()) *
+ StoreVal.getNumVectors());
}
/// Lower a store instruction with shape information.
@@ -1990,7 +1989,7 @@ class LowerMatrixIntrinsics {
}
MatrixTy getZeroMatrix(Type *EltType, unsigned R, unsigned C) {
- MatrixTy Res;
+ MatrixTy Res(isColumnMajor());
auto *ColumType = FixedVectorType::get(EltType, R);
for (unsigned I = 0; I < C; ++I)
Res.addVector(ConstantAggregateZero::get(ColumType));
@@ -2014,7 +2013,7 @@ class LowerMatrixIntrinsics {
Type *TileVecTy = FixedVectorType::get(MatMul->getType()->getScalarType(),
Opts.fuse_matrix_tile_size);
- MatrixTy TileResult;
+ MatrixTy TileResult(isColumnMajor());
// Insert in the inner loop header.
Builder.SetInsertPoint(TI.KLoop.Header->getTerminator());
// Create PHI nodes for the result columns to accumulate across iterations.
@@ -2183,7 +2182,7 @@ class LowerMatrixIntrinsics {
}
// Initialize the output
- MatrixTy Result(R, C, EltType);
+ MatrixTy Result(isColumnMajor(), R, C, EltType);
emitMatrixMultiply(Result, MA, MB, Builder, false, true,
getFastMathFlags(MatMul));
@@ -2194,7 +2193,7 @@ class LowerMatrixIntrinsics {
ToRemove.push_back(cast<Instruction>(Transpose));
// TODO: add a fake entry for the folded instruction so that this is
// included in the expression in the remark.
- Inst2ColumnMatrix[Transpose] = MatrixTy(M, C, EltType);
+ Inst2ColumnMatrix[Transpose] = MatrixTy(isColumnMajor(), M, C, EltType);
}
finalizeLowering(MatMul, Result, Builder);
return;
@@ -2306,7 +2305,7 @@ class LowerMatrixIntrinsics {
assert(LShape.NumColumns == RShape.NumRows);
// Initialize the output
- MatrixTy Result(R, C, EltType);
+ MatrixTy Result(isColumnMajor(), R, C, EltType);
assert(Lhs.getElementType() == Result.getElementType() &&
"Matrix multiply result element type does not match arguments.");
@@ -2317,7 +2316,7 @@ class LowerMatrixIntrinsics {
/// Lowers llvm.matrix.transpose.
MatrixTy LowerTranspose(CallInst *Inst, IRBuilder<> &Builder) {
- MatrixTy Result;
+ MatrixTy Result(isColumnMajor());
Value *InputVal = Inst->getArgOperand(0);
FixedVectorType *VectorTy = cast<FixedVectorType>(InputVal->getType());
ShapeInfo ArgShape(Inst->getArgOperand(1), Inst->getArgOperand(2));
@@ -2352,14 +2351,14 @@ class LowerMatrixIntrinsics {
/// Lower load instructions.
MatrixTy VisitLoad(LoadInst *Inst, const ShapeInfo &SI, Value *Ptr,
IRBuilder<> &Builder) {
- return LowerLoad(Inst, Ptr, Inst->getAlign(), getIndex(Ptr, SI.getStride()),
+ return LowerLoad(Inst, Ptr, Inst->getAlign(), getIndex(Ptr, getStride(SI)),
Inst->isVolatile(), SI, Builder);
}
MatrixTy VisitStore(StoreInst *Inst, const ShapeInfo &SI, Value *StoredVal,
Value *Ptr, IRBuilder<> &Builder) {
return LowerStore(Inst, StoredVal, Ptr, Inst->getAlign(),
- getIndex(Ptr, SI.getStride()), Inst->isVolatile(), SI,
+ getIndex(Ptr, getStride(SI)), Inst->isVolatile(), SI,
Builder);
}
@@ -2404,7 +2403,7 @@ class LowerMatrixIntrinsics {
Value *Lhs = Inst->getOperand(0);
Value *Rhs = Inst->getOperand(1);
- MatrixTy Result;
+ MatrixTy Result(isColumnMajor());
MatrixTy A = getMatrix(Lhs, SI, Builder);
MatrixTy B = getMatrix(Rhs, SI, Builder);
assert(A.isColumnMajor() == B.isColumnMajor() &&
@@ -2425,7 +2424,7 @@ class LowerMatrixIntrinsics {
IRBuilder<> &Builder) {
Value *Op = Inst->getOperand(0);
- MatrixTy Result;
+ MatrixTy Result(isColumnMajor());
MatrixTy M = getMatrix(Op, SI, Builder);
Builder.setFastMathFlags(getFastMathFlags(Inst));
@@ -2452,7 +2451,7 @@ class LowerMatrixIntrinsics {
IRBuilder<> &Builder) {
Value *Op = Inst->getOperand(0);
- MatrixTy Result;
+ MatrixTy Result(isColumnMajor());
MatrixTy M = getMatrix(Op, Shape, Builder);
Builder.setFastMathFlags(getFastMathFlags(Inst));
@@ -2475,7 +2474,7 @@ class LowerMatrixIntrinsics {
Value *OpA = Inst->getOperand(1);
Value *OpB = Inst->getOperand(2);
- MatrixTy Result;
+ MatrixTy Result(isColumnMajor());
MatrixTy A = getMatrix(OpA, Shape, Builder);
MatrixTy B = getMatrix(OpB, Shape, Builder);
@@ -2937,7 +2936,9 @@ PreservedAnalyses LowerMatrixIntrinsicsPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
- LowerMatrixIntrinsics LMT(F, TTI, Minimal ? nullptr : &AM);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ LowerMatrixIntrinsics LMT(Opts, F, TTI, Minimal ? nullptr : &AM);
if (LMT.Visit()) {
PreservedAnalyses PA;
if (!Minimal) {
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index c69ae80f494225..8d082b90996d03 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -633,11 +633,10 @@ class NewGVN {
SmallPtrSet<Instruction *, 8> InstructionsToErase;
public:
- NewGVN(Function &F, DominatorTree *DT, AssumptionCache *AC,
- TargetLibraryInfo *TLI, AliasAnalysis *AA, MemorySSA *MSSA,
- const DataLayout &DL)
- : Opts(ScalarOptions::Global), F(F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA),
- AC(AC), DL(DL),
+ NewGVN(const ScalarOptions &Opts, Function &F, DominatorTree *DT,
+ AssumptionCache *AC, TargetLibraryInfo *TLI, AliasAnalysis *AA,
+ MemorySSA *MSSA, const DataLayout &DL)
+ : Opts(Opts), F(F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC), DL(DL),
// Reuse ExpressionAllocator for PredicateInfo as well.
PredInfo(
std::make_unique<PredicateInfo>(F, *DT, *AC, ExpressionAllocator)),
@@ -4227,9 +4226,10 @@ PreservedAnalyses NewGVNPass::run(Function &F, AnalysisManager<Function> &AM) {
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &AA = AM.getResult<AAManager>(F);
auto &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool Changed =
- NewGVN(F, &DT, &AC, &TLI, &AA, &MSSA, F.getDataLayout())
- .runGVN();
+ NewGVN(Opts, F, &DT, &AC, &TLI, &AA, &MSSA, F.getDataLayout()).runGVN();
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
diff --git a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp
index eafb4cc0469259..ab55a0a27e2cd4 100644
--- a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp
+++ b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp
@@ -97,8 +97,7 @@ class PlaceBackedgeSafepointsLegacyPass : public FunctionPass {
bool CallSafepointsEnabled;
PlaceBackedgeSafepointsLegacyPass(bool CallSafepoints = false)
- : FunctionPass(ID), CallSafepointsEnabled(CallSafepoints),
- Opts(ScalarOptions::Global) {
+ : FunctionPass(ID), CallSafepointsEnabled(CallSafepoints) {
initializePlaceBackedgeSafepointsLegacyPassPass(
*PassRegistry::getPassRegistry());
}
@@ -113,6 +112,7 @@ class PlaceBackedgeSafepointsLegacyPass : public FunctionPass {
}
bool runOnFunction(Function &F) override {
+ Opts = &F.getContext().getLibraryOptions().get<ScalarOptions>();
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
@@ -134,7 +134,7 @@ class PlaceBackedgeSafepointsLegacyPass : public FunctionPass {
}
private:
- const ScalarOptions &Opts;
+ const ScalarOptions *Opts = nullptr;
ScalarEvolution *SE = nullptr;
DominatorTree *DT = nullptr;
LoopInfo *LI = nullptr;
@@ -191,8 +191,8 @@ bool PlaceBackedgeSafepointsLegacyPass::runOnLoop(Loop *L) {
// Make a policy decision about whether this loop needs a safepoint or
// not. Note that this is about unburdening the optimizer in loops, not
// avoiding the runtime cost of the actual safepoint.
- if (!Opts.spp_all_backedges) {
- if (mustBeFiniteCountedLoop(Opts, L, SE, Pred)) {
+ if (!Opts->spp_all_backedges) {
+ if (mustBeFiniteCountedLoop(*Opts, L, SE, Pred)) {
LLVM_DEBUG(dbgs() << "skipping safepoint placement in finite loop\n");
FiniteExecution++;
continue;
@@ -245,7 +245,8 @@ bool PlaceSafepointsPass::runImpl(Function &F, const TargetLibraryInfo &TLI) {
if (!shouldRewriteFunction(F))
return false;
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool Modified = false;
// In various bits below, we rely on the fact that uses are reachable from
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp
index 8ce7d7061b403b..0d2f7c5684e905 100644
--- a/llvm/lib/Transforms/Scalar/Reassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp
@@ -2554,7 +2554,7 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) {
// reordering on the values that live in the first seen basic block.
// The main idea is that we want to avoid forming expressions that would
// become loop dependent.
- if (ScalarOptions::Global.reassociate_use_cse_local) {
+ if (UseCSELocal) {
const BasicBlock *FirstSeenBB = nullptr;
int StartIdx = Ops.size() - 1;
// Skip the first value of the expression since we need at least two
@@ -2731,6 +2731,10 @@ PreservedAnalyses ReassociatePass::run(Function &F,
PreservedAnalyses ReassociatePass::runImpl(Function &F, UniformityInfo &UI) {
UA = &UI;
+ UseCSELocal = F.getContext()
+ .getLibraryOptions()
+ .get<ScalarOptions>()
+ .reassociate_use_cse_local;
// Get the functions basic blocks in Reverse Post Order. This order is used by
// BuildRankMap to pre calculate ranks correctly. It also excludes dead basic
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
index 93493e7f2877cd..35d86bafb5c532 100644
--- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -3012,7 +3012,8 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
assert(!F.isDeclaration() && !F.empty() &&
"need function body to rewrite statepoints in");
assert(shouldRewriteStatepointsIn(F) && "mismatch in rewrite decision");
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
auto NeedsRewrite = [&](Instruction &I) {
if (const auto *Call = dyn_cast<CallBase>(&I)) {
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index e6407049899ec4..90c0bb016711f1 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -6469,7 +6469,7 @@ bool SROA::promoteAllocas() {
if (PromotableAllocas.empty())
return false;
- if (ScalarOptions::Global.sroa_skip_mem2reg) {
+ if (C->getLibraryOptions().get<ScalarOptions>().sroa_skip_mem2reg) {
LLVM_DEBUG(dbgs() << "Not promoting allocas with mem2reg!\n");
} else {
LLVM_DEBUG(dbgs() << "Promoting allocas with mem2reg...\n");
diff --git a/llvm/lib/Transforms/Scalar/ScalarOptions.td b/llvm/lib/Transforms/Scalar/ScalarOptions.td
index 8ca44f7009eaff..0f7cba53e38509 100644
--- a/llvm/lib/Transforms/Scalar/ScalarOptions.td
+++ b/llvm/lib/Transforms/Scalar/ScalarOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def ScalarOptions : OptionsStruct<perContext = false>;
+def ScalarOptions : OptionsStruct;
// ADCE.cpp
// This is a temporary option until we change the interface to this pass based
diff --git a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
index 3c5c6359729027..574a9b78594940 100644
--- a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
+++ b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
@@ -1331,7 +1331,8 @@ bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &F) {
}
bool SeparateConstOffsetFromGEP::run(Function &F) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
if (Opts.disable_separate_const_offset_from_gep)
return false;
diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index 0d8b04c409d5bd..727b4b8505c433 100644
--- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -3385,7 +3385,8 @@ static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI,
TargetTransformInfo &TTI, bool Trivial,
bool NonTrivial, ScalarEvolution *SE,
MemorySSAUpdater *MSSAU, LPMUpdater &LoopUpdater) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
assert(L.isRecursivelyLCSSAForm(DT, LI) &&
"Loops must be in LCSSA form before unswitching.");
diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index c3d9c3644e8a60..7d33458784d4ac 100644
--- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -264,9 +264,13 @@ static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
return true;
}
+static void applyCommandLineOverridesToOptions(const ScalarOptions &Opts,
+ SimplifyCFGOptions &Options);
+
static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
- DominatorTree *DT,
- const SimplifyCFGOptions &Options) {
+ DominatorTree *DT, SimplifyCFGOptions Options) {
+ applyCommandLineOverridesToOptions(
+ F.getContext().getLibraryOptions().get<ScalarOptions>(), Options);
assert((!RequireAndPreserveDomTree ||
(DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
"Original domtree is invalid?");
@@ -281,8 +285,8 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
}
// Command-line settings override compile-time settings.
-static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
- const ScalarOptions &Opts = ScalarOptions::Global;
+static void applyCommandLineOverridesToOptions(const ScalarOptions &Opts,
+ SimplifyCFGOptions &Options) {
if (Opts.bonus_inst_threshold)
Options.BonusInstThreshold = *Opts.bonus_inst_threshold;
Options.ForwardSwitchCondToPhi =
@@ -304,14 +308,10 @@ static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
valueOr(Opts.speculate_unpredictables, Options.SpeculateUnpredictables);
}
-SimplifyCFGPass::SimplifyCFGPass() {
- applyCommandLineOverridesToOptions(Options);
-}
+SimplifyCFGPass::SimplifyCFGPass() = default;
SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts)
- : Options(Opts) {
- applyCommandLineOverridesToOptions(Options);
-}
+ : Options(Opts) {}
void SimplifyCFGPass::printPipeline(
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
@@ -368,9 +368,6 @@ struct CFGSimplifyPass : public FunctionPass {
: FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
-
- // Check for command-line overrides of options for debug/customization.
- applyCommandLineOverridesToOptions(Options);
}
bool runOnFunction(Function &F) override {
diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
index cdafa383fd0035..d2f643ad17f268 100644
--- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
+++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
@@ -82,10 +82,7 @@ class SpeculativeExecutionLegacyPass : public FunctionPass {
public:
static char ID;
explicit SpeculativeExecutionLegacyPass(bool OnlyIfDivergentTarget = false)
- : FunctionPass(ID),
- OnlyIfDivergentTarget(
- OnlyIfDivergentTarget ||
- ScalarOptions::Global.spec_exec_only_if_divergent_target),
+ : FunctionPass(ID), OnlyIfDivergentTarget(OnlyIfDivergentTarget),
Impl(OnlyIfDivergentTarget) {}
void getAnalysisUsage(AnalysisUsage &AU) const override;
@@ -128,7 +125,9 @@ bool SpeculativeExecutionLegacyPass::runOnFunction(Function &F) {
}
bool SpeculativeExecutionPass::runImpl(Function &F, TargetTransformInfo *TTI) {
- if (OnlyIfDivergentTarget && !TTI->hasBranchDivergence(&F)) {
+ Opts = &F.getContext().getLibraryOptions().get<ScalarOptions>();
+ if ((OnlyIfDivergentTarget || Opts->spec_exec_only_if_divergent_target) &&
+ !TTI->hasBranchDivergence(&F)) {
LLVM_DEBUG(dbgs() << "Not running SpeculativeExecution because "
"TTI->hasBranchDivergence() is false.\n");
return false;
@@ -259,7 +258,6 @@ static InstructionCost ComputeSpeculationCost(const Instruction *I,
bool SpeculativeExecutionPass::considerHoistingFromTo(
BasicBlock &FromBlock, BasicBlock &ToBlock) {
- const ScalarOptions &Opts = ScalarOptions::Global;
SmallPtrSet<const Instruction *, 8> NotHoisted;
auto HasNoUnhoistedInstr = [&NotHoisted](auto Values) {
for (const Value *V : Values) {
@@ -281,11 +279,11 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
if (Cost.isValid() && isSafeToSpeculativelyExecute(&I) &&
AllPrecedingUsesFromBlockHoisted(&I)) {
TotalSpeculationCost += Cost;
- if (TotalSpeculationCost > Opts.spec_exec_max_speculation_cost)
+ if (TotalSpeculationCost > Opts->spec_exec_max_speculation_cost)
return false; // too much to hoist
} else {
NotHoistedInstCount++;
- if (NotHoistedInstCount > Opts.spec_exec_max_not_hoisted)
+ if (NotHoistedInstCount > Opts->spec_exec_max_not_hoisted)
return false; // too much left behind
NotHoisted.insert(&I);
}
@@ -313,9 +311,7 @@ FunctionPass *llvm::createSpeculativeExecutionIfHasBranchDivergencePass() {
}
SpeculativeExecutionPass::SpeculativeExecutionPass(bool OnlyIfDivergentTarget)
- : OnlyIfDivergentTarget(
- OnlyIfDivergentTarget ||
- ScalarOptions::Global.spec_exec_only_if_divergent_target) {}
+ : OnlyIfDivergentTarget(OnlyIfDivergentTarget) {}
PreservedAnalyses SpeculativeExecutionPass::run(Function &F,
FunctionAnalysisManager &AM) {
diff --git a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
index 242bf1ac9ae42e..664d32c4ad39a0 100644
--- a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
@@ -152,9 +152,10 @@ class StraightLineStrengthReduceLegacyPass : public FunctionPass {
class StraightLineStrengthReduce {
public:
- StraightLineStrengthReduce(const DataLayout *DL, DominatorTree *DT,
- ScalarEvolution *SE, TargetTransformInfo *TTI)
- : DL(DL), DT(DT), SE(SE), TTI(TTI) {}
+ StraightLineStrengthReduce(const ScalarOptions &Opts, const DataLayout *DL,
+ DominatorTree *DT, ScalarEvolution *SE,
+ TargetTransformInfo *TTI)
+ : Opts(Opts), DL(DL), DT(DT), SE(SE), TTI(TTI) {}
// SLSR candidate. Such a candidate must be in one of the forms described in
// the header comments.
@@ -407,6 +408,7 @@ class StraightLineStrengthReduce {
static Value *emitBump(const Candidate &Basis, const Candidate &C,
IRBuilder<> &Builder, const DataLayout *DL);
+ const ScalarOptions &Opts;
const DataLayout *DL = nullptr;
DominatorTree *DT = nullptr;
ScalarEvolution *SE;
@@ -1094,7 +1096,7 @@ void StraightLineStrengthReduce::allocateCandidatesAndFindBasis(
// doing this early we avoid calling canReuseInstruction repeatedly for the
// same instruction. The DropList is stored on the Candidate so the flags can
// be dropped only if this candidate is used by an executed rewrite.
- if (!ScalarOptions::Global.enable_poison_reuse_guard ||
+ if (!Opts.enable_poison_reuse_guard ||
SE->canReuseInstruction(SE->getSCEV(I), I, Candidates.back().DropList)) {
CandidateDict.add(Candidates.back());
}
@@ -1404,7 +1406,9 @@ bool StraightLineStrengthReduceLegacyPass::runOnFunction(Function &F) {
auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- return StraightLineStrengthReduce(DL, DT, SE, TTI).runOnFunction(F);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ return StraightLineStrengthReduce(Opts, DL, DT, SE, TTI).runOnFunction(F);
}
bool StraightLineStrengthReduce::runOnFunction(Function &F) {
@@ -1454,7 +1458,9 @@ StraightLineStrengthReducePass::run(Function &F, FunctionAnalysisManager &AM) {
auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
- if (!StraightLineStrengthReduce(DL, DT, SE, TTI).runOnFunction(F))
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ if (!StraightLineStrengthReduce(Opts, DL, DT, SE, TTI).runOnFunction(F))
return PreservedAnalyses::all();
PreservedAnalyses PA;
diff --git a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
index 5b1063f37ff224..5a021e6384f1d3 100644
--- a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
@@ -357,7 +357,8 @@ class StructurizeCFG {
public:
void init(Region *R);
bool run(Region *R, DominatorTree *DT, const TargetTransformInfo *TTI);
- bool makeUniformRegion(Region *R, UniformityInfo &UA);
+ bool makeUniformRegion(const ScalarOptions &Opts, Region *R,
+ UniformityInfo &UA);
};
class StructurizeCFGLegacyPass : public RegionPass {
@@ -368,19 +369,18 @@ class StructurizeCFGLegacyPass : public RegionPass {
explicit StructurizeCFGLegacyPass(bool SkipUniformRegions_ = false)
: RegionPass(ID), SkipUniformRegions(SkipUniformRegions_) {
- SkipUniformRegions =
- valueOr(ScalarOptions::Global.structurizecfg_skip_uniform_regions,
- SkipUniformRegions);
initializeStructurizeCFGLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnRegion(Region *R, RGPassManager &RGM) override {
StructurizeCFG SCFG;
SCFG.init(R);
- if (SkipUniformRegions) {
+ const ScalarOptions &Opts =
+ R->getEntry()->getContext().getLibraryOptions().get<ScalarOptions>();
+ if (valueOr(Opts.structurizecfg_skip_uniform_regions, SkipUniformRegions)) {
UniformityInfo &UA =
getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
- if (SCFG.makeUniformRegion(R, UA))
+ if (SCFG.makeUniformRegion(Opts, R, UA))
return false;
}
Function *F = R->getEntry()->getParent();
@@ -393,8 +393,7 @@ class StructurizeCFGLegacyPass : public RegionPass {
StringRef getPassName() const override { return "Structurize control flow"; }
void getAnalysisUsage(AnalysisUsage &AU) const override {
- if (SkipUniformRegions)
- AU.addRequired<UniformityInfoWrapperPass>();
+ AU.addRequired<UniformityInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
@@ -1278,7 +1277,8 @@ void StructurizeCFG::rebuildSSA() {
}
}
-static bool hasOnlyUniformBranches(Region *R, unsigned UniformMDKindID,
+static bool hasOnlyUniformBranches(const ScalarOptions &Opts, Region *R,
+ unsigned UniformMDKindID,
const UniformityInfo &UA) {
// Bool for if all sub-regions are uniform.
bool SubRegionsAreUniform = true;
@@ -1316,7 +1316,7 @@ static bool hasOnlyUniformBranches(Region *R, unsigned UniformMDKindID,
if (!Br->getMetadata(UniformMDKindID)) {
// Early exit if we cannot have relaxed uniform regions.
- if (!ScalarOptions::Global.structurizecfg_relaxed_uniform_regions)
+ if (!Opts.structurizecfg_relaxed_uniform_regions)
return false;
SubRegionsAreUniform = false;
@@ -1346,7 +1346,8 @@ void StructurizeCFG::init(Region *R) {
this->UA = nullptr;
}
-bool StructurizeCFG::makeUniformRegion(Region *R, UniformityInfo &UA) {
+bool StructurizeCFG::makeUniformRegion(const ScalarOptions &Opts, Region *R,
+ UniformityInfo &UA) {
if (R->isTopLevelRegion())
return false;
@@ -1359,7 +1360,7 @@ bool StructurizeCFG::makeUniformRegion(Region *R, UniformityInfo &UA) {
unsigned UniformMDKindID =
R->getEntry()->getContext().getMDKindID("structurizecfg.uniform");
- if (hasOnlyUniformBranches(R, UniformMDKindID, UA)) {
+ if (hasOnlyUniformBranches(Opts, R, UniformMDKindID, UA)) {
LLVM_DEBUG(dbgs() << "Skipping region with uniform control flow: " << *R
<< '\n');
@@ -1439,11 +1440,7 @@ static void addRegionIntoQueue(Region &R, std::vector<Region *> &Regions) {
}
StructurizeCFGPass::StructurizeCFGPass(bool SkipUniformRegions_)
- : SkipUniformRegions(SkipUniformRegions_) {
- SkipUniformRegions =
- valueOr(ScalarOptions::Global.structurizecfg_skip_uniform_regions,
- SkipUniformRegions);
-}
+ : SkipUniformRegions(SkipUniformRegions_) {}
void StructurizeCFGPass::printPipeline(
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
@@ -1460,8 +1457,12 @@ PreservedAnalyses StructurizeCFGPass::run(Function &F,
DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
auto &RI = AM.getResult<RegionInfoAnalysis>(F);
TargetTransformInfo *TTI = &AM.getResult<TargetIRAnalysis>(F);
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
+ bool SkipUniform =
+ valueOr(Opts.structurizecfg_skip_uniform_regions, SkipUniformRegions);
UniformityInfo *UI = nullptr;
- if (SkipUniformRegions)
+ if (SkipUniform)
UI = &AM.getResult<UniformityInfoAnalysis>(F);
std::vector<Region *> Regions;
@@ -1473,7 +1474,7 @@ PreservedAnalyses StructurizeCFGPass::run(Function &F,
StructurizeCFG SCFG;
SCFG.init(R);
- if (SkipUniformRegions && SCFG.makeUniformRegion(R, *UI)) {
+ if (SkipUniform && SCFG.makeUniformRegion(Opts, R, *UI)) {
Changed = true; // May have added metadata.
continue;
}
diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
index f891bf693b560f..9b48f582821595 100644
--- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -1148,7 +1148,8 @@ bool TailRecursionEliminator::eliminate(
if (F.getFnAttribute("disable-tail-calls").getValueAsBool())
return false;
- const ScalarOptions &Opts = ScalarOptions::Global;
+ const ScalarOptions &Opts =
+ F.getContext().getLibraryOptions().get<ScalarOptions>();
bool MadeChange = false;
MadeChange |= markTails(Opts, F, ORE, PSI, BFI);
diff --git a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp
index 9cb7b1657aa0ea..3a551b4c1dbcd2 100644
--- a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp
+++ b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp
@@ -22,6 +22,7 @@
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Driver.h"
+#include "llvm/Support/LibraryOptionsContext.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/WithColor.h"
@@ -108,7 +109,8 @@ static int convert_main(int argc, const char *argv[]) {
exitWithErrorCode(EC, OutputFilename);
auto FS = vfs::getRealFileSystem();
- auto ReaderOrErr = CodeGenDataReader::create(Filename, *FS, LazyLoading);
+ auto ReaderOrErr = CodeGenDataReader::create(cl::LibraryOptionsContext(),
+ Filename, *FS, LazyLoading);
if (Error E = ReaderOrErr.takeError())
exitWithError(std::move(E), Filename);
@@ -206,7 +208,7 @@ static int merge_main(int argc, const char *argv[]) {
if (!Result)
exitWithError("failed to merge codegen data files.");
- GlobalFunctionMapRecord.finalize(SkipTrim);
+ GlobalFunctionMapRecord.finalize(cl::LibraryOptionsContext(), SkipTrim);
CodeGenDataWriter Writer;
if (!GlobalOutlineRecord.empty())
@@ -240,7 +242,8 @@ static int show_main(int argc, const char *argv[]) {
exitWithErrorCode(EC, OutputFilename);
auto FS = vfs::getRealFileSystem();
- auto ReaderOrErr = CodeGenDataReader::create(Filename, *FS, LazyLoading);
+ auto ReaderOrErr = CodeGenDataReader::create(cl::LibraryOptionsContext(),
+ Filename, *FS, LazyLoading);
if (Error E = ReaderOrErr.takeError())
exitWithError(std::move(E), Filename);
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 2dd062f8d2c9c0..fb56822589a11b 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -473,7 +473,7 @@ bool llvm::runPassPipeline(
Debugify.registerCallbacks(PIC, MAM);
}
- PipelineTuningOptions PTO;
+ PipelineTuningOptions PTO(&M.getContext().getLibraryOptions());
// LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized
// to false above so we shouldn't necessarily need to check whether or not the
// option has been enabled.
diff --git a/llvm/unittests/CGData/StableFunctionMapTest.cpp b/llvm/unittests/CGData/StableFunctionMapTest.cpp
index 5cf62ae0b39435..4727960be3e7c5 100644
--- a/llvm/unittests/CGData/StableFunctionMapTest.cpp
+++ b/llvm/unittests/CGData/StableFunctionMapTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CGData/StableFunctionMap.h"
+#include "llvm/Support/LibraryOptionsContext.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -90,7 +91,7 @@ TEST(StableFunctionMap, Finalize1) {
Map.insert(Func2);
// Instruction count is mis-matched, so they're not mergeable.
- Map.finalize();
+ Map.finalize(cl::LibraryOptionsContext());
EXPECT_THAT(Map, IsEmpty());
}
@@ -102,7 +103,7 @@ TEST(StableFunctionMap, Finalize2) {
Map.insert(Func2);
// Operand map size is mis-matched, so they're not mergeable.
- Map.finalize();
+ Map.finalize(cl::LibraryOptionsContext());
EXPECT_THAT(Map, IsEmpty());
}
@@ -114,7 +115,7 @@ TEST(StableFunctionMap, Finalize3) {
Map.insert(Func2);
// The same operand entry is removed, which is redundant.
- Map.finalize();
+ Map.finalize(cl::LibraryOptionsContext());
auto &M = Map.getFunctionMap();
EXPECT_THAT(M, SizeIs(1));
auto &FuncEntries = M.begin()->second.Entries;
diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index bd3264fb2e4b59..63c73b85231430 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -458,13 +458,13 @@ parsePollyCustomOptions(StringRef Params) {
/// @param EnableForOpt Whether to add Polly IR transformations. If False, only
/// the analysis passes are added, skipping Polly itself.
/// The IR may still be modified.
-static void buildCommonPollyPipeline(FunctionPassManager &PM,
- OptimizationLevel Level,
- IntrusiveRefCntPtr<vfs::FileSystem> FS,
- bool EnableForOpt) {
+static void
+buildCommonPollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
+ FunctionPassManager &PM, OptimizationLevel Level,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS,
+ bool EnableForOpt) {
PassBuilder PB(
- /*TM=*/nullptr,
- /*PipelineTuningOptions=*/{},
+ /*TM=*/nullptr, PipelineTuningOptions(LibraryOptions),
/*PGOOpt=*/{},
/*PIC=*/nullptr, std::move(FS));
@@ -480,9 +480,11 @@ static void buildCommonPollyPipeline(FunctionPassManager &PM,
PM.addPass(llvm::CFGPrinterPass());
}
-static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,
- llvm::OptimizationLevel Level,
- IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+static void
+buildEarlyPollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
+ llvm::ModulePassManager &MPM,
+ llvm::OptimizationLevel Level,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS) {
bool EnableForOpt =
shouldEnablePollyForOptimization() && Level != OptimizationLevel::O0;
if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
@@ -501,7 +503,8 @@ static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,
FPM = FunctionPassManager();
}
- buildCommonPollyPipeline(FPM, Level, std::move(FS), EnableForOpt);
+ buildCommonPollyPipeline(LibraryOptions, FPM, Level, std::move(FS),
+ EnableForOpt);
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
if (DumpAfter)
@@ -510,9 +513,10 @@ static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,
MPM.addPass(DumpModulePass(Filename, false));
}
-static void buildLatePollyPipeline(FunctionPassManager &PM,
- llvm::OptimizationLevel Level,
- IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+static void
+buildLatePollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
+ FunctionPassManager &PM, llvm::OptimizationLevel Level,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS) {
bool EnableForOpt =
shouldEnablePollyForOptimization() && Level != OptimizationLevel::O0;
if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
@@ -526,7 +530,8 @@ static void buildLatePollyPipeline(FunctionPassManager &PM,
"not supported with NPM",
false);
- buildCommonPollyPipeline(PM, Level, std::move(FS), EnableForOpt);
+ buildCommonPollyPipeline(LibraryOptions, PM, Level, std::move(FS),
+ EnableForOpt);
if (DumpAfter)
PM.addPass(DumpFunctionPass("-after"));
@@ -634,6 +639,7 @@ parseModulePipeline(StringRef Name, llvm::ModulePassManager &MPM,
void registerPollyPasses(PassBuilder &PB) {
PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();
IntrusiveRefCntPtr<vfs::FileSystem> FS = PB.getVirtualFileSystemPtr();
+ const cl::LibraryOptionsContext *LibraryOptions = PB.getLibraryOptions();
#define MODULE_PASS(NAME, CREATE_PASS, PARSER) \
{ \
@@ -677,14 +683,15 @@ void registerPollyPasses(PassBuilder &PB) {
switch (PassPosition) {
case POSITION_EARLY:
PB.registerPipelineStartEPCallback(
- [FS](ModulePassManager &MPM, OptimizationLevel Level) {
- buildEarlyPollyPipeline(MPM, Level, FS);
+ [FS, LibraryOptions](ModulePassManager &MPM, OptimizationLevel Level) {
+ buildEarlyPollyPipeline(LibraryOptions, MPM, Level, FS);
});
break;
case POSITION_BEFORE_VECTORIZER:
PB.registerVectorizerStartEPCallback(
- [FS](FunctionPassManager &FPM, OptimizationLevel Level) {
- buildLatePollyPipeline(FPM, Level, FS);
+ [FS, LibraryOptions](FunctionPassManager &FPM,
+ OptimizationLevel Level) {
+ buildLatePollyPipeline(LibraryOptions, FPM, Level, FS);
});
break;
}
diff --git a/polly/lib/Transform/ScopInliner.cpp b/polly/lib/Transform/ScopInliner.cpp
index 50082abf55a0d6..222f4914dd456c 100644
--- a/polly/lib/Transform/ScopInliner.cpp
+++ b/polly/lib/Transform/ScopInliner.cpp
@@ -54,7 +54,7 @@ bool runScopInlinerImpl(Function *F, SCC_t &SCC,
PassBuilder PB(
/*TM=*/nullptr,
- /*PipelineTuningOptions=*/{},
+ PipelineTuningOptions(&F->getContext().getLibraryOptions()),
/*PGOOpt=*/{},
/*PIC=*/nullptr, std::move(FS));
// Populate analysis managers and register Polly-specific analyses.
More information about the flang-commits
mailing list