LLVM: lib/LTO/LTOModule.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

38#include <system_error>

39using namespace llvm;

41

42LTOModule::LTOModule(std::unique_ptr M, MemoryBufferRef MBRef,

44 : Mod(std::move(M)), MBRef(MBRef), _target(TM) {

45 assert(_target && "target machine is null");

46 SymTab.addModule(Mod.get());

47}

48

50

51

52

58

62 if (!BufferOrErr)

63 return false;

64

66 BufferOrErr.get()->getMemBufferRef());

68}

69

72 if (!Result) {

74 return false;

75 }

76 return Result->IsThinLTO;

77}

78

84 return false;

88 if (!TripleOrErr)

89 return false;

91}

92

97 return "";

101 if (!ProducerOrErr)

102 return "";

103 return *ProducerOrErr;

104}

105

111 if (std::error_code EC = BufferOrErr.getError()) {

112 Context.emitError(EC.message());

113 return EC;

114 }

115 std::unique_ptr Buffer = std::move(BufferOrErr.get());

116 return makeLTOModule(Buffer->getMemBufferRef(), options, Context,

117 false);

118}

119

125

128 size_t map_size, off_t offset,

132 map_size, offset);

133 if (std::error_code EC = BufferOrErr.getError()) {

134 Context.emitError(EC.message());

135 return EC;

136 }

137 std::unique_ptr Buffer = std::move(BufferOrErr.get());

138 return makeLTOModule(Buffer->getMemBufferRef(), options, Context,

139 false);

140}

141

148 return makeLTOModule(Buffer, options, Context, false);

149}

150

153 const void *mem, size_t length,

157

158

160 makeLTOModule(Buffer, options, *Context, true);

161 if (Ret)

162 (*Ret)->OwnedContext = std::move(Context);

163 return Ret;

164}

165

168 bool ShouldBeLazy) {

169

174 Context.emitError(EC.message());

175 return EC;

176 }

177

178 if (!ShouldBeLazy) {

179

182 }

183

184

186 Context,

188}

189

193 ErrorOr<std::unique_ptr> MOrErr =

195 if (std::error_code EC = MOrErr.getError())

196 return EC;

197 std::unique_ptr &M = *MOrErr;

198

199 llvm::Triple Triple = M->getTargetTriple();

200 if (Triple.empty())

202

203

204 std::string errMsg;

206 if (!march) {

207 Context.emitError(errMsg);

209 }

210

211

212 SubtargetFeatures Features;

214 std::string FeatureStr = Features.getString();

215

216 std::string CPU;

219 CPU = "core2";

221 CPU = "yonah";

223 CPU = "apple-a12";

226 CPU = "cyclone";

227 }

228

229 TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr,

230 options, std::nullopt);

231

232 std::unique_ptr Ret(new LTOModule(std::move(M), Buffer, target));

233 Ret->parseSymbols();

234 Ret->parseMetadata();

235

236 return std::move(Ret);

237}

238

239

240std::unique_ptr

242 const char *startPtr = (const char*)mem;

244}

245

246

247bool

248LTOModule::objcClassNameFromExpression(const Constant *c, std::string &name) {

254 if (ca->isCString()) {

255 name = (".objc_class_name_" + ca->getAsCString()).str();

256 return true;

257 }

258 }

259 }

260 }

261 return false;

262}

263

264

265void LTOModule::addObjCClass(const GlobalVariable *clgv) {

267 if (!c) return;

268

269

270 std::string superclassName;

271 if (objcClassNameFromExpression(c->getOperand(1), superclassName)) {

272 auto IterBool = _undefines.try_emplace(superclassName);

273 if (IterBool.second) {

274 NameAndAttributes &info = IterBool.first->second;

275 info.name = IterBool.first->first();

277 info.isFunction = false;

278 info.symbol = clgv;

279 }

280 }

281

282

283 std::string className;

284 if (objcClassNameFromExpression(c->getOperand(2), className)) {

285 auto Iter = _defines.insert(className).first;

286

287 NameAndAttributes info;

288 info.name = Iter->first();

291 info.isFunction = false;

292 info.symbol = clgv;

293 _symbols.push_back(info);

294 }

295}

