extern "C" void LLVMRustWriteOutputFile(LLVMPassManagerRef PMR, LLVMModuleRef M, const char *triple, const char *path, LLVMCodeGenFileType FileType) { // Set compilation options. llvm::UnwindTablesMandatory = true; llvm::NoFramePointerElim = true; InitializeAllTargets(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); TargetMachine::setRelocationModel(Reloc::PIC_); std::string Err; const Target *TheTarget = TargetRegistry::lookupTarget(triple, Err); std::string FeaturesStr; TargetMachine *Target = TheTarget->createTargetMachine(triple, FeaturesStr); bool NoVerify = false; CodeGenOpt::Level OLvl = CodeGenOpt::Default; PassManager *PM = unwrap<PassManager>(PMR); std::string ErrorInfo; raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary); formatted_raw_ostream FOS(OS); TargetMachine::CodeGenFileType FileType2 = static_cast<TargetMachine::CodeGenFileType>(FileType); bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType2, OLvl, NoVerify); assert(!foo); (void)foo; PM->run(*unwrap(M)); delete Target; }
static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, raw_pwrite_stream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) { TargetMachine* TM = unwrap(T); Module* Mod = unwrap(M); legacy::PassManager pass; std::string error; Mod->setDataLayout(TM->createDataLayout()); TargetMachine::CodeGenFileType ft; switch (codegen) { case LLVMAssemblyFile: ft = TargetMachine::CGFT_AssemblyFile; break; default: ft = TargetMachine::CGFT_ObjectFile; break; } if (TM->addPassesToEmitFile(pass, OS, ft)) { error = "TargetMachine can't emit a file of this type"; *ErrorMessage = strdup(error.c_str()); return true; } pass.run(*Mod); OS.flush(); return false; }
extern "C" void LLVMRustWriteOutputFile(LLVMPassManagerRef PMR, LLVMModuleRef M, const char *triple, const char *path, TargetMachine::CodeGenFileType FileType, CodeGenOpt::Level OptLevel) { // Set compilation options. llvm::NoFramePointerElim = true; InitializeAllTargets(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); TargetMachine::setRelocationModel(Reloc::PIC_); std::string Err; const Target *TheTarget = TargetRegistry::lookupTarget(triple, Err); std::string FeaturesStr; std::string Trip(triple); std::string CPUStr = llvm::sys::getHostCPUName(); TargetMachine *Target = TheTarget->createTargetMachine(Trip, CPUStr, FeaturesStr); bool NoVerify = false; PassManager *PM = unwrap<PassManager>(PMR); std::string ErrorInfo; raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary); formatted_raw_ostream FOS(OS); bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, OptLevel, NoVerify); assert(!foo); (void)foo; PM->run(*unwrap(M)); delete Target; }
extern "C" bool LLVMRustWriteOutputFile(LLVMPassManagerRef PMR, LLVMModuleRef M, const char *triple, const char *feature, const char *path, TargetMachine::CodeGenFileType FileType, CodeGenOpt::Level OptLevel, bool EnableSegmentedStacks) { LLVMRustInitializeTargets(); // Initializing the command-line options more than once is not // allowed. So, check if they've already been initialized. // (This could happen if we're being called from rustpkg, for // example.) if (!EnableARMEHABI) { int argc = 3; const char* argv[] = {"rustc", "-arm-enable-ehabi", "-arm-enable-ehabi-descriptors"}; cl::ParseCommandLineOptions(argc, argv); } TargetOptions Options; Options.NoFramePointerElim = true; Options.EnableSegmentedStacks = EnableSegmentedStacks; Options.FixedStackSegmentSize = 2 * 1024 * 1024; // XXX: This is too big. PassManager *PM = unwrap<PassManager>(PMR); std::string Err; std::string Trip(Triple::normalize(triple)); std::string FeaturesStr(feature); std::string CPUStr("generic"); const Target *TheTarget = TargetRegistry::lookupTarget(Trip, Err); TargetMachine *Target = TheTarget->createTargetMachine(Trip, CPUStr, FeaturesStr, Options, Reloc::PIC_, CodeModel::Default, OptLevel); Target->addAnalysisPasses(*PM); bool NoVerify = false; std::string ErrorInfo; raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary); if (ErrorInfo != "") { LLVMRustError = ErrorInfo.c_str(); return false; } formatted_raw_ostream FOS(OS); bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, NoVerify); assert(!foo); (void)foo; PM->run(*unwrap(M)); delete Target; return true; }
void MCJITHelper::trackAsmCodeUtil(Module* M) { if (trackAsmCode) { formatted_raw_ostream formAsmFdStream(*asmFdStream); legacy::PassManager PM; PM.add(new DataLayoutPass()); TargetMachine *TM = JIT->getTargetMachine(); TM->addPassesToEmitFile(PM, formAsmFdStream, TargetMachine::CGFT_AssemblyFile); PM.run(*M); } }
std::unique_ptr<llvm::SmallVectorImpl<char>> getBPFObjectFromModule(llvm::Module *Module) { using namespace llvm; std::string TargetTriple("bpf-pc-linux"); std::string Error; const Target* Target = TargetRegistry::lookupTarget(TargetTriple, Error); if (!Target) { llvm::errs() << Error; return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr); } llvm::TargetOptions Opt; TargetMachine *TargetMachine = Target->createTargetMachine(TargetTriple, "generic", "", Opt, Reloc::Static); Module->setDataLayout(TargetMachine->createDataLayout()); Module->setTargetTriple(TargetTriple); std::unique_ptr<SmallVectorImpl<char>> Buffer(new SmallVector<char, 0>()); raw_svector_ostream ostream(*Buffer); legacy::PassManager PM; bool NotAdded; #if CLANG_VERSION_MAJOR < 7 NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, TargetMachine::CGFT_ObjectFile); #else NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, nullptr, TargetMachine::CGFT_ObjectFile); #endif if (NotAdded) { llvm::errs() << "TargetMachine can't emit a file of this type\n"; return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr); } PM.run(*Module); return Buffer; }
// stolen from LDC and modified // based on llc (from LLVM) code, University of Illinois Open Source License int LLVMWriteNativeAsmToFile(LLVMTargetMachineRef TMRef, LLVMModuleRef MRef, const char* filename, int opt, int pic) { TargetMachine* TM = unwrap(TMRef); Module* M = unwrap(MRef); TargetMachine::setRelocationModel(pic ? Reloc::PIC_ : Reloc::Default); #if 0 printf("trying to write native asm for target: %s\n", TM->getTarget().getName()); #endif std::string Err; // Build up all of the passes that we want to do to the module. FunctionPassManager Passes(M); // Add TargetData if (const TargetData *TD = TM->getTargetData()) Passes.add(new TargetData(*TD)); else assert(0); // Passes.add(new TargetData(M)); // debug info doesn't work properly with OptLevel != None! CodeGenOpt::Level OLvl = CodeGenOpt::Default; if (opt) OLvl = CodeGenOpt::Aggressive; else OLvl = CodeGenOpt::None; // open output file raw_fd_ostream out(filename, Err, raw_fd_ostream::F_Binary); assert(Err.empty()); // add codegen passes formatted_raw_ostream fout(out); bool error = TM->addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, OLvl); assert(error == false); // Target does not support generation of this file type! Passes.doInitialization(); // Run our queue of passes all at once now, efficiently. for (llvm::Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->isDeclaration()) Passes.run(*I); Passes.doFinalization(); fout.flush(); return 1; }
void outputAssemble(llvm::Module &module, raw_pwrite_stream &os) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); string err; Triple triple; const Target *target = TargetRegistry::lookupTarget("x86", triple, err); TargetOptions opt; TargetMachine *tm = target->createTargetMachine(triple.getTriple(), "i386", "", opt); PassManager passManager; addOptPasses(passManager); tm->addPassesToEmitFile(passManager, os, TargetMachine::CGFT_AssemblyFile, false); passManager.run(module); os.flush(); }
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { TargetMachine* TM = unwrap(T); Module* Mod = unwrap(M); PassManager pass; std::string error; const DataLayout* td = TM->getDataLayout(); if (!td) { error = "No DataLayout in TargetMachine"; *ErrorMessage = strdup(error.c_str()); return true; } pass.add(new DataLayout(*td)); TargetMachine::CodeGenFileType ft; switch (codegen) { case LLVMAssemblyFile: ft = TargetMachine::CGFT_AssemblyFile; break; default: ft = TargetMachine::CGFT_ObjectFile; break; } raw_fd_ostream dest(Filename, error, raw_fd_ostream::F_Binary); formatted_raw_ostream destf(dest); if (!error.empty()) { *ErrorMessage = strdup(error.c_str()); return true; } if (TM->addPassesToEmitFile(pass, destf, ft)) { error = "No DataLayout in TargetMachine"; *ErrorMessage = strdup(error.c_str()); return true; } pass.run(*Mod); destf.flush(); dest.flush(); return false; }
extern "C" bool LLVMRustWriteOutputFile(LLVMPassManagerRef PMR, LLVMModuleRef M, const char *triple, const char *path, TargetMachine::CodeGenFileType FileType, CodeGenOpt::Level OptLevel, bool EnableSegmentedStacks) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); TargetOptions Options; Options.NoFramePointerElim = true; Options.EnableSegmentedStacks = EnableSegmentedStacks; std::string Err; const Target *TheTarget = TargetRegistry::lookupTarget(triple, Err); std::string FeaturesStr; std::string Trip(triple); std::string CPUStr("generic"); TargetMachine *Target = TheTarget->createTargetMachine(Trip, CPUStr, FeaturesStr, Options, Reloc::PIC_, CodeModel::Default, OptLevel); bool NoVerify = false; PassManager *PM = unwrap<PassManager>(PMR); std::string ErrorInfo; raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary); if (ErrorInfo != "") { LLVMRustError = ErrorInfo.c_str(); return false; } formatted_raw_ostream FOS(OS); bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, NoVerify); assert(!foo); (void)foo; PM->run(*unwrap(M)); delete Target; return true; }
static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) { TargetMachine* TM = unwrap(T); Module* Mod = unwrap(M); PassManager pass; std::string error; const DataLayout *td = TM->getSubtargetImpl()->getDataLayout(); if (!td) { error = "No DataLayout in TargetMachine"; *ErrorMessage = strdup(error.c_str()); return true; } Mod->setDataLayout(td); pass.add(new DataLayoutPass()); TargetMachine::CodeGenFileType ft; switch (codegen) { case LLVMAssemblyFile: ft = TargetMachine::CGFT_AssemblyFile; break; default: ft = TargetMachine::CGFT_ObjectFile; break; } if (TM->addPassesToEmitFile(pass, OS, ft)) { error = "TargetMachine can't emit a file of this type"; *ErrorMessage = strdup(error.c_str()); return true; } pass.run(*Mod); OS.flush(); return false; }
static int runCompilePasses(Module *ModuleRef, unsigned ModuleIndex, ThreadedFunctionQueue *FuncQueue, const Triple &TheTriple, TargetMachine &Target, StringRef ProgramName, raw_pwrite_stream &OS){ PNaClABIErrorReporter ABIErrorReporter; if (SplitModuleCount > 1 || ExternalizeAll) { // Add function and global names, and give them external linkage. // This relies on LLVM's consistent auto-generation of names, we could // maybe do our own in case something changes there. for (Function &F : *ModuleRef) { if (!F.hasName()) F.setName("Function"); if (F.hasInternalLinkage()) F.setLinkage(GlobalValue::ExternalLinkage); } for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { if (!GI->hasName()) GI->setName("Global"); if (GI->hasInternalLinkage()) GI->setLinkage(GlobalValue::ExternalLinkage); } if (ModuleIndex > 0) { // Remove the initializers for all global variables, turning them into // declarations. for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { assert(GI->hasInitializer() && "Global variable missing initializer"); Constant *Init = GI->getInitializer(); GI->setInitializer(nullptr); if (Init->getNumUses() == 0) Init->destroyConstant(); } } } // Make all non-weak symbols hidden for better code. We cannot do // this for weak symbols. The linker complains when some weak // symbols are not resolved. for (Function &F : *ModuleRef) { if (!F.isWeakForLinker() && !F.hasLocalLinkage()) F.setVisibility(GlobalValue::HiddenVisibility); } for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { if (!GI->isWeakForLinker() && !GI->hasLocalLinkage()) GI->setVisibility(GlobalValue::HiddenVisibility); } // Build up all of the passes that we want to do to the module. std::unique_ptr<legacy::PassManagerBase> PM; if (LazyBitcode) PM.reset(new legacy::FunctionPassManager(ModuleRef)); else PM.reset(new legacy::PassManager()); // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *DL = Target.getDataLayout()) ModuleRef->setDataLayout(*DL); // For conformance with llc, we let the user disable LLVM IR verification with // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only // run it once, before PNaCl ABI verification. if (!NoVerify) PM->add(createVerifierPass()); // Add the ABI verifier pass before the analysis and code emission passes. if (PNaClABIVerify) PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); // Add the intrinsic resolution pass. It assumes ABI-conformant code. PM->add(createResolvePNaClIntrinsicsPass()); // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(TheTriple); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); PM->add(new TargetLibraryInfoWrapperPass(TLII)); // Allow subsequent passes and the backend to better optimize instructions // that were simplified for PNaCl's ABI. This pass uses the TargetLibraryInfo // above. PM->add(createBackendCanonicalizePass()); // Ask the target to add backend passes as necessary. We explicitly ask it // not to add the verifier pass because we added it earlier. if (Target.addPassesToEmitFile(*PM, OS, FileType, /* DisableVerify */ true)) { errs() << ProgramName << ": target does not support generation of this file type!\n"; return 1; } if (LazyBitcode) { auto FPM = static_cast<legacy::FunctionPassManager *>(PM.get()); FPM->doInitialization(); unsigned FuncIndex = 0; switch (SplitModuleSched) { case SplitModuleStatic: for (Function &F : *ModuleRef) { if (FuncQueue->GrabFunctionStatic(FuncIndex, ModuleIndex)) { FPM->run(F); CheckABIVerifyErrors(ABIErrorReporter, "Function " + F.getName()); F.Dematerialize(); } ++FuncIndex; } break; case SplitModuleDynamic: unsigned ChunkSize = 0; unsigned NumFunctions = FuncQueue->Size(); Module::iterator I = ModuleRef->begin(); while (FuncIndex < NumFunctions) { ChunkSize = FuncQueue->RecommendedChunkSize(); unsigned NextIndex; bool grabbed = FuncQueue->GrabFunctionDynamic(FuncIndex, ChunkSize, NextIndex); if (grabbed) { while (FuncIndex < NextIndex) { if (!I->isMaterializable() && I->isDeclaration()) { ++I; continue; } FPM->run(*I); CheckABIVerifyErrors(ABIErrorReporter, "Function " + I->getName()); I->Dematerialize(); ++FuncIndex; ++I; } } else { while (FuncIndex < NextIndex) { if (!I->isMaterializable() && I->isDeclaration()) { ++I; continue; } ++FuncIndex; ++I; } } } break; } FPM->doFinalization(); } else static_cast<legacy::PassManager *>(PM.get())->run(*ModuleRef); return 0; }
bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS) { // Create the TargetMachine for generating code. std::string Error; std::string Triple = TheModule->getTargetTriple(); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); if (!TheTarget) { Diags.Report(diag::err_fe_unable_to_create_target) << Error; return false; } // FIXME: Expose these capabilities via actual APIs!!!! Aside from just // being gross, this is also totally broken if we ever care about // concurrency. TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose); TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections); TargetMachine::setDataSections (CodeGenOpts.DataSections); // FIXME: Parse this earlier. llvm::CodeModel::Model CM; if (CodeGenOpts.CodeModel == "small") { CM = llvm::CodeModel::Small; } else if (CodeGenOpts.CodeModel == "kernel") { CM = llvm::CodeModel::Kernel; } else if (CodeGenOpts.CodeModel == "medium") { CM = llvm::CodeModel::Medium; } else if (CodeGenOpts.CodeModel == "large") { CM = llvm::CodeModel::Large; } else { assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!"); CM = llvm::CodeModel::Default; } std::vector<const char *> BackendArgs; BackendArgs.push_back("clang"); // Fake program name. if (!CodeGenOpts.DebugPass.empty()) { BackendArgs.push_back("-debug-pass"); BackendArgs.push_back(CodeGenOpts.DebugPass.c_str()); } if (!CodeGenOpts.LimitFloatPrecision.empty()) { BackendArgs.push_back("-limit-float-precision"); BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str()); } if (llvm::TimePassesIsEnabled) BackendArgs.push_back("-time-passes"); for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i) BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str()); if (CodeGenOpts.NoGlobalMerge) BackendArgs.push_back("-global-merge=false"); BackendArgs.push_back(0); llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, const_cast<char **>(&BackendArgs[0])); std::string FeaturesStr; if (TargetOpts.Features.size()) { SubtargetFeatures Features; for (std::vector<std::string>::const_iterator it = TargetOpts.Features.begin(), ie = TargetOpts.Features.end(); it != ie; ++it) Features.AddFeature(*it); FeaturesStr = Features.getString(); } llvm::Reloc::Model RM = llvm::Reloc::Default; if (CodeGenOpts.RelocationModel == "static") { RM = llvm::Reloc::Static; } else if (CodeGenOpts.RelocationModel == "pic") { RM = llvm::Reloc::PIC_; } else { assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" && "Invalid PIC model!"); RM = llvm::Reloc::DynamicNoPIC; } CodeGenOpt::Level OptLevel = CodeGenOpt::Default; switch (CodeGenOpts.OptimizationLevel) { default: break; case 0: OptLevel = CodeGenOpt::None; break; case 3: OptLevel = CodeGenOpt::Aggressive; break; } llvm::TargetOptions Options; // Set frame pointer elimination mode. if (!CodeGenOpts.DisableFPElim) { Options.NoFramePointerElim = false; Options.NoFramePointerElimNonLeaf = false; } else if (CodeGenOpts.OmitLeafFramePointer) { Options.NoFramePointerElim = false; Options.NoFramePointerElimNonLeaf = true; } else { Options.NoFramePointerElim = true; Options.NoFramePointerElimNonLeaf = true; } // Set float ABI type. if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp") Options.FloatABIType = llvm::FloatABI::Soft; else if (CodeGenOpts.FloatABI == "hard") Options.FloatABIType = llvm::FloatABI::Hard; else { assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!"); Options.FloatABIType = llvm::FloatABI::Default; } Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD; Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath; Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath; Options.UseSoftFloat = CodeGenOpts.SoftFloat; Options.StackAlignmentOverride = CodeGenOpts.StackAlignment; Options.RealignStack = CodeGenOpts.StackRealignment; TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, Options, RM, CM, OptLevel); if (CodeGenOpts.RelaxAll) TM->setMCRelaxAll(true); if (CodeGenOpts.SaveTempLabels) TM->setMCSaveTempLabels(true); if (CodeGenOpts.NoDwarf2CFIAsm) TM->setMCUseCFI(false); if (!CodeGenOpts.NoDwarfDirectoryAsm) TM->setMCUseDwarfDirectory(true); if (CodeGenOpts.NoExecStack) TM->setMCNoExecStack(true); // Create the code generator passes. PassManager *PM = getCodeGenPasses(); // Normal mode, emit a .s or .o file by running the code generator. Note, // this also adds codegenerator level optimization passes. TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile; if (Action == Backend_EmitObj) CGFT = TargetMachine::CGFT_ObjectFile; else if (Action == Backend_EmitMCNull) CGFT = TargetMachine::CGFT_Null; else assert(Action == Backend_EmitAssembly && "Invalid action!"); // Add ObjC ARC final-cleanup optimizations. This is done as part of the // "codegen" passes so that it isn't run multiple times when there is // inlining happening. if (LangOpts.ObjCAutoRefCount) PM->add(createObjCARCContractPass()); if (TM->addPassesToEmitFile(*PM, OS, CGFT, /*DisableVerify=*/!CodeGenOpts.VerifyModule)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); return false; } return true; }
bool BackendConsumer::AddEmitPasses() { if (Action == Backend_EmitNothing) return true; if (Action == Backend_EmitBC) { getPerModulePasses()->add(createBitcodeWriterPass(FormattedOutStream)); } else if (Action == Backend_EmitLL) { getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream)); } else { bool Fast = CodeGenOpts.OptimizationLevel == 0; // Create the TargetMachine for generating code. std::string Error; std::string Triple = TheModule->getTargetTriple(); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); if (!TheTarget) { Diags.Report(diag::err_fe_unable_to_create_target) << Error; return false; } // FIXME: Expose these capabilities via actual APIs!!!! Aside from just // being gross, this is also totally broken if we ever care about // concurrency. llvm::NoFramePointerElim = CodeGenOpts.DisableFPElim; if (CodeGenOpts.FloatABI == "soft") llvm::FloatABIType = llvm::FloatABI::Soft; else if (CodeGenOpts.FloatABI == "hard") llvm::FloatABIType = llvm::FloatABI::Hard; else { assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!"); llvm::FloatABIType = llvm::FloatABI::Default; } NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; llvm::UseSoftFloat = CodeGenOpts.SoftFloat; UnwindTablesMandatory = CodeGenOpts.UnwindTables; TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose); // FIXME: Parse this earlier. if (CodeGenOpts.RelocationModel == "static") { TargetMachine::setRelocationModel(llvm::Reloc::Static); } else if (CodeGenOpts.RelocationModel == "pic") { TargetMachine::setRelocationModel(llvm::Reloc::PIC_); } else { assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" && "Invalid PIC model!"); TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC); } // FIXME: Parse this earlier. if (CodeGenOpts.CodeModel == "small") { TargetMachine::setCodeModel(llvm::CodeModel::Small); } else if (CodeGenOpts.CodeModel == "kernel") { TargetMachine::setCodeModel(llvm::CodeModel::Kernel); } else if (CodeGenOpts.CodeModel == "medium") { TargetMachine::setCodeModel(llvm::CodeModel::Medium); } else if (CodeGenOpts.CodeModel == "large") { TargetMachine::setCodeModel(llvm::CodeModel::Large); } else { assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!"); TargetMachine::setCodeModel(llvm::CodeModel::Default); } std::vector<const char *> BackendArgs; BackendArgs.push_back("clang"); // Fake program name. if (!CodeGenOpts.DebugPass.empty()) { BackendArgs.push_back("-debug-pass"); BackendArgs.push_back(CodeGenOpts.DebugPass.c_str()); } if (!CodeGenOpts.LimitFloatPrecision.empty()) { BackendArgs.push_back("-limit-float-precision"); BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str()); } if (llvm::TimePassesIsEnabled) BackendArgs.push_back("-time-passes"); BackendArgs.push_back(0); llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, (char**) &BackendArgs[0]); std::string FeaturesStr; if (TargetOpts.CPU.size() || TargetOpts.Features.size()) { SubtargetFeatures Features; Features.setCPU(TargetOpts.CPU); for (std::vector<std::string>::const_iterator it = TargetOpts.Features.begin(), ie = TargetOpts.Features.end(); it != ie; ++it) Features.AddFeature(*it); FeaturesStr = Features.getString(); } TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr); // Set register scheduler & allocation policy. RegisterScheduler::setDefault(createDefaultScheduler); RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator : createLinearScanRegisterAllocator); // From llvm-gcc: // If there are passes we have to run on the entire module, we do codegen // as a separate "pass" after that happens. // FIXME: This is disabled right now until bugs can be worked out. Reenable // this for fast -O0 compiles! FunctionPassManager *PM = getCodeGenPasses(); CodeGenOpt::Level OptLevel = CodeGenOpt::Default; switch (CodeGenOpts.OptimizationLevel) { default: break; case 0: OptLevel = CodeGenOpt::None; break; case 3: OptLevel = CodeGenOpt::Aggressive; break; } // Normal mode, emit a .s or .o file by running the code generator. Note, // this also adds codegenerator level optimization passes. TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile; if (Action == Backend_EmitObj) CGFT = TargetMachine::CGFT_ObjectFile; if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); return false; } } return true; }