42#include <llvm-c/Core.h>
43#include <llvm-c/BitReader.h>
48#include <llvm/ADT/SetVector.h>
49#include <llvm/ADT/StringSet.h>
50#include <llvm/ADT/StringMap.h>
51#include <llvm/Analysis/ModuleSummaryAnalysis.h>
52#include <llvm/Bitcode/BitcodeReader.h>
53#include <llvm/IR/Attributes.h>
54#include <llvm/IR/DebugInfo.h>
55#include <llvm/IR/IntrinsicInst.h>
56#include <llvm/IR/IRBuilder.h>
57#include <llvm/IR/ModuleSummaryIndex.h>
58#include <llvm/Linker/IRMover.h>
59#include <llvm/Support/ManagedStatic.h>
60#include <llvm/Support/MemoryBuffer.h>
75 llvm::SmallVector<llvm::ModuleSummaryIndex *, 2>
searchpath;
106typedef llvm::StringMap<std::unique_ptr<llvm::Module> >
ModuleCache;
108typedef llvm::StringMap<std::unique_ptr<llvm::ModuleSummaryIndex> >
SummaryCache;
118static std::unique_ptr<llvm::ModuleSummaryIndex>
llvm_load_summary(llvm::StringRef path);
123 llvm::StringRef
Name);
139static llvm::SmallVector<llvm::GlobalValueSummary *, 1>
147#define ilog(...) (void) 0
170 llvm::Module *
mod = llvm::unwrap(
M);
182static std::unique_ptr<ImportMapTy>
203 for (
const llvm::Function &
funcDecl :
mod->functions())
241#if LLVM_VERSION_MAJOR >= 21
262 const llvm::FunctionSummary *fs;
267 fs = llvm::cast<llvm::FunctionSummary>(
gvs);
269 if (
gvs->notEligibleToImport())
271 ilog(
DEBUG1,
"ineligibile to import %s due to summary",
278 ilog(
DEBUG1,
"ineligibile to import %s due to early threshold: %u vs %u",
279 symbolName.data(), fs->instCount(),
inlineState.costLimit);
285 if (
defMod->materializeMetadata())
286 elog(
FATAL,
"failed to materialize metadata");
298 elog(
FATAL,
"failed to materialize metadata");
329 ilog(
DEBUG1,
"skipping inlining of %s due to late threshold %d vs %d",
335 ilog(
DEBUG1,
"inline top function %s total_instcount: %d, partial: %d",
419 llvm::Function *
F = llvm::dyn_cast<llvm::Function>(
valueToImport);
426 llvm::stripDebugInfo(*
F);
443 llvm::stripDebugInfo(*
AF);
448 valueToImport->setLinkage(LinkageTypes::AvailableExternallyLinkage);
459 [](llvm::GlobalValue &, llvm::IRMover::ValueAdder) {},
461 elog(
FATAL,
"function import failed with linker error");
481 return it->second.get();
484static std::unique_ptr<llvm::Module>
495 elog(
FATAL,
"failed to open bitcode file \"%s\": %s",
498 elog(
FATAL,
"failed to parse bitcode in file \"%s\"", path);
505 llvm::StripDebugInfo(*llvm::unwrap(
mod));
507 return std::unique_ptr<llvm::Module>(llvm::unwrap(
mod));
520 llvm::SmallPtrSet<const llvm::User *, 32>
Visited;
522 for (llvm::BasicBlock &
BB :
F)
524 for (llvm::Instruction &
I :
BB)
526 if (llvm::isa<llvm::DbgInfoIntrinsic>(
I))
529 llvm::SmallVector<llvm::User *, 8>
Worklist;
541 for (
auto &
OI :
U->operands()) {
542 llvm::User *
Operand = llvm::dyn_cast<llvm::User>(
OI);
545 if (llvm::isa<llvm::BlockAddress>(
Operand))
547 if (
auto *
GV = llvm::dyn_cast<llvm::GlobalVariable>(
Operand)) {
549 if (
GV->hasInitializer())
553 if (
auto *
CF = llvm::dyn_cast<llvm::Function>(
Operand)) {
586 if (
F.isInterposable())
593 if (
F.hasAvailableExternallyLinkage())
596 ilog(
DEBUG1,
"checking inlinability of %s",
F.getName().data());
599 elog(
FATAL,
"failed to materialize metadata");
601 if (
F.getAttributes().hasFnAttr(llvm::Attribute::NoInline))
603 ilog(
DEBUG1,
"ineligibile to import %s due to noinline",
612 if (rv->materialize())
613 elog(
FATAL,
"failed to materialize metadata");
619 if (rv->isThreadLocal())
621 ilog(
DEBUG1,
"cannot inline %s due to thread-local variable %s",
622 F.getName().data(), rv->getName().data());
630 if (rv->hasExternalLinkage() || rv->hasAvailableExternallyLinkage())
641 if (!rv->isConstant())
643 ilog(
DEBUG1,
"cannot inline %s due to uncloneable variable %s",
644 F.getName().data(), rv->getName().data());
648 ilog(
DEBUG1,
"memorizing global var %s linkage %d for inlining",
649 rv->getName().data(), (
int)rv->getLinkage());
667 elog(
FATAL,
"failed to materialize metadata");
703 worklist.push_back({funcName, searchpath});
706 "considering extern function %s at %d for inlining",
709 else if (!
it->second.inlined &&
710 (!
it->second.processed ||
it->second.allowReconsidering) &&
718 if (
it->second.processed)
721 "reconsidering extern function %s at %d for inlining, increasing from %d",
724 it->second.processed =
false;
725 it->second.allowReconsidering =
false;
726 worklist.push_back({funcName, searchpath});
747 "cannot inline %s due to required function %s not being inlinable",
767static std::unique_ptr<llvm::ModuleSummaryIndex>
770 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer> >
MBOrErr =
771 llvm::MemoryBuffer::getFile(path);
773 if (std::error_code
EC =
MBOrErr.getError())
775 ilog(
DEBUG1,
"failed to open %s: %s", path.data(),
776 EC.message().c_str());
780 llvm::MemoryBufferRef
ref(*
MBOrErr.get().get());
782 llvm::Expected<std::unique_ptr<llvm::ModuleSummaryIndex> >
IndexOrErr =
783 llvm::getModuleSummaryIndex(
ref);
786 elog(
FATAL,
"failed to load summary \"%s\": %s",
800#if LLVM_VERSION_MAJOR < 16
801#define starts_with startswith
803 if (!
modpath.starts_with(
"$libdir/"))
811 path = path.replace(0,
strlen(
"$libdir"), std::string(
pkglib_path) +
"/bitcode");
821 searchpath.push_back(
it->second.get());
828static llvm::SmallVector<llvm::GlobalValueSummary *, 1>
831 llvm::SmallVector<llvm::GlobalValueSummary *, 1>
matches;
833 for (
auto index : path)
839 for (
auto &
gv :
funcVI.getSummaryList())
849static llvm::Function*
852 llvm::StringRef
Name)
856 llvm::LLVMContext &
Context =
F->getContext();
859 llvm::BasicBlock *
BB;
862 AF = llvm::Function::Create(
F->getFunctionType(),
863 LinkageTypes::AvailableExternallyLinkage,
865 BB = llvm::BasicBlock::Create(
Context,
"entry",
AF);
869 fwdcall->addFnAttr(llvm::Attribute::AlwaysInline);
#define Assert(condition)
char pkglib_path[MAXPGPATH]
void llvm_split_symbol_name(const char *name, char **modname, char **funcname)
void llvm_inline(LLVMModuleRef M)
llvm::SmallVector< InlineWorkListItem, 128 > InlineWorkList
const int inline_initial_cost
static std::unique_ptr< llvm::ModuleSummaryIndex > llvm_load_summary(llvm::StringRef path)
void llvm_inline_reset_caches(void)
llvm::SmallVector< llvm::ModuleSummaryIndex *, 2 > InlineSearchPath
static llvm::SmallVector< llvm::GlobalValueSummary *, 1 > summaries_for_guid(const InlineSearchPath &path, llvm::GlobalValue::GUID guid)
const float inline_cost_decay_factor
llvm::StringMap< llvm::StringSet<> > ImportMapTy
static std::unique_ptr< llvm::Module > load_module(LLVMContextRef c, llvm::StringRef Identifier)
static void function_references(llvm::Function &F, int &running_instcount, llvm::SmallPtrSet< llvm::GlobalVariable *, 8 > &referencedVars, llvm::SmallPtrSet< llvm::Function *, 8 > &referencedFunctions)
static void add_module_to_inline_search_path(InlineSearchPath &path, llvm::StringRef modpath)
static llvm::Module * load_module_cached(LLVMContextRef c, llvm::StringRef modPath)
llvm::StringMap< FunctionInlineState > FunctionInlineStates
static llvm::Function * create_redirection_function(std::unique_ptr< llvm::Module > &importMod, llvm::Function *F, llvm::StringRef Name)
llvm::StringMap< std::unique_ptr< llvm::ModuleSummaryIndex > > SummaryCache
llvm::StringMap< std::unique_ptr< llvm::Module > > ModuleCache
llvm::ManagedStatic< ModuleCache > module_cache
llvm::ManagedStatic< SummaryCache > summary_cache
static std::unique_ptr< ImportMapTy > llvm_build_inline_plan(LLVMContextRef lc, llvm::Module *mod)
static void llvm_execute_inline_plan(llvm::Module *mod, ImportMapTy *globalsToInline)
static bool function_inlinable(llvm::Function &F, int threshold, FunctionInlineStates &functionState, InlineWorkList &worklist, InlineSearchPath &searchpath, llvm::SmallPtrSet< const llvm::Function *, 8 > &visitedFunctions, int &running_instcount, llvm::StringSet<> &importVars)
static char buf[DEFAULT_XLOG_SEG_SIZE]
llvm::StringRef symbolName
llvm::SmallVector< llvm::ModuleSummaryIndex *, 2 > searchpath