Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions llvm/include/llvm/Analysis/RuntimeLibcallInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===-- RuntimeLibcallInfo.h - Runtime library information ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_RUNTIMELIBCALLINFO_H
#define LLVM_ANALYSIS_RUNTIMELIBCALLINFO_H

#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/Pass.h"

namespace llvm {

class LLVM_ABI RuntimeLibraryAnalysis
: public AnalysisInfoMixin<RuntimeLibraryAnalysis> {
public:
using Result = RTLIB::RuntimeLibcallsInfo;

RuntimeLibraryAnalysis() = default;
RuntimeLibraryAnalysis(RTLIB::RuntimeLibcallsInfo &&BaselineInfoImpl)
: LibcallsInfo(std::move(BaselineInfoImpl)) {}
explicit RuntimeLibraryAnalysis(const Triple &T) : LibcallsInfo(T) {}

LLVM_ABI RTLIB::RuntimeLibcallsInfo run(const Module &M,
ModuleAnalysisManager &);

private:
friend AnalysisInfoMixin<RuntimeLibraryAnalysis>;
LLVM_ABI static AnalysisKey Key;

RTLIB::RuntimeLibcallsInfo LibcallsInfo;
};

class LLVM_ABI RuntimeLibraryInfoWrapper : public ImmutablePass {
RuntimeLibraryAnalysis RTLA;
std::optional<RTLIB::RuntimeLibcallsInfo> RTLCI;

public:
static char ID;
RuntimeLibraryInfoWrapper();
explicit RuntimeLibraryInfoWrapper(const Triple &T);
explicit RuntimeLibraryInfoWrapper(const RTLIB::RuntimeLibcallsInfo &RTLCI);

const RTLIB::RuntimeLibcallsInfo &getRTLCI(const Module &M) {
ModuleAnalysisManager DummyMAM;
RTLCI = RTLA.run(M, DummyMAM);
return *RTLCI;
}

void getAnalysisUsage(AnalysisUsage &AU) const override;
};

LLVM_ABI ModulePass *createRuntimeLibraryInfoWrapperPass();

} // namespace llvm

#endif
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/SelectionDAGISel.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class SelectionDAGISel {
public:
TargetMachine &TM;
const TargetLibraryInfo *LibInfo;
const RTLIB::RuntimeLibcallsInfo *RuntimeLibCallInfo;
std::unique_ptr<FunctionLoweringInfo> FuncInfo;
std::unique_ptr<SwiftErrorValueTracking> SwiftError;
MachineFunction *MF;
Expand Down
10 changes: 10 additions & 0 deletions llvm/include/llvm/IR/RuntimeLibcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
// This file implements a common interface to work with library calls into a
// runtime that may be emitted by a given backend.
//
// FIXME: This should probably move to Analysis
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_RUNTIME_LIBCALLS_H
Expand All @@ -20,6 +22,7 @@
#include "llvm/ADT/StringTable.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Compiler.h"
Expand Down Expand Up @@ -74,6 +77,8 @@ struct RuntimeLibcallsInfo {
public:
friend class llvm::LibcallLoweringInfo;

RuntimeLibcallsInfo() = default;

explicit RuntimeLibcallsInfo(
const Triple &TT,
ExceptionHandling ExceptionModel = ExceptionHandling::None,
Expand All @@ -89,6 +94,11 @@ struct RuntimeLibcallsInfo {
initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion, ABIName);
}

explicit RuntimeLibcallsInfo(const Module &M);

bool invalidate(Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &);

/// Get the libcall routine name for the specified libcall implementation.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl) {
if (CallImpl == RTLIB::Unsupported)
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ LLVM_ABI void initializeRemoveRedundantDebugValuesLegacyPass(PassRegistry &);
LLVM_ABI void initializeRenameIndependentSubregsLegacyPass(PassRegistry &);
LLVM_ABI void initializeReplaceWithVeclibLegacyPass(PassRegistry &);
LLVM_ABI void initializeResetMachineFunctionPass(PassRegistry &);
LLVM_ABI void initializeRuntimeLibraryInfoWrapperPass(PassRegistry &);
LLVM_ABI void initializeSCEVAAWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeSROALegacyPassPass(PassRegistry &);
LLVM_ABI void initializeSafeStackLegacyPassPass(PassRegistry &);
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Passes/CodeGenPassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
Expand Down Expand Up @@ -638,6 +639,8 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
/*Force=*/true);
addIRPass(RequireAnalysisPass<CollectorMetadataAnalysis, Module>(),
/*Force=*/true);
addIRPass(RequireAnalysisPass<RuntimeLibraryAnalysis, Module>(),
/*Force=*/true);
addISelPasses(addIRPass);
}

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Analysis/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeRegionPrinterPass(Registry);
initializeRegionOnlyViewerPass(Registry);
initializeRegionOnlyPrinterPass(Registry);
initializeRuntimeLibraryInfoWrapperPass(Registry);
initializeSCEVAAWrapperPassPass(Registry);
initializeScalarEvolutionWrapperPassPass(Registry);
initializeStackSafetyGlobalInfoWrapperPassPass(Registry);
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ add_llvm_component_library(LLVMAnalysis
RegionPass.cpp
RegionPrinter.cpp
ReplayInlineAdvisor.cpp
RuntimeLibcallInfo.cpp
ScalarEvolution.cpp
ScalarEvolutionAliasAnalysis.cpp
ScalarEvolutionDivision.cpp
Expand Down
43 changes: 43 additions & 0 deletions llvm/lib/Analysis/RuntimeLibcallInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===- RuntimeLibcallInfo.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/InitializePasses.h"

using namespace llvm;

AnalysisKey RuntimeLibraryAnalysis::Key;

RTLIB::RuntimeLibcallsInfo
RuntimeLibraryAnalysis::run(const Module &M, ModuleAnalysisManager &) {
return RTLIB::RuntimeLibcallsInfo(M);
}

INITIALIZE_PASS(RuntimeLibraryInfoWrapper, "runtime-library-info",
"Runtime Library Function Analysis", false, true)

RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper()
: ImmutablePass(ID), RTLA(RTLIB::RuntimeLibcallsInfo(Triple())) {}

char RuntimeLibraryInfoWrapper::ID = 0;

ModulePass *llvm::createRuntimeLibraryInfoWrapperPass() {
return new RuntimeLibraryInfoWrapper();
}

void RuntimeLibraryInfoWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}

