1 /*-------------------------------------------------------------------------
4 * Cross module inlining suitable for postgres' JIT
6 * The inliner iterates over external functions referenced from the passed
7 * module and attempts to inline those. It does so by utilizing pre-built
8 * indexes over both postgres core code and extension modules. When a match
9 * for an external function is found - not guaranteed! - the index will then
10 * be used to judge their instruction count / inline worthiness. After doing
11 * so for all external functions, all the referenced functions (and
12 * prerequisites) will be imported.
14 * Copyright (c) 2016-2025, PostgreSQL Global Development Group
17 * src/backend/lib/llvmjit/llvmjit_inline.cpp
19 *-------------------------------------------------------------------------
27 #include "jit/llvmjit.h"
34 #include <sys/types.h>
37 #include "common/string.h"
38 #include "miscadmin.h"
39 #include "storage/fd.h"
42 #include <llvm-c/Core.h>
43 #include <llvm-c/BitReader.h>
45 /* Avoid macro clash with LLVM's C++ headers */
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>
64 * Type used to represent modules InlineWorkListItem's subject is searched for
67 typedef llvm::SmallVector
<llvm::ModuleSummaryIndex
*, 2> InlineSearchPath
;
70 * Item in queue of to-be-checked symbols and corresponding queue.
72 typedef struct InlineWorkListItem
74 llvm::StringRef symbolName
;
75 llvm::SmallVector
<llvm::ModuleSummaryIndex
*, 2> searchpath
;
77 typedef llvm::SmallVector
<InlineWorkListItem
, 128> InlineWorkList
;
80 * Information about symbols processed during inlining. Used to prevent
81 * repeated searches and provide additional information.
83 typedef struct FunctionInlineState
88 bool allowReconsidering
;
89 } FunctionInlineState
;
90 typedef llvm::StringMap
<FunctionInlineState
> FunctionInlineStates
;
93 * Map of modules that should be inlined, with a list of the to-be inlined
96 typedef llvm::StringMap
<llvm::StringSet
<> > ImportMapTy
;
99 const float inline_cost_decay_factor
= 0.5;
100 const int inline_initial_cost
= 150;
103 * These are managed statics so LLVM knows to deallocate them during an
104 * LLVMShutdown(), rather than after (which'd cause crashes).
106 typedef llvm::StringMap
<std::unique_ptr
<llvm::Module
> > ModuleCache
;
107 llvm::ManagedStatic
<ModuleCache
> module_cache
;
108 typedef llvm::StringMap
<std::unique_ptr
<llvm::ModuleSummaryIndex
> > SummaryCache
;
109 llvm::ManagedStatic
<SummaryCache
> summary_cache
;
112 static std::unique_ptr
<ImportMapTy
> llvm_build_inline_plan(LLVMContextRef lc
, llvm::Module
*mod
);
113 static void llvm_execute_inline_plan(llvm::Module
*mod
,
114 ImportMapTy
*globalsToInline
);
116 static llvm::Module
* load_module_cached(LLVMContextRef c
, llvm::StringRef modPath
);
117 static std::unique_ptr
<llvm::Module
> load_module(LLVMContextRef c
, llvm::StringRef Identifier
);
118 static std::unique_ptr
<llvm::ModuleSummaryIndex
> llvm_load_summary(llvm::StringRef path
);
121 static llvm::Function
* create_redirection_function(std::unique_ptr
<llvm::Module
> &importMod
,
123 llvm::StringRef Name
);
125 static bool function_inlinable(llvm::Function
&F
,
127 FunctionInlineStates
&functionState
,
128 InlineWorkList
&worklist
,
129 InlineSearchPath
&searchpath
,
130 llvm::SmallPtrSet
<const llvm::Function
*, 8> &visitedFunctions
,
131 int &running_instcount
,
132 llvm::StringSet
<> &importVars
);
133 static void function_references(llvm::Function
&F
,
134 int &running_instcount
,
135 llvm::SmallPtrSet
<llvm::GlobalVariable
*, 8> &referencedVars
,
136 llvm::SmallPtrSet
<llvm::Function
*, 8> &referencedFunctions
);
138 static void add_module_to_inline_search_path(InlineSearchPath
& path
, llvm::StringRef modpath
);
139 static llvm::SmallVector
<llvm::GlobalValueSummary
*, 1>
140 summaries_for_guid(const InlineSearchPath
& path
, llvm::GlobalValue::GUID guid
);
142 /* verbose debugging for inliner development */
143 /* #define INLINE_DEBUG */
147 #define ilog(...) (void) 0
151 * Reset inlining related state. This needs to be called before the currently
152 * used LLVMContextRef is disposed (and a new one create), otherwise we would
153 * have dangling references to deleted modules.
156 llvm_inline_reset_caches(void)
158 module_cache
->clear();
159 summary_cache
->clear();
163 * Perform inlining of external function references in M based on a simple
164 * cost based analysis.
167 llvm_inline(LLVMModuleRef M
)
169 LLVMContextRef lc
= LLVMGetModuleContext(M
);
170 llvm::Module
*mod
= llvm::unwrap(M
);
172 std::unique_ptr
<ImportMapTy
> globalsToInline
= llvm_build_inline_plan(lc
, mod
);
173 if (!globalsToInline
)
175 llvm_execute_inline_plan(mod
, globalsToInline
.get());
179 * Build information necessary for inlining external function references in
182 static std::unique_ptr
<ImportMapTy
>
183 llvm_build_inline_plan(LLVMContextRef lc
, llvm::Module
*mod
)
185 std::unique_ptr
<ImportMapTy
> globalsToInline(new ImportMapTy());
186 FunctionInlineStates functionStates
;
187 InlineWorkList worklist
;
189 InlineSearchPath defaultSearchPath
;
191 /* attempt to add module to search path */
192 add_module_to_inline_search_path(defaultSearchPath
, "$libdir/postgres");
193 /* if postgres isn't available, no point continuing */
194 if (defaultSearchPath
.empty())
198 * Start inlining with current references to external functions by putting
199 * them on the inlining worklist. If, during inlining of those, new extern
200 * functions need to be inlined, they'll also be put there, with a lower
203 for (const llvm::Function
&funcDecl
: mod
->functions())
205 InlineWorkListItem item
= {};
206 FunctionInlineState inlineState
= {};
208 /* already has a definition */
209 if (!funcDecl
.isDeclaration())
212 /* llvm provides implementation */
213 if (funcDecl
.isIntrinsic())
216 item
.symbolName
= funcDecl
.getName();
217 item
.searchpath
= defaultSearchPath
;
218 worklist
.push_back(item
);
219 inlineState
.costLimit
= inline_initial_cost
;
220 inlineState
.processed
= false;
221 inlineState
.inlined
= false;
222 inlineState
.allowReconsidering
= false;
223 functionStates
[funcDecl
.getName()] = inlineState
;
227 * Iterate over pending worklist items, look them up in index, check
228 * whether they should be inlined.
230 while (!worklist
.empty())
232 InlineWorkListItem item
= worklist
.pop_back_val();
233 llvm::StringRef symbolName
= item
.symbolName
;
236 FunctionInlineState
&inlineState
= functionStates
[symbolName
];
237 llvm::GlobalValue::GUID funcGUID
;
239 llvm_split_symbol_name(symbolName
.data(), &cmodname
, &cfuncname
);
241 funcGUID
= llvm::GlobalValue::getGUID(cfuncname
);
243 /* already processed */
244 if (inlineState
.processed
)
249 add_module_to_inline_search_path(item
.searchpath
, cmodname
);
252 * Iterate over all known definitions of function, via the index. Then
253 * look up module(s), check if function actually is defined (there
254 * could be hash conflicts).
256 for (const auto &gvs
: summaries_for_guid(item
.searchpath
, funcGUID
))
258 const llvm::FunctionSummary
*fs
;
259 llvm::StringRef modPath
= gvs
->modulePath();
260 llvm::Module
*defMod
;
261 llvm::Function
*funcDef
;
263 fs
= llvm::cast
<llvm::FunctionSummary
>(gvs
);
265 if (gvs
->notEligibleToImport())
267 ilog(DEBUG1
, "ineligibile to import %s due to summary",
272 if ((int) fs
->instCount() > inlineState
.costLimit
)
274 ilog(DEBUG1
, "ineligibile to import %s due to early threshold: %u vs %u",
275 symbolName
.data(), fs
->instCount(), inlineState
.costLimit
);
276 inlineState
.allowReconsidering
= true;
280 defMod
= load_module_cached(lc
, modPath
);
281 if (defMod
->materializeMetadata())
282 elog(FATAL
, "failed to materialize metadata");
284 funcDef
= defMod
->getFunction(cfuncname
);
287 * This can happen e.g. in case of a hash collision of the
293 if (funcDef
->materialize())
294 elog(FATAL
, "failed to materialize metadata");
296 Assert(!funcDef
->isDeclaration());
297 Assert(funcDef
->hasExternalLinkage());
299 llvm::StringSet
<> importVars
;
300 llvm::SmallPtrSet
<const llvm::Function
*, 8> visitedFunctions
;
301 int running_instcount
= 0;
304 * Check whether function, and objects it depends on, are
307 if (function_inlinable(*funcDef
,
308 inlineState
.costLimit
,
317 * Check whether function and all its dependencies are too
318 * big. Dependencies already counted for other functions that
319 * will get inlined are not counted again. While this make
320 * things somewhat order dependent, I can't quite see a point
321 * in a different behaviour.
323 if (running_instcount
> inlineState
.costLimit
)
325 ilog(DEBUG1
, "skipping inlining of %s due to late threshold %d vs %d",
326 symbolName
.data(), running_instcount
, inlineState
.costLimit
);
327 inlineState
.allowReconsidering
= true;
331 ilog(DEBUG1
, "inline top function %s total_instcount: %d, partial: %d",
332 symbolName
.data(), running_instcount
, fs
->instCount());
334 /* import referenced function itself */
335 importVars
.insert(symbolName
);
338 llvm::StringSet
<> &modGlobalsToInline
= (*globalsToInline
)[modPath
];
339 for (auto& importVar
: importVars
)
340 modGlobalsToInline
.insert(importVar
.first());
341 Assert(modGlobalsToInline
.size() > 0);
344 /* mark function as inlined */
345 inlineState
.inlined
= true;
348 * Found definition to inline, don't look for further
349 * potential definitions.
355 ilog(DEBUG1
, "had to skip inlining %s",
358 /* It's possible there's another definition that's inlinable. */
363 * Signal that we're done with symbol, whether successful (inlined =
364 * true above) or not.
366 inlineState
.processed
= true;
369 return globalsToInline
;
373 * Perform the actual inlining of external functions (and their dependencies)
377 llvm_execute_inline_plan(llvm::Module
*mod
, ImportMapTy
*globalsToInline
)
379 llvm::IRMover
Mover(*mod
);
381 for (const auto& toInline
: *globalsToInline
)
383 const llvm::StringRef
& modPath
= toInline
.first();
384 const llvm::StringSet
<>& modGlobalsToInline
= toInline
.second
;
385 llvm::SetVector
<llvm::GlobalValue
*> GlobalsToImport
;
387 Assert(module_cache
->count(modPath
));
388 std::unique_ptr
<llvm::Module
> importMod(std::move((*module_cache
)[modPath
]));
389 module_cache
->erase(modPath
);
391 if (modGlobalsToInline
.empty())
394 for (auto &glob
: modGlobalsToInline
)
396 llvm::StringRef SymbolName
= glob
.first();
400 llvm_split_symbol_name(SymbolName
.data(), &modname
, &funcname
);
402 llvm::GlobalValue
*valueToImport
= importMod
->getNamedValue(funcname
);
405 elog(FATAL
, "didn't refind value %s to import", SymbolName
.data());
408 * For functions (global vars are only inlined if already static),
409 * mark imported variables as being clones from other
410 * functions. That a) avoids symbol conflicts b) allows the
411 * optimizer to perform inlining.
413 if (llvm::isa
<llvm::Function
>(valueToImport
))
415 llvm::Function
*F
= llvm::dyn_cast
<llvm::Function
>(valueToImport
);
416 typedef llvm::GlobalValue::LinkageTypes LinkageTypes
;
419 * Per-function info isn't necessarily stripped yet, as the
420 * module is lazy-loaded when stripped above.
422 llvm::stripDebugInfo(*F
);
425 * If the to-be-imported function is one referenced including
426 * its module name, create a tiny inline function that just
427 * forwards the call. One might think a GlobalAlias would do
428 * the trick, but a) IRMover doesn't override a declaration
429 * with an alias pointing to a definition (instead renaming
430 * it), b) Aliases can't be AvailableExternally.
436 AF
= create_redirection_function(importMod
, F
, SymbolName
);
438 GlobalsToImport
.insert(AF
);
439 llvm::stripDebugInfo(*AF
);
442 if (valueToImport
->hasExternalLinkage())
444 valueToImport
->setLinkage(LinkageTypes::AvailableExternallyLinkage
);
448 GlobalsToImport
.insert(valueToImport
);
449 ilog(DEBUG1
, "performing import of %s %s",
450 modPath
.data(), SymbolName
.data());
454 if (Mover
.move(std::move(importMod
), GlobalsToImport
.getArrayRef(),
455 [](llvm::GlobalValue
&, llvm::IRMover::ValueAdder
) {},
456 /*IsPerformingImport=*/false))
457 elog(FATAL
, "function import failed with linker error");
462 * Return a module identified by modPath, caching it in memory.
464 * Note that such a module may *not* be modified without copying, otherwise
465 * the cache state would get corrupted.
468 load_module_cached(LLVMContextRef lc
, llvm::StringRef modPath
)
470 auto it
= module_cache
->find(modPath
);
471 if (it
== module_cache
->end())
473 it
= module_cache
->insert(
474 std::make_pair(modPath
, load_module(lc
, modPath
))).first
;
477 return it
->second
.get();
480 static std::unique_ptr
<llvm::Module
>
481 load_module(LLVMContextRef lc
, llvm::StringRef Identifier
)
483 LLVMMemoryBufferRef buf
;
485 char path
[MAXPGPATH
];
488 snprintf(path
, MAXPGPATH
,"%s/bitcode/%s", pkglib_path
, Identifier
.data());
490 if (LLVMCreateMemoryBufferWithContentsOfFile(path
, &buf
, &msg
))
491 elog(FATAL
, "failed to open bitcode file \"%s\": %s",
493 if (LLVMGetBitcodeModuleInContext2(lc
, buf
, &mod
))
494 elog(FATAL
, "failed to parse bitcode in file \"%s\"", path
);
497 * Currently there's no use in more detailed debug info for JITed
498 * code. Until that changes, not much point in wasting memory and cycles
499 * on processing debuginfo.
501 llvm::StripDebugInfo(*llvm::unwrap(mod
));
503 return std::unique_ptr
<llvm::Module
>(llvm::unwrap(mod
));
507 * Compute list of referenced variables, functions and the instruction count
511 function_references(llvm::Function
&F
,
512 int &running_instcount
,
513 llvm::SmallPtrSet
<llvm::GlobalVariable
*, 8> &referencedVars
,
514 llvm::SmallPtrSet
<llvm::Function
*, 8> &referencedFunctions
)
516 llvm::SmallPtrSet
<const llvm::User
*, 32> Visited
;
518 for (llvm::BasicBlock
&BB
: F
)
520 for (llvm::Instruction
&I
: BB
)
522 if (llvm::isa
<llvm::DbgInfoIntrinsic
>(I
))
525 llvm::SmallVector
<llvm::User
*, 8> Worklist
;
526 Worklist
.push_back(&I
);
530 while (!Worklist
.empty()) {
531 llvm::User
*U
= Worklist
.pop_back_val();
534 if (!Visited
.insert(U
).second
)
537 for (auto &OI
: U
->operands()) {
538 llvm::User
*Operand
= llvm::dyn_cast
<llvm::User
>(OI
);
541 if (llvm::isa
<llvm::BlockAddress
>(Operand
))
543 if (auto *GV
= llvm::dyn_cast
<llvm::GlobalVariable
>(Operand
)) {
544 referencedVars
.insert(GV
);
545 if (GV
->hasInitializer())
546 Worklist
.push_back(GV
->getInitializer());
549 if (auto *CF
= llvm::dyn_cast
<llvm::Function
>(Operand
)) {
550 referencedFunctions
.insert(CF
);
553 Worklist
.push_back(Operand
);
561 * Check whether function F is inlinable and, if so, what globals need to be
564 * References to external functions from, potentially recursively, inlined
565 * functions are added to the passed in worklist.
568 function_inlinable(llvm::Function
&F
,
570 FunctionInlineStates
&functionStates
,
571 InlineWorkList
&worklist
,
572 InlineSearchPath
&searchpath
,
573 llvm::SmallPtrSet
<const llvm::Function
*, 8> &visitedFunctions
,
574 int &running_instcount
,
575 llvm::StringSet
<> &importVars
)
577 int subThreshold
= threshold
* inline_cost_decay_factor
;
578 llvm::SmallPtrSet
<llvm::GlobalVariable
*, 8> referencedVars
;
579 llvm::SmallPtrSet
<llvm::Function
*, 8> referencedFunctions
;
581 /* can't rely on what may be inlined */
582 if (F
.isInterposable())
586 * Can't rely on function being present. Alternatively we could create a
587 * static version of these functions?
589 if (F
.hasAvailableExternallyLinkage())
592 ilog(DEBUG1
, "checking inlinability of %s", F
.getName().data());
595 elog(FATAL
, "failed to materialize metadata");
597 if (F
.getAttributes().hasFnAttr(llvm::Attribute::NoInline
))
599 ilog(DEBUG1
, "ineligibile to import %s due to noinline",
604 function_references(F
, running_instcount
, referencedVars
, referencedFunctions
);
606 for (llvm::GlobalVariable
* rv
: referencedVars
)
608 if (rv
->materialize())
609 elog(FATAL
, "failed to materialize metadata");
612 * Don't inline functions that access thread local variables. That
613 * doesn't work on current LLVM releases (but might in future).
615 if (rv
->isThreadLocal())
617 ilog(DEBUG1
, "cannot inline %s due to thread-local variable %s",
618 F
.getName().data(), rv
->getName().data());
623 * Never want to inline externally visible vars, cheap enough to
626 if (rv
->hasExternalLinkage() || rv
->hasAvailableExternallyLinkage())
630 * If variable is file-local, we need to inline it, to be able to
631 * inline the function itself. Can't do that if the variable can be
632 * modified, because they'd obviously get out of sync.
634 * XXX: Currently not a problem, but there'd be problems with
635 * nontrivial initializers if they were allowed for postgres.
637 if (!rv
->isConstant())
639 ilog(DEBUG1
, "cannot inline %s due to uncloneable variable %s",
640 F
.getName().data(), rv
->getName().data());
644 ilog(DEBUG1
, "memorizing global var %s linkage %d for inlining",
645 rv
->getName().data(), (int)rv
->getLinkage());
647 importVars
.insert(rv
->getName());
648 /* small cost attributed to each cloned global */
649 running_instcount
+= 5;
652 visitedFunctions
.insert(&F
);
655 * Check referenced functions. Check whether used static ones are
656 * inlinable, and remember external ones for inlining.
658 for (llvm::Function
* referencedFunction
: referencedFunctions
)
660 llvm::StringSet
<> recImportVars
;
662 if (referencedFunction
->materialize())
663 elog(FATAL
, "failed to materialize metadata");
665 if (referencedFunction
->isIntrinsic())
668 /* if already visited skip, otherwise remember */
669 if (!visitedFunctions
.insert(referencedFunction
).second
)
673 * We don't inline external functions directly here, instead we put
674 * them on the worklist if appropriate and check them from
675 * llvm_build_inline_plan().
677 if (referencedFunction
->hasExternalLinkage())
679 llvm::StringRef funcName
= referencedFunction
->getName();
682 * Don't bother checking for inlining if remaining cost budget is
685 if (subThreshold
< 5)
688 auto it
= functionStates
.find(funcName
);
689 if (it
== functionStates
.end())
691 FunctionInlineState inlineState
;
693 inlineState
.costLimit
= subThreshold
;
694 inlineState
.processed
= false;
695 inlineState
.inlined
= false;
696 inlineState
.allowReconsidering
= false;
698 functionStates
[funcName
] = inlineState
;
699 worklist
.push_back({funcName
, searchpath
});
702 "considering extern function %s at %d for inlining",
703 funcName
.data(), subThreshold
);
705 else if (!it
->second
.inlined
&&
706 (!it
->second
.processed
|| it
->second
.allowReconsidering
) &&
707 it
->second
.costLimit
< subThreshold
)
710 * Update inlining threshold if higher. Need to re-queue
711 * to be processed if already processed with lower
714 if (it
->second
.processed
)
717 "reconsidering extern function %s at %d for inlining, increasing from %d",
718 funcName
.data(), subThreshold
, it
->second
.costLimit
);
720 it
->second
.processed
= false;
721 it
->second
.allowReconsidering
= false;
722 worklist
.push_back({funcName
, searchpath
});
724 it
->second
.costLimit
= subThreshold
;
729 /* can't rely on what may be inlined */
730 if (referencedFunction
->isInterposable())
733 if (!function_inlinable(*referencedFunction
,
743 "cannot inline %s due to required function %s not being inlinable",
744 F
.getName().data(), referencedFunction
->getName().data());
748 /* import referenced function itself */
749 importVars
.insert(referencedFunction
->getName());
751 /* import referenced function and its dependents */
752 for (auto& recImportVar
: recImportVars
)
753 importVars
.insert(recImportVar
.first());
760 * Attempt to load module summary located at path. Return empty pointer when
763 static std::unique_ptr
<llvm::ModuleSummaryIndex
>
764 llvm_load_summary(llvm::StringRef path
)
766 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
> > MBOrErr
=
767 llvm::MemoryBuffer::getFile(path
);
769 if (std::error_code EC
= MBOrErr
.getError())
771 ilog(DEBUG1
, "failed to open %s: %s", path
.data(),
772 EC
.message().c_str());
776 llvm::MemoryBufferRef
ref(*MBOrErr
.get().get());
778 llvm::Expected
<std::unique_ptr
<llvm::ModuleSummaryIndex
> > IndexOrErr
=
779 llvm::getModuleSummaryIndex(ref
);
781 return std::move(IndexOrErr
.get());
782 elog(FATAL
, "failed to load summary \"%s\": %s",
784 toString(IndexOrErr
.takeError()).c_str());
790 * Attempt to add modpath to the search path.
793 add_module_to_inline_search_path(InlineSearchPath
& searchpath
, llvm::StringRef modpath
)
795 /* only extension in libdir are candidates for inlining for now */
796 #if LLVM_VERSION_MAJOR < 16
797 #define starts_with startswith
799 if (!modpath
.starts_with("$libdir/"))
802 /* if there's no match, attempt to load */
803 auto it
= summary_cache
->find(modpath
);
804 if (it
== summary_cache
->end())
806 std::string
path(modpath
);
807 path
= path
.replace(0, strlen("$libdir"), std::string(pkglib_path
) + "/bitcode");
809 (*summary_cache
)[modpath
] = llvm_load_summary(path
);
810 it
= summary_cache
->find(modpath
);
813 Assert(it
!= summary_cache
->end());
815 /* if the entry isn't NULL, it's validly loaded */
817 searchpath
.push_back(it
->second
.get());
821 * Search for all references for functions hashing to guid in the search path,
822 * and return them in search path order.
824 static llvm::SmallVector
<llvm::GlobalValueSummary
*, 1>
825 summaries_for_guid(const InlineSearchPath
& path
, llvm::GlobalValue::GUID guid
)
827 llvm::SmallVector
<llvm::GlobalValueSummary
*, 1> matches
;
829 for (auto index
: path
)
831 llvm::ValueInfo funcVI
= index
->getValueInfo(guid
);
833 /* if index doesn't know function, we don't have a body, continue */
835 for (auto &gv
: funcVI
.getSummaryList())
836 matches
.push_back(gv
.get());
843 * Create inline wrapper with the name Name, redirecting the call to F.
845 static llvm::Function
*
846 create_redirection_function(std::unique_ptr
<llvm::Module
> &importMod
,
848 llvm::StringRef Name
)
850 typedef llvm::GlobalValue::LinkageTypes LinkageTypes
;
852 llvm::LLVMContext
&Context
= F
->getContext();
853 llvm::IRBuilder
<> Builder(Context
);
855 llvm::BasicBlock
*BB
;
856 llvm::CallInst
*fwdcall
;
858 AF
= llvm::Function::Create(F
->getFunctionType(),
859 LinkageTypes::AvailableExternallyLinkage
,
860 Name
, importMod
.get());
861 BB
= llvm::BasicBlock::Create(Context
, "entry", AF
);
863 Builder
.SetInsertPoint(BB
);
864 fwdcall
= Builder
.CreateCall(F
, &*AF
->arg_begin());
865 fwdcall
->addFnAttr(llvm::Attribute::AlwaysInline
);
866 Builder
.CreateRet(fwdcall
);