void CodeGen::initTargetMachine() { TripleStr = M->getTargetTriple(); Triple TheTriple(TripleStr); std::string ErrMsg; TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg); if (!TheTarget) message(LDPL_FATAL, "Target not found: %s", ErrMsg.c_str()); SubtargetFeatures Features = getFeatures(TheTriple); FeaturesString = Features.getString(); Options = InitTargetOptionsFromCodeGenFlags(); TM = createTargetMachine(); }
int main(int argc, char **argv) { // The command line is unusual compared to other fuzzers due to the need to // specify the target. Options like -triple, -mcpu, and -mattr work like // their counterparts in llvm-mc, while -fuzzer-args collects options for the // fuzzer itself. // // Examples: // // Fuzz the big-endian MIPS32R6 disassembler using 100,000 inputs of up to // 4-bytes each and use the contents of ./corpus as the test corpus: // llvm-mc-fuzzer -triple mips-linux-gnu -mcpu=mips32r6 -disassemble \ // -fuzzer-args -max_len=4 -runs=100000 ./corpus // // Infinitely fuzz the little-endian MIPS64R2 disassembler with the MSA // feature enabled using up to 64-byte inputs: // llvm-mc-fuzzer -triple mipsel-linux-gnu -mcpu=mips64r2 -mattr=msa \ // -disassemble -fuzzer-args ./corpus // // If your aim is to find instructions that are not tested, then it is // advisable to constrain the maximum input size to a single instruction // using -max_len as in the first example. This results in a test corpus of // individual instructions that test unique paths. Without this constraint, // there will be considerable redundancy in the corpus. LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllDisassemblers(); cl::ParseCommandLineOptions(argc, argv); // Package up features to be passed to target/subtarget // We have to pass it via a global since the callback doesn't // permit any user data. if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } if (Action == AC_Assemble) errs() << "error: -assemble is not implemented\n"; else if (Action == AC_Disassemble) return fuzzer::FuzzerDriver(argc, argv, DisassembleOneInput); llvm_unreachable("Unknown action"); return 1; }
bool LTOCodeGenerator::determineTarget(std::string& errMsg) { if (_target != NULL) return false; std::string TripleStr = _linker.getModule()->getTargetTriple(); if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); // create target machine from info for merged modules const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); if (march == NULL) return true; // The relocation model is actually a static member of TargetMachine and // needs to be set before the TargetMachine is instantiated. Reloc::Model RelocModel = Reloc::Default; switch (_codeModel) { case LTO_CODEGEN_PIC_MODEL_STATIC: RelocModel = Reloc::Static; break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC: RelocModel = Reloc::PIC_; break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: RelocModel = Reloc::DynamicNoPIC; break; } // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(Triple); std::string FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. if (_mCpu.empty() && Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::x86_64) _mCpu = "core2"; else if (Triple.getArch() == llvm::Triple::x86) _mCpu = "yonah"; } TargetOptions Options; LTOModule::getTargetOptions(Options); _target = march->createTargetMachine(TripleStr, _mCpu, FeatureStr, Options, RelocModel, CodeModel::Default, CodeGenOpt::Aggressive); return false; }
// Returns the TargetMachine instance or zero if no triple is provided. static TargetMachine* GetTargetMachine(Triple TheTriple) { std::string Error; // @LOCALMOD-BEGIN: Some optimization passes like SimplifyCFG do nice // things for code size, but only do it if the TTI says it is okay. // For now, use the ARM TTI for LE32 until we have an LE32 TTI. // https://code.google.com/p/nativeclient/issues/detail?id=2554 if (TheTriple.getArch() == Triple::le32) { TheTriple.setArchName("armv7a"); } // @LOCALMOD-END const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); // Some modules don't specify a triple, and this is okay. if (!TheTarget) { return nullptr; } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size() || MCPU == "native") { SubtargetFeatures Features; // If user asked for the 'native' CPU, we need to autodetect features. // This is necessary for x86 where the CPU might not support all the // features the autodetected CPU name lists in the target. For example, // not all Sandybridge processors support AVX. if (MCPU == "native") { StringMap<bool> HostFeatures; if (sys::getHostCPUFeatures(HostFeatures)) for (auto &F : HostFeatures) Features.AddFeature(F.first(), F.second); } for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } if (MCPU == "native") MCPU = sys::getHostCPUName(); return TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, InitTargetOptionsFromCodeGenFlags(), RelocModel, CMModel, GetCodeGenOptLevel()); }
void CodeGen::initTargetMachine() { const std::string &TripleStr = M->getTargetTriple(); Triple TheTriple(TripleStr); std::string ErrMsg; const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg); if (!TheTarget) message(LDPL_FATAL, "Target not found: %s", ErrMsg.c_str()); SubtargetFeatures Features = getFeatures(TheTriple); TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); CodeGenOpt::Level CGOptLevel = getCGOptLevel(); TM.reset(TheTarget->createTargetMachine( TripleStr, options::mcpu, Features.getString(), Options, RelocationModel, CodeModel::Default, CGOptLevel)); }
ErrorOr<std::unique_ptr<LTOModule>> LTOModule::makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options, LLVMContext &Context, bool ShouldBeLazy) { ErrorOr<std::unique_ptr<Module>> MOrErr = parseBitcodeFileImpl(Buffer, Context, ShouldBeLazy); if (std::error_code EC = MOrErr.getError()) return EC; std::unique_ptr<Module> &M = *MOrErr; std::string TripleStr = M->getTargetTriple(); if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); // find machine architecture for this module std::string errMsg; const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); if (!march) return std::unique_ptr<LTOModule>(nullptr); // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(Triple); std::string FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. std::string CPU; if (Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::x86_64) CPU = "core2"; else if (Triple.getArch() == llvm::Triple::x86) CPU = "yonah"; else if (Triple.getArch() == llvm::Triple::aarch64) CPU = "cyclone"; } TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options, None); M->setDataLayout(target->createDataLayout()); std::unique_ptr<LTOModule> Ret(new LTOModule(std::move(M), Buffer, target)); Ret->parseSymbols(); Ret->parseMetadata(); return std::move(Ret); }
LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, std::string &errMsg) { static bool Initialized = false; if (!Initialized) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmParsers(); Initialized = true; } // parse bitcode buffer OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext(), &errMsg)); if (!m) { delete buffer; return NULL; } std::string Triple = m->getTargetTriple(); if (Triple.empty()) Triple = sys::getDefaultTargetTriple(); // find machine architecture for this module const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); if (!march) return NULL; // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(llvm::Triple(Triple)); std::string FeatureStr = Features.getString(); std::string CPU; TargetOptions Options; getTargetOptions(Options); TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr, Options); LTOModule *Ret = new LTOModule(m.take(), target); if (Ret->parseSymbols(errMsg)) { delete Ret; return NULL; } return Ret; }
LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, TargetOptions options, std::string &errMsg) { // parse bitcode buffer OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext(), &errMsg)); if (!m) { delete buffer; return NULL; } std::string TripleStr = m->getTargetTriple(); if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); // find machine architecture for this module const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); if (!march) return NULL; // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(Triple); std::string FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. std::string CPU; if (Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::x86_64) CPU = "core2"; else if (Triple.getArch() == llvm::Triple::x86) CPU = "yonah"; } TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); LTOModule *Ret = new LTOModule(m.take(), target); if (Ret->parseSymbols(errMsg)) { delete Ret; return NULL; } return Ret; }
LLVMTargetMachineRef LLVMCreateTargetMachine(const char* cpu, const char* triple, const char** feats, size_t nfeats) { // based on LDC code // find target from the given triple and cpu const Target* target = NULL; for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) { #if 0 printf("cpu: %s target: %s\n", cpu, it->getName()); #endif if (strcmp(cpu, it->getName()) == 0) { target = &*it; break; } } assert(target != NULL); // add any features the user might have provided Twine twine; SubtargetFeatures features; //features.setCPU(cpu); for (size_t i = 0; i < nfeats; ++i) { features.AddFeature(feats[i]); twine = twine.concat(features.getString()); } // create machine TargetMachine* targetMachine = target->createTargetMachine(triple, twine.str()); if (!targetMachine) return NULL; return wrap(targetMachine); }
// Returns the TargetMachine instance or zero if no triple is provided. static TargetMachine* GetTargetMachine(Triple TheTriple) { std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); // Some modules don't specify a triple, and this is okay. if (!TheTarget) { return nullptr; } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size() || MCPU == "native") { SubtargetFeatures Features; // If user asked for the 'native' CPU, we need to autodetect features. // This is necessary for x86 where the CPU might not support all the // features the autodetected CPU name lists in the target. For example, // not all Sandybridge processors support AVX. if (MCPU == "native") { StringMap<bool> HostFeatures; if (sys::getHostCPUFeatures(HostFeatures)) for (auto &F : HostFeatures) Features.AddFeature(F.first(), F.second); } for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } if (MCPU == "native") MCPU = sys::getHostCPUName(); return TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, InitTargetOptionsFromCodeGenFlags(), RelocModel, CMModel, GetCodeGenOptLevel()); }
// Returns the TargetMachine instance or zero if no triple is provided. static TargetMachine* GetTargetMachine(Triple TheTriple) { std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); // Some modules don't specify a triple, and this is okay. if (!TheTarget) { return 0; } // 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(); } return TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, GetTargetOptions(), RelocModel, CMModel, GetCodeGenOptLevel()); }
TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { // Create the TargetMachine for generating code. std::string Error; std::string Triple = TheModule->getTargetTriple(); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); if (!TheTarget) { if (MustCreateTM) Diags.Report(diag::err_fe_unable_to_create_target) << Error; return nullptr; } 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("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()); } for (const std::string &BackendOption : CodeGenOpts.BackendOptions) BackendArgs.push_back(BackendOption.c_str()); BackendArgs.push_back(nullptr); llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, BackendArgs.data()); std::string FeaturesStr; if (!TargetOpts.Features.empty()) { SubtargetFeatures Features; for (const std::string &Feature : TargetOpts.Features) Features.AddFeature(Feature); 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 (!TargetOpts.Reciprocals.empty()) Options.Reciprocals = TargetRecip(TargetOpts.Reciprocals); Options.ThreadModel = llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel) .Case("posix", llvm::ThreadModel::POSIX) .Case("single", llvm::ThreadModel::Single); if (CodeGenOpts.DisableIntegratedAS) Options.DisableIntegratedAS = true; if (CodeGenOpts.CompressDebugSections) Options.CompressDebugSections = 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.StackAlignmentOverride = CodeGenOpts.StackAlignment; Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; Options.FunctionSections = CodeGenOpts.FunctionSections; Options.DataSections = CodeGenOpts.DataSections; Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames; Options.EmulatedTLS = CodeGenOpts.EmulatedTLS; Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm; Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings; Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; Options.MCOptions.ABIName = TargetOpts.ABI; TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, Options, RM, CM, OptLevel); return TM; }
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; }
/// ToggleFeature - Toggle a feature and returns the re-computed feature /// bits. This version will also change all implied bits. uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) { SubtargetFeatures Features; FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures, NumFeatures); return FeatureBits; }
static void codegen(std::unique_ptr<Module> M) { const std::string &TripleStr = M->getTargetTriple(); Triple TheTriple(TripleStr); std::string ErrMsg; const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg); if (!TheTarget) message(LDPL_FATAL, "Target not found: %s", ErrMsg.c_str()); if (unsigned NumOpts = options::extra.size()) cl::ParseCommandLineOptions(NumOpts, &options::extra[0]); SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(TheTriple); for (const std::string &A : MAttrs) Features.AddFeature(A); TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); CodeGenOpt::Level CGOptLevel; switch (options::OptLevel) { case 0: CGOptLevel = CodeGenOpt::None; break; case 1: CGOptLevel = CodeGenOpt::Less; break; case 2: CGOptLevel = CodeGenOpt::Default; break; case 3: CGOptLevel = CodeGenOpt::Aggressive; break; } std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine( TripleStr, options::mcpu, Features.getString(), Options, RelocationModel, CodeModel::Default, CGOptLevel)); runLTOPasses(*M, *TM); if (options::TheOutputType == options::OT_SAVE_TEMPS) saveBCFile(output_name + ".opt.bc", *M); SmallString<128> Filename; if (!options::obj_path.empty()) Filename = options::obj_path; else if (options::TheOutputType == options::OT_SAVE_TEMPS) Filename = output_name + ".o"; std::vector<SmallString<128>> Filenames(options::Parallelism); bool TempOutFile = Filename.empty(); { // Open a file descriptor for each backend thread. This is done in a block // so that the output file descriptors are closed before gold opens them. std::list<llvm::raw_fd_ostream> OSs; std::vector<llvm::raw_pwrite_stream *> OSPtrs(options::Parallelism); for (unsigned I = 0; I != options::Parallelism; ++I) { int FD; if (TempOutFile) { std::error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filenames[I]); if (EC) message(LDPL_FATAL, "Could not create temporary file: %s", EC.message().c_str()); } else { Filenames[I] = Filename; if (options::Parallelism != 1) Filenames[I] += utostr(I); std::error_code EC = sys::fs::openFileForWrite(Filenames[I], FD, sys::fs::F_None); if (EC) message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str()); } OSs.emplace_back(FD, true); OSPtrs[I] = &OSs.back(); } // Run backend threads. splitCodeGen(std::move(M), OSPtrs, options::mcpu, Features.getString(), Options, RelocationModel, CodeModel::Default, CGOptLevel); } for (auto &Filename : Filenames) { if (add_input_file(Filename.c_str()) != LDPS_OK) message(LDPL_FATAL, "Unable to add .o file to the link. File left behind in: %s", Filename.c_str()); if (TempOutFile) Cleanup.push_back(Filename.c_str()); } }
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; }
static void codegen(Module &M) { const std::string &TripleStr = M.getTargetTriple(); Triple TheTriple(TripleStr); std::string ErrMsg; const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg); if (!TheTarget) message(LDPL_FATAL, "Target not found: %s", ErrMsg.c_str()); if (unsigned NumOpts = options::extra.size()) cl::ParseCommandLineOptions(NumOpts, &options::extra[0]); SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(TheTriple); for (const std::string &A : MAttrs) Features.AddFeature(A); TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine( TripleStr, options::mcpu, Features.getString(), Options, RelocationModel, CodeModel::Default, CodeGenOpt::Aggressive)); runLTOPasses(M, *TM); PassManager CodeGenPasses; CodeGenPasses.add(new DataLayoutPass()); SmallString<128> Filename; int FD; if (options::obj_path.empty()) { std::error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); if (EC) message(LDPL_FATAL, "Could not create temorary file: %s", EC.message().c_str()); } else { Filename = options::obj_path; std::error_code EC = sys::fs::openFileForWrite(Filename.c_str(), FD, sys::fs::F_None); if (EC) message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str()); } { raw_fd_ostream OS(FD, true); formatted_raw_ostream FOS(OS); if (TM->addPassesToEmitFile(CodeGenPasses, FOS, TargetMachine::CGFT_ObjectFile)) message(LDPL_FATAL, "Failed to setup codegen"); CodeGenPasses.run(M); } if (add_input_file(Filename.c_str()) != LDPS_OK) message(LDPL_FATAL, "Unable to add .o file to the link. File left behind in: %s", Filename.c_str()); if (options::obj_path.empty()) Cleanup.push_back(Filename.c_str()); }
/// selectTarget - Pick a target either via -march or by guessing the native /// arch. Add any CPU features specified via -mcpu or -mattr. TargetMachine *MCJIT::selectTarget(Module *Mod, StringRef MArch, StringRef MCPU, const SmallVectorImpl<std::string>& MAttrs, std::string *ErrorStr) { Triple TheTriple(Mod->getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getHostTriple()); // Adjust the triple to match what the user requested. const Target *TheTarget = 0; if (!MArch.empty()) { for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) { if (MArch == it->getName()) { TheTarget = &*it; break; } } if (!TheTarget) { *ErrorStr = "No available targets are compatible with this -march, " "see -version for the available targets.\n"; return 0; } // Adjust the triple to match (if known), otherwise stick with the // module/host triple. Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); if (Type != Triple::UnknownArch) TheTriple.setArch(Type); } else { std::string Error; TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error); if (TheTarget == 0) { if (ErrorStr) *ErrorStr = Error; return 0; } } if (!TheTarget->hasJIT()) { errs() << "WARNING: This target JIT is not designed for the host you are" << " running. If bad things happen, please choose a different " << "-march switch.\n"; } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (!MCPU.empty() || !MAttrs.empty()) { SubtargetFeatures Features; Features.setCPU(MCPU); for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } // Allocate a target... TargetMachine *Target = TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr); assert(Target && "Could not allocate target machine!"); return Target; }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); TripleName = Triple::normalize(TripleName); setDwarfDebugFlags(argc, argv); setDwarfDebugProducer(); const char *ProgName = argv[0]; const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) return 1; std::unique_ptr<MemoryBuffer> BufferPtr; if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) { errs() << ProgName << ": " << ec.message() << '\n'; return 1; } MemoryBuffer *Buffer = BufferPtr.release(); SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(IncludeDirs); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); assert(MAI && "Unable to create target asm info!"); if (CompressDebugSections) { if (!zlib::isAvailable()) { errs() << ProgName << ": build tools with zlib to enable -compress-debug-sections"; return 1; } MAI->setCompressDebugSections(true); } // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx); if (SaveTempLabels) Ctx.setAllowTemporaryLabels(false); Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); if (DwarfVersion < 2 || DwarfVersion > 4) { errs() << ProgName << ": Dwarf version " << DwarfVersion << " is not supported." << '\n'; return 1; } Ctx.setDwarfVersion(DwarfVersion); if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DwarfDebugProducer.empty()) Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer)); if (!DebugCompilationDir.empty()) Ctx.setCompilationDir(DebugCompilationDir); if (!MainFileName.empty()) Ctx.setMainFileName(MainFileName); // 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(); } std::unique_ptr<tool_output_file> Out(GetOutputStream()); if (!Out) return 1; formatted_raw_ostream FOS(Out->os()); std::unique_ptr<MCStreamer> Str; std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); MCInstPrinter *IP = nullptr; if (FileType == OFT_AssemblyFile) { IP = TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI); // Set the display preference for hex vs. decimal immediates. IP->setPrintImmHex(PrintImmHex); // Set up the AsmStreamer. MCCodeEmitter *CE = nullptr; MCAsmBackend *MAB = nullptr; if (ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); } Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst)); } else if (FileType == OFT_Null) { Str.reset(createNullStreamer(Ctx)); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, FOS, CE, *STI, RelaxAll, NoExecStack)); } int Res = 1; bool disassemble = false; switch (Action) { case AC_AsLex: Res = AsLexInput(SrcMgr, *MAI, Out.get()); break; case AC_Assemble: Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII); break; case AC_MDisassemble: assert(IP && "Expected assembly output"); IP->setUseMarkup(1); disassemble = true; break; case AC_Disassemble: disassemble = true; break; } if (disassemble) Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer, SrcMgr, Out->os()); // Keep output if no errors. if (Res == 0) Out->keep(); return Res; }
static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF) { const Target *TheTarget = GetTarget(MachOOF); if (!TheTarget) { // GetTarget prints out stuff. return; } std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo()); std::unique_ptr<MCInstrAnalysis> InstrAnalysis( TheTarget->createMCInstrAnalysis(InstrInfo.get())); // 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(); } // Set up disassembler. std::unique_ptr<const MCRegisterInfo> MRI( TheTarget->createMCRegInfo(TripleName)); std::unique_ptr<const MCAsmInfo> AsmInfo( TheTarget->createMCAsmInfo(*MRI, TripleName)); std::unique_ptr<const MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr); std::unique_ptr<const MCDisassembler> DisAsm( TheTarget->createMCDisassembler(*STI, Ctx)); int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI)); if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) { errs() << "error: couldn't initialize disassembler for target " << TripleName << '\n'; return; } outs() << '\n' << Filename << ":\n\n"; MachO::mach_header Header = MachOOF->getHeader(); // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to // determine function locations will eventually go in MCObjectDisassembler. // FIXME: Using the -cfg command line option, this code used to be able to // annotate relocations with the referenced symbol's name, and if this was // inside a __[cf]string section, the data it points to. This is now replaced // by the upcoming MCSymbolizer, which needs the appropriate setup done above. std::vector<SectionRef> Sections; std::vector<SymbolRef> Symbols; SmallVector<uint64_t, 8> FoundFns; uint64_t BaseSegmentAddress; getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns, BaseSegmentAddress); // Sort the symbols by address, just in case they didn't come in that way. std::sort(Symbols.begin(), Symbols.end(), SymbolSorter()); // Build a data in code table that is sorted on by the address of each entry. uint64_t BaseAddress = 0; if (Header.filetype == MachO::MH_OBJECT) Sections[0].getAddress(BaseAddress); else BaseAddress = BaseSegmentAddress; DiceTable Dices; for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices(); DI != DE; ++DI) { uint32_t Offset; DI->getOffset(Offset); Dices.push_back(std::make_pair(BaseAddress + Offset, *DI)); } array_pod_sort(Dices.begin(), Dices.end()); #ifndef NDEBUG raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); #else raw_ostream &DebugOut = nulls(); #endif std::unique_ptr<DIContext> diContext; ObjectFile *DbgObj = MachOOF; // Try to find debug info and set up the DIContext for it. if (UseDbg) { // A separate DSym file path was specified, parse it as a macho file, // get the sections and supply it to the section name parsing machinery. if (!DSYMFile.empty()) { ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFileOrSTDIN(DSYMFile); if (std::error_code EC = Buf.getError()) { errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n'; return; } DbgObj = ObjectFile::createMachOObjectFile(Buf.get()).get().release(); } // Setup the DIContext diContext.reset(DIContext::getDWARFContext(*DbgObj)); } for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { bool SectIsText = false; Sections[SectIdx].isText(SectIsText); if (SectIsText == false) continue; StringRef SectName; if (Sections[SectIdx].getName(SectName) || SectName != "__text") continue; // Skip non-text sections DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl(); StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR); if (SegmentName != "__TEXT") continue; StringRef Bytes; Sections[SectIdx].getContents(Bytes); StringRefMemoryObject memoryObject(Bytes); bool symbolTableWorked = false; // Parse relocations. std::vector<std::pair<uint64_t, SymbolRef>> Relocs; for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) { uint64_t RelocOffset, SectionAddress; Reloc.getOffset(RelocOffset); Sections[SectIdx].getAddress(SectionAddress); RelocOffset -= SectionAddress; symbol_iterator RelocSym = Reloc.getSymbol(); Relocs.push_back(std::make_pair(RelocOffset, *RelocSym)); } array_pod_sort(Relocs.begin(), Relocs.end()); // Disassemble symbol by symbol. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { StringRef SymName; Symbols[SymIdx].getName(SymName); SymbolRef::Type ST; Symbols[SymIdx].getType(ST); if (ST != SymbolRef::ST_Function) continue; // Make sure the symbol is defined in this section. bool containsSym = false; Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym); if (!containsSym) continue; // Start at the address of the symbol relative to the section's address. uint64_t SectionAddress = 0; uint64_t Start = 0; Sections[SectIdx].getAddress(SectionAddress); Symbols[SymIdx].getAddress(Start); Start -= SectionAddress; // Stop disassembling either at the beginning of the next symbol or at // the end of the section. bool containsNextSym = false; uint64_t NextSym = 0; uint64_t NextSymIdx = SymIdx+1; while (Symbols.size() > NextSymIdx) { SymbolRef::Type NextSymType; Symbols[NextSymIdx].getType(NextSymType); if (NextSymType == SymbolRef::ST_Function) { Sections[SectIdx].containsSymbol(Symbols[NextSymIdx], containsNextSym); Symbols[NextSymIdx].getAddress(NextSym); NextSym -= SectionAddress; break; } ++NextSymIdx; } uint64_t SectSize; Sections[SectIdx].getSize(SectSize); uint64_t End = containsNextSym ? NextSym : SectSize; uint64_t Size; symbolTableWorked = true; outs() << SymName << ":\n"; DILineInfo lastLine; for (uint64_t Index = Start; Index < End; Index += Size) { MCInst Inst; uint64_t SectAddress = 0; Sections[SectIdx].getAddress(SectAddress); outs() << format("%8" PRIx64 ":\t", SectAddress + Index); // Check the data in code table here to see if this is data not an // instruction to be disassembled. DiceTable Dice; Dice.push_back(std::make_pair(SectAddress + Index, DiceRef())); dice_table_iterator DTI = std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(), compareDiceTableEntries); if (DTI != Dices.end()){ uint16_t Length; DTI->second.getLength(Length); DumpBytes(StringRef(Bytes.data() + Index, Length)); uint16_t Kind; DTI->second.getKind(Kind); DumpDataInCode(Bytes.data() + Index, Length, Kind); continue; } if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut, nulls())) { DumpBytes(StringRef(Bytes.data() + Index, Size)); IP->printInst(&Inst, outs(), ""); // Print debug info. if (diContext) { DILineInfo dli = diContext->getLineInfoForAddress(SectAddress + Index); // Print valid line info if it changed. if (dli != lastLine && dli.Line != 0) outs() << "\t## " << dli.FileName << ':' << dli.Line << ':' << dli.Column; lastLine = dli; } outs() << "\n"; } else { errs() << "llvm-objdump: warning: invalid instruction encoding\n"; if (Size == 0) Size = 1; // skip illegible bytes } } } if (!symbolTableWorked) { // Reading the symbol table didn't work, disassemble the whole section. uint64_t SectAddress; Sections[SectIdx].getAddress(SectAddress); uint64_t SectSize; Sections[SectIdx].getSize(SectSize); uint64_t InstSize; for (uint64_t Index = 0; Index < SectSize; Index += InstSize) { MCInst Inst; if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index, DebugOut, nulls())) { outs() << format("%8" PRIx64 ":\t", SectAddress + Index); DumpBytes(StringRef(Bytes.data() + Index, InstSize)); IP->printInst(&Inst, outs(), ""); outs() << "\n"; } else { errs() << "llvm-objdump: warning: invalid instruction encoding\n"; if (InstSize == 0) InstSize = 1; // skip illegible bytes } } } } }
#endif ) { // GC safe // Get the host information std::string TripleName = sys::getDefaultTargetTriple(); Triple TheTriple(Triple::normalize(TripleName)); std::string MCPU = sys::getHostCPUName(); #ifdef _CPU_ARM_ // The Raspberry Pi CPU is misdetected by LLVM (at least of version // 3.6); correct this. if (MCPU == "arm1176jz-s") MCPU = "arm1176jzf-s"; #endif SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(TheTriple); std::string err; const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, err); // Set up required helpers and streamer #ifdef LLVM35 std::unique_ptr<MCStreamer> Streamer; #else OwningPtr<MCStreamer> Streamer; #endif SourceMgr SrcMgr; #ifdef LLVM35 std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName));
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets first, so that --version shows registered targets. InitializeAllTargets(); InitializeAllAsmPrinters(); cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); // Load the module to be compiled... SMDiagnostic Err; std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.Print(argv[0], errs()); return 1; } Module &mod = *M.get(); // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod.setTargetTriple(TargetTriple); Triple TheTriple(mod.getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getHostTriple()); // Allocate target machine. First, check whether the user has explicitly // specified an architecture to compile for. If so we have to look it up by // name, because it might be a backend that has no mapping to a target triple. const Target *TheTarget = 0; if (!MArch.empty()) { for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) { if (MArch == it->getName()) { TheTarget = &*it; break; } } if (!TheTarget) { errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n"; return 1; } // Adjust the triple to match (if known), otherwise stick with the // module/host triple. Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); if (Type != Triple::UnknownArch) TheTriple.setArch(Type); } else { std::string Err; TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); if (TheTarget == 0) { errs() << argv[0] << ": error auto-selecting target for module '" << Err << "'. Please use the -march option to explicitly " << "pick a target.\n"; return 1; } } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MCPU.size() || MAttrs.size()) { SubtargetFeatures Features; Features.setCPU(MCPU); for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); // Figure out where we are going to send the output... formatted_raw_ostream *Out = GetOutputStream(TheTarget->getName(), argv[0]); if (Out == 0) return 1; 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; } // Request that addPassesToEmitFile run the Verifier after running // passes which modify the IR. #ifndef NDEBUG bool DisableVerify = false; #else bool DisableVerify = true; #endif // If this target requires addPassesToEmitWholeFile, do it now. This is // used by strange things like the C backend. if (Target.WantsWholeFile()) { PassManager PM; // Add the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) PM.add(new TargetData(*TD)); else PM.add(new TargetData(&mod)); if (!NoVerify) PM.add(createVerifierPass()); // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl, DisableVerify)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &fouts()) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } PM.run(mod); } else { // Build up all of the passes that we want to do to the module. FunctionPassManager Passes(M.get()); // Add the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) Passes.add(new TargetData(*TD)); else Passes.add(new TargetData(&mod)); #ifndef NDEBUG if (!NoVerify) Passes.add(createVerifierPass()); #endif // Override default to generate verbose assembly. Target.setAsmVerbosityDefault(true); if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl, DisableVerify)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &fouts()) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } Passes.doInitialization(); // Run our queue of passes all at once now, efficiently. // TODO: this could lazily stream functions out of the module. for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) if (!I->isDeclaration()) { if (DisableRedZone) I->addFnAttr(Attribute::NoRedZone); if (NoImplicitFloats) I->addFnAttr(Attribute::NoImplicitFloat); Passes.run(*I); } Passes.doFinalization(); } // Delete the ostream if it's not a stdout stream if (Out != &fouts()) delete Out; return 0; }
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets first, so that --version shows registered targets. InitializeAllTargets(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); // Load the module to be compiled... SMDiagnostic Err; std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.Print(argv[0], errs()); return 1; } Module &mod = *M.get(); // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod.setTargetTriple(Triple::normalize(TargetTriple)); Triple TheTriple(mod.getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getHostTriple()); // Allocate target machine. First, check whether the user has explicitly // specified an architecture to compile for. If so we have to look it up by // name, because it might be a backend that has no mapping to a target triple. const Target *TheTarget = 0; if (!MArch.empty()) { for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) { if (MArch == it->getName()) { TheTarget = &*it; break; } } if (!TheTarget) { errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n"; return 1; } // Adjust the triple to match (if known), otherwise stick with the // module/host triple. Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); if (Type != Triple::UnknownArch) TheTriple.setArch(Type); } else { std::string Err; TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); if (TheTarget == 0) { errs() << argv[0] << ": error auto-selecting target for module '" << Err << "'. Please use the -march option to explicitly " << "pick a target.\n"; return 1; } } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MCPU.size() || MAttrs.size()) { SubtargetFeatures Features; Features.setCPU(MCPU); for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); if (DisableDotLoc) Target.setMCUseLoc(false); if (TheTriple.getOS() == Triple::Darwin) { switch (TheTriple.getDarwinMajorNumber()) { case 7: case 8: case 9: // disable .loc support for older darwin OS. Target.setMCUseLoc(false); break; default: break; } } // 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; 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; } // Build up all of the passes that we want to do to the module. PassManager PM; // Add the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) PM.add(new TargetData(*TD)); else PM.add(new TargetData(&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()); // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) { 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; }
TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { // Create the TargetMachine for generating code. std::string Error; std::string Triple = TheModule->getTargetTriple(); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); if (!TheTarget) { if (MustCreateTM) Diags.Report(diag::err_fe_unable_to_create_target) << Error; return 0; } // 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; } SmallVector<const char *, 16> 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, 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; // 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.RealignStack = CodeGenOpts.StackRealignment; Options.DisableTailCalls = CodeGenOpts.DisableTailCalls; Options.TrapFuncName = CodeGenOpts.TrapFuncName; Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks; 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); return TM; }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(argv[0]); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); TripleName = Triple::normalize(TripleName); setDwarfDebugFlags(argc, argv); setDwarfDebugProducer(); const char *ProgName = argv[0]; const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) return 1; // Now that GetTarget() has (potentially) replaced TripleName, it's safe to // construct the Triple object. Triple TheTriple(TripleName); ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr = MemoryBuffer::getFileOrSTDIN(InputFilename); if (std::error_code EC = BufferPtr.getError()) { errs() << InputFilename << ": " << EC.message() << '\n'; return 1; } MemoryBuffer *Buffer = BufferPtr->get(); SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(IncludeDirs); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); assert(MAI && "Unable to create target asm info!"); MAI->setRelaxELFRelocations(RelaxELFRel); if (CompressDebugSections != DebugCompressionType::DCT_None) { if (!zlib::isAvailable()) { errs() << ProgName << ": build tools with zlib to enable -compress-debug-sections"; return 1; } MAI->setCompressDebugSections(CompressDebugSections); } // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. MCObjectFileInfo MOFI; MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr); MOFI.InitMCObjectFileInfo(TheTriple, PIC, CMModel, Ctx); if (SaveTempLabels) Ctx.setAllowTemporaryLabels(false); Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); // Default to 4 for dwarf version. unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4; if (DwarfVersion < 2 || DwarfVersion > 4) { errs() << ProgName << ": Dwarf version " << DwarfVersion << " is not supported." << '\n'; return 1; } Ctx.setDwarfVersion(DwarfVersion); if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DwarfDebugProducer.empty()) Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer)); if (!DebugCompilationDir.empty()) Ctx.setCompilationDir(DebugCompilationDir); else { // If no compilation dir is set, try to use the current directory. SmallString<128> CWD; if (!sys::fs::current_path(CWD)) Ctx.setCompilationDir(CWD); } if (!MainFileName.empty()) Ctx.setMainFileName(MainFileName); // 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(); } std::unique_ptr<tool_output_file> Out = GetOutputStream(); if (!Out) return 1; std::unique_ptr<buffer_ostream> BOS; raw_pwrite_stream *OS = &Out->os(); std::unique_ptr<MCStreamer> Str; std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); MCInstPrinter *IP = nullptr; if (FileType == OFT_AssemblyFile) { IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant, *MAI, *MCII, *MRI); // Set the display preference for hex vs. decimal immediates. IP->setPrintImmHex(PrintImmHex); // Set up the AsmStreamer. MCCodeEmitter *CE = nullptr; MCAsmBackend *MAB = nullptr; if (ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); } auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS); Str.reset(TheTarget->createAsmStreamer( Ctx, std::move(FOut), /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst)); } else if (FileType == OFT_Null) { Str.reset(TheTarget->createNullStreamer(Ctx)); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); // Don't waste memory on names of temp labels. Ctx.setUseNamesOnTempLabels(false); if (!Out->os().supportsSeeking()) { BOS = make_unique<buffer_ostream>(Out->os()); OS = BOS.get(); } MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer( TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ false)); if (NoExecStack) Str->InitSections(true); } int Res = 1; bool disassemble = false; switch (Action) { case AC_AsLex: Res = AsLexInput(SrcMgr, *MAI, Out->os()); break; case AC_Assemble: Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII, MCOptions); break; case AC_MDisassemble: assert(IP && "Expected assembly output"); IP->setUseMarkup(1); disassemble = true; break; case AC_Disassemble: disassemble = true; break; } if (disassemble) Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer, SrcMgr, Out->os()); // Keep output if no errors. if (Res == 0) Out->keep(); return Res; }
LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, TargetOptions options, std::string &errMsg) { // parse bitcode buffer ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(buffer, getGlobalContext()); if (std::error_code EC = ModuleOrErr.getError()) { errMsg = EC.message(); delete buffer; return nullptr; } std::unique_ptr<Module> m(ModuleOrErr.get()); std::string TripleStr = m->getTargetTriple(); if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); // find machine architecture for this module const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); if (!march) return nullptr; // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(Triple); std::string FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. std::string CPU; if (Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::x86_64) CPU = "core2"; else if (Triple.getArch() == llvm::Triple::x86) CPU = "yonah"; else if (Triple.getArch() == llvm::Triple::arm64 || Triple.getArch() == llvm::Triple::aarch64) CPU = "cyclone"; } TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); m->materializeAllPermanently(); LTOModule *Ret = new LTOModule(m.release(), target); // We need a MCContext set up in order to get mangled names of private // symbols. It is a bit odd that we need to report uses and definitions // of private symbols, but it does look like ld64 expects to be informed // of at least the ones with an 'l' prefix. MCContext &Context = Ret->_context; const TargetLoweringObjectFile &TLOF = target->getTargetLowering()->getObjFileLowering(); const_cast<TargetLoweringObjectFile &>(TLOF).Initialize(Context, *target); if (Ret->parseSymbols(errMsg)) { delete Ret; return nullptr; } Ret->parseMetadata(); return Ret; }
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets first, so that --version shows registered targets. InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); // Load the module to be compiled... SMDiagnostic Err; std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.print(argv[0], errs()); return 1; } Module &mod = *M.get(); // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod.setTargetTriple(Triple::normalize(TargetTriple)); // Figure out the target triple. Triple TheTriple(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() << 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.NoExcessFPPrecision = DisableExcessPrecision; 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.DisableJumpTables = DisableSwitchTables; Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; 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 (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 the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) PM.add(new TargetData(*TD)); else PM.add(new TargetData(&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()); // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify)) { 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; }
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; }
static int compileModule(StringRef ProgramName) { // Use a new context instead of the global context for the main module. It must // outlive the module object, declared below. We do this because // lib/CodeGen/PseudoSourceValue.cpp gets a type from the global context and // races with any other use of the context. Rather than doing an invasive // plumbing change to fix it, we work around it by using a new context here // and leaving PseudoSourceValue as the only user of the global context. std::unique_ptr<LLVMContext> MainContext(new LLVMContext()); std::unique_ptr<Module> MainMod; Triple TheTriple; PNaClABIErrorReporter ABIErrorReporter; std::unique_ptr<StreamingMemoryObject> StreamingObject; if (!MainContext) return 1; #if defined(PNACL_BROWSER_TRANSLATOR) StreamingObject.reset( new StreamingMemoryObjectImpl(getNaClBitcodeStreamer())); #else if (LazyBitcode) { std::string StrError; DataStreamer* FileStreamer(getDataFileStreamer(InputFilename, &StrError)); if (!StrError.empty()) { SMDiagnostic Err(InputFilename, SourceMgr::DK_Error, StrError); Err.print(ProgramName.data(), errs()); } if (!FileStreamer) return 1; StreamingObject.reset(new StreamingMemoryObjectImpl(FileStreamer)); } #endif MainMod = getModule(ProgramName, *MainContext.get(), StreamingObject.get()); if (!MainMod) return 1; if (PNaClABIVerify) { // Verify the module (but not the functions yet) std::unique_ptr<ModulePass> VerifyPass( createPNaClABIVerifyModulePass(&ABIErrorReporter, LazyBitcode)); VerifyPass->runOnModule(*MainMod); CheckABIVerifyErrors(ABIErrorReporter, "Module"); VerifyPass.reset(); } // 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(*MainMod); AddPNaClExternalDeclsPass.reset(); if (UserDefinedTriple.empty()) { report_fatal_error("-mtriple must be set to a target triple for pnacl-llc"); } else { MainMod->setTargetTriple(Triple::normalize(UserDefinedTriple)); TheTriple = Triple(MainMod->getTargetTriple()); } // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << ProgramName << ": " << Error; return 1; } TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); Options.DisableIntegratedAS = NoIntegratedAssembler; Options.MCOptions.AsmVerbose = true; if (GenerateSoftFloatCalls) FloatABIForCalls = FloatABI::Soft; // 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() << ProgramName << ": 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; } SmallVector<pthread_t, 4> Pthreads(SplitModuleCount); SmallVector<ThreadData, 4> ThreadDatas(SplitModuleCount); ThreadedFunctionQueue FuncQueue(MainMod.get(), SplitModuleCount); if (SplitModuleCount == 1) { // No need for dynamic scheduling with one thread. SplitModuleSched = SplitModuleStatic; return compileSplitModule(Options, TheTriple, TheTarget, FeaturesStr, OLvl, ProgramName, MainMod.get(), nullptr, 0, &FuncQueue); } for(unsigned ModuleIndex = 0; ModuleIndex < SplitModuleCount; ++ModuleIndex) { ThreadDatas[ModuleIndex].Options = &Options; ThreadDatas[ModuleIndex].TheTriple = &TheTriple; ThreadDatas[ModuleIndex].TheTarget = TheTarget; ThreadDatas[ModuleIndex].FeaturesStr = FeaturesStr; ThreadDatas[ModuleIndex].OLvl = OLvl; ThreadDatas[ModuleIndex].ProgramName = ProgramName.str(); ThreadDatas[ModuleIndex].GlobalModuleRef = MainMod.get(); ThreadDatas[ModuleIndex].StreamingObject = StreamingObject.get(); ThreadDatas[ModuleIndex].ModuleIndex = ModuleIndex; ThreadDatas[ModuleIndex].FuncQueue = &FuncQueue; if (pthread_create(&Pthreads[ModuleIndex], nullptr, runCompileThread, &ThreadDatas[ModuleIndex])) { report_fatal_error("Failed to create thread"); } } for(unsigned ModuleIndex = 0; ModuleIndex < SplitModuleCount; ++ModuleIndex) { void *retval; if (pthread_join(Pthreads[ModuleIndex], &retval)) report_fatal_error("Failed to join thread"); intptr_t ret = reinterpret_cast<intptr_t>(retval); if (ret != 0) report_fatal_error("Thread returned nonzero"); } return 0; }
extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc, char ***argv) { // The command line is unusual compared to other fuzzers due to the need to // specify the target. Options like -triple, -mcpu, and -mattr work like // their counterparts in llvm-mc, while -fuzzer-args collects options for the // fuzzer itself. // // Examples: // // Fuzz the big-endian MIPS32R6 disassembler using 100,000 inputs of up to // 4-bytes each and use the contents of ./corpus as the test corpus: // llvm-mc-fuzzer -triple mips-linux-gnu -mcpu=mips32r6 -disassemble \ // -fuzzer-args -max_len=4 -runs=100000 ./corpus // // Infinitely fuzz the little-endian MIPS64R2 disassembler with the MSA // feature enabled using up to 64-byte inputs: // llvm-mc-fuzzer -triple mipsel-linux-gnu -mcpu=mips64r2 -mattr=msa \ // -disassemble -fuzzer-args ./corpus // // If your aim is to find instructions that are not tested, then it is // advisable to constrain the maximum input size to a single instruction // using -max_len as in the first example. This results in a test corpus of // individual instructions that test unique paths. Without this constraint, // there will be considerable redundancy in the corpus. char **OriginalArgv = *argv; LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllAsmParsers(); cl::ParseCommandLineOptions(*argc, OriginalArgv); // Rebuild the argv without the arguments llvm-mc-fuzzer consumed so that // the driver can parse its arguments. // // FuzzerArgs cannot provide the non-const pointer that OriginalArgv needs. // Re-use the strings from OriginalArgv instead of copying FuzzerArg to a // non-const buffer to avoid the need to clean up when the fuzzer terminates. ModifiedArgv.push_back(OriginalArgv[0]); for (const auto &FuzzerArg : FuzzerArgs) { for (int i = 1; i < *argc; ++i) { if (FuzzerArg == OriginalArgv[i]) ModifiedArgv.push_back(OriginalArgv[i]); } } *argc = ModifiedArgv.size(); *argv = ModifiedArgv.data(); // Package up features to be passed to target/subtarget // We have to pass it via a global since the callback doesn't // permit any user data. if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } if (TripleName.empty()) TripleName = sys::getDefaultTargetTriple(); return 0; }