// Assume this is stable unless explicitly invalidated.
bool RTLIB::RuntimeLibcallsInfo::invalidate(
Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &) {
auto PAC = PA.getChecker<RuntimeLibraryAnalysis>();
return !PAC.preservedWhenStateless();
}
14 changes: 14 additions & 0 deletions llvm/lib/CodeGen/ExpandFp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/SimplifyQuery.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/ISDOpcodes.h"
Expand Down Expand Up @@ -1092,6 +1093,8 @@ class ExpandFpLegacyPass : public FunctionPass {
auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
auto *TLI = TM->getSubtargetImpl(F)->getTargetLowering();
AssumptionCache *AC = nullptr;
const RTLIB::RuntimeLibcallsInfo *Libcalls =
&getAnalysis<RuntimeLibraryInfoWrapper>().getRTLCI(*F.getParent());

if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone())
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
Expand All @@ -1104,6 +1107,7 @@ class ExpandFpLegacyPass : public FunctionPass {
AU.addRequired<AssumptionCacheTracker>();
AU.addPreserved<AAResultsWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addRequired<RuntimeLibraryInfoWrapper>();
}
};
} // namespace
Expand All @@ -1126,13 +1130,23 @@ PreservedAnalyses ExpandFpPass::run(Function &F, FunctionAnalysisManager &FAM) {
AssumptionCache *AC = nullptr;
if (OptLevel != CodeGenOptLevel::None)
AC = &FAM.getResult<AssumptionAnalysis>(F);

auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
const RTLIB::RuntimeLibcallsInfo *Libcalls =
MAMProxy.getCachedResult<RuntimeLibraryAnalysis>(*F.getParent());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arsenm In the PR description, you wrote:

Not sure I'm doing the new pass manager handling correctly. I do
not like needing to manually check if the cached module pass is
available and manually erroring in every pass.

I am not super familiar with the details of this, but I had a look at the implementation and the documentation. The documentation on ModuleAnalysisManagerFunctionProxy aka OuterAnalysisManagerProxy<ModuleAnalysisManager, Function> in include/llvm/IR/PassManager.h states that:

This proxy only exposes the const interface of the outer analysis manager,
to indicate that you cannot cause an outer analysis to run from within an
inner pass. Instead, you must rely on the getCachedResult API.
This is due to keeping potential future concurrency in mind.

Hence it seems to me that you cannot/should not request the computation of the analysis information from here and you need to do it in this way.

if (!Libcalls) {
F.getContext().emitError("'runtime-libcall-info' analysis required");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this pattern widely used? Should this just be an assert instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot assert Libcalls here. If nothing runs the analysis before this point, the result will be null. That's why the explicit require in the pass pipeline in the tests is necessary.

return PreservedAnalyses::all();
}

return runImpl(F, TLI, AC) ? PreservedAnalyses::none()
: PreservedAnalyses::all();
}

char ExpandFpLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(ExpandFpLegacyPass, "expand-fp",
"Expand certain fp instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(RuntimeLibraryInfoWrapper)
INITIALIZE_PASS_END(ExpandFpLegacyPass, "expand-fp", "Expand fp", false, false)

FunctionPass *llvm::createExpandFpPass(CodeGenOptLevel OptLevel) {
Expand Down
7 changes: 6 additions & 1 deletion llvm/lib/IR/RuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/StringTable.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/xxhash.h"
#include "llvm/TargetParser/ARMTargetParser.h"
Expand All @@ -25,6 +25,11 @@ using namespace RTLIB;
#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME
#include "llvm/IR/RuntimeLibcalls.inc"

RuntimeLibcallsInfo::RuntimeLibcallsInfo(const Module &M)
: RuntimeLibcallsInfo(M.getTargetTriple()) {
// TODO: Consider module flags
}

/// Set default libcall names. If a target wants to opt-out of a libcall it
/// should be placed here.
void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/Analysis/ScalarEvolutionDivision.h"
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis())
MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
MODULE_ANALYSIS("profile-summary", ProfileSummaryAnalysis())
MODULE_ANALYSIS("reg-usage", PhysicalRegisterUsageAnalysis())
MODULE_ANALYSIS("runtime-libcall-info", RuntimeLibraryAnalysis())
MODULE_ANALYSIS("stack-safety", StackSafetyGlobalAnalysis())
MODULE_ANALYSIS("verify", VerifierAnalysis())

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfoImpl *P) {

void llvm::initializeTarget(PassRegistry &Registry) {
initializeTargetLibraryInfoWrapperPassPass(Registry);
initializeRuntimeLibraryInfoWrapperPass(Registry);
initializeTargetTransformInfoWrapperPassPass(Registry);
}

Expand Down
Loading
Loading