296

297

298void LTOModule::addObjCCategory(const GlobalVariable *clgv) {

300 if (!c) return;

301

302

303 std::string targetclassName;

304 if (!objcClassNameFromExpression(c->getOperand(1), targetclassName))

305 return;

306

307 auto IterBool = _undefines.try_emplace(targetclassName);

308

309 if (!IterBool.second)

310 return;

311

312 NameAndAttributes &info = IterBool.first->second;

313 info.name = IterBool.first->first();

315 info.isFunction = false;

316 info.symbol = clgv;

317}

318

319

320void LTOModule::addObjCClassRef(const GlobalVariable *clgv) {

321 std::string targetclassName;

322 if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName))

323 return;

324

325 auto IterBool = _undefines.try_emplace(targetclassName);

326

327 if (!IterBool.second)

328 return;

329

330 NameAndAttributes &info = IterBool.first->second;

331 info.name = IterBool.first->first();

333 info.isFunction = false;

334 info.symbol = clgv;

335}

336

338 SmallString<64> Buffer;

339 {

340 raw_svector_ostream OS(Buffer);

341 SymTab.printSymbolName(OS, Sym);

343 }

344

346 addDefinedDataSymbol(Buffer, V);

347}

348

350

351 addDefinedSymbol(Name, v, false);

352

353 if (v->hasSection() )

354 return;

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

378 StringRef Section = GV->getSection();

379 if (Section.starts_with("__OBJC,__class,")) {

380 addObjCClass(GV);

381 }

382

383

384 else if (Section.starts_with("__OBJC,__category,")) {

385 addObjCCategory(GV);

386 }

387

388

389 else if (Section.starts_with("__OBJC,__cls_refs,")) {

390 addObjCClassRef(GV);

391 }

392 }

393}

394

396 SmallString<64> Buffer;

397 {

398 raw_svector_ostream OS(Buffer);

399 SymTab.printSymbolName(OS, Sym);

401 }

402

407 "Not function or function alias");

408

409 addDefinedFunctionSymbol(Buffer, GV);

410}

411

413

414 addDefinedSymbol(Name, F, true);

415}

416

419 uint32_t attr = 0;

421 attr = Log2(gv->getAlign().valueOrOne());

423 attr = Log2(f->getAlign().valueOrOne());

424

425

428 } else {

432 else

434 }

435

436

441 else

443

444

446

454 else

456

459

462

463 auto Iter = _defines.insert(Name).first;

464

465

466 NameAndAttributes info;

467 StringRef NameRef = Iter->first();

468 info.name = NameRef;

470 info.attributes = attr;

472 info.symbol = def;

473

474

475 _symbols.push_back(info);

476}

477

478

479

480void LTOModule::addAsmGlobalSymbol(StringRef name,

482 auto IterBool = _defines.insert(name);

483

484

485 if (!IterBool.second)

486 return;

487

488 NameAndAttributes &info = _undefines[IterBool.first->first()];

489

490 if (info.symbol == nullptr) {

491

492

493

494

495

496

497

498

499

500 info.name = IterBool.first->first();

501 info.attributes =

503 info.isFunction = false;

504 info.symbol = nullptr;

505

506

507 _symbols.push_back(info);

508 return;

509 }

510

511 if (info.isFunction)

513 else

514 addDefinedDataSymbol(info.name, info.symbol);

515

516 _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK;

517 _symbols.back().attributes |= scope;

518}

519

520

521

522void LTOModule::addAsmGlobalSymbolUndef(StringRef name) {

523 auto IterBool = _undefines.try_emplace(name);

524

525 _asm_undefines.push_back(IterBool.first->first());

526

527

528 if (!IterBool.second)

529 return;

530

533 NameAndAttributes &info = IterBool.first->second;

534 info.name = IterBool.first->first();

535 info.attributes = attr;

536 info.isFunction = false;

537 info.symbol = nullptr;

538}

539

540

