Skip to content

Commit 8f9c466

Browse files
committed
CodeGen: Add LibcallLoweringInfo analysis pass
The libcall lowering decisions should be program dependent, depending on the current module's RuntimeLibcallInfo. We need another related analysis derived from that plus the current function's subtarget to provide concrete lowering decisions. This takes on a somewhat unusual form. It's a Module analysis, with a lookup keyed on the subtarget. This is a separate module analysis from RuntimeLibraryAnalysis to avoid that depending on codegen. It's not a function pass to avoid depending on any particular function, to avoid repeated subtarget map lookups in most of the use passes, and to avoid any recomputation in the common case of one subtarget (and keeps it reusable across repeated compilations). This also switches ExpandFp and PreISelIntrinsicLowering as a sample function and module pass. Note this is not yet wired up to SelectionDAG, which is still using the LibcallLoweringInfo constructed inside of TargetLowering.
1 parent c024276 commit 8f9c466

36 files changed

+303
-61
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/StringExtras.h"
2020
#include "llvm/ADT/StringSwitch.h"
2121
#include "llvm/Analysis/GlobalsModRef.h"
22+
#include "llvm/Analysis/RuntimeLibcallInfo.h"
2223
#include "llvm/Analysis/TargetLibraryInfo.h"
2324
#include "llvm/Analysis/TargetTransformInfo.h"
2425
#include "llvm/Bitcode/BitcodeReader.h"
@@ -667,6 +668,11 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
667668
llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
668669
CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
669670

671+
const llvm::TargetOptions &Options = TM->Options;
672+
CodeGenPasses.add(new RuntimeLibraryInfoWrapper(
673+
TargetTriple, Options.ExceptionModel, Options.FloatABIType,
674+
Options.EABIVersion, Options.MCOptions.ABIName, Options.VecLib));
675+
670676
// Normal mode, emit a .s or .o file by running the code generator. Note,
671677
// this also adds codegenerator level optimization passes.
672678
CodeGenFileType CGFT = getCodeGenFileType(Action);

llvm/include/llvm/Analysis/RuntimeLibcallInfo.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ class LLVM_ABI RuntimeLibraryAnalysis
2222
RuntimeLibraryAnalysis() = default;
2323
RuntimeLibraryAnalysis(RTLIB::RuntimeLibcallsInfo &&BaselineInfoImpl)
2424
: LibcallsInfo(std::move(BaselineInfoImpl)) {}
25-
explicit RuntimeLibraryAnalysis(const Triple &T) : LibcallsInfo(T) {}
25+
RuntimeLibraryAnalysis(
26+
const Triple &TT,
27+
ExceptionHandling ExceptionModel = ExceptionHandling::None,
28+
FloatABI::ABIType FloatABI = FloatABI::Default,
29+
EABI EABIVersion = EABI::Default, StringRef ABIName = "",
30+
VectorLibrary VecLib = VectorLibrary::NoLibrary);
2631

