diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index ec609db8d3a3c..af3480d5755f1 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/RuntimeLibcallInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/BitcodeReader.h" @@ -655,6 +656,11 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses, llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib())); CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); + const llvm::TargetOptions &Options = TM->Options; + CodeGenPasses.add(new RuntimeLibraryInfoWrapper( + TargetTriple, Options.ExceptionModel, Options.FloatABIType, + Options.EABIVersion, Options.MCOptions.ABIName, Options.VecLib)); + // Normal mode, emit a .s or .o file by running the code generator. Note, // this also adds codegenerator level optimization passes. CodeGenFileType CGFT = getCodeGenFileType(Action); diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h index 28a2ec47f81ad..b0f398d6e2b28 100644 --- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h +++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h @@ -22,11 +22,18 @@ class LLVM_ABI RuntimeLibraryAnalysis RuntimeLibraryAnalysis() = default; RuntimeLibraryAnalysis(RTLIB::RuntimeLibcallsInfo &&BaselineInfoImpl) : LibcallsInfo(std::move(BaselineInfoImpl)) {} - explicit RuntimeLibraryAnalysis(const Triple &T) : LibcallsInfo(T) {} + RuntimeLibraryAnalysis( + const Triple &TT, + ExceptionHandling ExceptionModel = ExceptionHandling::None, + FloatABI::ABIType FloatABI = FloatABI::Default, + EABI EABIVersion = EABI::Default, StringRef ABIName = "", + VectorLibrary VecLib = VectorLibrary::NoLibrary); LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M, ModuleAnalysisManager &); + operator bool() const { return LibcallsInfo.has_value(); } + private: friend AnalysisInfoMixin; LLVM_ABI static AnalysisKey Key; @@ -41,12 +48,19 @@ class LLVM_ABI RuntimeLibraryInfoWrapper : public ImmutablePass { public: static char ID; RuntimeLibraryInfoWrapper(); - explicit RuntimeLibraryInfoWrapper(const Triple &T); - explicit RuntimeLibraryInfoWrapper(const RTLIB::RuntimeLibcallsInfo &RTLCI); + RuntimeLibraryInfoWrapper( + const Triple &TT, + ExceptionHandling ExceptionModel = ExceptionHandling::None, + FloatABI::ABIType FloatABI = FloatABI::Default, + EABI EABIVersion = EABI::Default, StringRef ABIName = "", + VectorLibrary VecLib = VectorLibrary::NoLibrary); const RTLIB::RuntimeLibcallsInfo &getRTLCI(const Module &M) { - ModuleAnalysisManager DummyMAM; - RTLCI = RTLA.run(M, DummyMAM); + if (!RTLCI) { + ModuleAnalysisManager DummyMAM; + RTLCI = RTLA.run(M, DummyMAM); + } + return *RTLCI; } 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 AuxObservers, - LostDebugLocObserver &LocObserver, - MachineIRBuilder &MIRBuilder, GISelValueTracking *VT); + static MFResult legalizeMachineFunction( + MachineFunction &MF, const LegalizerInfo &LI, + ArrayRef 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 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 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 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 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 8624fd2403a12..47c0dd315d3b5 100644 --- a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h +++ b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h @@ -9,12 +9,17 @@ #ifndef LLVM_CODEGEN_LIBCALLLOWERINGINFO_H #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; +/// Tracks which library functions to use for a particular subtarget. class LibcallLoweringInfo { private: const RTLIB::RuntimeLibcallsInfo &RTLCI; @@ -73,6 +78,75 @@ class LibcallLoweringInfo { } }; +/// Record a mapping from subtarget to LibcallLoweringInfo. +class LibcallLoweringModuleAnalysisResult { +private: + using LibcallLoweringMap = + DenseMap; + mutable LibcallLoweringMap LoweringMap; + const RTLIB::RuntimeLibcallsInfo *RTLCI = nullptr; + +public: + LibcallLoweringModuleAnalysisResult() = default; + LibcallLoweringModuleAnalysisResult(RTLIB::RuntimeLibcallsInfo &RTLCI) + : RTLCI(&RTLCI) {} + + void init(const RTLIB::RuntimeLibcallsInfo *RT) { RTLCI = RT; } + + void clear() { + RTLCI = nullptr; + LoweringMap.clear(); + } + + operator bool() const { return RTLCI != nullptr; } + + LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &, + ModuleAnalysisManager::Invalidator &); + + const LibcallLoweringInfo & + getLibcallLowering(const TargetSubtargetInfo &Subtarget) const { + return LoweringMap.try_emplace(&Subtarget, *RTLCI, Subtarget).first->second; + } +}; + +class LibcallLoweringModuleAnalysis + : public AnalysisInfoMixin { +private: + friend AnalysisInfoMixin; + static AnalysisKey Key; + + LibcallLoweringModuleAnalysisResult LibcallLoweringMap; + +public: + using Result = LibcallLoweringModuleAnalysisResult; + + LLVM_ABI Result run(Module &M, ModuleAnalysisManager &); +}; + +class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass { + LibcallLoweringModuleAnalysisResult Result; + RuntimeLibraryInfoWrapper *RuntimeLibcallsWrapper = nullptr; + +public: + static char ID; + LibcallLoweringInfoWrapper(); + + const LibcallLoweringInfo & + getLibcallLowering(const Module &M, const TargetSubtargetInfo &Subtarget) { + return getResult(M).getLibcallLowering(Subtarget); + } + + const LibcallLoweringModuleAnalysisResult &getResult(const Module &M) { + if (!Result) + Result.init(&RuntimeLibcallsWrapper->getRTLCI(M)); + return Result; + } + + void initializePass() override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + void releaseMemory() override; +}; + } // end namespace llvm #endif // LLVM_CODEGEN_LIBCALLLOWERINGINFO_H 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/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 10a4d8525a9e8..c718e29b99ff4 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -133,6 +133,7 @@ LLVM_ABI void initializeGlobalMergeFuncPassWrapperPass(PassRegistry &); LLVM_ABI void initializeGlobalMergePass(PassRegistry &); LLVM_ABI void initializeGlobalsAAWrapperPassPass(PassRegistry &); LLVM_ABI void initializeHardwareLoopsLegacyPass(PassRegistry &); +LLVM_ABI void initializeLibcallLoweringInfoWrapperPass(PassRegistry &); LLVM_ABI void initializeMIRProfileLoaderPassPass(PassRegistry &); LLVM_ABI void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry &); LLVM_ABI void initializeIRTranslatorPass(PassRegistry &); diff --git a/llvm/lib/Analysis/RuntimeLibcallInfo.cpp b/llvm/lib/Analysis/RuntimeLibcallInfo.cpp index 9ea789a4ee45a..1c5a1cc75b7bd 100644 --- a/llvm/lib/Analysis/RuntimeLibcallInfo.cpp +++ b/llvm/lib/Analysis/RuntimeLibcallInfo.cpp @@ -13,6 +13,15 @@ using namespace llvm; AnalysisKey RuntimeLibraryAnalysis::Key; +RuntimeLibraryAnalysis::RuntimeLibraryAnalysis(const Triple &TT, + ExceptionHandling ExceptionModel, + FloatABI::ABIType FloatABI, + EABI EABIVersion, + StringRef ABIName, + VectorLibrary VecLib) + : LibcallsInfo(std::in_place, TT, ExceptionModel, FloatABI, EABIVersion, + ABIName, VecLib) {} + RTLIB::RuntimeLibcallsInfo RuntimeLibraryAnalysis::run(const Module &M, ModuleAnalysisManager &) { if (!LibcallsInfo) @@ -26,6 +35,13 @@ INITIALIZE_PASS(RuntimeLibraryInfoWrapper, "runtime-library-info", RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper() : ImmutablePass(ID), RTLA(RTLIB::RuntimeLibcallsInfo(Triple())) {} +RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper( + const Triple &TT, ExceptionHandling ExceptionModel, + FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, + VectorLibrary VecLib) + : ImmutablePass(ID), RTLCI(std::in_place, TT, ExceptionModel, FloatABI, + EABIVersion, ABIName, VecLib) {} + char RuntimeLibraryInfoWrapper::ID = 0; ModulePass *llvm::createRuntimeLibraryInfoWrapperPass() { diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index 9795a0b707fd3..fe293c63fa762 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -57,6 +57,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeInterleavedLoadCombinePass(Registry); initializeInterleavedAccessPass(Registry); initializeJMCInstrumenterPass(Registry); + initializeLibcallLoweringInfoWrapperPass(Registry); initializeLiveDebugValuesLegacyPass(Registry); initializeLiveDebugVariablesWrapperLegacyPass(Registry); initializeLiveIntervalsWrapperPassPass(Registry); diff --git a/llvm/lib/CodeGen/ExpandFp.cpp b/llvm/lib/CodeGen/ExpandFp.cpp index f44eb227133ae..7d333be7ed6fc 100644 --- a/llvm/lib/CodeGen/ExpandFp.cpp +++ b/llvm/lib/CodeGen/ExpandFp.cpp @@ -975,11 +975,12 @@ static RTLIB::Libcall fremToLibcall(Type *Ty) { /* Return true if, according to \p LibInfo, the target either directly supports the frem instruction for the \p Ty, has a custom lowering, or uses a libcall. */ -static bool targetSupportsFrem(const TargetLowering &TLI, Type *Ty) { +static bool targetSupportsFrem(const TargetLowering &TLI, + const LibcallLoweringInfo &Libcalls, Type *Ty) { if (!TLI.isOperationExpand(ISD::FREM, EVT::getEVT(Ty))) return true; - return TLI.getLibcallName(fremToLibcall(Ty->getScalarType())); + return Libcalls.getLibcallName(fremToLibcall(Ty->getScalarType())); } static void addToWorklist(Instruction &I, @@ -991,7 +992,7 @@ static void addToWorklist(Instruction &I, } static bool runImpl(Function &F, const TargetLowering &TLI, - AssumptionCache *AC) { + const LibcallLoweringInfo &Libcalls, AssumptionCache *AC) { SmallVector Worklist; unsigned MaxLegalFpConvertBitWidth = @@ -1010,7 +1011,7 @@ static bool runImpl(Function &F, const TargetLowering &TLI, switch (I.getOpcode()) { case Instruction::FRem: - return !targetSupportsFrem(TLI, Ty) && + return !targetSupportsFrem(TLI, Libcalls, Ty) && FRemExpander::canExpandType(Ty->getScalarType()); case Instruction::FPToUI: @@ -1090,20 +1091,27 @@ class ExpandFpLegacyPass : public FunctionPass { bool runOnFunction(Function &F) override { auto *TM = &getAnalysis().getTM(); - auto *TLI = TM->getSubtargetImpl(F)->getTargetLowering(); + const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(F); + auto *TLI = Subtarget->getTargetLowering(); AssumptionCache *AC = nullptr; + const LibcallLoweringInfo &Libcalls = + getAnalysis().getLibcallLowering( + *F.getParent(), *Subtarget); + if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone()) AC = &getAnalysis().getAssumptionCache(F); - return runImpl(F, *TLI, AC); + return runImpl(F, *TLI, Libcalls, AC); } void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); AU.addRequired(); if (OptLevel != CodeGenOptLevel::None) AU.addRequired(); AU.addPreserved(); AU.addPreserved(); + AU.addRequired(); } }; } // namespace @@ -1126,13 +1134,29 @@ PreservedAnalyses ExpandFpPass::run(Function &F, FunctionAnalysisManager &FAM) { AssumptionCache *AC = nullptr; if (OptLevel != CodeGenOptLevel::None) AC = &FAM.getResult(F); - return runImpl(F, TLI, AC) ? PreservedAnalyses::none() - : PreservedAnalyses::all(); + + auto &MAMProxy = FAM.getResult(F); + + const LibcallLoweringModuleAnalysisResult *LibcallLowering = + MAMProxy.getCachedResult(*F.getParent()); + + if (!LibcallLowering) { + F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() + + "' analysis required"); + return PreservedAnalyses::all(); + } + + const LibcallLoweringInfo &Libcalls = + LibcallLowering->getLibcallLowering(*STI); + + return runImpl(F, TLI, Libcalls, AC) ? PreservedAnalyses::none() + : PreservedAnalyses::all(); } char ExpandFpLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN(ExpandFpLegacyPass, "expand-fp", "Expand certain fp instructions", false, false) +INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper) INITIALIZE_PASS_END(ExpandFpLegacyPass, "expand-fp", "Expand fp", false, false) FunctionPass *llvm::createExpandFpPass(CodeGenOptLevel OptLevel) { 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(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); @@ -172,12 +174,11 @@ class LegalizerWorkListManager : public GISelChangeObserver { }; } // namespace -Legalizer::MFResult -Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, - ArrayRef AuxObservers, - LostDebugLocObserver &LocObserver, - MachineIRBuilder &MIRBuilder, - GISelValueTracking *VT) { +Legalizer::MFResult Legalizer::legalizeMachineFunction( + MachineFunction &MF, const LegalizerInfo &LI, + ArrayRef 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 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().getLibcallLowering( + *MF.getFunction().getParent(), Subtarget); + // This allows Known Bits Analysis in the legalizer. GISelValueTracking *VT = &getAnalysis().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 Args, - const CallingConv::ID CC, LostDebugLocObserver &LocObserver, - MachineInstr *MI) { +LegalizerHelper::LegalizeResult LegalizerHelper::createLibcall( + const char *Name, const CallLowering::ArgInfo &Result, + ArrayRef 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 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 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 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 LibcallResult = createLibcall( - MIRBuilder, getRTLibDesc(MI.getOpcode(), Size), {DstFrac, OpType, 0}, + getRTLibDesc(MI.getOpcode(), Size), {DstFrac, OpType, 0}, {{Src, OpType, 0}, {StackPtrInt, PointerType::get(Ctx, AddrSpace), 1}}, LocObserver, &MI); @@ -745,8 +750,8 @@ LegalizerHelper::emitModfLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, } LegalizerHelper::LegalizeResult -llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, - MachineInstr &MI, LostDebugLocObserver &LocObserver) { +LegalizerHelper::createMemLibcall(MachineRegisterInfo &MRI, MachineInstr &MI, + LostDebugLocObserver &LocObserver) const { auto &Ctx = MIRBuilder.getMF().getFunction().getContext(); SmallVector Args; @@ -984,10 +989,9 @@ static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType, llvm_unreachable("Unsupported libcall function"); } -static LegalizerHelper::LegalizeResult -conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType, - Type *FromType, LostDebugLocObserver &LocObserver, - const TargetLowering &TLI, bool IsSigned = false) { +LegalizerHelper::LegalizeResult LegalizerHelper::conversionLibcall( + MachineInstr &MI, Type *ToType, Type *FromType, + LostDebugLocObserver &LocObserver, bool IsSigned) const { CallLowering::ArgInfo Arg = {MI.getOperand(1).getReg(), FromType, 0}; if (FromType->isIntegerTy()) { if (TLI.shouldSignExtendTypeInLibCall(FromType, IsSigned)) @@ -997,9 +1001,8 @@ conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType, } RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType); - return createLibcall(MIRBuilder, Libcall, - {MI.getOperand(0).getReg(), ToType, 0}, Arg, LocObserver, - &MI); + return createLibcall(Libcall, {MI.getOperand(0).getReg(), ToType, 0}, Arg, + LocObserver, &MI); } static RTLIB::Libcall @@ -1041,8 +1044,7 @@ getStateLibraryFunctionFor(MachineInstr &MI, const TargetLowering &TLI) { // %0:_(s32) = G_LOAD % 1 // LegalizerHelper::LegalizeResult -LegalizerHelper::createGetStateLibcall(MachineIRBuilder &MIRBuilder, - MachineInstr &MI, +LegalizerHelper::createGetStateLibcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { const DataLayout &DL = MIRBuilder.getDataLayout(); auto &MF = MIRBuilder.getMF(); @@ -1061,11 +1063,10 @@ LegalizerHelper::createGetStateLibcall(MachineIRBuilder &MIRBuilder, unsigned TempAddrSpace = DL.getAllocaAddrSpace(); Type *StatePtrTy = PointerType::get(Ctx, TempAddrSpace); RTLIB::Libcall RTLibcall = getStateLibraryFunctionFor(MI, TLI); - auto Res = - createLibcall(MIRBuilder, RTLibcall, - CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0), - CallLowering::ArgInfo({Temp.getReg(0), StatePtrTy, 0}), - LocObserver, nullptr); + auto Res = createLibcall( + RTLibcall, CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0), + CallLowering::ArgInfo({Temp.getReg(0), StatePtrTy, 0}), LocObserver, + nullptr); if (Res != LegalizerHelper::Legalized) return Res; @@ -1081,8 +1082,7 @@ LegalizerHelper::createGetStateLibcall(MachineIRBuilder &MIRBuilder, // using transient space in stack. In this case the library function reads // content of memory region. LegalizerHelper::LegalizeResult -LegalizerHelper::createSetStateLibcall(MachineIRBuilder &MIRBuilder, - MachineInstr &MI, +LegalizerHelper::createSetStateLibcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { const DataLayout &DL = MIRBuilder.getDataLayout(); auto &MF = MIRBuilder.getMF(); @@ -1106,7 +1106,7 @@ LegalizerHelper::createSetStateLibcall(MachineIRBuilder &MIRBuilder, unsigned TempAddrSpace = DL.getAllocaAddrSpace(); Type *StatePtrTy = PointerType::get(Ctx, TempAddrSpace); RTLIB::Libcall RTLibcall = getStateLibraryFunctionFor(MI, TLI); - return createLibcall(MIRBuilder, RTLibcall, + return createLibcall(RTLibcall, CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0), CallLowering::ArgInfo({Temp.getReg(0), StatePtrTy, 0}), LocObserver, nullptr); @@ -1152,8 +1152,7 @@ getFCMPLibcallDesc(const CmpInst::Predicate Pred, unsigned Size) { } LegalizerHelper::LegalizeResult -LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder, - MachineInstr &MI, +LegalizerHelper::createFCMPLibcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { auto &MF = MIRBuilder.getMF(); auto &Ctx = MF.getFunction().getContext(); @@ -1183,7 +1182,7 @@ LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder, Register Temp = MRI.createGenericVirtualRegister(TempLLT); // Generate libcall, holding result in Temp const auto Status = createLibcall( - MIRBuilder, Libcall, {Temp, Type::getInt32Ty(Ctx), 0}, + Libcall, {Temp, Type::getInt32Ty(Ctx), 0}, {{Cmp->getLHSReg(), OpType, 0}, {Cmp->getRHSReg(), OpType, 1}}, LocObserver, &MI); if (!Status) @@ -1282,8 +1281,7 @@ LegalizerHelper::createFCMPLibcall(MachineIRBuilder &MIRBuilder, // `((const femode_t *) -1)`. Such assumption is used here. If for some target // it is not true, the target must provide custom lowering. LegalizerHelper::LegalizeResult -LegalizerHelper::createResetStateLibcall(MachineIRBuilder &MIRBuilder, - MachineInstr &MI, +LegalizerHelper::createResetStateLibcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { const DataLayout &DL = MIRBuilder.getDataLayout(); auto &MF = MIRBuilder.getMF(); @@ -1299,10 +1297,9 @@ LegalizerHelper::createResetStateLibcall(MachineIRBuilder &MIRBuilder, MIRBuilder.buildIntToPtr(Dest, DefValue); RTLIB::Libcall RTLibcall = getStateLibraryFunctionFor(MI, TLI); - return createLibcall(MIRBuilder, RTLibcall, - CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0), - CallLowering::ArgInfo({Dest.getReg(), StatePtrTy, 0}), - LocObserver, &MI); + return createLibcall( + RTLibcall, CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0), + CallLowering::ArgInfo({Dest.getReg(), StatePtrTy, 0}), LocObserver, &MI); } LegalizerHelper::LegalizeResult @@ -1408,7 +1405,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { } auto Libcall = getRTLibDesc(MI.getOpcode(), Size); LegalizeResult Status = - createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ITy, 0}, + createLibcall(Libcall, {MI.getOperand(0).getReg(), ITy, 0}, {{MI.getOperand(1).getReg(), HLTy, 0}}, LocObserver, &MI); if (Status != Legalized) return Status; @@ -1431,9 +1428,8 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { {MI.getOperand(1).getReg(), HLTy, 0}, {MI.getOperand(2).getReg(), ITy, 1}}; Args[1].Flags[0].setSExt(); - LegalizeResult Status = - createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), HLTy, 0}, - Args, LocObserver, &MI); + LegalizeResult Status = createLibcall( + Libcall, {MI.getOperand(0).getReg(), HLTy, 0}, Args, LocObserver, &MI); if (Status != Legalized) return Status; break; @@ -1444,14 +1440,13 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { Type *ToTy = getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(0).getReg())); if (!FromTy || !ToTy) return UnableToLegalize; - LegalizeResult Status = - conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver, TLI); + LegalizeResult Status = conversionLibcall(MI, ToTy, FromTy, LocObserver); if (Status != Legalized) return Status; break; } case TargetOpcode::G_FCMP: { - LegalizeResult Status = createFCMPLibcall(MIRBuilder, MI, LocObserver); + LegalizeResult Status = createFCMPLibcall(MI, LocObserver); if (Status != Legalized) return Status; MI.eraseFromParent(); @@ -1465,8 +1460,8 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); if ((ToSize != 32 && ToSize != 64 && ToSize != 128) || !FromTy) return UnableToLegalize; - LegalizeResult Status = conversionLibcall( - MI, MIRBuilder, Type::getIntNTy(Ctx, ToSize), FromTy, LocObserver, TLI); + LegalizeResult Status = conversionLibcall(MI, Type::getIntNTy(Ctx, ToSize), + FromTy, LocObserver); if (Status != Legalized) return Status; break; @@ -1479,9 +1474,8 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { if ((FromSize != 32 && FromSize != 64 && FromSize != 128) || !ToTy) return UnableToLegalize; bool IsSigned = MI.getOpcode() == TargetOpcode::G_SITOFP; - LegalizeResult Status = - conversionLibcall(MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize), - LocObserver, TLI, IsSigned); + LegalizeResult Status = conversionLibcall( + MI, ToTy, Type::getIntNTy(Ctx, FromSize), LocObserver, IsSigned); if (Status != Legalized) return Status; break; @@ -1504,7 +1498,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { case TargetOpcode::G_MEMMOVE: case TargetOpcode::G_MEMSET: { LegalizeResult Result = - createMemLibcall(MIRBuilder, *MIRBuilder.getMRI(), MI, LocObserver); + createMemLibcall(*MIRBuilder.getMRI(), MI, LocObserver); if (Result != Legalized) return Result; MI.eraseFromParent(); @@ -1512,22 +1506,21 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { } case TargetOpcode::G_GET_FPENV: case TargetOpcode::G_GET_FPMODE: { - LegalizeResult Result = createGetStateLibcall(MIRBuilder, MI, LocObserver); + LegalizeResult Result = createGetStateLibcall(MI, LocObserver); if (Result != Legalized) return Result; break; } case TargetOpcode::G_SET_FPENV: case TargetOpcode::G_SET_FPMODE: { - LegalizeResult Result = createSetStateLibcall(MIRBuilder, MI, LocObserver); + LegalizeResult Result = createSetStateLibcall(MI, LocObserver); if (Result != Legalized) return Result; break; } case TargetOpcode::G_RESET_FPENV: case TargetOpcode::G_RESET_FPMODE: { - LegalizeResult Result = - createResetStateLibcall(MIRBuilder, MI, LocObserver); + LegalizeResult Result = createResetStateLibcall(MI, LocObserver); if (Result != Legalized) return Result; break; diff --git a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp index 6f3607e8db824..388d2b009a9ef 100644 --- a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp +++ b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp @@ -7,7 +7,10 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LibcallLoweringInfo.h" +#include "llvm/Analysis/RuntimeLibcallInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/InitializePasses.h" +#include "llvm/Target/TargetMachine.h" using namespace llvm; @@ -28,3 +31,45 @@ LibcallLoweringInfo::LibcallLoweringInfo( Subtarget.initLibcallLoweringInfo(*this); } + +AnalysisKey LibcallLoweringModuleAnalysis::Key; + +bool LibcallLoweringModuleAnalysisResult::invalidate( + Module &, const PreservedAnalyses &PA, + ModuleAnalysisManager::Invalidator &) { + // Passes that change the runtime libcall set must explicitly invalidate this + // pass. + auto PAC = PA.getChecker(); + return !PAC.preservedWhenStateless(); +} + +LibcallLoweringModuleAnalysisResult +LibcallLoweringModuleAnalysis::run(Module &M, ModuleAnalysisManager &MAM) { + LibcallLoweringMap.init(&MAM.getResult(M)); + return LibcallLoweringMap; +} + +INITIALIZE_PASS_BEGIN(LibcallLoweringInfoWrapper, "libcall-lowering-info", + "Library Function Lowering Analysis", false, true) +INITIALIZE_PASS_DEPENDENCY(RuntimeLibraryInfoWrapper) +INITIALIZE_PASS_END(LibcallLoweringInfoWrapper, "libcall-lowering-info", + "Library Function Lowering Analysis", false, true) + +char LibcallLoweringInfoWrapper::ID = 0; + +LibcallLoweringInfoWrapper::LibcallLoweringInfoWrapper() : ImmutablePass(ID) {} + +void LibcallLoweringInfoWrapper::initializePass() { + RuntimeLibcallsWrapper = &getAnalysis(); +} + +void LibcallLoweringInfoWrapper::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); +} + +void LibcallLoweringInfoWrapper::releaseMemory() { Result.clear(); } + +ModulePass *llvm::createLibcallLoweringInfoWrapper() { + return new LibcallLoweringInfoWrapper(); +} diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp index d738dc4eea36d..2336bb1f05be3 100644 --- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp +++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp @@ -17,6 +17,7 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/CodeGen/ExpandVectorPredication.h" +#include "llvm/CodeGen/LibcallLoweringInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetPassConfig.h" @@ -51,6 +52,7 @@ namespace { struct PreISelIntrinsicLowering { const TargetMachine *TM; + const LibcallLoweringModuleAnalysisResult &ModuleLibcalls; const function_ref LookupTTI; const function_ref LookupTLI; @@ -61,11 +63,13 @@ struct PreISelIntrinsicLowering { explicit PreISelIntrinsicLowering( const TargetMachine *TM_, + const LibcallLoweringModuleAnalysisResult &ModuleLibcalls_, function_ref LookupTTI_, function_ref LookupTLI_, bool UseMemIntrinsicLibFunc_ = true) - : TM(TM_), LookupTTI(LookupTTI_), LookupTLI(LookupTLI_), - UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) {} + : TM(TM_), ModuleLibcalls(ModuleLibcalls_), LookupTTI(LookupTTI_), + LookupTLI(LookupTLI_), UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) { + } static bool shouldExpandMemIntrinsicWithSize(Value *Size, const TargetTransformInfo &TTI); @@ -230,21 +234,26 @@ bool PreISelIntrinsicLowering::shouldExpandMemIntrinsicWithSize( return SizeVal > Threshold || Threshold == 0; } -static bool canEmitLibcall(const TargetMachine *TM, Function *F, - RTLIB::Libcall LC) { +static bool +canEmitLibcall(const LibcallLoweringModuleAnalysisResult &ModuleLowering, + const TargetMachine *TM, Function *F, RTLIB::Libcall LC) { // TODO: Should this consider the address space of the memcpy? if (!TM) return true; - const TargetLowering *TLI = TM->getSubtargetImpl(*F)->getTargetLowering(); - return TLI->getLibcallName(LC) != nullptr; + const LibcallLoweringInfo &Lowering = + ModuleLowering.getLibcallLowering(*TM->getSubtargetImpl(*F)); + return Lowering.getLibcallImpl(LC) != RTLIB::Unsupported; } -static bool canEmitMemcpy(const TargetMachine *TM, Function *F) { +static bool +canEmitMemcpy(const LibcallLoweringModuleAnalysisResult &ModuleLowering, + const TargetMachine *TM, Function *F) { // TODO: Should this consider the address space of the memcpy? if (!TM) return true; - const TargetLowering *TLI = TM->getSubtargetImpl(*F)->getTargetLowering(); - return TLI->getMemcpyImpl() != RTLIB::Unsupported; + const LibcallLoweringInfo &Lowering = + ModuleLowering.getLibcallLowering(*TM->getSubtargetImpl(*F)); + return Lowering.getMemcpyImpl() != RTLIB::Unsupported; } // Return a value appropriate for use with the memset_pattern16 libcall, if @@ -317,7 +326,8 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses( Function *ParentFunc = Memcpy->getFunction(); const TargetTransformInfo &TTI = LookupTTI(*ParentFunc); if (shouldExpandMemIntrinsicWithSize(Memcpy->getLength(), TTI)) { - if (UseMemIntrinsicLibFunc && canEmitMemcpy(TM, ParentFunc)) + if (UseMemIntrinsicLibFunc && + canEmitMemcpy(ModuleLibcalls, TM, ParentFunc)) break; // TODO: For optsize, emit the loop into a separate function @@ -349,7 +359,7 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses( const TargetTransformInfo &TTI = LookupTTI(*ParentFunc); if (shouldExpandMemIntrinsicWithSize(Memmove->getLength(), TTI)) { if (UseMemIntrinsicLibFunc && - canEmitLibcall(TM, ParentFunc, RTLIB::MEMMOVE)) + canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMMOVE)) break; if (expandMemMoveAsLoop(Memmove, TTI)) { @@ -366,7 +376,7 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses( const TargetTransformInfo &TTI = LookupTTI(*ParentFunc); if (shouldExpandMemIntrinsicWithSize(Memset->getLength(), TTI)) { if (UseMemIntrinsicLibFunc && - canEmitLibcall(TM, ParentFunc, RTLIB::MEMSET)) + canEmitLibcall(ModuleLibcalls, TM, ParentFunc, RTLIB::MEMSET)) break; expandMemSetAsLoop(Memset); @@ -619,10 +629,14 @@ class PreISelIntrinsicLoweringLegacyPass : public ModulePass { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); + AU.addRequired(); AU.addRequired(); } bool runOnModule(Module &M) override { + const LibcallLoweringModuleAnalysisResult &ModuleLibcalls = + getAnalysis().getResult(M); + auto LookupTTI = [this](Function &F) -> TargetTransformInfo & { return this->getAnalysis().getTTI(F); }; @@ -631,7 +645,7 @@ class PreISelIntrinsicLoweringLegacyPass : public ModulePass { }; const auto *TM = &getAnalysis().getTM(); - PreISelIntrinsicLowering Lowering(TM, LookupTTI, LookupTLI); + PreISelIntrinsicLowering Lowering(TM, ModuleLibcalls, LookupTTI, LookupTLI); return Lowering.lowerIntrinsics(M); } }; @@ -643,6 +657,8 @@ char PreISelIntrinsicLoweringLegacyPass::ID; INITIALIZE_PASS_BEGIN(PreISelIntrinsicLoweringLegacyPass, "pre-isel-intrinsic-lowering", "Pre-ISel Intrinsic Lowering", false, false) +INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper) +INITIALIZE_PASS_DEPENDENCY(RuntimeLibraryInfoWrapper) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) @@ -654,9 +670,12 @@ ModulePass *llvm::createPreISelIntrinsicLoweringPass() { return new PreISelIntrinsicLoweringLegacyPass(); } -PreservedAnalyses PreISelIntrinsicLoweringPass::run(Module &M, - ModuleAnalysisManager &AM) { - auto &FAM = AM.getResult(M).getManager(); +PreservedAnalyses +PreISelIntrinsicLoweringPass::run(Module &M, ModuleAnalysisManager &MAM) { + const LibcallLoweringModuleAnalysisResult &LibcallLowering = + MAM.getResult(M); + + auto &FAM = MAM.getResult(M).getManager(); auto LookupTTI = [&FAM](Function &F) -> TargetTransformInfo & { return FAM.getResult(F); @@ -665,7 +684,7 @@ PreservedAnalyses PreISelIntrinsicLoweringPass::run(Module &M, return FAM.getResult(F); }; - PreISelIntrinsicLowering Lowering(TM, LookupTTI, LookupTLI); + PreISelIntrinsicLowering Lowering(TM, LibcallLowering, LookupTTI, LookupTLI); if (!Lowering.lowerIntrinsics(M)) return PreservedAnalyses::all(); else diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index ceae0d29eea90..a791c4038a3b9 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -599,6 +599,8 @@ TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM) // including this pass itself. initializeCodeGen(PR); + initializeLibcallLoweringInfoWrapperPass(PR); + // Also register alias analysis passes required by codegen passes. initializeBasicAAWrapperPassPass(PR); initializeAAResultsWrapperPassPass(PR); diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 93118becedbac..f9cde383ce32d 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -17,6 +17,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/ModuleSummaryAnalysis.h" +#include "llvm/Analysis/RuntimeLibcallInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" @@ -446,6 +447,11 @@ static void codegen(const Config &Conf, TargetMachine *TM, legacy::PassManager CodeGenPasses; TargetLibraryInfoImpl TLII(Mod.getTargetTriple()); CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII)); + CodeGenPasses.add(new RuntimeLibraryInfoWrapper( + Mod.getTargetTriple(), TM->Options.ExceptionModel, + TM->Options.FloatABIType, TM->Options.EABIVersion, + TM->Options.MCOptions.ABIName, TM->Options.VecLib)); + // No need to make index available if the module is empty. // In theory these passes should not use the index for an empty // module, however, this guards against doing any unnecessary summary-based diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 074c328ef0931..e9874ecd553ee 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -30,6 +30,7 @@ MODULE_ANALYSIS("ir2vec-vocab", IR2VecVocabAnalysis()) MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis()) MODULE_ANALYSIS("last-run-tracking", LastRunTrackingAnalysis()) MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis()) +MODULE_ANALYSIS("libcall-lowering-info", LibcallLoweringModuleAnalysis()) MODULE_ANALYSIS("module-summary", ModuleSummaryIndexAnalysis()) MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis()) MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC)) diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp index cdff649ecfa57..ad3e4f116321b 100644 --- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -365,10 +365,10 @@ bool ARMLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, StructType *RetTy = StructType::get(Ctx, {ArgTy, ArgTy}, /* Packed */ true); Register RetRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult}; - auto Status = createLibcall(MIRBuilder, Libcall, {RetRegs, RetTy, 0}, - {{MI.getOperand(1).getReg(), ArgTy, 0}, - {MI.getOperand(2).getReg(), ArgTy, 0}}, - LocObserver, &MI); + auto Status = Helper.createLibcall(Libcall, {RetRegs, RetTy, 0}, + {{MI.getOperand(1).getReg(), ArgTy, 0}, + {MI.getOperand(2).getReg(), ArgTy, 0}}, + LocObserver, &MI); if (Status != LegalizerHelper::Legalized) return false; break; @@ -401,11 +401,11 @@ bool ARMLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, SmallVector Results; for (auto Libcall : Libcalls) { auto LibcallResult = MRI.createGenericVirtualRegister(LLT::scalar(32)); - auto Status = createLibcall(MIRBuilder, Libcall.LibcallID, - {LibcallResult, RetTy, 0}, - {{MI.getOperand(2).getReg(), ArgTy, 0}, - {MI.getOperand(3).getReg(), ArgTy, 0}}, - LocObserver, &MI); + auto Status = + Helper.createLibcall(Libcall.LibcallID, {LibcallResult, RetTy, 0}, + {{MI.getOperand(2).getReg(), ArgTy, 0}, + {MI.getOperand(3).getReg(), ArgTy, 0}}, + LocObserver, &MI); if (Status != LegalizerHelper::Legalized) return false; diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll index abc67eec32391..96f5e5a4afb3e 100644 --- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll @@ -5,9 +5,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: Assumption Cache Tracker diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll index e1481667a4ab7..2102029e608ab 100644 --- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll @@ -5,9 +5,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: Type-Based Alias Analysis diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll index 1f7888a633d62..8364e680bc8c7 100644 --- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll +++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll @@ -14,9 +14,11 @@ ; REQUIRES: asserts ; GCN-O0:Target Library Information +; GCN-O0-NEXT:Runtime Library Function Analysis ; GCN-O0-NEXT:Target Pass Configuration ; GCN-O0-NEXT:Machine Module Information ; GCN-O0-NEXT:Target Transform Information +; GCN-O0-NEXT:Library Function Lowering Analysis ; GCN-O0-NEXT:Assumption Cache Tracker ; GCN-O0-NEXT:Profile summary info ; GCN-O0-NEXT:Argument Register Usage Information Storage @@ -161,9 +163,11 @@ ; GCN-O0-NEXT: Free MachineFunction ; GCN-O1:Target Library Information +; GCN-O1-NEXT:Runtime Library Function Analysis ; GCN-O1-NEXT:Target Pass Configuration ; GCN-O1-NEXT:Machine Module Information ; GCN-O1-NEXT:Target Transform Information +; GCN-O1-NEXT:Library Function Lowering Analysis ; GCN-O1-NEXT:Assumption Cache Tracker ; GCN-O1-NEXT:Profile summary info ; GCN-O1-NEXT:AMDGPU Address space based Alias Analysis @@ -453,9 +457,11 @@ ; GCN-O1-NEXT: Free MachineFunction ; GCN-O1-OPTS:Target Library Information +; GCN-O1-OPTS-NEXT:Runtime Library Function Analysis ; GCN-O1-OPTS-NEXT:Target Pass Configuration ; GCN-O1-OPTS-NEXT:Machine Module Information ; GCN-O1-OPTS-NEXT:Target Transform Information +; GCN-O1-OPTS-NEXT:Library Function Lowering Analysis ; GCN-O1-OPTS-NEXT:Assumption Cache Tracker ; GCN-O1-OPTS-NEXT:Profile summary info ; GCN-O1-OPTS-NEXT:AMDGPU Address space based Alias Analysis @@ -773,9 +779,11 @@ ; GCN-O1-OPTS-NEXT: Free MachineFunction ; GCN-O2:Target Library Information +; GCN-O2-NEXT:Runtime Library Function Analysis ; GCN-O2-NEXT:Target Pass Configuration ; GCN-O2-NEXT:Machine Module Information ; GCN-O2-NEXT:Target Transform Information +; GCN-O2-NEXT:Library Function Lowering Analysis ; GCN-O2-NEXT:Assumption Cache Tracker ; GCN-O2-NEXT:Profile summary info ; GCN-O2-NEXT:AMDGPU Address space based Alias Analysis @@ -1098,9 +1106,11 @@ ; GCN-O2-NEXT: Free MachineFunction ; GCN-O3:Target Library Information +; GCN-O3-NEXT:Runtime Library Function Analysis ; GCN-O3-NEXT:Target Pass Configuration ; GCN-O3-NEXT:Machine Module Information ; GCN-O3-NEXT:Target Transform Information +; GCN-O3-NEXT:Library Function Lowering Analysis ; GCN-O3-NEXT:Assumption Cache Tracker ; GCN-O3-NEXT:Profile summary info ; GCN-O3-NEXT:AMDGPU Address space based Alias Analysis diff --git a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll index 9006b5c8d6fe1..5f4fccdd72b12 100644 --- a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll +++ b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll @@ -9,9 +9,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info diff --git a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll index 661f67d4989c4..546ed6cec5c4a 100644 --- a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll +++ b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll @@ -17,9 +17,11 @@ ; LAXX-LABEL: Pass Arguments: ; LAXX-NEXT: Target Library Information +; LAXX-NEXT: Runtime Library Function Analysis ; LAXX-NEXT: Target Pass Configuration ; LAXX-NEXT: Machine Module Information ; LAXX-NEXT: Target Transform Information +; LAXX-NEXT: Library Function Lowering Analysis ; LAXX-NEXT: Assumption Cache Tracker ; LAXX-NEXT: Type-Based Alias Analysis ; LAXX-NEXT: Scoped NoAlias Alias Analysis diff --git a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll index 38b1074e55d22..ac04be436f6a1 100644 --- a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll +++ b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll @@ -6,9 +6,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info diff --git a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll index 7cbb1a1c98873..fd8fd5fa34a17 100644 --- a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll +++ b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll @@ -5,9 +5,11 @@ ; REQUIRES: asserts ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Type-Based Alias Analysis ; CHECK-NEXT: Scoped NoAlias Alias Analysis diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll index 8714b286374a5..42d30fcef2a9b 100644 --- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll @@ -9,9 +9,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll index 3e2de780524b6..85027a56a1348 100644 --- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll @@ -9,9 +9,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: Type-Based Alias Analysis diff --git a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll index 6db375445e4a3..3a1d0f7b5d218 100644 --- a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll +++ b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll @@ -11,9 +11,11 @@ ; REQUIRES:asserts ; SPIRV-O0:Target Library Information +; SPIRV-O0-NEXT:Runtime Library Function Analysis ; SPIRV-O0-NEXT:Target Pass Configuration ; SPIRV-O0-NEXT:Machine Module Information ; SPIRV-O0-NEXT:Target Transform Information +; SPIRV-O0-NEXT:Library Function Lowering Analysis ; SPIRV-O0-NEXT:Create Garbage Collector Module Metadata ; SPIRV-O0-NEXT:Assumption Cache Tracker ; SPIRV-O0-NEXT:Profile summary info @@ -83,9 +85,11 @@ ; SPIRV-O0-NEXT: Free MachineFunction ; SPIRV-Opt:Target Library Information +; SPIRV-Opt-NEXT:Runtime Library Function Analysis ; SPIRV-Opt-NEXT:Target Pass Configuration ; SPIRV-Opt-NEXT:Machine Module Information ; SPIRV-Opt-NEXT:Target Transform Information +; SPIRV-Opt-NEXT:Library Function Lowering Analysis ; SPIRV-Opt-NEXT:Assumption Cache Tracker ; SPIRV-Opt-NEXT:Type-Based Alias Analysis ; SPIRV-Opt-NEXT:Scoped NoAlias Alias Analysis diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll index 78a02b11b17bb..9223348abbcb9 100644 --- a/llvm/test/CodeGen/X86/O0-pipeline.ll +++ b/llvm/test/CodeGen/X86/O0-pipeline.ll @@ -7,9 +7,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Create Garbage Collector Module Metadata ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info diff --git a/llvm/test/CodeGen/X86/opt-pipeline.ll b/llvm/test/CodeGen/X86/opt-pipeline.ll index 276232e27c000..9f08658e067ab 100644 --- a/llvm/test/CodeGen/X86/opt-pipeline.ll +++ b/llvm/test/CodeGen/X86/opt-pipeline.ll @@ -13,9 +13,11 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Runtime Library Function Analysis ; CHECK-NEXT: Target Pass Configuration ; CHECK-NEXT: Machine Module Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Library Function Lowering Analysis ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Type-Based Alias Analysis ; CHECK-NEXT: Scoped NoAlias Alias Analysis diff --git a/llvm/test/Transforms/ExpandFp/AMDGPU/frem-inf.ll b/llvm/test/Transforms/ExpandFp/AMDGPU/frem-inf.ll index f70f0d25f172d..54ece8d52f08a 100644 --- a/llvm/test/Transforms/ExpandFp/AMDGPU/frem-inf.ll +++ b/llvm/test/Transforms/ExpandFp/AMDGPU/frem-inf.ll @@ -1,5 +1,5 @@ -; RUN: opt -mtriple=amdgcn -passes="expand-fp" %s -S -o - | FileCheck --check-prefixes CHECK %s -; RUN: opt -mtriple=amdgcn -passes="expand-fp" %s -S -o - | FileCheck --check-prefixes CHECK,OPT1 %s +; RUN: opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -o - | FileCheck --check-prefixes CHECK %s +; RUN: opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -o - | FileCheck --check-prefixes CHECK,OPT1 %s ; Check the handling of potentially infinite numerators in the frem ; expansion at different optimization levels and with different diff --git a/llvm/test/Transforms/ExpandFp/AMDGPU/frem.ll b/llvm/test/Transforms/ExpandFp/AMDGPU/frem.ll index 4c0f9db147c96..5cd6f1e8a6086 100644 --- a/llvm/test/Transforms/ExpandFp/AMDGPU/frem.ll +++ b/llvm/test/Transforms/ExpandFp/AMDGPU/frem.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt -mtriple=amdgcn -passes="expand-fp" %s -S -o - | FileCheck %s +; RUN: opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -o - | FileCheck %s define amdgpu_kernel void @frem_f16(ptr addrspace(1) %out, ptr addrspace(1) %in1, ; CHECK-LABEL: define amdgpu_kernel void @frem_f16( diff --git a/llvm/test/Transforms/ExpandFp/AMDGPU/missing-analysis.ll b/llvm/test/Transforms/ExpandFp/AMDGPU/missing-analysis.ll new file mode 100644 index 0000000000000..2d5f2a7223e3a --- /dev/null +++ b/llvm/test/Transforms/ExpandFp/AMDGPU/missing-analysis.ll @@ -0,0 +1,6 @@ +; RUN: not opt -mtriple=amdgcn -passes=expand-fp -disable-output %s 2>&1 | FileCheck %s + +; CHECK: 'LibcallLoweringModuleAnalysis' analysis required +define void @empty() { + ret void +} diff --git a/llvm/test/Transforms/ExpandFp/AMDGPU/pass-parameters.ll b/llvm/test/Transforms/ExpandFp/AMDGPU/pass-parameters.ll index 03cafd4ff1160..794d5805291b0 100644 --- a/llvm/test/Transforms/ExpandFp/AMDGPU/pass-parameters.ll +++ b/llvm/test/Transforms/ExpandFp/AMDGPU/pass-parameters.ll @@ -1,18 +1,18 @@ -; RUN: opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null -; RUN: opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null -; RUN: opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null -; RUN: opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null +; RUN: opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output +; RUN: opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output +; RUN: opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output +; RUN: opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output -; RUN: not opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=TOO-LARGE %s +; RUN: not opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output 2>&1 | FileCheck --check-prefix=TOO-LARGE %s ; TOO-LARGE: {{.*}}invalid optimization level for expand-fp pass: 4 -; RUN: not opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=NON-NUMERIC %s +; RUN: not opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output 2>&1 | FileCheck --check-prefix=NON-NUMERIC %s ; NON-NUMERIC: {{.*}}invalid expand-fp pass parameter -; RUN: not opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=NEGATIVE %s +; RUN: not opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output 2>&1 | FileCheck --check-prefix=NEGATIVE %s ; NEGATIVE: {{.*}}invalid expand-fp pass parameter 'O-1' -; RUN: not opt -mtriple=amdgcn -passes="expand-fp" %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=NO-O-PREFIX %s +; RUN: not opt -mtriple=amdgcn -passes="require,expand-fp" %s -S -disable-output 2>&1 | FileCheck --check-prefix=NO-O-PREFIX %s ; NO-O-PREFIX: {{.*}}invalid expand-fp pass parameter 'foo' define void @empty() { diff --git a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptosi129.ll b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptosi129.ll index f5bf8bb61a16e..0cf8829aec037 100644 --- a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptosi129.ll +++ b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptosi129.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -mtriple=x86_64-- --expand-fp < %s | FileCheck %s -; RUN: opt -S -mtriple=x86_64-- -passes=expand-fp < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -passes='require,expand-fp' < %s | FileCheck %s define i129 @halftosi129(half %a) { ; CHECK-LABEL: @halftosi129( diff --git a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptoui129.ll b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptoui129.ll index 94ed32abe46f8..055e3e0dc261d 100644 --- a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptoui129.ll +++ b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptoui129.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -mtriple=x86_64-- --expand-fp < %s | FileCheck %s -; RUN: opt -S -mtriple=x86_64-- -passes=expand-fp < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -passes='require,expand-fp' < %s | FileCheck %s define i129 @halftoui129(half %a) { ; CHECK-LABEL: @halftoui129( diff --git a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-si129tofp.ll b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-si129tofp.ll index 8820b873f3818..af053e82a62a4 100644 --- a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-si129tofp.ll +++ b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-si129tofp.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -mtriple=x86_64-- --expand-fp < %s | FileCheck %s -; RUN: opt -S -mtriple=x86_64-- -passes=expand-fp < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -passes='require,expand-fp' < %s | FileCheck %s define half @si129tohalf(i129 %a) { ; CHECK-LABEL: @si129tohalf( diff --git a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-ui129tofp.ll b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-ui129tofp.ll index b58d88bc02c79..ede9b2a4cd049 100644 --- a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-ui129tofp.ll +++ b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-ui129tofp.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -mtriple=x86_64-- --expand-fp < %s | FileCheck %s -; RUN: opt -S -mtriple=x86_64-- -passes=expand-fp < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -passes='require,expand-fp' < %s | FileCheck %s define half @ui129tohalf(i129 %a) { ; CHECK-LABEL: @ui129tohalf( diff --git a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-optnone.ll b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-optnone.ll index 78bc0006fda23..e78eaeb70fbf1 100644 --- a/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-optnone.ll +++ b/llvm/test/Transforms/ExpandLargeFpConvert/X86/expand-large-fp-optnone.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S -mtriple=x86_64-- --expand-fp < %s | FileCheck %s -; RUN: opt -S -mtriple=x86_64-- -passes=expand-fp < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -passes='require,expand-fp' < %s | FileCheck %s ; expand-fp must also run with optnone diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp index 7ba17e5b82095..6d4989e278fc1 100644 --- a/llvm/tools/llc/NewPMDriver.cpp +++ b/llvm/tools/llc/NewPMDriver.cpp @@ -14,8 +14,10 @@ #include "NewPMDriver.h" #include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/RuntimeLibcallInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/CodeGen/LibcallLoweringInfo.h" #include "llvm/CodeGen/MIRParser/MIRParser.h" #include "llvm/CodeGen/MIRPrinter.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" @@ -136,6 +138,16 @@ int llvm::compileModuleWithNewPM( SI.registerCallbacks(PIC, &MAM); FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); }); + + MAM.registerPass([&] { + const TargetOptions &Options = Target->Options; + return RuntimeLibraryAnalysis( + M->getTargetTriple(), Target->Options.ExceptionModel, + Target->Options.FloatABIType, Target->Options.EABIVersion, + Options.MCOptions.ABIName, Target->Options.VecLib); + }); + MAM.registerPass([&] { return LibcallLoweringModuleAnalysis(); }); + MAM.registerPass([&] { return MachineModuleAnalysis(MMI); }); ModulePassManager MPM; diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index ad31a0ec63387..613780ecbfb40 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/RuntimeLibcallInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/CodeGen/CommandFlags.h" #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" @@ -727,6 +728,10 @@ static int compileModule(char **argv, LLVMContext &Context, // Build up all of the passes that we want to do to the module. legacy::PassManager PM; PM.add(new TargetLibraryInfoWrapperPass(TLII)); + PM.add(new RuntimeLibraryInfoWrapper( + M->getTargetTriple(), Target->Options.ExceptionModel, + Target->Options.FloatABIType, Target->Options.EABIVersion, + Options.MCOptions.ABIName, Target->Options.VecLib)); { raw_pwrite_stream *OS = &Out->os(); diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp index 01d7ac8e3f959..3209b652b44b4 100644 --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -21,6 +21,7 @@ #include "llvm/Analysis/RuntimeLibcallInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/CodeGen/LibcallLoweringInfo.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/LLVMContext.h" @@ -352,9 +353,9 @@ static void registerEPCallbacks(PassBuilder &PB) { bool llvm::runPassPipeline( StringRef Arg0, Module &M, TargetMachine *TM, TargetLibraryInfoImpl *TLII, - RTLIB::RuntimeLibcallsInfo &RTLCI, ToolOutputFile *Out, - ToolOutputFile *ThinLTOLinkOut, ToolOutputFile *OptRemarkFile, - StringRef PassPipeline, ArrayRef PassPlugins, + ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut, + ToolOutputFile *OptRemarkFile, StringRef PassPipeline, + ArrayRef PassPlugins, ArrayRef> PassBuilderCallbacks, OutputKind OK, VerifierKind VK, bool ShouldPreserveAssemblyUseListOrder, bool ShouldPreserveBitcodeUseListOrder, bool EmitSummaryIndex, @@ -410,14 +411,24 @@ bool llvm::runPassPipeline( P->CSAction = PGOOptions::CSIRUse; } } - if (TM) - TM->setPGOOption(P); LoopAnalysisManager LAM; FunctionAnalysisManager FAM; CGSCCAnalysisManager CGAM; ModuleAnalysisManager MAM; - MAM.registerPass([&] { return RuntimeLibraryAnalysis(std::move(RTLCI)); }); + + if (TM) { + TM->setPGOOption(P); + + MAM.registerPass([&] { + const TargetOptions &Options = TM->Options; + return RuntimeLibraryAnalysis(M.getTargetTriple(), Options.ExceptionModel, + Options.FloatABIType, Options.EABIVersion, + Options.MCOptions.ABIName, Options.VecLib); + }); + + MAM.registerPass([&] { return LibcallLoweringModuleAnalysis(); }); + } PassInstrumentationCallbacks PIC; PrintPassOptions PrintPassOpts; diff --git a/llvm/tools/opt/NewPMDriver.h b/llvm/tools/opt/NewPMDriver.h index 31da61b9c0cae..042d5d4bbfe47 100644 --- a/llvm/tools/opt/NewPMDriver.h +++ b/llvm/tools/opt/NewPMDriver.h @@ -31,10 +31,6 @@ class TargetMachine; class ToolOutputFile; class TargetLibraryInfoImpl; -namespace RTLIB { -struct RuntimeLibcallsInfo; -} - extern cl::opt DebugifyEach; extern cl::opt DebugifyExport; @@ -71,9 +67,9 @@ void printPasses(raw_ostream &OS); /// nullptr. bool runPassPipeline( StringRef Arg0, Module &M, TargetMachine *TM, TargetLibraryInfoImpl *TLII, - RTLIB::RuntimeLibcallsInfo &RTLCI, ToolOutputFile *Out, - ToolOutputFile *ThinLinkOut, ToolOutputFile *OptRemarkFile, - StringRef PassPipeline, ArrayRef PassPlugins, + ToolOutputFile *Out, ToolOutputFile *ThinLinkOut, + ToolOutputFile *OptRemarkFile, StringRef PassPipeline, + ArrayRef PassPlugins, ArrayRef> PassBuilderCallbacks, opt_tool::OutputKind OK, opt_tool::VerifierKind VK, bool ShouldPreserveAssemblyUseListOrder, diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp index f8be9f16aada6..ac318e6bc1eb4 100644 --- a/llvm/tools/opt/optdriver.cpp +++ b/llvm/tools/opt/optdriver.cpp @@ -657,6 +657,13 @@ optMain(int argc, char **argv, return 1; } + TargetOptions CodeGenFlagsOptions; + const TargetOptions *Options = TM ? &TM->Options : &CodeGenFlagsOptions; + if (!TM) { + CodeGenFlagsOptions = + codegen::InitTargetOptionsFromCodeGenFlags(ModuleTriple); + } + // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M); @@ -674,13 +681,8 @@ optMain(int argc, char **argv, M->addModuleFlag(Module::Error, "UnifiedLTO", 1); } - VectorLibrary VecLib = codegen::getVectorLibrary(); // Add an appropriate TargetLibraryInfo pass for the module's triple. - TargetLibraryInfoImpl TLII(ModuleTriple, VecLib); - - RTLIB::RuntimeLibcallsInfo RTLCI(ModuleTriple, codegen::getExceptionModel(), - codegen::getFloatABIForCalls(), - codegen::getEABIVersion(), ABIName, VecLib); + TargetLibraryInfoImpl TLII(ModuleTriple, Options->VecLib); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) @@ -756,7 +758,7 @@ optMain(int argc, char **argv, // string. Hand off the rest of the functionality to the new code for that // layer. if (!runPassPipeline( - argv[0], *M, TM.get(), &TLII, RTLCI, Out.get(), ThinLinkOut.get(), + argv[0], *M, TM.get(), &TLII, Out.get(), ThinLinkOut.get(), RemarksFile.get(), Pipeline, PluginList, PassBuilderCallbacks, OK, VK, /* ShouldPreserveAssemblyUseListOrder */ false, /* ShouldPreserveBitcodeUseListOrder */ true, EmitSummaryIndex, @@ -804,6 +806,9 @@ optMain(int argc, char **argv, (VerifyDebugInfoPreserve && !VerifyEachDebugInfoPreserve); Passes.add(new TargetLibraryInfoWrapperPass(TLII)); + Passes.add(new RuntimeLibraryInfoWrapper( + ModuleTriple, Options->ExceptionModel, Options->FloatABIType, + Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib)); // Add internal analysis passes from the target machine. Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis() diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h index 4b82f572150e5..dbea3f608a881 100644 --- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h +++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h @@ -124,6 +124,8 @@ class GISelMITest : public ::testing::Test { B.setMF(*MF); MRI = &MF->getRegInfo(); B.setInsertPt(*EntryMBB, EntryMBB->end()); + RTLCI.emplace(TM->getTargetTriple()); + LibcallLowering.emplace(*RTLCI, MF->getSubtarget()); } LLVMContext Context; @@ -135,6 +137,8 @@ class GISelMITest : public ::testing::Test { MachineBasicBlock *EntryMBB; MachineIRBuilder B; MachineRegisterInfo *MRI; + std::optional RTLCI; + std::optional LibcallLowering; }; class AArch64GISelMITest : public GISelMITest { diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp index 22181ce33f0da..f80082fdd46d0 100644 --- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp @@ -2050,7 +2050,7 @@ TEST_F(AArch64GISelMITest, LibcallFPExt) { B.buildInstr(TargetOpcode::G_FPEXT, {S128}, {Copies[1]}); AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBFPExt1, DummyLocObserver)); @@ -2094,7 +2094,7 @@ TEST_F(AArch64GISelMITest, LibcallFPTrunc) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBFPTrunc1, DummyLocObserver)); @@ -2162,7 +2162,7 @@ TEST_F(AArch64GISelMITest, LibcallMul) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBMul32, DummyLocObserver)); @@ -2220,7 +2220,7 @@ TEST_F(AArch64GISelMITest, LibcallSRem) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBSRem32, DummyLocObserver)); @@ -2278,7 +2278,7 @@ TEST_F(AArch64GISelMITest, LibcallURem) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBURem32, DummyLocObserver)); @@ -2337,7 +2337,7 @@ TEST_F(AArch64GISelMITest, LibcallCtlzZeroUndef) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBCtlz32, DummyLocObserver)); @@ -2389,7 +2389,7 @@ TEST_F(AArch64GISelMITest, LibcallFAdd) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBAdd32, DummyLocObserver)); @@ -2442,7 +2442,7 @@ TEST_F(AArch64GISelMITest, LibcallFSub) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBSub32, DummyLocObserver)); @@ -2494,7 +2494,7 @@ TEST_F(AArch64GISelMITest, LibcallFMul) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -2548,7 +2548,7 @@ TEST_F(AArch64GISelMITest, LibcallFDiv) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBDiv32, DummyLocObserver)); @@ -2599,7 +2599,7 @@ TEST_F(AArch64GISelMITest, LibcallFExp) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBExp32, DummyLocObserver)); @@ -2647,7 +2647,7 @@ TEST_F(AArch64GISelMITest, LibcallFExp2) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBExp232, DummyLocObserver)); @@ -2695,7 +2695,7 @@ TEST_F(AArch64GISelMITest, LibcallFRem) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBFRem32, DummyLocObserver)); @@ -2743,7 +2743,7 @@ TEST_F(AArch64GISelMITest, LibcallFPow) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBPow32, DummyLocObserver)); @@ -2792,7 +2792,7 @@ TEST_F(AArch64GISelMITest, LibcallFMa) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; LostDebugLocObserver DummyLocObserver(""); - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.libcall(*MIBMa32, DummyLocObserver)); @@ -2839,7 +2839,7 @@ TEST_F(AArch64GISelMITest, LibcallFCeil) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -2887,7 +2887,7 @@ TEST_F(AArch64GISelMITest, LibcallFFloor) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -2935,7 +2935,7 @@ TEST_F(AArch64GISelMITest, LibcallFMinNum) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -2986,7 +2986,7 @@ TEST_F(AArch64GISelMITest, LibcallFMaxNum) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -3037,7 +3037,7 @@ TEST_F(AArch64GISelMITest, LibcallFSqrt) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -3085,7 +3085,7 @@ TEST_F(AArch64GISelMITest, LibcallFRint) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -3136,7 +3136,7 @@ TEST_F(AArch64GISelMITest, LibcallFNearbyInt) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); LostDebugLocObserver DummyLocObserver(""); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -3181,7 +3181,7 @@ TEST_F(AArch64GISelMITest, NarrowScalarExtract) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.narrowScalar(*MIBExtractS32, 1, S32)); @@ -3229,7 +3229,7 @@ TEST_F(AArch64GISelMITest, LowerInsert) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.lower(*InsertS64S32, 0, LLT{})); @@ -3307,7 +3307,7 @@ TEST_F(AArch64GISelMITest, LowerFFloor) { auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs); AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); // Perform Legalization EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.lower(*Floor, 0, LLT())); @@ -3340,7 +3340,7 @@ TEST_F(AArch64GISelMITest, LowerBSWAP) { auto BSwap = B.buildBSwap(LLT::fixed_vector(2, 32), Cast); AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); // Perform Legalization EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.lower(*BSwap, 0, LLT())); @@ -3417,7 +3417,7 @@ TEST_F(AArch64GISelMITest, LowerUDIVREM) { B.buildInstr(TargetOpcode::G_UDIVREM, {S64, S64}, {Copies[0], Copies[1]}); AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); // Perform Legalization EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.lower(*UDivrem, 0, S64)); @@ -3451,7 +3451,7 @@ TEST_F(AArch64GISelMITest, LowerSelect) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); // Perform Legalization EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, Helper.lower(*SELECT, 0, S32)); @@ -3492,7 +3492,7 @@ TEST_F(AArch64GISelMITest, WidenUnmerge) { AInfo Info(MF->getSubtarget()); DummyGISelObserver Observer; - LegalizerHelper Helper(*MF, Info, Observer, B); + LegalizerHelper Helper(*MF, Info, Observer, B, &*LibcallLowering); // Perform Legalization EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, @@ -3701,10 +3701,11 @@ TEST_F(AArch64GISelMITest, CreateLibcall) { LLVMContext &Ctx = MF->getFunction().getContext(); auto *RetTy = Type::getVoidTy(Ctx); + LegalizerHelper Helper(*MF, Info, Observer, B); EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, - createLibcall(B, "abort", {{}, RetTy, 0}, {}, CallingConv::C, - DummyLocObserver, nullptr)); + Helper.createLibcall("abort", {{}, RetTy, 0}, {}, CallingConv::C, + DummyLocObserver, nullptr)); auto CheckStr = R"( CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp index c5992ebb831ed..1c90267ed28aa 100644 --- a/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp @@ -69,7 +69,7 @@ TEST_F(AArch64GISelMITest, BasicLegalizerTest) { GISelValueTracking VT(*MF); Legalizer::MFResult Result = Legalizer::legalizeMachineFunction( - *MF, LI, {&LocObserver}, LocObserver, B, &VT); + *MF, LI, {&LocObserver}, LocObserver, B, /*Libcalls=*/nullptr, &VT); EXPECT_TRUE(isNullMIPtr(Result.FailedOn)); EXPECT_TRUE(Result.Changed); @@ -161,7 +161,7 @@ TEST_F(AArch64GISelMITest, UnorderedArtifactCombiningTest) { // the process follows def-use chains, making them shorter at each step, thus // combining everything that can be combined in O(n) time. Legalizer::MFResult Result = Legalizer::legalizeMachineFunction( - *MF, LI, {&LocObserver}, LocObserver, B, &VT); + *MF, LI, {&LocObserver}, LocObserver, B, /*Libcalls=*/nullptr, &VT); EXPECT_TRUE(isNullMIPtr(Result.FailedOn)); EXPECT_TRUE(Result.Changed); @@ -201,7 +201,7 @@ TEST_F(AArch64GISelMITest, UnorderedArtifactCombiningManyCopiesTest) { GISelValueTracking VT(*MF); Legalizer::MFResult Result = Legalizer::legalizeMachineFunction( - *MF, LI, {&LocObserver}, LocObserver, B, &VT); + *MF, LI, {&LocObserver}, LocObserver, B, /*Libcalls=*/nullptr, &VT); EXPECT_TRUE(isNullMIPtr(Result.FailedOn)); EXPECT_TRUE(Result.Changed);