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(); }
static int compileModule(char **argv, LLVMContext &Context) { // Load the module to be compiled... SMDiagnostic Err; std::unique_ptr<Module> M; Triple TheTriple; bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); // If user just wants to list available options, skip module loading if (!SkipModule) { M = parseIRFile(InputFilename, Err, Context); if (!M) { Err.print(argv[0], errs()); return 1; } // Verify module immediately to catch problems before doInitialization() is // called on any passes. if (!NoVerify && verifyModule(*M, &errs())) { errs() << argv[0] << ": " << InputFilename << ": error: input module is broken!\n"; return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); TheTriple = Triple(M->getTargetTriple()); } else { TheTriple = Triple(Triple::normalize(TargetTriple)); } if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << argv[0] << ": " << Error; return 1; } std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr(); CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); Options.DisableIntegratedAS = NoIntegratedAssembler; Options.MCOptions.ShowMCEncoding = ShowMCEncoding; Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory; Options.MCOptions.AsmVerbose = AsmVerbose; std::unique_ptr<TargetMachine> Target( TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(Target && "Could not allocate target machine!"); // If we don't have a module then just exit now. We do this down // here since the CPU/Feature help is underneath the target machine // creation. if (SkipModule) return 0; assert(M && "Should have exited if we didn't have a module!"); if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; // Figure out where we are going to send the output. std::unique_ptr<tool_output_file> Out = GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]); if (!Out) return 1; // Build up all of the passes that we want to do to the module. legacy::PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple())); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); PM.add(new TargetLibraryInfoWrapperPass(TLII)); // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *DL = Target->getDataLayout()) M->setDataLayout(*DL); // Override function attributes based on CPUStr, FeaturesStr, and Options. // Pass AlwaysRecordAttrs=false as we want to override an attribute only when // the corresponding cl::opt has been provided on llc's command line. setFunctionAttributes(CPUStr, FeaturesStr, Options, *M, /* AlwaysRecordAttrs */ false); if (RelaxAll.getNumOccurrences() > 0 && FileType != TargetMachine::CGFT_ObjectFile) errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj"; { raw_pwrite_stream *OS = &Out->os(); std::unique_ptr<buffer_ostream> BOS; if (FileType != TargetMachine::CGFT_AssemblyFile && !Out->os().supportsSeeking()) { BOS = make_unique<buffer_ostream>(*OS); OS = BOS.get(); } AnalysisID StartAfterID = nullptr; AnalysisID StopAfterID = nullptr; const PassRegistry *PR = PassRegistry::getPassRegistry(); if (!StartAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StartAfter); if (!PI) { errs() << argv[0] << ": start-after pass is not registered.\n"; return 1; } StartAfterID = PI->getTypeInfo(); } if (!StopAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StopAfter); if (!PI) { errs() << argv[0] << ": stop-after pass is not registered.\n"; return 1; } StopAfterID = PI->getTypeInfo(); } // Ask the target to add backend passes as necessary. if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartAfterID, StopAfterID)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); PM.run(*M); } // Declare success. Out->keep(); return 0; }
static int compileSplitModule(const TargetOptions &Options, const Triple &TheTriple, const Target *TheTarget, const std::string &FeaturesStr, CodeGenOpt::Level OLvl, const StringRef &ProgramName, Module *GlobalModuleRef, StreamingMemoryObject *StreamingObject, unsigned ModuleIndex, ThreadedFunctionQueue *FuncQueue) { std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); if (RelaxAll.getNumOccurrences() > 0 && FileType != TargetMachine::CGFT_ObjectFile) errs() << ProgramName << ": warning: ignoring -mc-relax-all because filetype != obj"; // The OwningPtrs are only used if we are not the primary module. std::unique_ptr<LLVMContext> C; std::unique_ptr<Module> M; Module *ModuleRef = nullptr; if (ModuleIndex == 0) { ModuleRef = GlobalModuleRef; } else { C.reset(new LLVMContext()); M = getModule(ProgramName, *C, StreamingObject); if (!M) return 1; // M owns the temporary module, but use a reference through ModuleRef // to also work in the case we are using GlobalModuleRef. ModuleRef = M.get(); // Add declarations for external functions required by PNaCl. The // ResolvePNaClIntrinsics function pass running during streaming // depends on these declarations being in the module. std::unique_ptr<ModulePass> AddPNaClExternalDeclsPass( createAddPNaClExternalDeclsPass()); AddPNaClExternalDeclsPass->runOnModule(*ModuleRef); AddPNaClExternalDeclsPass.reset(); } ModuleRef->setTargetTriple(Triple::normalize(UserDefinedTriple)); { #if !defined(PNACL_BROWSER_TRANSLATOR) // Figure out where we are going to send the output. std::string N(MainOutputFilename); raw_string_ostream OutFileName(N); if (ModuleIndex > 0) OutFileName << ".module" << ModuleIndex; std::unique_ptr<tool_output_file> Out = GetOutputStream(TheTarget->getName(), TheTriple.getOS(), OutFileName.str()); if (!Out) return 1; raw_pwrite_stream *OS = &Out->os(); std::unique_ptr<buffer_ostream> BOS; if (FileType != TargetMachine::CGFT_AssemblyFile && !Out->os().supportsSeeking()) { BOS = make_unique<buffer_ostream>(*OS); OS = BOS.get(); } #else auto OS = llvm::make_unique<raw_fd_ostream>( getObjectFileFD(ModuleIndex), /* ShouldClose */ true); OS->SetBufferSize(1 << 20); #endif int ret = runCompilePasses(ModuleRef, ModuleIndex, FuncQueue, TheTriple, Target, ProgramName, *OS); if (ret) return ret; #if defined(PNACL_BROWSER_TRANSLATOR) OS->flush(); #else // Declare success. Out->keep(); #endif // PNACL_BROWSER_TRANSLATOR } return 0; }
void jl_dump_native(const char *bc_fname, const char *obj_fname, const char *sysimg_data, size_t sysimg_len) { assert(imaging_mode); // We don't want to use MCJIT's target machine because // it uses the large code model and we may potentially // want less optimizations there. Triple TheTriple = Triple(jl_TargetMachine->getTargetTriple()); // make sure to emit the native object format, even if FORCE_ELF was set in codegen #if defined(_OS_WINDOWS_) #ifdef LLVM35 TheTriple.setObjectFormat(Triple::COFF); #else TheTriple.setEnvironment(Triple::UnknownEnvironment); #endif #elif defined(_OS_DARWIN_) #ifdef LLVM35 TheTriple.setObjectFormat(Triple::MachO); #else TheTriple.setEnvironment(Triple::MachO); #endif #endif #ifdef LLVM35 std::unique_ptr<TargetMachine> #else OwningPtr<TargetMachine> #endif TM(jl_TargetMachine->getTarget().createTargetMachine( TheTriple.getTriple(), jl_TargetMachine->getTargetCPU(), jl_TargetMachine->getTargetFeatureString(), jl_TargetMachine->Options, #if defined(_OS_LINUX_) || defined(_OS_FREEBSD_) Reloc::PIC_, #elif defined(LLVM39) Optional<Reloc::Model>(), #else Reloc::Default, #endif CodeModel::Default, CodeGenOpt::Aggressive // -O3 TODO: respect command -O0 flag? )); #ifdef LLVM37 legacy::PassManager PM; #else PassManager PM; #endif #ifndef LLVM37 PM.add(new TargetLibraryInfo(Triple(TM->getTargetTriple()))); #else PM.add(new TargetLibraryInfoWrapperPass(Triple(TM->getTargetTriple()))); #endif // set up optimization passes #ifdef LLVM37 // No DataLayout pass needed anymore. #elif defined(LLVM36) PM.add(new DataLayoutPass()); #elif defined(LLVM35) PM.add(new DataLayoutPass(*jl_ExecutionEngine->getDataLayout())); #else PM.add(new DataLayout(*jl_ExecutionEngine->getDataLayout())); #endif addOptimizationPasses(&PM); std::unique_ptr<raw_fd_ostream> bc_OS; std::unique_ptr<raw_fd_ostream> obj_OS; #ifdef LLVM37 // 3.7 simplified formatted output; just use the raw stream alone std::unique_ptr<raw_fd_ostream> &bc_FOS = bc_OS; std::unique_ptr<raw_fd_ostream> &obj_FOS = obj_OS; #else std::unique_ptr<formatted_raw_ostream> bc_FOS; std::unique_ptr<formatted_raw_ostream> obj_FOS; #endif if (bc_fname) { #if defined(LLVM35) // call output handler directly to avoid special case handling of `-` filename int FD; std::error_code EC = sys::fs::openFileForWrite(bc_fname, FD, sys::fs::F_None); bc_OS.reset(new raw_fd_ostream(FD, true)); std::string err; if (EC) err = "ERROR: failed to open --output-bc file '" + std::string(bc_fname) + "': " + EC.message(); #else std::string err; bc_OS.reset(new raw_fd_ostream(bc_fname, err, raw_fd_ostream::F_Binary)); #endif if (!err.empty()) jl_safe_printf("%s\n", err.c_str()); else { #ifndef LLVM37 bc_FOS.reset(new formatted_raw_ostream(*bc_OS.get())); #endif PM.add(createBitcodeWriterPass(*bc_FOS.get())); // Unroll small loops } } if (obj_fname) { #if defined(LLVM35) // call output handler directly to avoid special case handling of `-` filename int FD; std::error_code EC = sys::fs::openFileForWrite(obj_fname, FD, sys::fs::F_None); obj_OS.reset(new raw_fd_ostream(FD, true)); std::string err; if (EC) err = "ERROR: failed to open --output-o file '" + std::string(obj_fname) + "': " + EC.message(); #else std::string err; obj_OS.reset(new raw_fd_ostream(obj_fname, err, raw_fd_ostream::F_Binary)); #endif if (!err.empty()) jl_safe_printf("%s\n", err.c_str()); else { #ifndef LLVM37 obj_FOS.reset(new formatted_raw_ostream(*obj_OS.get())); #endif if (TM->addPassesToEmitFile(PM, *obj_FOS.get(), TargetMachine::CGFT_ObjectFile, false)) { jl_safe_printf("ERROR: target does not support generation of object files\n"); } } } ValueToValueMapTy VMap; #if defined(USE_MCJIT) || defined(USE_ORCJIT) // now copy the module (if using the old JIT), since PM.run may modify it Module *clone = shadow_output; #else Module *clone = CloneModule(shadow_output, VMap); #endif #ifdef LLVM37 // Reset the target triple to make sure it matches the new target machine clone->setTargetTriple(TM->getTargetTriple().str()); #ifdef LLVM38 clone->setDataLayout(TM->createDataLayout()); #else clone->setDataLayout(TM->getDataLayout()->getStringRepresentation()); #endif #endif // add metadata information jl_gen_llvm_globaldata(clone, VMap, sysimg_data, sysimg_len); // do the actual work PM.run(*clone); #if !defined(USE_MCJIT) && !defined(USE_ORCJIT) delete clone; #endif imaging_mode = false; }
llvm::Error dwarfgen::Generator::init(Triple TheTriple, uint16_t V) { Version = V; std::string ErrorStr; std::string TripleName; // Get the target. const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); if (!TheTarget) return make_error<StringError>(ErrorStr, inconvertibleErrorCode()); TripleName = TheTriple.getTriple(); // Create all the MC Objects. MRI.reset(TheTarget->createMCRegInfo(TripleName)); if (!MRI) return make_error<StringError>(Twine("no register info for target ") + TripleName, inconvertibleErrorCode()); MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName)); if (!MAI) return make_error<StringError>("no asm info for target " + TripleName, inconvertibleErrorCode()); MOFI.reset(new MCObjectFileInfo); MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get())); MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, CodeModel::Default, *MC); MCTargetOptions Options; MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, "", Options); if (!MAB) return make_error<StringError>("no asm backend for target " + TripleName, inconvertibleErrorCode()); MII.reset(TheTarget->createMCInstrInfo()); if (!MII) return make_error<StringError>("no instr info info for target " + TripleName, inconvertibleErrorCode()); MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); if (!MSTI) return make_error<StringError>("no subtarget info for target " + TripleName, inconvertibleErrorCode()); MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC); if (!MCE) return make_error<StringError>("no code emitter for target " + TripleName, inconvertibleErrorCode()); Stream = make_unique<raw_svector_ostream>(FileBytes); MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); MS = TheTarget->createMCObjectStreamer( TheTriple, *MC, *MAB, *Stream, MCE, *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ false); if (!MS) return make_error<StringError>("no object streamer for target " + TripleName, inconvertibleErrorCode()); // Finally create the AsmPrinter we'll use to emit the DIEs. TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), None)); if (!TM) return make_error<StringError>("no target machine for target " + TripleName, inconvertibleErrorCode()); Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS))); if (!Asm) return make_error<StringError>("no asm printer for target " + TripleName, inconvertibleErrorCode()); // Set the DWARF version correctly on all classes that we use. MC->setDwarfVersion(Version); Asm->setDwarfVersion(Version); StringPool = llvm::make_unique<DwarfStringPool>(Allocator, *Asm, StringRef()); return Error::success(); }
static int compileModule(char **argv, LLVMContext &Context) { // Load the module to be compiled... SMDiagnostic Err; std::unique_ptr<Module> M; std::unique_ptr<MIRParser> MIR; Triple TheTriple; bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); // If user just wants to list available options, skip module loading if (!SkipModule) { if (StringRef(InputFilename).endswith_lower(".mir")) { MIR = createMIRParserFromFile(InputFilename, Err, Context); if (MIR) M = MIR->parseLLVMModule(); } else M = parseIRFile(InputFilename, Err, Context); if (!M) { Err.print(argv[0], errs()); return 1; } // Verify module immediately to catch problems before doInitialization() is // called on any passes. if (!NoVerify && verifyModule(*M, &errs())) { errs() << argv[0] << ": " << InputFilename << ": error: input module is broken!\n"; return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); TheTriple = Triple(M->getTargetTriple()); } else { TheTriple = Triple(Triple::normalize(TargetTriple)); } if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << argv[0] << ": " << Error; return 1; } std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr(); CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); Options.DisableIntegratedAS = NoIntegratedAssembler; Options.MCOptions.ShowMCEncoding = ShowMCEncoding; Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory; Options.MCOptions.AsmVerbose = AsmVerbose; Options.MCOptions.PreserveAsmComments = PreserveComments; Options.MCOptions.IASSearchPaths = IncludeDirs; std::unique_ptr<TargetMachine> Target( TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, FeaturesStr, Options, getRelocModel(), CMModel, OLvl)); assert(Target && "Could not allocate target machine!"); // If we don't have a module then just exit now. We do this down // here since the CPU/Feature help is underneath the target machine // creation. if (SkipModule) return 0; assert(M && "Should have exited if we didn't have a module!"); if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; // Figure out where we are going to send the output. std::unique_ptr<tool_output_file> Out = GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]); if (!Out) return 1; // Build up all of the passes that we want to do to the module. legacy::PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple())); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); PM.add(new TargetLibraryInfoWrapperPass(TLII)); // Add the target data from the target machine, if it exists, or the module. M->setDataLayout(Target->createDataLayout()); // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. setFunctionAttributes(CPUStr, FeaturesStr, *M); if (RelaxAll.getNumOccurrences() > 0 && FileType != TargetMachine::CGFT_ObjectFile) errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj"; { raw_pwrite_stream *OS = &Out->os(); // Manually do the buffering rather than using buffer_ostream, // so we can memcmp the contents in CompileTwice mode SmallVector<char, 0> Buffer; std::unique_ptr<raw_svector_ostream> BOS; if ((FileType != TargetMachine::CGFT_AssemblyFile && !Out->os().supportsSeeking()) || CompileTwice) { BOS = make_unique<raw_svector_ostream>(Buffer); OS = BOS.get(); } if (!RunPassNames->empty()) { if (!StartAfter.empty() || !StopAfter.empty() || !StartBefore.empty() || !StopBefore.empty()) { errs() << argv[0] << ": start-after and/or stop-after passes are " "redundant when run-pass is specified.\n"; return 1; } if (!MIR) { errs() << argv[0] << ": run-pass needs a .mir input.\n"; return 1; } LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine&>(*Target); TargetPassConfig &TPC = *LLVMTM.createPassConfig(PM); PM.add(&TPC); MachineModuleInfo *MMI = new MachineModuleInfo(&LLVMTM); MMI->setMachineFunctionInitializer(MIR.get()); PM.add(MMI); TPC.printAndVerify(""); for (const std::string &RunPassName : *RunPassNames) { if (addPass(PM, argv[0], RunPassName, TPC)) return 1; } PM.add(createPrintMIRPass(*OS)); } else { const char *argv0 = argv[0]; AnalysisID StartBeforeID = getPassID(argv0, "start-before", StartBefore); AnalysisID StartAfterID = getPassID(argv0, "start-after", StartAfter); AnalysisID StopAfterID = getPassID(argv0, "stop-after", StopAfter); AnalysisID StopBeforeID = getPassID(argv0, "stop-before", StopBefore); if (StartBeforeID && StartAfterID) { errs() << argv[0] << ": -start-before and -start-after specified!\n"; return 1; } if (StopBeforeID && StopAfterID) { errs() << argv[0] << ": -stop-before and -stop-after specified!\n"; return 1; } // Ask the target to add backend passes as necessary. if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartBeforeID, StartAfterID, StopBeforeID, StopAfterID, MIR.get())) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; } } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // If requested, run the pass manager over the same module again, // to catch any bugs due to persistent state in the passes. Note that // opt has the same functionality, so it may be worth abstracting this out // in the future. SmallVector<char, 0> CompileTwiceBuffer; if (CompileTwice) { std::unique_ptr<Module> M2(llvm::CloneModule(M.get())); PM.run(*M2); CompileTwiceBuffer = Buffer; Buffer.clear(); } PM.run(*M); auto HasError = *static_cast<bool *>(Context.getDiagnosticContext()); if (HasError) return 1; // Compare the two outputs and make sure they're the same if (CompileTwice) { if (Buffer.size() != CompileTwiceBuffer.size() || (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) != 0)) { errs() << "Running the pass manager twice changed the output.\n" "Writing the result of the second run to the specified output\n" "To generate the one-run comparison binary, just run without\n" "the compile-twice option\n"; Out->os() << Buffer; Out->keep(); return 1; } } if (BOS) { Out->os() << Buffer; } } // Declare success. Out->keep(); return 0; }
static int compileModule(char **argv, LLVMContext &Context) { // Load the module to be compiled... SMDiagnostic Err; std::auto_ptr<Module> M; Module *mod = 0; Triple TheTriple; bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); // If user just wants to list available options, skip module loading if (!SkipModule) { M.reset(ParseIRFile(InputFilename, Err, Context)); mod = M.get(); if (mod == 0) { Err.print(argv[0], errs()); return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod->setTargetTriple(Triple::normalize(TargetTriple)); TheTriple = Triple(mod->getTargetTriple()); } else { TheTriple = Triple(Triple::normalize(TargetTriple)); } if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << argv[0] << ": " << Error; return 1; } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options; Options.LessPreciseFPMADOption = EnableFPMAD; Options.NoFramePointerElim = DisableFPElim; Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf; Options.AllowFPOpFusion = FuseFPOps; Options.UnsafeFPMath = EnableUnsafeFPMath; Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; Options.HonorSignDependentRoundingFPMathOption = EnableHonorSignDependentRoundingFPMath; Options.UseSoftFloat = GenerateSoftFloatCalls; if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; Options.NoZerosInBSS = DontPlaceZerosInBSS; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; Options.DisableTailCalls = DisableTailCalls; Options.StackAlignmentOverride = OverrideStackAlignment; Options.RealignStack = EnableRealignStack; Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; Options.UseInitArray = UseInitArray; Options.SSPBufferSize = SSPBufferSize; std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(target.get() && "Could not allocate target machine!"); assert(mod && "Should have exited after outputting help!"); TargetMachine &Target = *target.get(); if (DisableDotLoc) Target.setMCUseLoc(false); if (DisableCFI) Target.setMCUseCFI(false); if (EnableDwarfDirectory) Target.setMCUseDwarfDirectory(true); if (GenerateSoftFloatCalls) FloatABIForCalls = FloatABI::Soft; // Disable .loc support for older OS X versions. if (TheTriple.isMacOSX() && TheTriple.isMacOSXVersionLT(10, 6)) Target.setMCUseLoc(false); // Figure out where we are going to send the output. OwningPtr<tool_output_file> Out (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); if (!Out) return 1; // Build up all of the passes that we want to do to the module. PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple); if (DisableSimplifyLibCalls) TLI->disableAllFunctions(); PM.add(TLI); if (target.get()) { PM.add(createNoTTIPass(target->getScalarTargetTransformInfo(), target->getVectorTargetTransformInfo())); } // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *TD = Target.getDataLayout()) PM.add(new DataLayout(*TD)); else PM.add(new DataLayout(mod)); // Override default to generate verbose assembly. Target.setAsmVerbosityDefault(true); if (RelaxAll) { if (FileType != TargetMachine::CGFT_ObjectFile) errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj"; else Target.setMCRelaxAll(true); } { formatted_raw_ostream FOS(Out->os()); AnalysisID StartAfterID = 0; AnalysisID StopAfterID = 0; const PassRegistry *PR = PassRegistry::getPassRegistry(); if (!StartAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StartAfter); if (!PI) { errs() << argv[0] << ": start-after pass is not registered.\n"; return 1; } StartAfterID = PI->getTypeInfo(); } if (!StopAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StopAfter); if (!PI) { errs() << argv[0] << ": stop-after pass is not registered.\n"; return 1; } StopAfterID = PI->getTypeInfo(); } // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify, StartAfterID, StopAfterID)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); PM.run(*mod); } // Declare success. Out->keep(); return 0; }
static int compileModule(char **argv, LLVMContext &Context) { // Load the module to be compiled... SMDiagnostic Err; std::unique_ptr<Module> M; Module *mod = 0; Triple TheTriple; bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); // If user just wants to list available options, skip module loading if (!SkipModule) { M = parseIRFile(InputFilename, Err, Context); mod = M.get(); if (mod == 0) { Err.print(argv[0], errs()); return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod->setTargetTriple(Triple::normalize(TargetTriple)); TheTriple = Triple(mod->getTargetTriple()); } else { TheTriple = Triple(Triple::normalize(TargetTriple)); } if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; // Override MArch MArch = "c"; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << argv[0] << ": " << Error; return 1; } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options; Options.LessPreciseFPMADOption = EnableFPMAD; Options.AllowFPOpFusion = FuseFPOps; Options.UnsafeFPMath = EnableUnsafeFPMath; Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; Options.HonorSignDependentRoundingFPMathOption = EnableHonorSignDependentRoundingFPMath; if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; Options.NoZerosInBSS = DontPlaceZerosInBSS; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; Options.StackAlignmentOverride = OverrideStackAlignment; Options.PositionIndependentExecutable = EnablePIE; //Jackson Korba 9/30/14 //OwningPtr<targetMachine> std::unique_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(target.get() && "Could not allocate target machine!"); assert(mod && "Should have exited after outputting help!"); TargetMachine &Target = *target.get(); // Disable .loc support for older OS X versions. if (TheTriple.isMacOSX() && TheTriple.isMacOSXVersionLT(10, 6)){} //TODO: Find a replacement to this function /* Greg Simpson 6-09-13 no member named setMCUseLoc removed statement Target.setMCUseLoc(false); */ //Jackson Korba 9/30/14 std::unique_ptr<tool_output_file> Out (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); if (!Out) return 1; // Build up all of the passes that we want to do to the module. legacy::PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoWrapperPass *TLI = new TargetLibraryInfoWrapperPass(TheTriple); PM.add(TLI); // Add intenal analysis passes from the target machine. PM.add(createTargetTransformInfoWrapperPass(Target.getTargetIRAnalysis())); if (RelaxAll) { if (FileType != TargetMachine::CGFT_ObjectFile) errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj"; } { AnalysisID StartAfterID = 0; AnalysisID StopAfterID = 0; const PassRegistry *PR = PassRegistry::getPassRegistry(); if (!StartAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StartAfter); if (!PI) { errs() << argv[0] << ": start-after pass is not registered.\n"; return 1; } StartAfterID = PI->getTypeInfo(); } if (!StopAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StopAfter); if (!PI) { errs() << argv[0] << ": stop-after pass is not registered.\n"; return 1; } StopAfterID = PI->getTypeInfo(); } // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(PM, Out->os(), FileType, NoVerify, StartAfterID, StopAfterID)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); PM.run(*mod); } // Declare success. Out->keep(); return 0; }
// takes the running content that has collected in the shadow module and dump it to disk // this builds the object file portion of the sysimage files for fast startup static void jl_dump_shadow(char *fname, int jit_model, const char *sysimg_data, size_t sysimg_len, bool dump_as_bc) { #ifdef LLVM36 std::error_code err; StringRef fname_ref = StringRef(fname); raw_fd_ostream OS(fname_ref, err, sys::fs::F_None); #elif defined(LLVM35) std::string err; raw_fd_ostream OS(fname, err, sys::fs::F_None); #else std::string err; raw_fd_ostream OS(fname, err); #endif #ifdef LLVM37 // 3.7 simplified formatted output; just use the raw stream alone raw_fd_ostream& FOS(OS); #else formatted_raw_ostream FOS(OS); #endif // We don't want to use MCJIT's target machine because // it uses the large code model and we may potentially // want less optimizations there. Triple TheTriple = Triple(jl_TargetMachine->getTargetTriple()); #if defined(_OS_WINDOWS_) && defined(FORCE_ELF) #ifdef LLVM35 TheTriple.setObjectFormat(Triple::COFF); #else TheTriple.setEnvironment(Triple::UnknownEnvironment); #endif #elif defined(_OS_DARWIN_) && defined(FORCE_ELF) #ifdef LLVM35 TheTriple.setObjectFormat(Triple::MachO); #else TheTriple.setEnvironment(Triple::MachO); #endif #endif #ifdef LLVM35 std::unique_ptr<TargetMachine> #else OwningPtr<TargetMachine> #endif TM(jl_TargetMachine->getTarget().createTargetMachine( TheTriple.getTriple(), jl_TargetMachine->getTargetCPU(), jl_TargetMachine->getTargetFeatureString(), jl_TargetMachine->Options, #if defined(_OS_LINUX_) || defined(_OS_FREEBSD_) Reloc::PIC_, #else jit_model ? Reloc::PIC_ : Reloc::Default, #endif jit_model ? CodeModel::JITDefault : CodeModel::Default, CodeGenOpt::Aggressive // -O3 TODO: respect command -O0 flag? )); #ifdef LLVM38 legacy::PassManager PM; #else PassManager PM; #endif #ifndef LLVM37 PM.add(new TargetLibraryInfo(Triple(TM->getTargetTriple()))); #else PM.add(new TargetLibraryInfoWrapperPass(Triple(TM->getTargetTriple()))); #endif // set up optimization passes #ifdef LLVM37 // No DataLayout pass needed anymore. #elif defined(LLVM36) PM.add(new DataLayoutPass()); #elif defined(LLVM35) PM.add(new DataLayoutPass(*jl_ExecutionEngine->getDataLayout())); #else PM.add(new DataLayout(*jl_ExecutionEngine->getDataLayout())); #endif addOptimizationPasses(&PM); if (!dump_as_bc) { if (TM->addPassesToEmitFile(PM, FOS, TargetMachine::CGFT_ObjectFile, false)) { jl_error("Could not generate obj file for this target"); } } // now copy the module, since PM.run may modify it ValueToValueMapTy VMap; #ifdef LLVM38 Module *clone = CloneModule(shadow_output, VMap).release(); #else Module *clone = CloneModule(shadow_output, VMap); #endif #ifdef LLVM37 // Reset the target triple to make sure it matches the new target machine clone->setTargetTriple(TM->getTargetTriple().str()); #ifdef LLVM38 clone->setDataLayout(TM->createDataLayout()); #else clone->setDataLayout(TM->getDataLayout()->getStringRepresentation()); #endif #endif // add metadata information jl_gen_llvm_globaldata(clone, VMap, sysimg_data, sysimg_len); // do the actual work PM.run(*clone); if (dump_as_bc) WriteBitcodeToFile(clone, FOS); delete clone; }
bool llvm::dwarf::utils::isConfigurationSupported(Triple &T) { initLLVMIfNeeded(); std::string Err; return TargetRegistry::lookupTarget(T.getTriple(), Err); }
static int compileModule(char **argv, LLVMContext &Context) { // Load the module to be compiled... SMDiagnostic Err; std::unique_ptr<Module> M; Module *mod = nullptr; Triple TheTriple; bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); // If user asked for the 'native' CPU, autodetect here. If autodection fails, // this will set the CPU to an empty string which tells the target to // pick a basic default. if (MCPU == "native") MCPU = sys::getHostCPUName(); // If user just wants to list available options, skip module loading if (!SkipModule) { M = parseIRFile(InputFilename, Err, Context); mod = M.get(); if (mod == nullptr) { Err.print(argv[0], errs()); return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod->setTargetTriple(Triple::normalize(TargetTriple)); TheTriple = Triple(mod->getTargetTriple()); } else { TheTriple = Triple(Triple::normalize(TargetTriple)); } if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << argv[0] << ": " << Error; return 1; } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); Options.DisableIntegratedAS = NoIntegratedAssembler; Options.MCOptions.ShowMCEncoding = ShowMCEncoding; Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory; Options.MCOptions.AsmVerbose = AsmVerbose; std::unique_ptr<TargetMachine> target( TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(target.get() && "Could not allocate target machine!"); // If we don't have a module then just exit now. We do this down // here since the CPU/Feature help is underneath the target machine // creation. if (SkipModule) return 0; assert(mod && "Should have exited if we didn't have a module!"); TargetMachine &Target = *target.get(); if (GenerateSoftFloatCalls) FloatABIForCalls = FloatABI::Soft; // Figure out where we are going to send the output. std::unique_ptr<tool_output_file> Out( GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); if (!Out) return 1; // Build up all of the passes that we want to do to the module. PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple); if (DisableSimplifyLibCalls) TLI->disableAllFunctions(); PM.add(TLI); // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *DL = Target.getSubtargetImpl()->getDataLayout()) mod->setDataLayout(DL); PM.add(new DataLayoutPass(mod)); if (RelaxAll.getNumOccurrences() > 0 && FileType != TargetMachine::CGFT_ObjectFile) errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj"; { formatted_raw_ostream FOS(Out->os()); AnalysisID StartAfterID = nullptr; AnalysisID StopAfterID = nullptr; const PassRegistry *PR = PassRegistry::getPassRegistry(); if (!StartAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StartAfter); if (!PI) { errs() << argv[0] << ": start-after pass is not registered.\n"; return 1; } StartAfterID = PI->getTypeInfo(); } if (!StopAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StopAfter); if (!PI) { errs() << argv[0] << ": stop-after pass is not registered.\n"; return 1; } StopAfterID = PI->getTypeInfo(); } // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify, StartAfterID, StopAfterID)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); PM.run(*mod); } // Declare success. Out->keep(); return 0; }
llvm::TargetMachine* BackendPass::CreateTargetMachine(clang::DiagnosticsEngine& Diags, const clang::TargetOptions& TargetOpts, const clang::LangOptions& LangOpts, const clang::CodeGenOptions& CodeGenOpts) { // Create the TargetMachine for generating code. unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel) .Case("small", llvm::CodeModel::Small) .Case("kernel", llvm::CodeModel::Kernel) .Case("medium", llvm::CodeModel::Medium) .Case("large", llvm::CodeModel::Large) .Case("default", llvm::CodeModel::Default) .Default(~0u); assert(CodeModel != ~0u && "invalid code model!"); llvm::CodeModel::Model CM = static_cast<llvm::CodeModel::Model>(CodeModel); SmallVector<const char *, 16> BackendArgs; BackendArgs.push_back("cling"); // 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, BackendArgs.data()); 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; if (CodeGenOpts.DisableIntegratedAS) Options.DisableIntegratedAS = true; // Set frame pointer elimination mode. if (!CodeGenOpts.DisableFPElim) { Options.NoFramePointerElim = false; } else if (CodeGenOpts.OmitLeafFramePointer) { Options.NoFramePointerElim = false; } else { Options.NoFramePointerElim = true; } if (CodeGenOpts.UseInitArray) Options.UseInitArray = 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; } // Set FP fusion mode. switch (CodeGenOpts.getFPContractMode()) { case CodeGenOptions::FPC_Off: Options.AllowFPOpFusion = llvm::FPOpFusion::Strict; break; case CodeGenOptions::FPC_On: Options.AllowFPOpFusion = llvm::FPOpFusion::Standard; break; case CodeGenOptions::FPC_Fast: Options.AllowFPOpFusion = llvm::FPOpFusion::Fast; break; } 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.DisableTailCalls = CodeGenOpts.DisableTailCalls; Options.TrapFuncName = CodeGenOpts.TrapFuncName; Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; Options.FunctionSections = CodeGenOpts.FunctionSections; Options.DataSections = CodeGenOpts.DataSections; Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm; Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; Triple TheTriple; TheTriple.setTriple(sys::getProcessTriple()); std::string Error; const Target* TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error); if (!TheTarget) { Diags.Report(diag::err_fe_unable_to_create_target) << Error; return 0; } TargetMachine *TM = TheTarget->createTargetMachine(TheTriple.getTriple(), TargetOpts.CPU, FeaturesStr, Options, RM, CM, OptLevel); return TM; }
static void compile(Module &m, string outputPath) { string err; Triple triple = Triple(m.getTargetTriple()); Target const *target = TargetRegistry::lookupTarget(MArch, triple, err); if (!target) { report_fatal_error("Unable to find target:\n " + err); } CodeGenOpt::Level level = CodeGenOpt::Default; switch (optLevel) { default: report_fatal_error("Invalid optimization level.\n"); // No fall through case '0': level = CodeGenOpt::None; break; case '1': level = CodeGenOpt::Less; break; case '2': level = CodeGenOpt::Default; break; case '3': level = CodeGenOpt::Aggressive; break; } string FeaturesStr; TargetOptions options = InitTargetOptionsFromCodeGenFlags(); unique_ptr<TargetMachine> machine(target->createTargetMachine(triple.getTriple(), MCPU, FeaturesStr, options, RelocModel, CMModel, level)); assert(machine.get() && "Could not allocate target machine!"); if (FloatABIForCalls != FloatABI::Default) { options.FloatABIType = FloatABIForCalls; } std::error_code errc; auto out = std::make_unique<tool_output_file>(outputPath.c_str(), errc, sys::fs::F_None); if (!out) { report_fatal_error("Unable to create file:\n " + errc.message()); } // Build up all of the passes that we want to do to the module. legacy::PassManager pm; // Add target specific info and transforms TargetLibraryInfoImpl tlii(Triple(m.getTargetTriple())); pm.add(new TargetLibraryInfoWrapperPass(tlii)); m.setDataLayout(machine->createDataLayout()); { // Bound this scope raw_pwrite_stream *os(&out->os()); FileType = TargetMachine::CGFT_ObjectFile; std::unique_ptr<buffer_ostream> bos; if (!out->os().supportsSeeking()) { bos = std::make_unique<buffer_ostream>(*os); os = bos.get(); } // Ask the target to add backend passes as necessary. if (machine->addPassesToEmitFile(pm, *os, FileType)) { report_fatal_error("target does not support generation " "of this file type!\n"); } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); pm.run(m); } // Keep the output binary if we've been successful to this point. out->keep(); }
void jl_dump_native(const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname, const char *sysimg_data, size_t sysimg_len) { JL_TIMING(NATIVE_DUMP); // We don't want to use MCJIT's target machine because // it uses the large code model and we may potentially // want less optimizations there. Triple TheTriple = Triple(jl_TargetMachine->getTargetTriple()); // make sure to emit the native object format, even if FORCE_ELF was set in codegen #if defined(_OS_WINDOWS_) TheTriple.setObjectFormat(Triple::COFF); #elif defined(_OS_DARWIN_) TheTriple.setObjectFormat(Triple::MachO); TheTriple.setOS(llvm::Triple::MacOSX); #endif std::unique_ptr<TargetMachine> TM(jl_TargetMachine->getTarget().createTargetMachine( TheTriple.getTriple(), jl_TargetMachine->getTargetCPU(), jl_TargetMachine->getTargetFeatureString(), jl_TargetMachine->Options, #if defined(_OS_LINUX_) || defined(_OS_FREEBSD_) Reloc::PIC_, #else Optional<Reloc::Model>(), #endif #if defined(_CPU_PPC_) || defined(_CPU_PPC64_) // On PPC the small model is limited to 16bit offsets CodeModel::Medium, #else // Use small model so that we can use signed 32bits offset in the function and GV tables CodeModel::Small, #endif CodeGenOpt::Aggressive // -O3 TODO: respect command -O0 flag? )); legacy::PassManager PM; addTargetPasses(&PM, TM.get()); // set up optimization passes SmallVector<char, 128> bc_Buffer; SmallVector<char, 128> obj_Buffer; SmallVector<char, 128> unopt_bc_Buffer; raw_svector_ostream bc_OS(bc_Buffer); raw_svector_ostream obj_OS(obj_Buffer); raw_svector_ostream unopt_bc_OS(unopt_bc_Buffer); std::vector<NewArchiveMember> bc_Archive; std::vector<NewArchiveMember> obj_Archive; std::vector<NewArchiveMember> unopt_bc_Archive; std::vector<std::string> outputs; if (unopt_bc_fname) PM.add(createBitcodeWriterPass(unopt_bc_OS)); if (bc_fname || obj_fname) addOptimizationPasses(&PM, jl_options.opt_level, true); if (bc_fname) PM.add(createBitcodeWriterPass(bc_OS)); if (obj_fname) if (TM->addPassesToEmitFile(PM, obj_OS, TargetMachine::CGFT_ObjectFile, false)) jl_safe_printf("ERROR: target does not support generation of object files\n"); // Reset the target triple to make sure it matches the new target machine shadow_output->setTargetTriple(TM->getTargetTriple().str()); #if JL_LLVM_VERSION >= 40000 DataLayout DL = TM->createDataLayout(); DL.reset(DL.getStringRepresentation() + "-ni:10:11:12"); shadow_output->setDataLayout(DL); #else shadow_output->setDataLayout(TM->createDataLayout()); #endif // add metadata information if (imaging_mode) { emit_offset_table(shadow_output, jl_sysimg_gvars, "jl_sysimg_gvars"); emit_offset_table(shadow_output, jl_sysimg_fvars, "jl_sysimg_fvars"); // reflect the address of the jl_RTLD_DEFAULT_handle variable // back to the caller, so that we can check for consistency issues GlobalValue *jlRTLD_DEFAULT_var = shadow_output->getNamedValue("jl_RTLD_DEFAULT_handle"); addComdat(new GlobalVariable(*shadow_output, jlRTLD_DEFAULT_var->getType(), true, GlobalVariable::ExternalLinkage, jlRTLD_DEFAULT_var, "jl_RTLD_DEFAULT_handle_pointer")); } // do the actual work auto add_output = [&] (Module &M, StringRef unopt_bc_Name, StringRef bc_Name, StringRef obj_Name) { PM.run(M); if (unopt_bc_fname) emit_result(unopt_bc_Archive, unopt_bc_Buffer, unopt_bc_Name, outputs); if (bc_fname) emit_result(bc_Archive, bc_Buffer, bc_Name, outputs); if (obj_fname) emit_result(obj_Archive, obj_Buffer, obj_Name, outputs); }; add_output(*shadow_output, "unopt.bc", "text.bc", "text.o"); LLVMContext &Context = shadow_output->getContext(); std::unique_ptr<Module> sysimage(new Module("sysimage", Context)); sysimage->setTargetTriple(shadow_output->getTargetTriple()); sysimage->setDataLayout(shadow_output->getDataLayout()); addComdat(new GlobalVariable(*sysimage, T_size, true, GlobalVariable::ExternalLinkage, ConstantInt::get(T_size, globalUnique + 1), "jl_globalUnique")); if (sysimg_data) { Constant *data = ConstantDataArray::get(Context, ArrayRef<uint8_t>((const unsigned char*)sysimg_data, sysimg_len)); addComdat(new GlobalVariable(*sysimage, data->getType(), false, GlobalVariable::ExternalLinkage, data, "jl_system_image_data"))->setAlignment(64); Constant *len = ConstantInt::get(T_size, sysimg_len); addComdat(new GlobalVariable(*sysimage, len->getType(), true, GlobalVariable::ExternalLinkage, len, "jl_system_image_size")); } add_output(*sysimage, "data.bc", "data.bc", "data.o"); object::Archive::Kind Kind = getDefaultForHost(TheTriple); if (unopt_bc_fname) handleAllErrors(writeArchive(unopt_bc_fname, unopt_bc_Archive, true, Kind, true, false), reportWriterError); if (bc_fname) handleAllErrors(writeArchive(bc_fname, bc_Archive, true, Kind, true, false), reportWriterError); if (obj_fname) handleAllErrors(writeArchive(obj_fname, obj_Archive, true, Kind, true, false), reportWriterError); imaging_mode = false; }
bool DwarfStreamer::init(Triple TheTriple) { std::string ErrorStr; std::string TripleName; StringRef Context = "dwarf streamer init"; // Get the target. const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); if (!TheTarget) return error(ErrorStr, Context); TripleName = TheTriple.getTriple(); // Create all the MC Objects. MRI.reset(TheTarget->createMCRegInfo(TripleName)); if (!MRI) return error(Twine("no register info for target ") + TripleName, Context); MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName)); if (!MAI) return error("no asm info for target " + TripleName, Context); MOFI.reset(new MCObjectFileInfo); MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get())); MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, *MC); MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); if (!MSTI) return error("no subtarget info for target " + TripleName, Context); MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions); if (!MAB) return error("no asm backend for target " + TripleName, Context); MII.reset(TheTarget->createMCInstrInfo()); if (!MII) return error("no instr info info for target " + TripleName, Context); MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC); if (!MCE) return error("no code emitter for target " + TripleName, Context); switch (Options.FileType) { case OutputFileType::Assembly: { MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(), *MAI, *MII, *MRI); MS = TheTarget->createAsmStreamer( *MC, llvm::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP, std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB), true); break; } case OutputFileType::Object: { MS = TheTarget->createMCObjectStreamer( TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE), *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ false); break; } } if (!MS) return error("no object streamer for target " + TripleName, Context); // Finally create the AsmPrinter we'll use to emit the DIEs. TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), None)); if (!TM) return error("no target machine for target " + TripleName, Context); Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS))); if (!Asm) return error("no asm printer for target " + TripleName, Context); RangesSectionSize = 0; LocSectionSize = 0; LineSectionSize = 0; FrameSectionSize = 0; return true; }
// The following function is adapted from llc.cpp int CompileModule(Module *mod, raw_string_ostream &os, bool emitBRIG, int OptLevel) { // Load the module to be compiled... SMDiagnostic Err; Triple TheTriple; TheTriple = Triple(mod->getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << Error; return 0; } // Package up features to be passed to target/subtarget std::string FeaturesStr; CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { case 0: OLvl = CodeGenOpt::None; break; case 1: OLvl = CodeGenOpt::Less; break; case 2: OLvl = CodeGenOpt::Default; break; case 3: OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options; std::unique_ptr<TargetMachine> target( TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(target.get() && "Could not allocate target machine!"); assert(mod && "Should have exited if we didn't have a module!"); TargetMachine &Target = *target.get(); if (GenerateSoftFloatCalls) FloatABIForCalls = FloatABI::Soft; // Build up all of the passes that we want to do to the module. PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple); if (DisableSimplifyLibCalls) TLI->disableAllFunctions(); PM.add(TLI); // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *DL = Target.getSubtargetImpl()->getDataLayout()) mod->setDataLayout(DL); PM.add(new DataLayoutPass()); auto FileType = (emitBRIG ? TargetMachine::CGFT_ObjectFile : TargetMachine::CGFT_AssemblyFile); formatted_raw_ostream FOS(os); // Ask the target to add backend passes as necessary. bool Verify = false; if (Target.addPassesToEmitFile(PM, FOS, FileType, Verify)) { errs() << "target does not support generation of this" << " file type!\n"; return 0; } PM.run(*mod); return 1; }