22 #include "llvm/Config/config.h"
55 #include <system_error>
59 #ifdef LLVM_VERSION_INFO
60 return PACKAGE_NAME
" version " PACKAGE_VERSION
", " LLVM_VERSION_INFO;
62 return PACKAGE_NAME
" version " PACKAGE_VERSION;
68 initializeLTOPasses();
72 : OwnedContext(std::move(Context)), Context(*OwnedContext),
73 IRLinker(new
Module(
"ld-temp.o", *OwnedContext)) {
74 initializeLTOPasses();
77 void LTOCodeGenerator::destroyMergedModule() {
80 "The linker's module should be the same as the owned module");
82 OwnedModule =
nullptr;
88 destroyMergedModule();
93 for (std::vector<char *>::iterator
I = CodegenOptions.begin(),
94 E = CodegenOptions.end();
102 void LTOCodeGenerator::initializeLTOPasses() {
131 "Expected module in same context");
136 for (
int i = 0, e = undefs.size(); i != e; ++i)
137 AsmUndefinedRefs[undefs[i]] = 1;
144 "Expected module in same context");
147 destroyMergedModule();
148 AsmUndefinedRefs.
clear();
154 for (
int I = 0, E = Undefs.size();
I != E; ++
I)
155 AsmUndefinedRefs[Undefs[
I]] = 1;
165 EmitDwarfDebugInfo =
false;
169 EmitDwarfDebugInfo =
true;
188 std::string &errMsg) {
189 if (!determineTarget(errMsg))
193 applyScopeRestrictions();
199 errMsg =
"could not open bitcode file for writing: ";
209 errMsg =
"could not write bitcode file: ";
219 bool LTOCodeGenerator::compileOptimizedToFile(
const char **
name,
220 std::string &errMsg) {
227 errMsg = EC.message();
235 objFile.os().close();
236 if (objFile.os().has_error()) {
237 objFile.os().clear_error();
248 NativeObjectPath = Filename.
c_str();
249 *name = NativeObjectPath.c_str();
253 std::unique_ptr<MemoryBuffer>
256 if (!compileOptimizedToFile(&name, errMsg))
262 if (std::error_code EC = BufferOrErr.
getError()) {
263 errMsg = EC.message();
271 return std::move(*BufferOrErr);
277 bool disableGVNLoadPRE,
278 bool disableVectorization,
279 std::string &errMsg) {
280 if (!
optimize(disableInline, disableGVNLoadPRE,
281 disableVectorization, errMsg))
284 return compileOptimizedToFile(name, errMsg);
287 std::unique_ptr<MemoryBuffer>
289 bool disableVectorization, std::string &errMsg) {
290 if (!
optimize(disableInline, disableGVNLoadPRE,
291 disableVectorization, errMsg))
297 bool LTOCodeGenerator::determineTarget(std::string &errMsg) {
302 if (TripleStr.empty())
333 std::string FeatureStr =
Features.getString();
366 void LTOCodeGenerator::
369 std::vector<const char*> &MustPreserveList,
383 if (MustPreserveSymbols.
count(Buffer))
385 if (AsmUndefinedRefs.
count(Buffer))
393 if (isa<Function>(GV) &&
400 if (!LLVMUsed)
return;
422 Libcalls.push_back(TLI.
getName(F));
431 if (Lowering && TLSet.
insert(Lowering).second)
436 if (
const char *
Name =
438 Libcalls.push_back(
Name);
442 Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
446 void LTOCodeGenerator::applyScopeRestrictions() {
447 if (ScopeRestrictionsDone || !ShouldInternalize)
457 std::vector<const char*> MustPreserveList;
459 std::vector<StringRef> Libcalls;
466 e = mergedModule->
end(); f != e; ++f)
467 applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler);
470 applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler);
472 e = mergedModule->
alias_end(); a != e; ++a)
473 applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler);
478 if (LLVMCompilerUsed)
481 if (!AsmUsed.
empty()) {
483 std::vector<Constant*> asmUsed2;
484 for (
auto *GV : AsmUsed) {
486 asmUsed2.push_back(c);
494 "llvm.compiler.used");
496 LLVMCompilerUsed->setSection(
"llvm.metadata");
502 passes.
run(*mergedModule);
504 ScopeRestrictionsDone =
true;
509 bool DisableGVNLoadPRE,
510 bool DisableVectorization,
511 std::string &errMsg) {
512 if (!this->determineTarget(errMsg))
518 this->applyScopeRestrictions();
532 PMB.LoopVectorize = !DisableVectorization;
533 PMB.SLPVectorize = !DisableVectorization;
537 PMB.OptLevel = OptLevel;
538 PMB.VerifyInput =
true;
539 PMB.VerifyOutput =
true;
541 PMB.populateLTOPassManager(passes);
544 passes.
run(*mergedModule);
550 std::string &errMsg) {
551 if (!this->determineTarget(errMsg))
564 errMsg =
"target file type not supported";
569 codeGenPasses.
run(*mergedModule);
577 for (std::pair<StringRef, StringRef> o =
getToken(options);
578 !o.first.empty(); o =
getToken(o.second)) {
581 if (CodegenOptions.empty())
582 CodegenOptions.push_back(strdup(
"libLLVMLTO"));
583 CodegenOptions.push_back(strdup(o.first.str().c_str()));
589 if (!CodegenOptions.empty())
591 const_cast<char **
>(&CodegenOptions[0]));
594 void LTOCodeGenerator::DiagnosticHandler(
const DiagnosticInfo &DI,
599 void LTOCodeGenerator::DiagnosticHandler2(
const DiagnosticInfo &DI) {
617 std::string MsgStorage;
625 assert(DiagHandler &&
"Invalid diagnostic handler");
626 (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
632 this->DiagHandler = DiagHandler;
633 this->DiagContext = Ctxt;
635 return Context.setDiagnosticHandler(
nullptr,
nullptr);
638 Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler,
this,
void initializeFunctionAttrsPass(PassRegistry &)
std::error_code getError() const
Represents either an error or a value T.
Special purpose, only applies to global arrays.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PassManagerBuilder - This class is used to set up a standard optimization sequence for languages like...
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate=false) const
bool compile_to_file(const char **name, bool disableInline, bool disableGVNLoadPRE, bool disableVectorization, std::string &errMsg)
A Module instance is used to store all the information related to an LLVM module. ...
void initializeSimpleInlinerPass(PassRegistry &)
void initializeJumpThreadingPass(PassRegistry &)
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
unsigned getNumOperands() const
bool optimize(bool disableInline, bool disableGVNLoadPRE, bool disableVectorization, std::string &errMsg)
Optimize merged modules using various IPO passes.
lto_codegen_diagnostic_severity_t
Diagnostic severity.
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
void initializeInternalizePassPass(PassRegistry &)
FunctionPass * createVerifierPass(bool FatalErrors=true)
Create a verifier pass.
ImmutablePass * createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA)
Create an analysis pass wrapper around a TTI object.
const FeatureBitset Features
bool addModule(struct LTOModule *)
void setDataLayout(StringRef Desc)
Set the data layout.
Implementation of the target library information.
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
void initializeSROA_DTPass(PassRegistry &)
StringRef getName() const
Return a constant reference to the value's name.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
const Triple & getTargetTriple() const
void initializePruneEHPass(PassRegistry &)
void add(Pass *P) override
Add a pass to the queue of passes to run.
bool has_error() const
Return the value of the flag in this raw_fd_ostream indicating whether an output error has been encou...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
bool has(LibFunc::Func F) const
Tests whether a library function is available.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void initializeMergedLoadStoreMotionPass(PassRegistry &)
void initializeArgPromotionPass(PassRegistry &)
void initializeGlobalOptPass(PassRegistry &)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
const Module & getModule() const
void eraseFromParent() override
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool hasPrivateLinkage() const
void setTargetOptions(TargetOptions options)
global_iterator global_begin()
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Pass * createObjCARCContractPass()
ArrayType - Class to represent array types.
static const char * getVersionString()
TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, Reloc::Model RM=Reloc::Default, CodeModel::Model CM=CodeModel::Default, CodeGenOpt::Level OL=CodeGenOpt::Default) const
createTargetMachine - Create a target specific machine implementation for the specified Triple...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
DiagnosticSeverity getSeverity() const
void initializeGlobalsModRefPass(PassRegistry &)
bool linkInModule(Module *Src, bool OverrideSymbols=false)
Link Src into the composite.
PassManager manages ModulePassManagers.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool writeMergedModules(const char *path, std::string &errMsg)
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
This is the base abstract class for diagnostic reporting in the backend.
cl::opt< Reloc::Model > RelocModel("relocation-model", cl::desc("Choose relocation model"), cl::init(Reloc::Default), cl::values(clEnumValN(Reloc::Default,"default","Target default relocation model"), clEnumValN(Reloc::Static,"static","Non-relocatable code"), clEnumValN(Reloc::PIC_,"pic","Fully relocatable, position independent code"), clEnumValN(Reloc::DynamicNoPIC,"dynamic-no-pic","Relocatable external references, non-relocatable code"), clEnumValEnd))
void setCodeGenDebugOptions(const char *opts)
setCodeGenDebugOptions - Set codegen debugging options to aid in debugging LTO problems.
alias_iterator alias_end()
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important base class in LLVM.
void WriteBitcodeToFile(const Module *M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false)
Write the specified module to the specified raw output stream.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
virtual TargetIRAnalysis getTargetIRAnalysis()
Get a TargetIRAnalysis appropriate for the target.
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
void setModule(struct LTOModule *)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Value * getOperand(unsigned i) const
void initializeIPSCCPPass(PassRegistry &)
void initializeLICMPass(PassRegistry &)
C++ class which implements the opaque lto_module_t type.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
virtual void print(DiagnosticPrinter &DP) const =0
Print using the given DP a user-friendly message.
void setModule(Module *Dst)
Set the composite to the passed-in module.
static void accumulateAndSortLibcalls(std::vector< StringRef > &Libcalls, const TargetLibraryInfo &TLI, const Module &Mod, const TargetMachine &TM)
void(* lto_diagnostic_handler_t)(lto_codegen_diagnostic_severity_t severity, const char *diag, void *ctxt)
Diagnostic handler type.
Triple - Helper class for working with autoconf configuration names.
C++ class which implements the opaque lto_code_gen_t type.
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
global_iterator global_end()
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
std::unique_ptr< MemoryBuffer > compileOptimized(std::string &errMsg)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
shadow stack gc Shadow Stack GC Lowering
const DataLayout * getDataLayout() const
Deprecated in 3.7, will be removed in 3.8.
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
virtual const TargetLowering * getTargetLowering() const
void initializeSROA_SSAUpPass(PassRegistry &)
alias_iterator alias_begin()
Value * stripPointerCasts()
Strip off pointer casts, all-zero GEPs, and aliases.
Target - Wrapper for Target specific information.
ConstantArray - Constant Array Declarations.
SubtargetFeatures - Manages the enabling and disabling of subtarget specific features.
void ParseCommandLineOptions(int argc, const char *const *argv, const char *Overview=nullptr)
void initializeDCEPass(PassRegistry &)
void initializeDAHPass(PassRegistry &)
virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &, CodeGenFileType, bool=true, AnalysisID=nullptr, AnalysisID=nullptr, AnalysisID=nullptr, MachineFunctionInitializer *=nullptr)
Add passes to the specified pass manager to get the specified file emitted.
void initializeSROAPass(PassRegistry &)
void initializeGlobalDCEPass(PassRegistry &)
Basic diagnostic printer that uses an underlying raw_ostream.
StringRef getName(LibFunc::Func F) const
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatileSize=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath)
Create a file in the system temporary directory.
static void findUsedValues(GlobalVariable *LLVMUsed, SmallPtrSetImpl< GlobalValue * > &UsedValues)
static ArrayType * get(Type *ElementType, uint64_t NumElements)
ArrayType::get - This static method is the primary way to construct an ArrayType. ...
const std::vector< const char * > & getAsmUndefinedRefs()
ModulePass * createInternalizePass(ArrayRef< const char * > ExportList)
createInternalizePass - This pass loops over all of the functions in the input module, internalizing all globals (functions and variables) it can.
void initializeConstantMergePass(PassRegistry &)
void initializeInstructionCombiningPassPass(PassRegistry &)
void close()
Manually flush the stream and close the file.
An abstract base class for streams implementations that also support a pwrite operation.
void initializeCFGSimplifyPassPass(PassRegistry &)
void initializeMemCpyOptPass(PassRegistry &)
Module * getModule() const
A raw_ostream that writes to an std::string.
Pass * createFunctionInliningPass()
createFunctionInliningPass - Return a new pass object that uses a heuristic to inline direct function...
void setCodePICModel(lto_codegen_model)
Primary interface to the complete machine description for the target machine.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
void parseCodeGenDebugOptions()
std::unique_ptr< MemoryBuffer > compile(bool disableInline, bool disableGVNLoadPRE, bool disableVectorization, std::string &errMsg)
LLVMContext & getGlobalContext()
getGlobalContext - Returns a global context.
GlobalVariable * getGlobalVariable(StringRef Name) const
Look up the specified global variable in the module symbol table.
void setDiagnosticHandler(lto_diagnostic_handler_t, void *)
LLVMContext & getContext() const
Get the global data context.
This file describes how to lower LLVM code to machine code.
void clear_error()
Set the flag read by has_error() to false.
void setDebugInfo(lto_debug_model)
void initializeGVNPass(PassRegistry &)