42#include <system_error>
49 assert(_target &&
"target machine is null");
50 SymTab.addModule(
Mod.get());
70 BufferOrErr.
get()->getMemBufferRef());
80 return Result->IsThinLTO;
107 return *ProducerOrErr;
115 if (std::error_code EC = BufferOrErr.
getError()) {
119 std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.
get());
120 return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
132 size_t map_size, off_t offset,
137 if (std::error_code EC = BufferOrErr.
getError()) {
141 std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.
get());
142 return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
152 return makeLTOModule(Buffer, options, Context,
false);
157 const void *mem,
size_t length,
164 makeLTOModule(Buffer, options, *Context,
true);
166 (*Ret)->OwnedContext = std::move(Context);
199 if (std::error_code EC = MOrErr.
getError())
201 std::unique_ptr<Module> &
M = *MOrErr;
203 std::string TripleStr =
M->getTargetTriple();
204 if (TripleStr.empty())
217 std::string FeatureStr = Features.
getString();
233 options, std::nullopt);
235 std::unique_ptr<LTOModule>
Ret(
new LTOModule(std::move(M), Buffer, target));
237 Ret->parseMetadata();
239 return std::move(Ret);
243std::unique_ptr<MemoryBuffer>
245 const char *startPtr = (
const char*)mem;
251LTOModule::objcClassNameFromExpression(
const Constant *c, std::string &
name) {
252 if (
const ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) {
255 Constant *cn = gvn->getInitializer();
257 if (ca->isCString()) {
258 name = (
".objc_class_name_" + ca->getAsCString()).str();
273 std::string superclassName;
274 if (objcClassNameFromExpression(c->
getOperand(1), superclassName)) {
276 _undefines.
insert(std::make_pair(superclassName, NameAndAttributes()));
277 if (IterBool.second) {
278 NameAndAttributes &
info = IterBool.first->second;
279 info.name = IterBool.first->first();
281 info.isFunction =
false;
287 std::string className;
288 if (objcClassNameFromExpression(c->
getOperand(2), className)) {
289 auto Iter = _defines.
insert(className).first;
291 NameAndAttributes
info;
292 info.name = Iter->first();
295 info.isFunction =
false;
297 _symbols.push_back(
info);
307 std::string targetclassName;
308 if (!objcClassNameFromExpression(c->
getOperand(1), targetclassName))
312 _undefines.
insert(std::make_pair(targetclassName, NameAndAttributes()));
314 if (!IterBool.second)
317 NameAndAttributes &
info = IterBool.first->second;
318 info.name = IterBool.first->first();
320 info.isFunction =
false;
326 std::string targetclassName;
327 if (!objcClassNameFromExpression(clgv->
getInitializer(), targetclassName))
331 _undefines.
insert(std::make_pair(targetclassName, NameAndAttributes()));
333 if (!IterBool.second)
336 NameAndAttributes &
info = IterBool.first->second;
337 info.name = IterBool.first->first();
339 info.isFunction =
false;
352 addDefinedDataSymbol(Buffer, V);
357 addDefinedSymbol(
Name, v,
false);
359 if (!
v->hasSection() )
385 if (
Section.starts_with(
"__OBJC,__class,")) {
390 else if (
Section.starts_with(
"__OBJC,__category,")) {
395 else if (
Section.starts_with(
"__OBJC,__cls_refs,")) {
409 auto *GV = cast<GlobalValue *>(
Sym);
410 assert((isa<Function>(GV) ||
411 (isa<GlobalAlias>(GV) &&
412 isa<Function>(cast<GlobalAlias>(GV)->getAliasee()))) &&
413 "Not function or function alias");
415 addDefinedFunctionSymbol(Buffer, GV);
420 addDefinedSymbol(
Name,
F,
true);
463 if (isa<GlobalAlias>(def))
469 NameAndAttributes
info;
473 info.attributes = attr;
478 _symbols.push_back(
info);
488 if (!IterBool.second)
491 NameAndAttributes &
info = _undefines[IterBool.first->first()];
493 if (
info.symbol ==
nullptr) {
503 info.name = IterBool.first->first();
506 info.isFunction =
false;
507 info.symbol =
nullptr;
510 _symbols.push_back(
info);
515 addDefinedFunctionSymbol(
info.name, cast<Function>(
info.symbol));
517 addDefinedDataSymbol(
info.name,
info.symbol);
519 _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK;
520 _symbols.back().attributes |= scope;
526 auto IterBool = _undefines.
insert(std::make_pair(
name, NameAndAttributes()));
528 _asm_undefines.push_back(IterBool.first->first());
531 if (!IterBool.second)
536 NameAndAttributes &
info = IterBool.first->second;
537 info.name = IterBool.first->first();
538 info.attributes = attr;
539 info.isFunction =
false;
540 info.symbol =
nullptr;
554 _undefines.
insert(std::make_pair(
name.str(), NameAndAttributes()));
557 if (!IterBool.second)
560 NameAndAttributes &
info = IterBool.first->second;
562 info.name = IterBool.first->first();
564 const GlobalValue *decl = dyn_cast_if_present<GlobalValue *>(
Sym);
571 info.isFunction = isFunc;
575void LTOModule::parseSymbols() {
577 auto *GV = dyn_cast_if_present<GlobalValue *>(
Sym);
594 addAsmGlobalSymbolUndef(
Name);
602 auto *
F = dyn_cast<Function>(GV);
604 addPotentialUndefinedSymbol(
Sym,
F !=
nullptr);
609 addDefinedFunctionSymbol(
Sym);
613 if (isa<GlobalVariable>(GV)) {
614 addDefinedDataSymbol(
Sym);
618 assert(isa<GlobalAlias>(GV));
620 if (isa<Function>(cast<GlobalAlias>(GV)->getAliasee()))
621 addDefinedFunctionSymbol(
Sym);
623 addDefinedDataSymbol(
Sym);
628 e = _undefines.
end(); u != e; ++u) {
631 if (_defines.
count(
u->getKey()))
continue;
632 NameAndAttributes
info =
u->getValue();
633 _symbols.push_back(
info);
638void LTOModule::parseMetadata() {
643 getModule().getNamedMetadata(
"llvm.linker.options")) {
644 for (
unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
646 for (
unsigned ii = 0, ie = MDOptions->
getNumOperands(); ii != ie; ++ii) {
654 const Triple TT(_target->getTargetTriple());
655 if (!
TT.isOSBinFormatCOFF())
658 for (
const NameAndAttributes &
Sym : _symbols) {
666 size_t buffer_size,
const char *path,
667 std::string &outErr) {
675 return ObjOrErr->release();
677 outErr = std::string(path) +
703 if (
auto *GV = dyn_cast_if_present<GlobalValue *>(
Sym)) {
705 if (
Name.consume_front(
"llvm.global_")) {
706 if (
Name ==
"ctors" ||
Name ==
"dtors")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
static ErrorOr< std::unique_ptr< Module > > parseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context, bool ShouldBeLazy)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isFunction(SDValue Op)
An array constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
A constant value that is initialized with an expression using other constant values.
This is an important base class in LLVM.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
bool hasLinkOnceLinkage() const
bool hasLocalLinkage() const
bool hasHiddenVisibility() const
bool hasExternalWeakLinkage() const
bool hasWeakLinkage() const
bool hasCommonLinkage() const
bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
bool hasProtectedVisibility() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
This is an important class for using LLVM in a threaded context.
void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
StringRef getString() const
This interface provides simple read-only access to a block of memory, and provides simple methods for...
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFileSlice(sys::fs::file_t FD, const Twine &Filename, uint64_t MapSize, int64_t Offset, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Given an already-open file descriptor, map some slice of it into a MemoryBuffer.
MemoryBufferRef getMemBufferRef() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
void printSymbolName(raw_ostream &OS, Symbol S) const
uint32_t getSymbolFlags(Symbol S) const
ArrayRef< Symbol > symbols() const
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::pair< typename Base::iterator, bool > insert(StringRef key)
Manages the enabling and disabling of subtarget specific features.
void getDefaultSubtargetFeatures(const Triple &Triple)
Adds the default features for the specified target triple.
std::string getString() const
Returns features as a string.
Primary interface to the complete machine description for the target machine.
Target - Wrapper for Target specific information.
TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOptLevel OL=CodeGenOptLevel::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
Triple - Helper class for working with autoconf configuration names.
bool isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
Value * getOperand(unsigned i) const
static Expected< MemoryBufferRef > findBitcodeInMemBuffer(MemoryBufferRef Object)
Finds and returns bitcode in the given memory buffer (which may be either a bitcode file or a native ...
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
@ LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN
@ LTO_SYMBOL_PERMISSIONS_CODE
@ LTO_SYMBOL_DEFINITION_REGULAR
@ LTO_SYMBOL_SCOPE_DEFAULT
@ LTO_SYMBOL_SCOPE_INTERNAL
@ LTO_SYMBOL_SCOPE_HIDDEN
@ LTO_SYMBOL_DEFINITION_TENTATIVE
@ LTO_SYMBOL_PERMISSIONS_DATA
@ LTO_SYMBOL_SCOPE_PROTECTED
@ LTO_SYMBOL_PERMISSIONS_RODATA
@ LTO_SYMBOL_DEFINITION_WEAKUNDEF
@ LTO_SYMBOL_DEFINITION_UNDEFINED
@ LTO_SYMBOL_DEFINITION_WEAK
Expected< uint32_t > getCPUSubType(const Triple &T)
Expected< uint32_t > getCPUType(const Triple &T)
file_t convertFDToNativeFile(int FD)
Converts from a Posix file descriptor number to a native file handle.
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Expected< std::unique_ptr< Module > > parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, ParserCallbacks Callbacks={})
Read the specified bitcode file, returning the module.
std::error_code make_error_code(BitcodeError E)
Expected< std::string > getBitcodeTargetTriple(MemoryBufferRef Buffer)
Read the header of the specified bitcode buffer and extract just the triple information.
ErrorOr< T > expectedToErrorOrAndEmitErrors(LLVMContext &Ctx, Expected< T > Val)
Expected< std::string > getBitcodeProducerString(MemoryBufferRef Buffer)
Read the header of the specified bitcode buffer and extract just the producer string information.
Expected< std::unique_ptr< Module > > getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context, bool ShouldLazyLoadMetadata=false, bool IsImporting=false, ParserCallbacks Callbacks={})
Read the header of the specified bitcode buffer and prepare for lazy deserialization of function bodi...
Expected< BitcodeLTOInfo > getBitcodeLTOInfo(MemoryBufferRef Buffer)
Returns LTO information for the specified bitcode file.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV, const Triple &TT, Mangler &Mangler)
const char * toString(DWARFSectionKind Kind)
unsigned Log2(Align A)
Returns the log2 of the alignment.
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Implement std::hash so that hash_code can be used in STL containers.
C++ class which implements the opaque lto_module_t type.
static ErrorOr< std::unique_ptr< LTOModule > > createFromFile(LLVMContext &Context, StringRef path, const TargetOptions &options)
Create an LTOModule.
static bool isBitcodeFile(const void *mem, size_t length)
Returns 'true' if the file or memory contents is LLVM bitcode.
Expected< uint32_t > getMachOCPUType() const
static std::unique_ptr< MemoryBuffer > makeBuffer(const void *mem, size_t length, StringRef name="")
Create a MemoryBuffer from a memory range with an optional name.
static size_t getDependentLibraryCount(lto::InputFile *input)
bool hasCtorDtor() const
Returns true if the module has either the @llvm.global_ctors or the @llvm.global_dtors symbol.
static const char * getDependentLibrary(lto::InputFile *input, size_t index, size_t *size)
const Module & getModule() const
static ErrorOr< std::unique_ptr< LTOModule > > createFromOpenFileSlice(LLVMContext &Context, int fd, StringRef path, size_t map_size, off_t offset, const TargetOptions &options)
static std::string getProducerString(MemoryBuffer *Buffer)
Returns a string representing the producer identification stored in the bitcode, or "" if the bitcode...
static bool isBitcodeForTarget(MemoryBuffer *memBuffer, StringRef triplePrefix)
Returns 'true' if the memory buffer is LLVM bitcode for the specified triple.
bool isThinLTO()
Returns 'true' if the Module is produced for ThinLTO.
static ErrorOr< std::unique_ptr< LTOModule > > createFromOpenFile(LLVMContext &Context, int fd, StringRef path, size_t size, const TargetOptions &options)
static ErrorOr< std::unique_ptr< LTOModule > > createInLocalContext(std::unique_ptr< LLVMContext > Context, const void *mem, size_t length, const TargetOptions &options, StringRef path)
static ErrorOr< std::unique_ptr< LTOModule > > createFromBuffer(LLVMContext &Context, const void *mem, size_t length, const TargetOptions &options, StringRef path="")
Expected< uint32_t > getMachOCPUSubType() const
static lto::InputFile * createInputFile(const void *buffer, size_t buffer_size, const char *path, std::string &out_error)
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.