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}));
  });
}
示例#2
0
文件: dsymutil.cpp 项目: mkurdej/llvm
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;
}
示例#3
0
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();
}
示例#4
0
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;
}