2732
LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
2833
ModuleAnalysisManager &);
@@ -41,8 +46,12 @@ class LLVM_ABI RuntimeLibraryInfoWrapper : public ImmutablePass {
4146
public:
4247
static char ID;
4348
RuntimeLibraryInfoWrapper();
44-
explicit RuntimeLibraryInfoWrapper(const Triple &T);
45-
explicit RuntimeLibraryInfoWrapper(const RTLIB::RuntimeLibcallsInfo &RTLCI);
49+
RuntimeLibraryInfoWrapper(
50+
const Triple &TT,
51+
ExceptionHandling ExceptionModel = ExceptionHandling::None,
52+
FloatABI::ABIType FloatABI = FloatABI::Default,
53+
EABI EABIVersion = EABI::Default, StringRef ABIName = "",
54+
VectorLibrary VecLib = VectorLibrary::NoLibrary);
4655

4756
const RTLIB::RuntimeLibcallsInfo &getRTLCI(const Module &M) {
4857
ModuleAnalysisManager DummyMAM;

llvm/include/llvm/CodeGen/LibcallLoweringInfo.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
#ifndef LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
1010
#define LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
1111

12+
#include "llvm/ADT/DenseMap.h"
1213
#include "llvm/IR/RuntimeLibcalls.h"
14+
#include "llvm/Pass.h"
1315

1416
namespace llvm {
1517

1618
class TargetSubtargetInfo;
19+
class TargetMachine;
1720

21+
/// Tracks which library functions to use for a particular subtarget.
1822
class LibcallLoweringInfo {
1923
private:
2024
const RTLIB::RuntimeLibcallsInfo &RTLCI;
@@ -73,6 +77,70 @@ class LibcallLoweringInfo {
7377
}
7478
};
7579

80+
/// Record a mapping from subtarget to LibcallLoweringInfo.
81+
class LibcallLoweringModuleAnalysisResult {
82+
private:
83+
using LibcallLoweringMap =
84+
DenseMap<const TargetSubtargetInfo *, LibcallLoweringInfo>;
85+
mutable LibcallLoweringMap LoweringMap;
86+
const RTLIB::RuntimeLibcallsInfo *RTLCI = nullptr;
87+
88+
public:
89+
LibcallLoweringModuleAnalysisResult() = default;
90+
LibcallLoweringModuleAnalysisResult(RTLIB::RuntimeLibcallsInfo &RTLCI)
91+
: RTLCI(&RTLCI) {}
92+
93+
void init(const RTLIB::RuntimeLibcallsInfo *RT) { RTLCI = RT; }
94+
95+
void clear() {
96+
RTLCI = nullptr;
97+
LoweringMap.clear();
98+
}
99+
100+
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
101+
ModuleAnalysisManager::Invalidator &);
102+
103+
const LibcallLoweringInfo &
104+
getLibcallLowering(const TargetSubtargetInfo &Subtarget) const {
105+
return LoweringMap.try_emplace(&Subtarget, *RTLCI, Subtarget).first->second;
106+
}
107+
};
108+
109+
class LibcallLoweringModuleAnalysis
110+
: public AnalysisInfoMixin<LibcallLoweringModuleAnalysis> {
111+
private:
112+
friend AnalysisInfoMixin<LibcallLoweringModuleAnalysis>;
113+
LLVM_ABI static AnalysisKey Key;
114+
115+
LibcallLoweringModuleAnalysisResult LibcallLoweringMap;
116+
117+
public:
118+
using Result = LibcallLoweringModuleAnalysisResult;
119+
120+
LLVM_ABI Result run(Module &M, ModuleAnalysisManager &);
121+
};
122+
123+
class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass {
124+
LibcallLoweringModuleAnalysisResult Result;
125+
126+
public:
127+
static char ID;
128+
LibcallLoweringInfoWrapper();
129+
130+
const LibcallLoweringInfo &
131+
getLibcallLowering(const TargetSubtargetInfo &Subtarget) const {
132+
return Result.getLibcallLowering(Subtarget);
133+
}
134+
135+
const LibcallLoweringModuleAnalysisResult &getResult() const {
136+
return Result;
137+
}
138+
139+
bool doInitialization(Module &M) override;
140+
void getAnalysisUsage(AnalysisUsage &AU) const override;
141+
void releaseMemory() override;
142+
};
143+
76144
} // end namespace llvm
77145

78146
#endif // LLVM_CODEGEN_LIBCALLLOWERINGINFO_H

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ LLVM_ABI void initializeGlobalMergeFuncPassWrapperPass(PassRegistry &);
133133
LLVM_ABI void initializeGlobalMergePass(PassRegistry &);
134134
LLVM_ABI void initializeGlobalsAAWrapperPassPass(PassRegistry &);
135135
LLVM_ABI void initializeHardwareLoopsLegacyPass(PassRegistry &);
136+
LLVM_ABI void initializeLibcallLoweringInfoWrapperPass(PassRegistry &);
136137
LLVM_ABI void initializeMIRProfileLoaderPassPass(PassRegistry &);
137138
LLVM_ABI void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry &);
138139
LLVM_ABI void initializeIRTranslatorPass(PassRegistry &);