542 bool isFunc) {

543 SmallString<64> name;

544 {

545 raw_svector_ostream OS(name);

546 SymTab.printSymbolName(OS, Sym);

547 name.c_str();

548 }

549

550 auto IterBool = _undefines.try_emplace(name.str());

551

552

553 if (!IterBool.second)

554 return;

555

556 NameAndAttributes &info = IterBool.first->second;

557

558 info.name = IterBool.first->first();

559

561

564 else

566

567 info.isFunction = isFunc;

568 info.symbol = decl;

569}

570

571void LTOModule::parseSymbols() {

572 for (auto Sym : SymTab.symbols()) {

574 uint32_t Flags = SymTab.getSymbolFlags(Sym);

576 continue;

577

579

580 if (!GV) {

581 SmallString<64> Buffer;

582 {

583 raw_svector_ostream OS(Buffer);

584 SymTab.printSymbolName(OS, Sym);

586 }

587 StringRef Name = Buffer;

588

589 if (IsUndefined)

590 addAsmGlobalSymbolUndef(Name);

593 else

595 continue;

596 }

597

599 if (IsUndefined) {

600 addPotentialUndefinedSymbol(Sym, F != nullptr);

601 continue;

602 }

603

604 if (F) {

605 addDefinedFunctionSymbol(Sym);

606 continue;

607 }

608

610 addDefinedDataSymbol(Sym);

611 continue;

612 }

613

615

617 addDefinedFunctionSymbol(Sym);

618 else

619 addDefinedDataSymbol(Sym);

620 }

621

622

623 for (const auto &[Key, Value] : _undefines) {

624

625

626 if (!_defines.contains(Key))

627 _symbols.push_back(Value);

628 }

629}

630

631

632void LTOModule::parseMetadata() {

633 raw_string_ostream OS(LinkerOpts);

634

635

636 if (NamedMDNode *LinkerOptions =

637 getModule().getNamedMetadata("llvm.linker.options")) {

638 for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {

639 MDNode *MDOptions = LinkerOptions->getOperand(i);

640 for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {

642 OS << " " << MDOption->getString();

643 }

644 }

645 }

646

647

648 const Triple TT(_target->getTargetTriple());

649 if (TT.isOSBinFormatCOFF())

650 return;

651 Mangler M;

652 for (const NameAndAttributes &Sym : _symbols) {

653 if (!Sym.symbol)

654 continue;

656 }

657}

658

660 size_t buffer_size, const char *path,

661 std::string &outErr) {

662 StringRef Data((const char *)buffer, buffer_size);

664

667

668 if (ObjOrErr)

669 return ObjOrErr->release();

670

671 outErr = std::string(path) +

672 ": Could not read LTO input file: " + toString(ObjOrErr.takeError());

673 return nullptr;

674}

675

679

681 size_t *size) {

684 return S.data();

685}

686

690

694

696 for (auto Sym : SymTab.symbols()) {

699 if (Name.consume_front("llvm.global_")) {

700 if (Name == "ctors" || Name == "dtors")

701 return true;

702 }

703 }

704 }

705 return false;

706}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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)

Definition LTOModule.cpp:167

if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod

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.

bool hasLinkOnceLinkage() const

bool hasLocalLinkage() const

bool hasHiddenVisibility() const

bool hasExternalWeakLinkage() const

bool hasWeakLinkage() const

bool hasCommonLinkage() const

LLVM_ABI 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.

const MDOperand & getOperand(unsigned I) const

unsigned getNumOperands() const

Return number of MDNode operands.

LLVM_ABI 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,...

PointerUnion< GlobalValue *, AsmSymbol * > Symbol

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).

LLVM_ABI void getDefaultSubtargetFeatures(const Triple &Triple)

Adds the default features for the specified target triple.

LLVM_ABI std::string getString() const

Returns features as a string.

Primary interface to the complete machine description for the target machine.

TargetMachine * createTargetMachine(const Triple &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.

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, DriverKit, XROS, or bridgeOS).

bool empty() const

Whether the triple is empty / default constructed.

Value * getOperand(unsigned i) const

static LLVM_ABI Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)

Create an InputFile.

ArrayRef< StringRef > getDependentLibraries() const

Returns dependent library specifiers from the input file.

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 ...

@ 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

LLVM_ABI Expected< uint32_t > getCPUSubType(const Triple &T)

LLVM_ABI Expected< uint32_t > getCPUType(const Triple &T)

