Skip to content

Commit 2b0bb19

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 eab23e1 commit 2b0bb19

36 files changed

+325
-68
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: 17 additions & 5 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,12 +46,19 @@ 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) {
48-
ModuleAnalysisManager DummyMAM;
49-
RTLCI = RTLA.run(M, DummyMAM);
57+
if (!RTLCI) {
58+
ModuleAnalysisManager DummyMAM;
59+
RTLCI = RTLA.run(M, DummyMAM);
60+
}
61+
5062
return *RTLCI;
5163
}
5264

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+
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: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -975,11 +975,12 @@ static RTLIB::Libcall fremToLibcall(Type *Ty) {
975975
/* Return true if, according to \p LibInfo, the target either directly
976976
supports the frem instruction for the \p Ty, has a custom lowering,
977977
or uses a libcall. */
978-
static bool targetSupportsFrem(const TargetLowering &TLI, Type *Ty) {
978+
static bool targetSupportsFrem(const TargetLowering &TLI,
979+
const LibcallLoweringInfo &Libcalls, Type *Ty) {
979980
if (!TLI.isOperationExpand(ISD::FREM, EVT::getEVT(Ty)))
980981
return true;
981982

982-
return TLI.getLibcallName(fremToLibcall(Ty->getScalarType()));
983+
return Libcalls.getLibcallName(fremToLibcall(Ty->getScalarType()));
983984
}
984985

985986
static void addToWorklist(Instruction &I,
@@ -991,7 +992,7 @@ static void addToWorklist(Instruction &I,
991992
}
992993

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

997998
unsigned MaxLegalFpConvertBitWidth =
@@ -1010,7 +1011,7 @@ static bool runImpl(Function &F, const TargetLowering &TLI,
10101011

10111012
switch (I.getOpcode()) {
10121013
case Instruction::FRem:
1013-
return !targetSupportsFrem(TLI, Ty) &&
1014+
return !targetSupportsFrem(TLI, Libcalls, Ty) &&
10141015
FRemExpander::canExpandType(Ty->getScalarType());
10151016

10161017
case Instruction::FPToUI:
@@ -1090,20 +1091,27 @@ class ExpandFpLegacyPass : public FunctionPass {
10901091

10911092
bool runOnFunction(Function &F) override {
10921093
auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
1093-
auto *TLI = TM->getSubtargetImpl(F)->getTargetLowering();
1094+
const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(F);
1095+
auto *TLI = Subtarget->getTargetLowering();
10941096
AssumptionCache *AC = nullptr;
10951097

1098+
const LibcallLoweringInfo &Libcalls =
1099+
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
1100+
*Subtarget);
1101+
10961102
if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone())
10971103
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
1098-
return runImpl(F, *TLI, AC);
1104+
return runImpl(F, *TLI, Libcalls, AC);
10991105
}
11001106

11011107
void getAnalysisUsage(AnalysisUsage &AU) const override {
1108+
AU.addRequired<LibcallLoweringInfoWrapper>();
11021109
AU.addRequired<TargetPassConfig>();
11031110
if (OptLevel != CodeGenOptLevel::None)
11041111
AU.addRequired<AssumptionCacheTracker>();
11051112
AU.addPreserved<AAResultsWrapperPass>();
11061113
AU.addPreserved<GlobalsAAWrapperPass>();
1114+
AU.addRequired<LibcallLoweringInfoWrapper>();
11071115
}
11081116
};
11091117
} // namespace
@@ -1126,13 +1134,29 @@ PreservedAnalyses ExpandFpPass::run(Function &F, FunctionAnalysisManager &FAM) {
11261134
AssumptionCache *AC = nullptr;
11271135
if (OptLevel != CodeGenOptLevel::None)
11281136
AC = &FAM.getResult<AssumptionAnalysis>(F);
1129-
return runImpl(F, TLI, AC) ? PreservedAnalyses::none()
1130-
: PreservedAnalyses::all();
1137+
1138+
auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
1139+
1140+
const LibcallLoweringModuleAnalysisResult *LibcallLowering =
1141+
MAMProxy.getCachedResult<LibcallLoweringModuleAnalysis>(*F.getParent());
1142+
1143+
if (!LibcallLowering) {
1144+
F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() +
1145+
"' analysis required");
1146+
return PreservedAnalyses::all();
1147+
}
1148+
1149+
const LibcallLoweringInfo &Libcalls =
1150+
LibcallLowering->getLibcallLowering(*STI);
1151+
1152+
return runImpl(F, TLI, Libcalls, AC) ? PreservedAnalyses::none()
1153+
: PreservedAnalyses::all();
11311154
}
11321155

11331156
char ExpandFpLegacyPass::ID = 0;
11341157
INITIALIZE_PASS_BEGIN(ExpandFpLegacyPass, "expand-fp",
11351158
"Expand certain fp instructions", false, false)
1159+
INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
11361160
INITIALIZE_PASS_END(ExpandFpLegacyPass, "expand-fp", "Expand fp", false, false)
11371161

11381162
FunctionPass *llvm::createExpandFpPass(CodeGenOptLevel OptLevel) {

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)