llvm/lib/Analysis/RuntimeLibcallInfo.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ using namespace llvm;
1313

1414
AnalysisKey RuntimeLibraryAnalysis::Key;
1515

16+
RuntimeLibraryAnalysis::RuntimeLibraryAnalysis(const Triple &TT,
17+
ExceptionHandling ExceptionModel,
18+
FloatABI::ABIType FloatABI,
19+
EABI EABIVersion,
20+
StringRef ABIName,
21+
VectorLibrary VecLib)
22+
: LibcallsInfo(std::in_place, TT, ExceptionModel, FloatABI, EABIVersion,
23+
ABIName, VecLib) {}
24+
1625
RTLIB::RuntimeLibcallsInfo
1726
RuntimeLibraryAnalysis::run(const Module &M, ModuleAnalysisManager &) {
1827
if (!LibcallsInfo)
@@ -26,6 +35,13 @@ INITIALIZE_PASS(RuntimeLibraryInfoWrapper, "runtime-library-info",
2635
RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper()
2736
: ImmutablePass(ID), RTLA(RTLIB::RuntimeLibcallsInfo(Triple())) {}
2837

38+
RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper(
39+
const Triple &TT, ExceptionHandling ExceptionModel,
40+
FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName,
41+
VectorLibrary VecLib)
42+
: ImmutablePass(ID), RTLCI(std::in_place, TT, ExceptionModel, FloatABI,
43+
EABIVersion, ABIName, VecLib) {}
44+
2945
char RuntimeLibraryInfoWrapper::ID = 0;
3046

3147
ModulePass *llvm::createRuntimeLibraryInfoWrapperPass() {

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
5757
initializeInterleavedLoadCombinePass(Registry);
5858
initializeInterleavedAccessPass(Registry);
5959
initializeJMCInstrumenterPass(Registry);
60+
initializeLibcallLoweringInfoWrapperPass(Registry);
6061
initializeLiveDebugValuesLegacyPass(Registry);
6162
initializeLiveDebugVariablesWrapperLegacyPass(Registry);
6263
initializeLiveIntervalsWrapperPassPass(Registry);

llvm/lib/CodeGen/ExpandFp.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,7 @@ static void addToWorklist(Instruction &I,
991991
}
992992

993993
static bool runImpl(Function &F, const TargetLowering &TLI,
994-
AssumptionCache *AC) {
994+
const LibcallLoweringInfo &Libcalls, AssumptionCache *AC) {
995995
SmallVector<Instruction *, 4> Worklist;
996996

997997
unsigned MaxLegalFpConvertBitWidth =
@@ -1090,12 +1090,17 @@ class ExpandFpLegacyPass : public FunctionPass {
10901090

10911091
bool runOnFunction(Function &F) override {
10921092
auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
1093-
auto *TLI = TM->getSubtargetImpl(F)->getTargetLowering();
1093+
const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(F);
1094+
auto *TLI = Subtarget->getTargetLowering();
10941095
AssumptionCache *AC = nullptr;
10951096

1097+
const LibcallLoweringInfo &Libcalls =
1098+
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
1099+
*Subtarget);
1100+
10961101
if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone())
10971102
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
1098-
return runImpl(F, *TLI, AC);
1103+
return runImpl(F, *TLI, Libcalls, AC);
10991104
}
11001105

11011106
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -1104,6 +1109,7 @@ class ExpandFpLegacyPass : public FunctionPass {
11041109
AU.addRequired<AssumptionCacheTracker>();
11051110
AU.addPreserved<AAResultsWrapperPass>();
11061111
AU.addPreserved<GlobalsAAWrapperPass>();
1112+
AU.addRequired<LibcallLoweringInfoWrapper>();
11071113
}
11081114
};
11091115
} // namespace
@@ -1126,8 +1132,23 @@ PreservedAnalyses ExpandFpPass::run(Function &F, FunctionAnalysisManager &FAM) {
11261132
AssumptionCache *AC = nullptr;
11271133
if (OptLevel != CodeGenOptLevel::None)
11281134
AC = &FAM.getResult<AssumptionAnalysis>(F);
1129-
return runImpl(F, TLI, AC) ? PreservedAnalyses::none()
1130-
: PreservedAnalyses::all();
1135+
1136+
auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
1137+
1138+
const LibcallLoweringModuleAnalysisResult *LibcallLowering =
1139+
MAMProxy.getCachedResult<LibcallLoweringModuleAnalysis>(*F.getParent());
1140+
1141+
if (!LibcallLowering) {
1142+
F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() +
1143+
"' analysis required");
1144+
return PreservedAnalyses::all();
1145+
}
1146+
1147+
const LibcallLoweringInfo &Libcalls =
1148+
LibcallLowering->getLibcallLowering(*STI);
1149+
1150+
return runImpl(F, TLI, Libcalls, AC) ? PreservedAnalyses::none()
1151+
: PreservedAnalyses::all();
11311152
}
11321153