A private "module" namespace for types and utilities used by GVN.

LLVM_ABI file_t convertFDToNativeFile(int FD)

Converts from a Posix file descriptor number to a native file handle.

LLVM_ABI 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.

LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})

Log all errors (if any) in E to OS.

FunctionAddr VTableAddr Value

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.

LLVM_ABI 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)

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto dyn_cast_if_present(const Y &Val)

dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...

LLVM_ABI 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)

LLVM_ABI Expected< std::string > getBitcodeProducerString(MemoryBufferRef Buffer)

Read the header of the specified bitcode buffer and extract just the producer string information.

LLVM_ABI 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...

LLVM_ABI Expected< BitcodeLTOInfo > getBitcodeLTOInfo(MemoryBufferRef Buffer)

Returns LTO information for the specified bitcode file.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV, const Triple &TT, Mangler &Mangler)

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

unsigned Log2(Align A)

Returns the log2 of the alignment.

LLVM_ABI 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.

static LLVM_ABI ErrorOr< std::unique_ptr< LTOModule > > createFromFile(LLVMContext &Context, StringRef path, const TargetOptions &options)

Create an LTOModule.

Definition LTOModule.cpp:107

static LLVM_ABI bool isBitcodeFile(const void *mem, size_t length)

Returns 'true' if the file or memory contents is LLVM bitcode.

Definition LTOModule.cpp:53

LLVM_ABI Expected< uint32_t > getMachOCPUType() const

Definition LTOModule.cpp:687

static LLVM_ABI std::unique_ptr< MemoryBuffer > makeBuffer(const void *mem, size_t length, StringRef name="")

Create a MemoryBuffer from a memory range with an optional name.

Definition LTOModule.cpp:241

static LLVM_ABI size_t getDependentLibraryCount(lto::InputFile *input)

Definition LTOModule.cpp:676

LLVM_ABI bool hasCtorDtor() const

Returns true if the module has either the @llvm.global_ctors or the @llvm.global_dtors symbol.

Definition LTOModule.cpp:695

static LLVM_ABI const char * getDependentLibrary(lto::InputFile *input, size_t index, size_t *size)

Definition LTOModule.cpp:680

const Module & getModule() const

static LLVM_ABI ErrorOr< std::unique_ptr< LTOModule > > createFromOpenFileSlice(LLVMContext &Context, int fd, StringRef path, size_t map_size, off_t offset, const TargetOptions &options)

Definition LTOModule.cpp:127

static LLVM_ABI std::string getProducerString(MemoryBuffer *Buffer)

Returns a string representing the producer identification stored in the bitcode, or "" if the bitcode...

Definition LTOModule.cpp:93

static LLVM_ABI bool isBitcodeForTarget(MemoryBuffer *memBuffer, StringRef triplePrefix)

Returns 'true' if the memory buffer is LLVM bitcode for the specified triple.

Definition LTOModule.cpp:79

LLVM_ABI bool isThinLTO()

Returns 'true' if the Module is produced for ThinLTO.

Definition LTOModule.cpp:70

static LLVM_ABI ErrorOr< std::unique_ptr< LTOModule > > createFromOpenFile(LLVMContext &Context, int fd, StringRef path, size_t size, const TargetOptions &options)

Definition LTOModule.cpp:121

static LLVM_ABI ErrorOr< std::unique_ptr< LTOModule > > createInLocalContext(std::unique_ptr< LLVMContext > Context, const void *mem, size_t length, const TargetOptions &options, StringRef path)

Definition LTOModule.cpp:152

static LLVM_ABI ErrorOr< std::unique_ptr< LTOModule > > createFromBuffer(LLVMContext &Context, const void *mem, size_t length, const TargetOptions &options, StringRef path="")

Definition LTOModule.cpp:143

LLVM_ABI Expected< uint32_t > getMachOCPUSubType() const

Definition LTOModule.cpp:691

static LLVM_ABI lto::InputFile * createInputFile(const void *buffer, size_t buffer_size, const char *path, std::string &out_error)

Definition LTOModule.cpp:659

static const Target * lookupTarget(StringRef TripleStr, std::string &Error)

lookupTarget - Lookup a target based on a target triple.