void StructuredLoopToSelectionReductionOpportunity:: AdaptPhiInstructionsForAddedEdge(uint32_t from_id, BasicBlock* to_block) { to_block->ForEachPhiInst([this, &from_id](Instruction* phi_inst) { // Add to the phi operand an (undef, from_id) pair to reflect the added // edge. auto undef_id = FindOrCreateGlobalUndef(context_, phi_inst->type_id()); phi_inst->AddOperand(Operand(SPV_OPERAND_TYPE_ID, {undef_id})); phi_inst->AddOperand(Operand(SPV_OPERAND_TYPE_ID, {from_id})); }); }
static bool createPlistFile(llvm::StringRef Bin, llvm::StringRef BundleRoot) { if (NoOutput) return true; // Create plist file to write to. llvm::SmallString<128> InfoPlist(BundleRoot); llvm::sys::path::append(InfoPlist, "Contents/Info.plist"); std::error_code EC; llvm::raw_fd_ostream PL(InfoPlist, EC, llvm::sys::fs::F_Text); if (EC) { llvm::errs() << "error: cannot create plist file " << InfoPlist << ": " << EC.message() << '\n'; return false; } CFBundleInfo BI = getBundleInfo(Bin); if (BI.IDStr.empty()) { llvm::StringRef BundleID = *llvm::sys::path::rbegin(BundleRoot); if (llvm::sys::path::extension(BundleRoot) == ".dSYM") BI.IDStr = llvm::sys::path::stem(BundleID); else BI.IDStr = BundleID; } // Print out information to the plist file. PL << "<?xml version=\"1.0\" encoding=\"UTF-8\"\?>\n" << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" " << "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" << "<plist version=\"1.0\">\n" << "\t<dict>\n" << "\t\t<key>CFBundleDevelopmentRegion</key>\n" << "\t\t<string>English</string>\n" << "\t\t<key>CFBundleIdentifier</key>\n" << "\t\t<string>com.apple.xcode.dsym." << BI.IDStr << "</string>\n" << "\t\t<key>CFBundleInfoDictionaryVersion</key>\n" << "\t\t<string>6.0</string>\n" << "\t\t<key>CFBundlePackageType</key>\n" << "\t\t<string>dSYM</string>\n" << "\t\t<key>CFBundleSignature</key>\n" << "\t\t<string>\?\?\?\?</string>\n"; if (!BI.OmitShortVersion()) PL << "\t\t<key>CFBundleShortVersionString</key>\n" << "\t\t<string>" << BI.ShortVersionStr << "</string>\n"; PL << "\t\t<key>CFBundleVersion</key>\n" << "\t\t<string>" << BI.VersionStr << "</string>\n"; if (!Toolchain.empty()) PL << "\t\t<key>Toolchain</key>\n" << "\t\t<string>" << Toolchain << "</string>\n"; PL << "\t</dict>\n" << "</plist>\n"; PL.close(); return true; }
static std::string getOutputFileName(llvm::StringRef InputFile) { // When updating, do in place replacement. if (OutputFileOpt.empty() && Update) return InputFile; // If a flat dSYM has been requested, things are pretty simple. if (FlatOut) { if (OutputFileOpt.empty()) { if (InputFile == "-") return "a.out.dwarf"; return (InputFile + ".dwarf").str(); } return OutputFileOpt; } // We need to create/update a dSYM bundle. // A bundle hierarchy looks like this: // <bundle name>.dSYM/ // Contents/ // Info.plist // Resources/ // DWARF/ // <DWARF file(s)> std::string DwarfFile = InputFile == "-" ? llvm::StringRef("a.out") : InputFile; llvm::SmallString<128> BundleDir(OutputFileOpt); if (BundleDir.empty()) BundleDir = DwarfFile + ".dSYM"; if (!createBundleDir(BundleDir) || !createPlistFile(DwarfFile, BundleDir)) return ""; llvm::sys::path::append(BundleDir, "Contents", "Resources", "DWARF", llvm::sys::path::filename(DwarfFile)); return BundleDir.str(); }
int main(int argc, char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); llvm::PrettyStackTraceProgram StackPrinter(argc, argv); llvm::llvm_shutdown_obj Shutdown; void *P = (void *)(intptr_t)getOutputFileName; std::string SDKPath = llvm::sys::fs::getMainExecutable(argv[0], P); SDKPath = llvm::sys::path::parent_path(SDKPath); HideUnrelatedOptions(DsymCategory); llvm::cl::ParseCommandLineOptions( argc, argv, "manipulate archived DWARF debug symbol files.\n\n" "dsymutil links the DWARF debug information found in the object files\n" "for the executable <input file> by using debug symbols information\n" "contained in its symbol table.\n"); if (Help) { PrintHelpMessage(); return 0; } if (Version) { llvm::cl::PrintVersionMessage(); return 0; } auto OptionsOrErr = getOptions(); if (!OptionsOrErr) { errs() << "error: " << toString(OptionsOrErr.takeError()); return 1; } llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); auto InputsOrErr = getInputs(OptionsOrErr->Update); if (!InputsOrErr) { errs() << "error: " << toString(InputsOrErr.takeError()) << '\n'; return 1; } if (!FlatOut && OutputFileOpt == "-") { llvm::errs() << "error: cannot emit to standard output without --flat\n"; return 1; } if (InputsOrErr->size() > 1 && FlatOut && !OutputFileOpt.empty()) { llvm::errs() << "error: cannot use -o with multiple inputs in flat mode\n"; return 1; } for (const auto &Arch : ArchFlags) if (Arch != "*" && Arch != "all" && !llvm::object::MachOObjectFile::isValidArch(Arch)) { llvm::errs() << "error: Unsupported cpu architecture: '" << Arch << "'\n"; return 1; } for (auto &InputFile : *InputsOrErr) { // Dump the symbol table for each input file and requested arch if (DumpStab) { if (!dumpStab(InputFile, ArchFlags, OsoPrependPath)) return 1; continue; } auto DebugMapPtrsOrErr = parseDebugMap(InputFile, ArchFlags, OsoPrependPath, Verbose, InputIsYAMLDebugMap); if (auto EC = DebugMapPtrsOrErr.getError()) { llvm::errs() << "error: cannot parse the debug map for \"" << InputFile << "\": " << EC.message() << '\n'; return 1; } if (OptionsOrErr->Update) { // The debug map should be empty. Add one object file corresponding to // the input file. for (auto &Map : *DebugMapPtrsOrErr) Map->addDebugMapObject(InputFile, llvm::sys::TimePoint<std::chrono::seconds>()); } // Ensure that the debug map is not empty (anymore). if (DebugMapPtrsOrErr->empty()) { llvm::errs() << "error: no architecture to link\n"; return 1; } if (NumThreads == 0) NumThreads = llvm::thread::hardware_concurrency(); if (DumpDebugMap || Verbose) NumThreads = 1; NumThreads = std::min<unsigned>(NumThreads, DebugMapPtrsOrErr->size()); llvm::ThreadPool Threads(NumThreads); // If there is more than one link to execute, we need to generate // temporary files. bool NeedsTempFiles = !DumpDebugMap && (OutputFileOpt != "-") && (DebugMapPtrsOrErr->size() != 1 || OptionsOrErr->Update); llvm::SmallVector<MachOUtils::ArchAndFilename, 4> TempFiles; TempFileVector TempFileStore; std::atomic_char AllOK(1); for (auto &Map : *DebugMapPtrsOrErr) { if (Verbose || DumpDebugMap) Map->print(llvm::outs()); if (DumpDebugMap) continue; if (Map->begin() == Map->end()) llvm::errs() << "warning: no debug symbols in executable (-arch " << MachOUtils::getArchName(Map->getTriple().getArchName()) << ")\n"; // Using a std::shared_ptr rather than std::unique_ptr because move-only // types don't work with std::bind in the ThreadPool implementation. std::shared_ptr<raw_fd_ostream> OS; std::string OutputFile = getOutputFileName(InputFile); if (NeedsTempFiles) { Expected<sys::fs::TempFile> T = createTempFile(); if (!T) { errs() << toString(T.takeError()); return 1; } OS = std::make_shared<raw_fd_ostream>(T->FD, /*shouldClose*/ false); OutputFile = T->TmpName; TempFileStore.Files.push_back(std::move(*T)); TempFiles.emplace_back(Map->getTriple().getArchName().str(), OutputFile); } else { std::error_code EC; OS = std::make_shared<raw_fd_ostream>(NoOutput ? "-" : OutputFile, EC, sys::fs::F_None); if (EC) { errs() << OutputFile << ": " << EC.message(); return 1; } } auto LinkLambda = [&, OutputFile](std::shared_ptr<raw_fd_ostream> Stream) { AllOK.fetch_and(linkDwarf(*Stream, *Map, *OptionsOrErr)); Stream->flush(); if (Verify && !NoOutput) AllOK.fetch_and(verify(OutputFile, Map->getTriple().getArchName())); }; // FIXME: The DwarfLinker can have some very deep recursion that can max // out the (significantly smaller) stack when using threads. We don't // want this limitation when we only have a single thread. if (NumThreads == 1) LinkLambda(OS); else Threads.async(LinkLambda, OS); } Threads.wait(); if (!AllOK) return 1; if (NeedsTempFiles && !MachOUtils::generateUniversalBinary( TempFiles, getOutputFileName(InputFile), *OptionsOrErr, SDKPath)) return 1; } return 0; }