11331154
char ExpandFpLegacyPass::ID = 0;

llvm/lib/CodeGen/LibcallLoweringInfo.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/CodeGen/LibcallLoweringInfo.h"
10+
#include "llvm/Analysis/RuntimeLibcallInfo.h"
1011
#include "llvm/CodeGen/TargetSubtargetInfo.h"
12+
#include "llvm/InitializePasses.h"
13+
#include "llvm/Target/TargetMachine.h"
1114

1215
using namespace llvm;
1316

@@ -28,3 +31,42 @@ LibcallLoweringInfo::LibcallLoweringInfo(
2831

2932
Subtarget.initLibcallLoweringInfo(*this);
3033
}
34+
35+
AnalysisKey LibcallLoweringModuleAnalysis::Key;
36+
37+
bool LibcallLoweringModuleAnalysisResult::invalidate(
38+
Module &, const PreservedAnalyses &PA,
39+
ModuleAnalysisManager::Invalidator &) {
40+
// Passes that change the runtime libcall set must explicitly invalidate this
41+
// pass.
42+
auto PAC = PA.getChecker<LibcallLoweringModuleAnalysis>();
43+
return !PAC.preservedWhenStateless();
44+
}
45+
46+
LibcallLoweringModuleAnalysisResult
47+
LibcallLoweringModuleAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
48+
LibcallLoweringMap.init(&MAM.getResult<RuntimeLibraryAnalysis>(M));
49+
return LibcallLoweringMap;
50+
}
51+
52+
INITIALIZE_PASS_BEGIN(LibcallLoweringInfoWrapper, "libcall-lowering-info",
53+
"Library Function Lowering Analysis", false, true)
54+
INITIALIZE_PASS_DEPENDENCY(RuntimeLibraryInfoWrapper)
55+
INITIALIZE_PASS_END(LibcallLoweringInfoWrapper, "libcall-lowering-info",
56+
"Library Function Lowering Analysis", false, true)
57+
58+
char LibcallLoweringInfoWrapper::ID = 0;
59+
60+
LibcallLoweringInfoWrapper::LibcallLoweringInfoWrapper() : ImmutablePass(ID) {}
61+
62+
bool LibcallLoweringInfoWrapper::doInitialization(Module &M) {
63+
Result.init(&getAnalysis<RuntimeLibraryInfoWrapper>().getRTLCI(M));
64+
return false;
65+
}
66+
67+
void LibcallLoweringInfoWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
68+
AU.addRequired<RuntimeLibraryInfoWrapper>();
69+
AU.setPreservesAll();
70+
}
71+
72+
void LibcallLoweringInfoWrapper::releaseMemory() { Result.clear(); }

0 commit comments

Comments
 (0)