-
Notifications
You must be signed in to change notification settings - Fork 15.4k
GlobalISel: Use LibcallLoweringInfo analysis in legalizer #170328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
GlobalISel: Use LibcallLoweringInfo analysis in legalizer #170328
Conversation
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.
|
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-backend-aarch64 Author: Matt Arsenault (arsenm) ChangesGlobalISel: Use LibcallLoweringInfo analysis in legalizer This is mostly boilerplate to move various freestanding utility I had a lot of trouble getting this to work in the legacy pass Old pass manager hacking Patch is 49.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/170328.diff 15 Files Affected:
diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
index 2d31c8aa6301b..b0f398d6e2b28 100644
--- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
+++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
@@ -32,6 +32,8 @@ class LLVM_ABI RuntimeLibraryAnalysis
LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
ModuleAnalysisManager &);
+ operator bool() const { return LibcallsInfo.has_value(); }
+
private:
friend AnalysisInfoMixin<RuntimeLibraryAnalysis>;
LLVM_ABI static AnalysisKey Key;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
class MachineIRBuilder;
class MachineInstr;
class GISelChangeObserver;
+class LibcallLoweringInfo;
class LostDebugLocObserver;
class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &MF) override;
- static MFResult
- legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
- ArrayRef<GISelChangeObserver *> AuxObservers,
- LostDebugLocObserver &LocObserver,
- MachineIRBuilder &MIRBuilder, GISelValueTracking *VT);
+ static MFResult legalizeMachineFunction(
+ MachineFunction &MF, const LegalizerInfo &LI,
+ ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+ const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
};
} // End namespace llvm.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
MachineRegisterInfo &MRI;
const LegalizerInfo &LI;
const TargetLowering &TLI;
- GISelValueTracking *VT;
+
+ // FIXME: Should probably make Libcalls mandatory
+ const LibcallLoweringInfo *Libcalls = nullptr;
+ GISelValueTracking *VT = nullptr;
public:
enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
/// Expose LegalizerInfo so the clients can re-use.
const LegalizerInfo &getLegalizerInfo() const { return LI; }
const TargetLowering &getTargetLowering() const { return TLI; }
+ const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
GISelValueTracking *getValueTracking() const { return VT; }
LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
- MachineIRBuilder &B);
+ MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls = nullptr);
LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer, MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls = nullptr,
GISelValueTracking *VT = nullptr);
/// Replace \p MI by a sequence of legal instructions that can implement the
@@ -178,6 +184,37 @@ class LegalizerHelper {
/// def by inserting a G_BITCAST from \p CastTy
LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
+ // Useful for libcalls where all operands have the same type.
+ LLVM_ABI LegalizeResult
+ simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
+ Type *OpType, LostDebugLocObserver &LocObserver) const;
+
+ LLVM_ABI LegalizeResult conversionLibcall(MachineInstr &MI, Type *ToType,
+ Type *FromType,
+ LostDebugLocObserver &LocObserver,
+ bool IsSigned = false) const;
+
+ /// Helper function that creates a libcall to the given \p Name using the
+ /// given calling convention \p CC.
+ LLVM_ABI LegalizeResult createLibcall(const char *Name,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args,
+ CallingConv::ID CC,
+ LostDebugLocObserver &LocObserver,
+ MachineInstr *MI = nullptr) const;
+
+ /// Helper function that creates the given libcall.
+ LLVM_ABI LegalizeResult createLibcall(RTLIB::Libcall Libcall,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args,
+ LostDebugLocObserver &LocObserver,
+ MachineInstr *MI = nullptr) const;
+
+ /// Create a libcall to memcpy et al.
+ LLVM_ABI LegalizeResult
+ createMemLibcall(MachineRegisterInfo &MRI, MachineInstr &MI,
+ LostDebugLocObserver &LocObserver) const;
+
private:
LegalizeResult
widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
@@ -278,17 +315,13 @@ class LegalizerHelper {
bool IsVolatile);
// Implements floating-point environment read/write via library function call.
- LegalizeResult createGetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createGetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createSetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createSetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createResetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createResetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createFCMPLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createFCMPLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
MachineInstrBuilder
@@ -539,26 +572,6 @@ class LegalizerHelper {
LLVM_ABI LegalizeResult lowerVAArg(MachineInstr &MI);
};
-/// Helper function that creates a libcall to the given \p Name using the given
-/// calling convention \p CC.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC,
- LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
-
-/// Helper function that creates the given libcall.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
-
-/// Create a libcall to memcpy et al.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
- MachineInstr &MI, LostDebugLocObserver &LocObserver);
-
} // End namespace llvm.
#endif
diff --git a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
index 3e0137710e8eb..47c0dd315d3b5 100644
--- a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
+++ b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
@@ -10,11 +10,12 @@
#define LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/Pass.h"
namespace llvm {
-
+class RuntimeLibraryInfoWrapper;
class TargetSubtargetInfo;
class TargetMachine;
@@ -97,6 +98,8 @@ class LibcallLoweringModuleAnalysisResult {
LoweringMap.clear();
}
+ operator bool() const { return RTLCI != nullptr; }
+
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &);
@@ -122,21 +125,24 @@ class LibcallLoweringModuleAnalysis
class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass {
LibcallLoweringModuleAnalysisResult Result;
+ RuntimeLibraryInfoWrapper *RuntimeLibcallsWrapper = nullptr;
public:
static char ID;
LibcallLoweringInfoWrapper();
const LibcallLoweringInfo &
- getLibcallLowering(const TargetSubtargetInfo &Subtarget) const {
- return Result.getLibcallLowering(Subtarget);
+ getLibcallLowering(const Module &M, const TargetSubtargetInfo &Subtarget) {
+ return getResult(M).getLibcallLowering(Subtarget);
}
- const LibcallLoweringModuleAnalysisResult &getResult() const {
+ const LibcallLoweringModuleAnalysisResult &getResult(const Module &M) {
+ if (!Result)
+ Result.init(&RuntimeLibcallsWrapper->getRTLCI(M));
return Result;
}
- bool doInitialization(Module &M) override;
+ void initializePass() override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override;
};
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index a8525554b142e..168be429e13a6 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -487,6 +487,8 @@ LLVM_ABI FunctionPass *createInterleavedLoadCombinePass();
///
LLVM_ABI ModulePass *createLowerEmuTLSPass();
+LLVM_ABI ModulePass *createLibcallLoweringInfoWrapper();
+
/// This pass lowers the \@llvm.load.relative and \@llvm.objc.* intrinsics to
/// instructions. This is unsafe to do earlier because a pass may combine the
/// constant initializer into the load, which may result in an overflowing
diff --git a/llvm/lib/CodeGen/ExpandFp.cpp b/llvm/lib/CodeGen/ExpandFp.cpp
index 13ed4846d2bf7..7d333be7ed6fc 100644
--- a/llvm/lib/CodeGen/ExpandFp.cpp
+++ b/llvm/lib/CodeGen/ExpandFp.cpp
@@ -1097,7 +1097,7 @@ class ExpandFpLegacyPass : public FunctionPass {
const LibcallLoweringInfo &Libcalls =
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
- *Subtarget);
+ *F.getParent(), *Subtarget);
if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone())
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
index 0f0656aaa4f45..711f7a0b5c35b 100644
--- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -73,6 +73,7 @@ char Legalizer::ID = 0;
INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
"Legalize the Machine IR a function's Machine IR", false,
false)
+INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
@@ -83,6 +84,7 @@ INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
Legalizer::Legalizer() : MachineFunctionPass(ID) { }
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<LibcallLoweringInfoWrapper>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<GISelCSEAnalysisWrapperPass>();
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
@@ -172,12 +174,11 @@ class LegalizerWorkListManager : public GISelChangeObserver {
};
} // namespace
-Legalizer::MFResult
-Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
- ArrayRef<GISelChangeObserver *> AuxObservers,
- LostDebugLocObserver &LocObserver,
- MachineIRBuilder &MIRBuilder,
- GISelValueTracking *VT) {
+Legalizer::MFResult Legalizer::legalizeMachineFunction(
+ MachineFunction &MF, const LegalizerInfo &LI,
+ ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+ const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT) {
MIRBuilder.setMF(MF);
MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -216,7 +217,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
// Now install the observer as the delegate to MF.
// This will keep all the observers notified about new insertions/deletions.
RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
- LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, VT);
+ LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, Libcalls, VT);
LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI, VT);
bool Changed = false;
SmallVector<MachineInstr *, 128> RetryList;
@@ -339,13 +340,19 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
if (VerifyDebugLocs > DebugLocVerifyLevel::None)
AuxObservers.push_back(&LocObserver);
+ const TargetSubtargetInfo &Subtarget = MF.getSubtarget();
+
+ const LibcallLoweringInfo &Libcalls =
+ getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
+ *MF.getFunction().getParent(), Subtarget);
+
// This allows Known Bits Analysis in the legalizer.
GISelValueTracking *VT =
&getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
- const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
+ const LegalizerInfo &LI = *Subtarget.getLegalizerInfo();
MFResult Result = legalizeMachineFunction(MF, LI, AuxObservers, LocObserver,
- *MIRBuilder, VT);
+ *MIRBuilder, &Libcalls, VT);
if (Result.FailedOn) {
reportGISelFailure(MF, MORE, "gisel-legalize",
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 1aa1d465d8da6..32cda979a0cda 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -104,16 +104,19 @@ static Type *getFloatTypeForLLT(LLVMContext &Ctx, LLT Ty) {
LegalizerHelper::LegalizerHelper(MachineFunction &MF,
GISelChangeObserver &Observer,
- MachineIRBuilder &Builder)
+ MachineIRBuilder &Builder,
+ const LibcallLoweringInfo *Libcalls)
: MIRBuilder(Builder), Observer(Observer), MRI(MF.getRegInfo()),
LI(*MF.getSubtarget().getLegalizerInfo()),
- TLI(*MF.getSubtarget().getTargetLowering()), VT(nullptr) {}
+ TLI(*MF.getSubtarget().getTargetLowering()), Libcalls(Libcalls) {}
LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer,
- MachineIRBuilder &B, GISelValueTracking *VT)
+ MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls,
+ GISelValueTracking *VT)
: MIRBuilder(B), Observer(Observer), MRI(MF.getRegInfo()), LI(LI),
- TLI(*MF.getSubtarget().getTargetLowering()), VT(VT) {}
+ TLI(*MF.getSubtarget().getTargetLowering()), Libcalls(Libcalls), VT(VT) {}
LegalizerHelper::LegalizeResult
LegalizerHelper::legalizeInstrStep(MachineInstr &MI,
@@ -581,12 +584,10 @@ static bool isLibCallInTailPosition(const CallLowering::ArgInfo &Result,
return true;
}
-LegalizerHelper::LegalizeResult
-llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- const CallingConv::ID CC, LostDebugLocObserver &LocObserver,
- MachineInstr *MI) {
+LegalizerHelper::LegalizeResult LegalizerHelper::createLibcall(
+ const char *Name, const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args, const CallingConv::ID CC,
+ LostDebugLocObserver &LocObserver, MachineInstr *MI) const {
auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
CallLowering::CallLoweringInfo Info;
@@ -628,31 +629,36 @@ llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
return LegalizerHelper::Legalized;
}
-LegalizerHelper::LegalizeResult
-llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- LostDebugLocObserver &LocObserver, MachineInstr *MI) {
- auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
- const char *Name = TLI.getLibcallName(Libcall);
- if (!Name)
+LegalizerHelper::LegalizeResult LegalizerHelper::createLibcall(
+ RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args, LostDebugLocObserver &LocObserver,
+ MachineInstr *MI) const {
+ if (!Libcalls)
return LegalizerHelper::UnableToLegalize;
- const CallingConv::ID CC = TLI.getLibcallCallingConv(Libcall);
- return createLibcall(MIRBuilder, Name, Result, Args, CC, LocObserver, MI);
+
+ RTLIB::LibcallImpl LibcallImpl = Libcalls->getLibcallImpl(Libcall);
+ if (LibcallImpl == RTLIB::Unsupported)
+ return LegalizerHelper::UnableToLegalize;
+
+ auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
+
+ StringRef Name = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpl);
+ const CallingConv::ID CC = TLI.getLibcallImplCallingConv(LibcallImpl);
+ return createLibcall(Name.data(), Result, Args, CC, LocObserver, MI);
}
// Useful for libcalls where all operands have the same type.
-static LegalizerHelper::LegalizeResult
-simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
- Type *OpType, LostDebugLocObserver &LocObserver) {
+LegalizerHelper::LegalizeResult
+LegalizerHelper::simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
+ unsigned Size, Type *OpType,
+ LostDebugLocObserver &LocObserver) const {
auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
// FIXME: What does the original arg index mean here?
SmallVector<CallLowering::ArgInfo, 3> Args;
for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
Args.push_back({MO.getReg(), OpType, 0});
- return createLibcall(MIRBuilder, Libcall,
- {MI.getOperand(0).getReg(), OpType, 0}, Args,
+ return createLibcall(Libcall, {MI.getOperand(0).getReg(), OpType, 0}, Args,
LocObserver, &MI);
}
@@ -681,13 +687,12 @@ LegalizerHelper::LegalizeResult LegalizerHelper::emitSincosLibcall(
.getReg(0);
auto &Ctx = MF.getFunction().getContext();
- auto LibcallResult =
- createLibcall(MIRBuilder, getRTLibDesc(MI.getOpcode(), Size),
- {{0}, Type::getVoidTy(Ctx), 0},
- {{Src, OpType, 0},
- {StackPtrSin, PointerType::get(Ctx, AddrSpace), 1},
- {StackPtrCos, PointerType::get(Ctx, AddrSpace), 2}},
- LocObserver, &MI);
+ auto LibcallResult = createLibcall(
+ getRTLibDesc(MI.getOpcode(), Size), {{0}, Type::getVoidTy(Ctx), 0},
+ {{Src, OpType, 0},
+ {StackPtrSin, PointerType::get(Ctx, AddrSpace), 1},
+ {StackPtrCos, PointerType::get(Ctx, AddrSpace), 2}},
+ LocObserver, &MI);
if (LibcallResult != LegalizeResult::Legalized)
return LegalizerHelper::UnableToLegalize;
@@ -728,7 +733,7 @@ LegalizerHelper::emitModfLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
auto &Ctx = MF.getFunction().getContext();
auto Libc...
[truncated]
|
|
@llvm/pr-subscribers-backend-x86 Author: Matt Arsenault (arsenm) ChangesGlobalISel: Use LibcallLoweringInfo analysis in legalizer This is mostly boilerplate to move various freestanding utility I had a lot of trouble getting this to work in the legacy pass Old pass manager hacking Patch is 49.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/170328.diff 15 Files Affected:
diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
index 2d31c8aa6301b..b0f398d6e2b28 100644
--- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
+++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
@@ -32,6 +32,8 @@ class LLVM_ABI RuntimeLibraryAnalysis
LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
ModuleAnalysisManager &);
+ operator bool() const { return LibcallsInfo.has_value(); }
+
private:
friend AnalysisInfoMixin<RuntimeLibraryAnalysis>;
LLVM_ABI static AnalysisKey Key;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
class MachineIRBuilder;
class MachineInstr;
class GISelChangeObserver;
+class LibcallLoweringInfo;
class LostDebugLocObserver;
class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &MF) override;
- static MFResult
- legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
- ArrayRef<GISelChangeObserver *> AuxObservers,
- LostDebugLocObserver &LocObserver,
- MachineIRBuilder &MIRBuilder, GISelValueTracking *VT);
+ static MFResult legalizeMachineFunction(
+ MachineFunction &MF, const LegalizerInfo &LI,
+ ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+ const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
};
} // End namespace llvm.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
MachineRegisterInfo &MRI;
const LegalizerInfo &LI;
const TargetLowering &TLI;
- GISelValueTracking *VT;
+
+ // FIXME: Should probably make Libcalls mandatory
+ const LibcallLoweringInfo *Libcalls = nullptr;
+ GISelValueTracking *VT = nullptr;
public:
enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
/// Expose LegalizerInfo so the clients can re-use.
const LegalizerInfo &getLegalizerInfo() const { return LI; }
const TargetLowering &getTargetLowering() const { return TLI; }
+ const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
GISelValueTracking *getValueTracking() const { return VT; }
LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
- MachineIRBuilder &B);
+ MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls = nullptr);
LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer, MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls = nullptr,
GISelValueTracking *VT = nullptr);
/// Replace \p MI by a sequence of legal instructions that can implement the
@@ -178,6 +184,37 @@ class LegalizerHelper {
/// def by inserting a G_BITCAST from \p CastTy
LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
+ // Useful for libcalls where all operands have the same type.
+ LLVM_ABI LegalizeResult
+ simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
+ Type *OpType, LostDebugLocObserver &LocObserver) const;
+
+ LLVM_ABI LegalizeResult conversionLibcall(MachineInstr &MI, Type *ToType,
+ Type *FromType,
+ LostDebugLocObserver &LocObserver,
+ bool IsSigned = false) const;
+
+ /// Helper function that creates a libcall to the given \p Name using the
+ /// given calling convention \p CC.
+ LLVM_ABI LegalizeResult createLibcall(const char *Name,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args,
+ CallingConv::ID CC,
+ LostDebugLocObserver &LocObserver,
+ MachineInstr *MI = nullptr) const;
+
+ /// Helper function that creates the given libcall.
+ LLVM_ABI LegalizeResult createLibcall(RTLIB::Libcall Libcall,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args,
+ LostDebugLocObserver &LocObserver,
+ MachineInstr *MI = nullptr) const;
+
+ /// Create a libcall to memcpy et al.
+ LLVM_ABI LegalizeResult
+ createMemLibcall(MachineRegisterInfo &MRI, MachineInstr &MI,
+ LostDebugLocObserver &LocObserver) const;
+
private:
LegalizeResult
widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
@@ -278,17 +315,13 @@ class LegalizerHelper {
bool IsVolatile);
// Implements floating-point environment read/write via library function call.
- LegalizeResult createGetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createGetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createSetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createSetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createResetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createResetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createFCMPLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createFCMPLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
MachineInstrBuilder
@@ -539,26 +572,6 @@ class LegalizerHelper {
LLVM_ABI LegalizeResult lowerVAArg(MachineInstr &MI);
};
-/// Helper function that creates a libcall to the given \p Name using the given
-/// calling convention \p CC.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC,
- LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
-
-/// Helper function that creates the given libcall.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
-
-/// Create a libcall to memcpy et al.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
- MachineInstr &MI, LostDebugLocObserver &LocObserver);
-
} // End namespace llvm.
#endif
diff --git a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
index 3e0137710e8eb..47c0dd315d3b5 100644
--- a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
+++ b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
@@ -10,11 +10,12 @@
#define LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/Pass.h"
namespace llvm {
-
+class RuntimeLibraryInfoWrapper;
class TargetSubtargetInfo;
class TargetMachine;
@@ -97,6 +98,8 @@ class LibcallLoweringModuleAnalysisResult {
LoweringMap.clear();
}
+ operator bool() const { return RTLCI != nullptr; }
+
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &);
@@ -122,21 +125,24 @@ class LibcallLoweringModuleAnalysis
class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass {
LibcallLoweringModuleAnalysisResult Result;
+ RuntimeLibraryInfoWrapper *RuntimeLibcallsWrapper = nullptr;
public:
static char ID;
LibcallLoweringInfoWrapper();
const LibcallLoweringInfo &
- getLibcallLowering(const TargetSubtargetInfo &Subtarget) const {
- return Result.getLibcallLowering(Subtarget);
+ getLibcallLowering(const Module &M, const TargetSubtargetInfo &Subtarget) {
+ return getResult(M).getLibcallLowering(Subtarget);
}
- const LibcallLoweringModuleAnalysisResult &getResult() const {
+ const LibcallLoweringModuleAnalysisResult &getResult(const Module &M) {
+ if (!Result)
+ Result.init(&RuntimeLibcallsWrapper->getRTLCI(M));
return Result;
}
- bool doInitialization(Module &M) override;
+ void initializePass() override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override;
};
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index a8525554b142e..168be429e13a6 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -487,6 +487,8 @@ LLVM_ABI FunctionPass *createInterleavedLoadCombinePass();
///
LLVM_ABI ModulePass *createLowerEmuTLSPass();
+LLVM_ABI ModulePass *createLibcallLoweringInfoWrapper();
+
/// This pass lowers the \@llvm.load.relative and \@llvm.objc.* intrinsics to
/// instructions. This is unsafe to do earlier because a pass may combine the
/// constant initializer into the load, which may result in an overflowing
diff --git a/llvm/lib/CodeGen/ExpandFp.cpp b/llvm/lib/CodeGen/ExpandFp.cpp
index 13ed4846d2bf7..7d333be7ed6fc 100644
--- a/llvm/lib/CodeGen/ExpandFp.cpp
+++ b/llvm/lib/CodeGen/ExpandFp.cpp
@@ -1097,7 +1097,7 @@ class ExpandFpLegacyPass : public FunctionPass {
const LibcallLoweringInfo &Libcalls =
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
- *Subtarget);
+ *F.getParent(), *Subtarget);
if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone())
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
index 0f0656aaa4f45..711f7a0b5c35b 100644
--- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -73,6 +73,7 @@ char Legalizer::ID = 0;
INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
"Legalize the Machine IR a function's Machine IR", false,
false)
+INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
@@ -83,6 +84,7 @@ INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
Legalizer::Legalizer() : MachineFunctionPass(ID) { }
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<LibcallLoweringInfoWrapper>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<GISelCSEAnalysisWrapperPass>();
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
@@ -172,12 +174,11 @@ class LegalizerWorkListManager : public GISelChangeObserver {
};
} // namespace
-Legalizer::MFResult
-Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
- ArrayRef<GISelChangeObserver *> AuxObservers,
- LostDebugLocObserver &LocObserver,
- MachineIRBuilder &MIRBuilder,
- GISelValueTracking *VT) {
+Legalizer::MFResult Legalizer::legalizeMachineFunction(
+ MachineFunction &MF, const LegalizerInfo &LI,
+ ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+ const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT) {
MIRBuilder.setMF(MF);
MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -216,7 +217,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
// Now install the observer as the delegate to MF.
// This will keep all the observers notified about new insertions/deletions.
RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
- LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, VT);
+ LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, Libcalls, VT);
LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI, VT);
bool Changed = false;
SmallVector<MachineInstr *, 128> RetryList;
@@ -339,13 +340,19 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
if (VerifyDebugLocs > DebugLocVerifyLevel::None)
AuxObservers.push_back(&LocObserver);
+ const TargetSubtargetInfo &Subtarget = MF.getSubtarget();
+
+ const LibcallLoweringInfo &Libcalls =
+ getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
+ *MF.getFunction().getParent(), Subtarget);
+
// This allows Known Bits Analysis in the legalizer.
GISelValueTracking *VT =
&getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
- const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
+ const LegalizerInfo &LI = *Subtarget.getLegalizerInfo();
MFResult Result = legalizeMachineFunction(MF, LI, AuxObservers, LocObserver,
- *MIRBuilder, VT);
+ *MIRBuilder, &Libcalls, VT);
if (Result.FailedOn) {
reportGISelFailure(MF, MORE, "gisel-legalize",
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 1aa1d465d8da6..32cda979a0cda 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -104,16 +104,19 @@ static Type *getFloatTypeForLLT(LLVMContext &Ctx, LLT Ty) {
LegalizerHelper::LegalizerHelper(MachineFunction &MF,
GISelChangeObserver &Observer,
- MachineIRBuilder &Builder)
+ MachineIRBuilder &Builder,
+ const LibcallLoweringInfo *Libcalls)
: MIRBuilder(Builder), Observer(Observer), MRI(MF.getRegInfo()),
LI(*MF.getSubtarget().getLegalizerInfo()),
- TLI(*MF.getSubtarget().getTargetLowering()), VT(nullptr) {}
+ TLI(*MF.getSubtarget().getTargetLowering()), Libcalls(Libcalls) {}
LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer,
- MachineIRBuilder &B, GISelValueTracking *VT)
+ MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls,
+ GISelValueTracking *VT)
: MIRBuilder(B), Observer(Observer), MRI(MF.getRegInfo()), LI(LI),
- TLI(*MF.getSubtarget().getTargetLowering()), VT(VT) {}
+ TLI(*MF.getSubtarget().getTargetLowering()), Libcalls(Libcalls), VT(VT) {}
LegalizerHelper::LegalizeResult
LegalizerHelper::legalizeInstrStep(MachineInstr &MI,
@@ -581,12 +584,10 @@ static bool isLibCallInTailPosition(const CallLowering::ArgInfo &Result,
return true;
}
-LegalizerHelper::LegalizeResult
-llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- const CallingConv::ID CC, LostDebugLocObserver &LocObserver,
- MachineInstr *MI) {
+LegalizerHelper::LegalizeResult LegalizerHelper::createLibcall(
+ const char *Name, const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args, const CallingConv::ID CC,
+ LostDebugLocObserver &LocObserver, MachineInstr *MI) const {
auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
CallLowering::CallLoweringInfo Info;
@@ -628,31 +629,36 @@ llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
return LegalizerHelper::Legalized;
}
-LegalizerHelper::LegalizeResult
-llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- LostDebugLocObserver &LocObserver, MachineInstr *MI) {
- auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
- const char *Name = TLI.getLibcallName(Libcall);
- if (!Name)
+LegalizerHelper::LegalizeResult LegalizerHelper::createLibcall(
+ RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args, LostDebugLocObserver &LocObserver,
+ MachineInstr *MI) const {
+ if (!Libcalls)
return LegalizerHelper::UnableToLegalize;
- const CallingConv::ID CC = TLI.getLibcallCallingConv(Libcall);
- return createLibcall(MIRBuilder, Name, Result, Args, CC, LocObserver, MI);
+
+ RTLIB::LibcallImpl LibcallImpl = Libcalls->getLibcallImpl(Libcall);
+ if (LibcallImpl == RTLIB::Unsupported)
+ return LegalizerHelper::UnableToLegalize;
+
+ auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
+
+ StringRef Name = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpl);
+ const CallingConv::ID CC = TLI.getLibcallImplCallingConv(LibcallImpl);
+ return createLibcall(Name.data(), Result, Args, CC, LocObserver, MI);
}
// Useful for libcalls where all operands have the same type.
-static LegalizerHelper::LegalizeResult
-simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
- Type *OpType, LostDebugLocObserver &LocObserver) {
+LegalizerHelper::LegalizeResult
+LegalizerHelper::simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
+ unsigned Size, Type *OpType,
+ LostDebugLocObserver &LocObserver) const {
auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
// FIXME: What does the original arg index mean here?
SmallVector<CallLowering::ArgInfo, 3> Args;
for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
Args.push_back({MO.getReg(), OpType, 0});
- return createLibcall(MIRBuilder, Libcall,
- {MI.getOperand(0).getReg(), OpType, 0}, Args,
+ return createLibcall(Libcall, {MI.getOperand(0).getReg(), OpType, 0}, Args,
LocObserver, &MI);
}
@@ -681,13 +687,12 @@ LegalizerHelper::LegalizeResult LegalizerHelper::emitSincosLibcall(
.getReg(0);
auto &Ctx = MF.getFunction().getContext();
- auto LibcallResult =
- createLibcall(MIRBuilder, getRTLibDesc(MI.getOpcode(), Size),
- {{0}, Type::getVoidTy(Ctx), 0},
- {{Src, OpType, 0},
- {StackPtrSin, PointerType::get(Ctx, AddrSpace), 1},
- {StackPtrCos, PointerType::get(Ctx, AddrSpace), 2}},
- LocObserver, &MI);
+ auto LibcallResult = createLibcall(
+ getRTLibDesc(MI.getOpcode(), Size), {{0}, Type::getVoidTy(Ctx), 0},
+ {{Src, OpType, 0},
+ {StackPtrSin, PointerType::get(Ctx, AddrSpace), 1},
+ {StackPtrCos, PointerType::get(Ctx, AddrSpace), 2}},
+ LocObserver, &MI);
if (LibcallResult != LegalizeResult::Legalized)
return LegalizerHelper::UnableToLegalize;
@@ -728,7 +733,7 @@ LegalizerHelper::emitModfLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
auto &Ctx = MF.getFunction().getContext();
auto Libc...
[truncated]
|
|
@llvm/pr-subscribers-llvm-transforms Author: Matt Arsenault (arsenm) ChangesGlobalISel: Use LibcallLoweringInfo analysis in legalizer This is mostly boilerplate to move various freestanding utility I had a lot of trouble getting this to work in the legacy pass Old pass manager hacking Patch is 49.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/170328.diff 15 Files Affected:
diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
index 2d31c8aa6301b..b0f398d6e2b28 100644
--- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
+++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
@@ -32,6 +32,8 @@ class LLVM_ABI RuntimeLibraryAnalysis
LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
ModuleAnalysisManager &);
+ operator bool() const { return LibcallsInfo.has_value(); }
+
private:
friend AnalysisInfoMixin<RuntimeLibraryAnalysis>;
LLVM_ABI static AnalysisKey Key;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index a94daa202d856..f8e629bc50a90 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,6 +33,7 @@ class LegalizerInfo;
class MachineIRBuilder;
class MachineInstr;
class GISelChangeObserver;
+class LibcallLoweringInfo;
class LostDebugLocObserver;
class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -70,11 +71,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &MF) override;
- static MFResult
- legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
- ArrayRef<GISelChangeObserver *> AuxObservers,
- LostDebugLocObserver &LocObserver,
- MachineIRBuilder &MIRBuilder, GISelValueTracking *VT);
+ static MFResult legalizeMachineFunction(
+ MachineFunction &MF, const LegalizerInfo &LI,
+ ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+ const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
};
} // End namespace llvm.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a458cbd94ccb1..11f734ec64eb1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,7 +59,10 @@ class LegalizerHelper {
MachineRegisterInfo &MRI;
const LegalizerInfo &LI;
const TargetLowering &TLI;
- GISelValueTracking *VT;
+
+ // FIXME: Should probably make Libcalls mandatory
+ const LibcallLoweringInfo *Libcalls = nullptr;
+ GISelValueTracking *VT = nullptr;
public:
enum LegalizeResult {
@@ -78,12 +81,15 @@ class LegalizerHelper {
/// Expose LegalizerInfo so the clients can re-use.
const LegalizerInfo &getLegalizerInfo() const { return LI; }
const TargetLowering &getTargetLowering() const { return TLI; }
+ const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
GISelValueTracking *getValueTracking() const { return VT; }
LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
- MachineIRBuilder &B);
+ MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls = nullptr);
LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer, MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls = nullptr,
GISelValueTracking *VT = nullptr);
/// Replace \p MI by a sequence of legal instructions that can implement the
@@ -178,6 +184,37 @@ class LegalizerHelper {
/// def by inserting a G_BITCAST from \p CastTy
LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
+ // Useful for libcalls where all operands have the same type.
+ LLVM_ABI LegalizeResult
+ simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
+ Type *OpType, LostDebugLocObserver &LocObserver) const;
+
+ LLVM_ABI LegalizeResult conversionLibcall(MachineInstr &MI, Type *ToType,
+ Type *FromType,
+ LostDebugLocObserver &LocObserver,
+ bool IsSigned = false) const;
+
+ /// Helper function that creates a libcall to the given \p Name using the
+ /// given calling convention \p CC.
+ LLVM_ABI LegalizeResult createLibcall(const char *Name,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args,
+ CallingConv::ID CC,
+ LostDebugLocObserver &LocObserver,
+ MachineInstr *MI = nullptr) const;
+
+ /// Helper function that creates the given libcall.
+ LLVM_ABI LegalizeResult createLibcall(RTLIB::Libcall Libcall,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args,
+ LostDebugLocObserver &LocObserver,
+ MachineInstr *MI = nullptr) const;
+
+ /// Create a libcall to memcpy et al.
+ LLVM_ABI LegalizeResult
+ createMemLibcall(MachineRegisterInfo &MRI, MachineInstr &MI,
+ LostDebugLocObserver &LocObserver) const;
+
private:
LegalizeResult
widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
@@ -278,17 +315,13 @@ class LegalizerHelper {
bool IsVolatile);
// Implements floating-point environment read/write via library function call.
- LegalizeResult createGetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createGetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createSetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createSetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createResetStateLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createResetStateLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
- LegalizeResult createFCMPLibcall(MachineIRBuilder &MIRBuilder,
- MachineInstr &MI,
+ LegalizeResult createFCMPLibcall(MachineInstr &MI,
LostDebugLocObserver &LocObserver);
MachineInstrBuilder
@@ -539,26 +572,6 @@ class LegalizerHelper {
LLVM_ABI LegalizeResult lowerVAArg(MachineInstr &MI);
};
-/// Helper function that creates a libcall to the given \p Name using the given
-/// calling convention \p CC.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC,
- LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
-
-/// Helper function that creates the given libcall.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
-
-/// Create a libcall to memcpy et al.
-LLVM_ABI LegalizerHelper::LegalizeResult
-createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
- MachineInstr &MI, LostDebugLocObserver &LocObserver);
-
} // End namespace llvm.
#endif
diff --git a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
index 3e0137710e8eb..47c0dd315d3b5 100644
--- a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
+++ b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
@@ -10,11 +10,12 @@
#define LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/Pass.h"
namespace llvm {
-
+class RuntimeLibraryInfoWrapper;
class TargetSubtargetInfo;
class TargetMachine;
@@ -97,6 +98,8 @@ class LibcallLoweringModuleAnalysisResult {
LoweringMap.clear();
}
+ operator bool() const { return RTLCI != nullptr; }
+
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &);
@@ -122,21 +125,24 @@ class LibcallLoweringModuleAnalysis
class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass {
LibcallLoweringModuleAnalysisResult Result;
+ RuntimeLibraryInfoWrapper *RuntimeLibcallsWrapper = nullptr;
public:
static char ID;
LibcallLoweringInfoWrapper();
const LibcallLoweringInfo &
- getLibcallLowering(const TargetSubtargetInfo &Subtarget) const {
- return Result.getLibcallLowering(Subtarget);
+ getLibcallLowering(const Module &M, const TargetSubtargetInfo &Subtarget) {
+ return getResult(M).getLibcallLowering(Subtarget);
}
- const LibcallLoweringModuleAnalysisResult &getResult() const {
+ const LibcallLoweringModuleAnalysisResult &getResult(const Module &M) {
+ if (!Result)
+ Result.init(&RuntimeLibcallsWrapper->getRTLCI(M));
return Result;
}
- bool doInitialization(Module &M) override;
+ void initializePass() override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override;
};
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index a8525554b142e..168be429e13a6 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -487,6 +487,8 @@ LLVM_ABI FunctionPass *createInterleavedLoadCombinePass();
///
LLVM_ABI ModulePass *createLowerEmuTLSPass();
+LLVM_ABI ModulePass *createLibcallLoweringInfoWrapper();
+
/// This pass lowers the \@llvm.load.relative and \@llvm.objc.* intrinsics to
/// instructions. This is unsafe to do earlier because a pass may combine the
/// constant initializer into the load, which may result in an overflowing
diff --git a/llvm/lib/CodeGen/ExpandFp.cpp b/llvm/lib/CodeGen/ExpandFp.cpp
index 13ed4846d2bf7..7d333be7ed6fc 100644
--- a/llvm/lib/CodeGen/ExpandFp.cpp
+++ b/llvm/lib/CodeGen/ExpandFp.cpp
@@ -1097,7 +1097,7 @@ class ExpandFpLegacyPass : public FunctionPass {
const LibcallLoweringInfo &Libcalls =
getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
- *Subtarget);
+ *F.getParent(), *Subtarget);
if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone())
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
index 0f0656aaa4f45..711f7a0b5c35b 100644
--- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -73,6 +73,7 @@ char Legalizer::ID = 0;
INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
"Legalize the Machine IR a function's Machine IR", false,
false)
+INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
@@ -83,6 +84,7 @@ INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
Legalizer::Legalizer() : MachineFunctionPass(ID) { }
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<LibcallLoweringInfoWrapper>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<GISelCSEAnalysisWrapperPass>();
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
@@ -172,12 +174,11 @@ class LegalizerWorkListManager : public GISelChangeObserver {
};
} // namespace
-Legalizer::MFResult
-Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
- ArrayRef<GISelChangeObserver *> AuxObservers,
- LostDebugLocObserver &LocObserver,
- MachineIRBuilder &MIRBuilder,
- GISelValueTracking *VT) {
+Legalizer::MFResult Legalizer::legalizeMachineFunction(
+ MachineFunction &MF, const LegalizerInfo &LI,
+ ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
+ const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT) {
MIRBuilder.setMF(MF);
MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -216,7 +217,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
// Now install the observer as the delegate to MF.
// This will keep all the observers notified about new insertions/deletions.
RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
- LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, VT);
+ LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, Libcalls, VT);
LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI, VT);
bool Changed = false;
SmallVector<MachineInstr *, 128> RetryList;
@@ -339,13 +340,19 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
if (VerifyDebugLocs > DebugLocVerifyLevel::None)
AuxObservers.push_back(&LocObserver);
+ const TargetSubtargetInfo &Subtarget = MF.getSubtarget();
+
+ const LibcallLoweringInfo &Libcalls =
+ getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
+ *MF.getFunction().getParent(), Subtarget);
+
// This allows Known Bits Analysis in the legalizer.
GISelValueTracking *VT =
&getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
- const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
+ const LegalizerInfo &LI = *Subtarget.getLegalizerInfo();
MFResult Result = legalizeMachineFunction(MF, LI, AuxObservers, LocObserver,
- *MIRBuilder, VT);
+ *MIRBuilder, &Libcalls, VT);
if (Result.FailedOn) {
reportGISelFailure(MF, MORE, "gisel-legalize",
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 1aa1d465d8da6..32cda979a0cda 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -104,16 +104,19 @@ static Type *getFloatTypeForLLT(LLVMContext &Ctx, LLT Ty) {
LegalizerHelper::LegalizerHelper(MachineFunction &MF,
GISelChangeObserver &Observer,
- MachineIRBuilder &Builder)
+ MachineIRBuilder &Builder,
+ const LibcallLoweringInfo *Libcalls)
: MIRBuilder(Builder), Observer(Observer), MRI(MF.getRegInfo()),
LI(*MF.getSubtarget().getLegalizerInfo()),
- TLI(*MF.getSubtarget().getTargetLowering()), VT(nullptr) {}
+ TLI(*MF.getSubtarget().getTargetLowering()), Libcalls(Libcalls) {}
LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer,
- MachineIRBuilder &B, GISelValueTracking *VT)
+ MachineIRBuilder &B,
+ const LibcallLoweringInfo *Libcalls,
+ GISelValueTracking *VT)
: MIRBuilder(B), Observer(Observer), MRI(MF.getRegInfo()), LI(LI),
- TLI(*MF.getSubtarget().getTargetLowering()), VT(VT) {}
+ TLI(*MF.getSubtarget().getTargetLowering()), Libcalls(Libcalls), VT(VT) {}
LegalizerHelper::LegalizeResult
LegalizerHelper::legalizeInstrStep(MachineInstr &MI,
@@ -581,12 +584,10 @@ static bool isLibCallInTailPosition(const CallLowering::ArgInfo &Result,
return true;
}
-LegalizerHelper::LegalizeResult
-llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- const CallingConv::ID CC, LostDebugLocObserver &LocObserver,
- MachineInstr *MI) {
+LegalizerHelper::LegalizeResult LegalizerHelper::createLibcall(
+ const char *Name, const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args, const CallingConv::ID CC,
+ LostDebugLocObserver &LocObserver, MachineInstr *MI) const {
auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
CallLowering::CallLoweringInfo Info;
@@ -628,31 +629,36 @@ llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
return LegalizerHelper::Legalized;
}
-LegalizerHelper::LegalizeResult
-llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
- const CallLowering::ArgInfo &Result,
- ArrayRef<CallLowering::ArgInfo> Args,
- LostDebugLocObserver &LocObserver, MachineInstr *MI) {
- auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
- const char *Name = TLI.getLibcallName(Libcall);
- if (!Name)
+LegalizerHelper::LegalizeResult LegalizerHelper::createLibcall(
+ RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args, LostDebugLocObserver &LocObserver,
+ MachineInstr *MI) const {
+ if (!Libcalls)
return LegalizerHelper::UnableToLegalize;
- const CallingConv::ID CC = TLI.getLibcallCallingConv(Libcall);
- return createLibcall(MIRBuilder, Name, Result, Args, CC, LocObserver, MI);
+
+ RTLIB::LibcallImpl LibcallImpl = Libcalls->getLibcallImpl(Libcall);
+ if (LibcallImpl == RTLIB::Unsupported)
+ return LegalizerHelper::UnableToLegalize;
+
+ auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
+
+ StringRef Name = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpl);
+ const CallingConv::ID CC = TLI.getLibcallImplCallingConv(LibcallImpl);
+ return createLibcall(Name.data(), Result, Args, CC, LocObserver, MI);
}
// Useful for libcalls where all operands have the same type.
-static LegalizerHelper::LegalizeResult
-simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
- Type *OpType, LostDebugLocObserver &LocObserver) {
+LegalizerHelper::LegalizeResult
+LegalizerHelper::simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
+ unsigned Size, Type *OpType,
+ LostDebugLocObserver &LocObserver) const {
auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
// FIXME: What does the original arg index mean here?
SmallVector<CallLowering::ArgInfo, 3> Args;
for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
Args.push_back({MO.getReg(), OpType, 0});
- return createLibcall(MIRBuilder, Libcall,
- {MI.getOperand(0).getReg(), OpType, 0}, Args,
+ return createLibcall(Libcall, {MI.getOperand(0).getReg(), OpType, 0}, Args,
LocObserver, &MI);
}
@@ -681,13 +687,12 @@ LegalizerHelper::LegalizeResult LegalizerHelper::emitSincosLibcall(
.getReg(0);
auto &Ctx = MF.getFunction().getContext();
- auto LibcallResult =
- createLibcall(MIRBuilder, getRTLibDesc(MI.getOpcode(), Size),
- {{0}, Type::getVoidTy(Ctx), 0},
- {{Src, OpType, 0},
- {StackPtrSin, PointerType::get(Ctx, AddrSpace), 1},
- {StackPtrCos, PointerType::get(Ctx, AddrSpace), 2}},
- LocObserver, &MI);
+ auto LibcallResult = createLibcall(
+ getRTLibDesc(MI.getOpcode(), Size), {{0}, Type::getVoidTy(Ctx), 0},
+ {{Src, OpType, 0},
+ {StackPtrSin, PointerType::get(Ctx, AddrSpace), 1},
+ {StackPtrCos, PointerType::get(Ctx, AddrSpace), 2}},
+ LocObserver, &MI);
if (LibcallResult != LegalizeResult::Legalized)
return LegalizerHelper::UnableToLegalize;
@@ -728,7 +733,7 @@ LegalizerHelper::emitModfLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
auto &Ctx = MF.getFunction().getContext();
auto Libc...
[truncated]
|
This is mostly boilerplate to move various freestanding utility functions into LegalizerHelper. LibcallLoweringInfo is currently optional, mostly because threading it through assorted other uses of LegalizerHelper is more difficult. I had a lot of trouble getting this to work in the legacy pass manager with setRequiresCodeGenSCCOrder, and am not happy with the result. A sub-pass manager is introduced and this is invalidated, so we're re-computing this unnecessarily.
17769e5 to
0c95e55
Compare

GlobalISel: Use LibcallLoweringInfo analysis in legalizer
This is mostly boilerplate to move various freestanding utility
functions into LegalizerHelper. LibcallLoweringInfo is currently
optional, mostly because threading it through assorted other
uses of LegalizerHelper is more difficult.
I had a lot of trouble getting this to work in the legacy pass
manager with setRequiresCodeGenSCCOrder, and am not happy with the
result. A sub-pass manager is introduced and this is invalidated,
so we're re-computing this unnecessarily.
Old pass manager hacking