Esempio n. 1
0
void SILPassManager::run() {
  const SILOptions &Options = getOptions();
  (void) Options;

  if (SILPrintAll) {
    if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) {
      llvm::dbgs() << "*** SIL module before transformation ("
                   << NumOptimizationIterations << ") ***\n";
      Mod->dump(Options.EmitVerboseSIL);
    } else {
      for (auto &F : *Mod) {
        if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun) {
          llvm::dbgs() << "*** SIL function before transformation ("
                       << NumOptimizationIterations << ") ***\n";
          F.dump(Options.EmitVerboseSIL);
        }
        if (!SILPrintOnlyFuns.empty() &&
            F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos) {
          llvm::dbgs() << "*** SIL function before transformation ("
                       << NumOptimizationIterations << ") ***\n";
          F.dump(Options.EmitVerboseSIL);
        }
      }
    }
  }
  runOneIteration();
}
Esempio n. 2
0
// Test the function and pass names we're given against the debug
// options that force us to break prior to a given pass and/or on a
// given function.
static bool breakBeforeRunning(StringRef fnName, StringRef passName) {
  if (SILBreakOnFun.empty() && SILBreakOnPass.empty())
    return false;

  if (SILBreakOnFun.empty() && passName == SILBreakOnPass)
    return true;

  if (SILBreakOnPass.empty() && fnName == SILBreakOnFun)
    return true;

  return fnName == SILBreakOnFun && passName == SILBreakOnPass;
}
Esempio n. 3
0
// Test the function and pass names we're given against the debug
// options that force us to break prior to a given pass and/or on a
// given function.
static bool breakBeforeRunning(StringRef fnName, SILFunctionTransform *SFT) {
  if (SILBreakOnFun.empty() && SILBreakOnPass.empty())
    return false;

  if (SILBreakOnFun.empty()
      && (SFT->getName() == SILBreakOnPass || SFT->getTag() == SILBreakOnPass))
    return true;

  if (SILBreakOnPass.empty() && fnName == SILBreakOnFun)
    return true;

  return fnName == SILBreakOnFun
    && (SFT->getName() == SILBreakOnPass || SFT->getTag() == SILBreakOnPass);
}
Esempio n. 4
0
static void printModule(SILModule *Mod, bool EmitVerboseSIL) {
  if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) {
    Mod->dump();
    return;
  }
  for (auto &F : *Mod) {
    if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun)
      F.dump(EmitVerboseSIL);

    if (!SILPrintOnlyFuns.empty() &&
        F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos)
      F.dump(EmitVerboseSIL);
  }
}
Esempio n. 5
0
// main function
int
main(int argc, char* argv[])
{
    llvm::llvm_shutdown_obj llvm_manager(false);

    cl::SetVersionPrinter(&PrintVersion);
    cl::ParseCommandLineOptions(argc, argv, "", true);

    // Handle special exiting options
    if (show_license)
    {
        for (std::size_t i=0; i<sizeof(license_msg)/sizeof(license_msg[0]); i++)
            llvm::outs() << license_msg[i] << '\n';
        return EXIT_SUCCESS;
    }

    DiagnosticOptions diag_opts;
    diag_opts.ShowOptionNames = 1;
    diag_opts.ShowSourceRanges = 1;
    TextDiagnosticPrinter diag_printer(llvm::errs(), diag_opts);
    IntrusiveRefCntPtr<DiagnosticIDs> diagids(new DiagnosticIDs);
    DiagnosticsEngine diags(diagids, &diag_printer, false);
    FileSystemOptions opts;
    FileManager file_mgr(opts);
    SourceManager source_mgr(diags, file_mgr);
    diags.setSourceManager(&source_mgr);
    diag_printer.setPrefix("ygas");

    for (std::vector<std::string>::const_iterator i=unknown_options.begin(),
         end=unknown_options.end(); i != end; ++i)
    {
        diags.Report(diag::warn_unknown_command_line_option) << *i;
    }

    // Load standard modules
    if (!LoadStandardPlugins())
    {
        diags.Report(diag::fatal_standard_modules);
        return EXIT_FAILURE;
    }

#ifndef BUILD_STATIC
    // Load plugins
    for (std::vector<std::string>::const_iterator i=plugin_names.begin(),
         end=plugin_names.end(); i != end; ++i)
    {
        if (!LoadPlugin(*i))
            diags.Report(diag::warn_plugin_load) << *i;
    }
#endif

    // Default to stdin if no filename specified.
    if (in_filename.empty())
        in_filename = "-";

    return do_assemble(source_mgr, diags);
}
Esempio n. 6
0
void SILFunction::viewCFG() const {
/// When asserts are disabled, this should be a NoOp.
#ifndef NDEBUG
    // If we have a target function, only print that function out.
    if (!TargetFunction.empty() && !(getName().str() == TargetFunction))
      return;

  ViewGraph(const_cast<SILFunction *>(this), "cfg" + getName().str());
#endif
}
Esempio n. 7
0
static void viewCFGHelper(const SILFunction* f, bool skipBBContents) {
/// When asserts are disabled, this should be a NoOp.
#ifndef NDEBUG
    // If we have a target function, only print that function out.
    if (!TargetFunction.empty() && !(f->getName().str() == TargetFunction))
      return;

    ViewGraph(const_cast<SILFunction *>(f), "cfg" + f->getName().str(),
              /*shortNames=*/skipBBContents);
#endif
}
Esempio n. 8
0
static bool doPrintBefore(SILTransform *T, SILFunction *F) {
  if (!SILPrintOnlyFun.empty() && F && F->getName() != SILPrintOnlyFun)
    return false;

  if (!SILPrintOnlyFuns.empty() && F &&
      F->getName().find(SILPrintOnlyFuns, 0) == StringRef::npos)
    return false;

  auto MatchFun = [&](const std::string &Str) -> bool {
    return T->getName().find(Str) != StringRef::npos;
  };

  if (SILPrintBefore.end() !=
      std::find_if(SILPrintBefore.begin(), SILPrintBefore.end(), MatchFun))
    return true;

  if (SILPrintAround.end() !=
      std::find_if(SILPrintAround.begin(), SILPrintAround.end(), MatchFun))
    return true;

  return false;
}
int main(int argc, char **argv) {
  // Parse the command line arguments
  llvm::cl::ParseCommandLineOptions(argc, argv);

// Read the module file
#if LLVM_VERSION_MAJOR > 3 ||                                                  \
    (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6)
  std::unique_ptr<llvm::Module> module;
#else
  llvm::Module *module;
#endif

  module = getModuleFromIRFile(BitcodeFilename);
  if (!module) {
    llvm::errs() << "Something is wrong with your bitcode file" << '\n';
    return -1;
  }

  // Get the entry function
  llvm::Function *entry = module->getFunction(EntryFunction);
  if (!entry) {
    llvm::errs() << "Entry function " << EntryFunction << " not found" << '\n';
    return -1;
  }

  if (TargetFunction.empty()) {
    CountInstructions stratDistance;
    FinalReturn stratTarget;
    Dijkstra s(&stratDistance, &stratTarget, &(entry->front().front()));

    llvm::outs() << "Minimal Instruction from " << EntryFunction
                 << " to final return: " << s.searchForMinimalDistance()
                 << '\n';
  } else {
    llvm::Function *target = module->getFunction(TargetFunction);

    if (!target) {
      llvm::errs() << "Target function " << TargetFunction << " not found"
                   << '\n';
      return -1;
    }

    CountDecisions stratDistance;
    CallToSpecificFunction stratTarget(TargetFunction);
    Dijkstra s(&stratDistance, &stratTarget, &(entry->front().front()));

    llvm::outs() << "Minimal Decisions from " << EntryFunction << " to call of "
                 << TargetFunction << ": " << s.searchForMinimalDistance()
                 << '\n';
  }
}
Esempio n. 10
0
void CallGraphNode::print(llvm::raw_ostream &OS) const {
  OS << CallGraphFileCheckPrefix << "Function #" << Ordinal << ": " <<
    getFunction()->getName() << "\n";
  OS << CallGraphFileCheckPrefix << "Demangled: " <<
    demangle_wrappers::demangleSymbolAsString(getFunction()->getName()) << "\n";
  printFlag(OS, "Trivially dead", isTriviallyDead());
  printFlag(OS, "All callers known", isCallerEdgesComplete());

  auto &CalleeEdges = getCalleeEdges();
  if (!CalleeEdges.empty()) {
    OS << CallGraphFileCheckPrefix << "Call sites:\n";

    llvm::SmallVector<CallGraphEdge *, 8> OrderedCalleeEdges;
    orderEdges(CalleeEdges, OrderedCalleeEdges);

    for (auto *Edge : OrderedCalleeEdges) {
      OS << "\n";
      Edge->print(OS, /* Indent= */ 2);
    }
    OS << "\n";
  }

  auto &CallerEdges = getCallerEdges();
  if (!CallerEdges.empty()) {
    OS << CallGraphFileCheckPrefix <<
      (!isCallerEdgesComplete() ? "Known " : "");
    OS << "Callers:\n";

    llvm::SmallVector<CallGraphEdge *, 8> OrderedCallerEdges;
    orderEdges(CallerEdges, OrderedCallerEdges);

    llvm::SetVector<SILFunction *> Callers;

    for (auto *Edge : OrderedCallerEdges)
      Callers.insert(Edge->getInstruction()->getFunction());

    for (auto *Caller : Callers) {
      OS << "\n";
      indent(OS, 2);
      OS << CallGraphFileCheckPrefix << "Name: " << Caller->getName() << "\n";
      indent(OS, 2);
      OS << CallGraphFileCheckPrefix << "Demangled: " <<
        demangle_wrappers::demangleSymbolAsString(Caller->getName()) << "\n";
    }
    OS << "\n";
  }

  if (!CallGraphFileCheckPrefix.empty())
    getFunction()->print(OS);
}
Esempio n. 11
0
static llvm::tool_output_file *
GetOutputStream() {
 
    if (OutputFilename.empty()) {
        OutputFilename = GetFileNameRoot(InputFilename) + ".o";
    }
    
    string error;
    unsigned openFlags = llvm::raw_fd_ostream::F_Binary;
    llvm::tool_output_file * FDOut = new llvm::tool_output_file(OutputFilename.c_str(), error, openFlags);
    
    if (!error.empty()) {
        llvm::errs() << error << '\n';
        delete FDOut;
        return NULL;
    }
    
    return FDOut;
}
Esempio n. 12
0
static void getFunctionNames(std::vector<std::string> &Names) {
  std::copy(CommandLineFunctionNames.begin(), CommandLineFunctionNames.end(),
            std::back_inserter(Names));

  if (!FunctionNameFile.empty()) {
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
        llvm::MemoryBuffer::getFileOrSTDIN(FunctionNameFile);
    if (!FileBufOrErr) {
      fprintf(stderr, "Error! Failed to open file: %s\n",
              InputFilename.c_str());
      exit(-1);
    }
    StringRef Buffer = FileBufOrErr.get()->getBuffer();
    while (!Buffer.empty()) {
      StringRef Token, NewBuffer;
      std::tie(Token, NewBuffer) = llvm::getToken(Buffer, "\n");
      if (Token.empty()) {
        break;
      }
      Names.push_back(Token);
      Buffer = NewBuffer;
    }
  }
}
Esempio n. 13
0
static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) {
  using namespace llvm;

  assert(!resultFiles.empty());

  std::map<StringRef, StringRef> resultMap;

  for (ArrayRef<std::string>::iterator
         I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) {
    StringRef fname(*I);
    if (!fname.endswith(".result")) {
      errs() << "error: filename '" << fname
                   << "' does not have '.result' extension\n";
      return true;
    }
    resultMap[sys::path::stem(fname)] = fname;
  }

  ErrorOr<std::unique_ptr<MemoryBuffer>> inputBuf = std::error_code();
  if (RemappingsFile.empty())
    inputBuf = MemoryBuffer::getSTDIN();
  else
    inputBuf = MemoryBuffer::getFile(RemappingsFile);
  if (!inputBuf) {
    errs() << "error: could not read remappings input\n";
    return true;
  }

  SmallVector<StringRef, 8> strs;
  inputBuf.get()->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
                                    /*KeepEmpty=*/false);

  if (strs.empty()) {
    errs() << "error: no files to verify from stdin\n";
    return true;
  }
  if (strs.size() % 2 != 0) {
    errs() << "error: files to verify are not original/result pairs\n";
    return true;
  }

  for (unsigned i = 0, e = strs.size(); i != e; i += 2) {
    StringRef inputOrigFname = strs[i];
    StringRef inputResultFname = strs[i+1];

    std::map<StringRef, StringRef>::iterator It;
    It = resultMap.find(sys::path::filename(inputOrigFname));
    if (It == resultMap.end()) {
      errs() << "error: '" << inputOrigFname << "' is not in the list of "
             << "transformed files to verify\n";
      return true;
    }

    if (!sys::fs::exists(It->second)) {
      errs() << "error: '" << It->second << "' does not exist\n";
      return true;
    }
    if (!sys::fs::exists(inputResultFname)) {
      errs() << "error: '" << inputResultFname << "' does not exist\n";
      return true;
    }

    if (!filesCompareEqual(It->second, inputResultFname)) {
      errs() << "error: '" << It->second << "' is different than "
             << "'" << inputResultFname << "'\n";
      return true;
    }

    resultMap.erase(It);
  }

  if (!resultMap.empty()) {
    for (std::map<StringRef, StringRef>::iterator
           I = resultMap.begin(), E = resultMap.end(); I != E; ++I)
      errs() << "error: '" << I->second << "' was not verified!\n";
    return true;
  }

  return false; 
}
Esempio n. 14
0
int main(int argc, char *argv[]) {
  llvm::cl::SetVersionPrinter(PrintVersion);
  llvm::cl::ParseCommandLineOptions(argc, argv, "CFG to LLVM");


  if (InputFilename.empty() || OutputFilename.empty()) {
    std::cerr
        << "Must specify an input and output file";
    return EXIT_FAILURE;
  }

  auto context = new llvm::LLVMContext;

  if (!InitArch(context, OS, Arch)) {
    std::cerr
        << "Cannot initialize for arch " << Arch
        << " and OS " << OS << std::endl;
    return EXIT_FAILURE;
  }

  auto M = CreateModule(context);
  if (!M) {
    return EXIT_FAILURE;
  }

  auto triple = M->getTargetTriple();

  //reproduce NativeModule from CFG input argument
  try {
    auto mod = ReadProtoBuf(InputFilename);
    if (!mod) {
      std::cerr << "Unable to read module from CFG" << std::endl;
      return EXIT_FAILURE;
    }

    //now, convert it to an LLVM module
    ArchInitAttachDetach(M);

    if (!LiftCodeIntoModule(mod, M)) {
      std::cerr << "Failure to convert to LLVM module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::set<VA> entry_point_pcs;
    for (const auto &entry_point_name : EntryPoints) {
      auto entry_pc = FindSymbolInModule(mod, entry_point_name);
      if (entry_pc != static_cast<VA>( -1)) {
        std::cerr << "Adding entry point: " << entry_point_name << std::endl
                  << entry_point_name << " is implemented by sub_" << std::hex
                  << entry_pc << std::endl;

        if ( !ArchAddEntryPointDriver(M, entry_point_name, entry_pc)) {
          return EXIT_FAILURE;
        }

        entry_point_pcs.insert(entry_pc);
      } else {
        std::cerr << "Could not find entry point: " << entry_point_name
                  << "; aborting" << std::endl;
        return EXIT_FAILURE;
      }
    }

    RenameLiftedFunctions(mod, M, entry_point_pcs);

    // will abort if verification fails
    if (llvm::verifyModule( *M, &llvm::errs())) {
      std::cerr << "Could not verify module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::error_code ec;
    llvm::tool_output_file Out(OutputFilename.c_str(), ec,
                               llvm::sys::fs::F_None);
    llvm::WriteBitcodeToFile(M, Out.os());
    Out.keep();

  } catch (std::exception &e) {
    std::cerr << "error: " << std::endl << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
Esempio n. 15
0
static void indent(llvm::raw_ostream &OS, int Indent) {
  if (!CallGraphFileCheckPrefix.empty()) return;

  std::string Blanks(Indent, ' ');
  OS << Blanks;
}
Esempio n. 16
0
static int
DoDump(const std::string& in_filename,
       yasm::SourceManager& source_mgr,
       yasm::Diagnostic& diags)
{
    yasm::FileManager file_mgr;

    // open the input file or STDIN (for filename of "-")
    if (in_filename == "-")
    {
        source_mgr.createMainFileIDForMemBuffer(llvm::MemoryBuffer::getSTDIN());
    }
    else
    {
        const yasm::FileEntry* in = file_mgr.getFile(in_filename);
        if (!in)
        {
            diags.Report(yasm::SourceLocation(), yasm::diag::err_file_open)
                << in_filename;
        }
        source_mgr.createMainFileID(in, yasm::SourceLocation());
    }

    const llvm::MemoryBuffer* in_file =
        source_mgr.getBuffer(source_mgr.getMainFileID());
    yasm::SourceLocation sloc =
        source_mgr.getLocForStartOfFile(source_mgr.getMainFileID());

    std::auto_ptr<yasm::ObjectFormatModule> objfmt_module(0);
    std::string arch_keyword, machine;

    if (!objfmt_keyword.empty())
    {
        objfmt_keyword = llvm::LowercaseString(objfmt_keyword);
        if (!yasm::isModule<yasm::ObjectFormatModule>(objfmt_keyword))
        {
            diags.Report(sloc, yasm::diag::err_unrecognized_object_format)
                << objfmt_keyword;
            return EXIT_FAILURE;
        }

        // Object format forced by user
        objfmt_module =
            yasm::LoadModule<yasm::ObjectFormatModule>(objfmt_keyword);

        if (objfmt_module.get() == 0)
        {
            diags.Report(sloc, yasm::diag::fatal_module_load)
                << "object format" << objfmt_keyword;
            return EXIT_FAILURE;
        }

        if (!objfmt_module->Taste(*in_file, &arch_keyword, &machine))
        {
            diags.Report(sloc, yasm::diag::err_unrecognized_object_file)
                << objfmt_module->getKeyword();
            return EXIT_FAILURE;
        }
    }
    else
    {
        // Need to loop through available object formats, and taste each one
        yasm::ModuleNames list = yasm::getModules<yasm::ObjectFormatModule>();
        yasm::ModuleNames::iterator i=list.begin(), end=list.end();
        for (; i != end; ++i)
        {
            objfmt_module = yasm::LoadModule<yasm::ObjectFormatModule>(*i);
            if (objfmt_module->Taste(*in_file, &arch_keyword, &machine))
                break;
        }
        if (i == end)
        {
            diags.Report(sloc, yasm::diag::err_unrecognized_file_format);
            return EXIT_FAILURE;
        }
    }

    std::auto_ptr<yasm::ArchModule> arch_module =
        yasm::LoadModule<yasm::ArchModule>(arch_keyword);
    if (arch_module.get() == 0)
    {
        diags.Report(sloc, yasm::diag::fatal_module_load)
            << "architecture" << arch_keyword;
        return EXIT_FAILURE;
    }

    std::auto_ptr<yasm::Arch> arch = arch_module->Create();
    if (!arch->setMachine(machine))
    {
        diags.Report(sloc, yasm::diag::fatal_module_combo)
            << "machine" << machine
            << "architecture" << arch_module->getKeyword();
        return EXIT_FAILURE;
    }

    yasm::Object object("", in_filename, arch.get());

    if (!objfmt_module->isOkObject(object))
    {
        diags.Report(sloc, yasm::diag::fatal_objfmt_machine_mismatch)
            << objfmt_module->getKeyword()
            << arch_module->getKeyword()
            << arch->getMachine();
        return EXIT_FAILURE;
    }

    std::auto_ptr<yasm::ObjectFormat> objfmt = objfmt_module->Create(object);
    if (!objfmt->Read(source_mgr, diags))
        return EXIT_FAILURE;

    llvm::outs() << in_filename << ":     file format "
                 << objfmt_module->getKeyword() << "\n\n";

    if (show_section_headers)
        DumpSectionHeaders(object);
    if (show_symbols)
        DumpSymbols(object);
    if (show_relocs)
        DumpRelocs(object);
    if (show_contents)
        DumpContents(object);
    return EXIT_SUCCESS;
}
Esempio n. 17
0
int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift SIL optimizer\n");

  if (PrintStats)
    llvm::EnableStatistics();

  CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(
      llvm::sys::fs::getMainExecutable(argv[0],
          reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  // Give the context the list of search paths to use for modules.
  Invocation.setImportSearchPaths(ImportPaths);
  std::vector<SearchPathOptions::FrameworkSearchPath> FramePaths;
  for (const auto &path : FrameworkPaths) {
    FramePaths.push_back({path, /*isSystem=*/false});
  }
  Invocation.setFrameworkSearchPaths(FramePaths);
  // Set the SDK path and target if given.
  if (SDKPath.getNumOccurrences() == 0) {
    const char *SDKROOT = getenv("SDKROOT");
    if (SDKROOT)
      SDKPath = SDKROOT;
  }
  if (!SDKPath.empty())
    Invocation.setSDKPath(SDKPath);
  if (!Target.empty())
    Invocation.setTargetTriple(Target);
  if (!ResourceDir.empty())
    Invocation.setRuntimeResourcePath(ResourceDir);
  Invocation.getFrontendOptions().EnableResilience = EnableResilience;
  // Set the module cache path. If not passed in we use the default swift module
  // cache.
  Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
  Invocation.setParseStdlib();
  Invocation.getLangOptions().DisableAvailabilityChecking = true;
  Invocation.getLangOptions().EnableAccessControl = false;
  Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
  Invocation.getLangOptions().EnableObjCInterop =
    llvm::Triple(Target).isOSDarwin();

  Invocation.getLangOptions().ASTVerifierProcessCount =
      ASTVerifierProcessCount;
  Invocation.getLangOptions().ASTVerifierProcessId =
      ASTVerifierProcessId;
  Invocation.getLangOptions().EnableSILOpaqueValues = EnableSILOpaqueValues;

  // Setup the SIL Options.
  SILOptions &SILOpts = Invocation.getSILOptions();
  SILOpts.InlineThreshold = SILInlineThreshold;
  SILOpts.VerifyAll = EnableSILVerifyAll;
  SILOpts.RemoveRuntimeAsserts = RemoveRuntimeAsserts;
  SILOpts.AssertConfig = AssertConfId;
  if (OptimizationGroup != OptGroup::Diagnostics)
    SILOpts.Optimization = SILOptions::SILOptMode::Optimize;
  SILOpts.EnableSILOwnership = EnableSILOwnershipOpt;
  SILOpts.AssumeUnqualifiedOwnershipWhenParsing =
    AssumeUnqualifiedOwnershipWhenParsing;

  switch (EnforceExclusivity) {
  case EnforceExclusivityMode::Unchecked:
    // This option is analogous to the -Ounchecked optimization setting.
    // It will disable dynamic checking but still diagnose statically.
    SILOpts.EnforceExclusivityStatic = true;
    SILOpts.EnforceExclusivityDynamic = false;
    break;
  case EnforceExclusivityMode::Checked:
    SILOpts.EnforceExclusivityStatic = true;
    SILOpts.EnforceExclusivityDynamic = true;
    break;
  case EnforceExclusivityMode::DynamicOnly:
    // This option is intended for staging purposes. The intent is that
    // it will eventually be removed.
    SILOpts.EnforceExclusivityStatic = false;
    SILOpts.EnforceExclusivityDynamic = true;
    break;
  case EnforceExclusivityMode::None:
    // This option is for staging purposes.
    SILOpts.EnforceExclusivityStatic = false;
    SILOpts.EnforceExclusivityDynamic = false;
    break;
  }

  // Load the input file.
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
    llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (!FileBufOrErr) {
    fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str());
    exit(-1);
  }

  // If it looks like we have an AST, set the source file kind to SIL and the
  // name of the module to the file's name.
  Invocation.addInputBuffer(FileBufOrErr.get().get());

  serialization::ExtendedValidationInfo extendedInfo;
  auto result = serialization::validateSerializedAST(
      FileBufOrErr.get()->getBuffer(), &extendedInfo);
  bool HasSerializedAST = result.status == serialization::Status::Valid;

  if (HasSerializedAST) {
    const StringRef Stem = ModuleName.size() ?
                             StringRef(ModuleName) :
                             llvm::sys::path::stem(InputFilename);
    Invocation.setModuleName(Stem);
    Invocation.setInputKind(InputFileKind::IFK_Swift_Library);
  } else {
    const StringRef Name = ModuleName.size() ? StringRef(ModuleName) : "main";
    Invocation.setModuleName(Name);
    Invocation.setInputKind(InputFileKind::IFK_SIL);
  }

  CompilerInstance CI;
  PrintingDiagnosticConsumer PrintDiags;
  CI.addDiagnosticConsumer(&PrintDiags);

  if (!PerformWMO) {
    auto &FrontendOpts = Invocation.getFrontendOptions();
    if (!InputFilename.empty() && InputFilename != "-") {
      FrontendOpts.PrimaryInput = SelectedInput(
          FrontendOpts.InputFilenames.size());
    } else {
      FrontendOpts.PrimaryInput = SelectedInput(
          FrontendOpts.InputBuffers.size(), SelectedInput::InputKind::Buffer);
    }
  }

  if (CI.setup(Invocation))
    return 1;

  CI.performSema();

  // If parsing produced an error, don't run any passes.
  if (CI.getASTContext().hadError())
    return 1;

  // Load the SIL if we have a module. We have to do this after SILParse
  // creating the unfortunate double if statement.
  if (HasSerializedAST) {
    assert(!CI.hasSILModule() &&
           "performSema() should not create a SILModule.");
    CI.setSILModule(SILModule::createEmptyModule(
        CI.getMainModule(), CI.getSILOptions(), PerformWMO));
    std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create(
        CI.getASTContext(), CI.getSILModule(), nullptr);

    if (extendedInfo.isSIB() || DisableSILLinking)
      SL->getAllForModule(CI.getMainModule()->getName(), nullptr);
    else
      SL->getAll();
  }

  // If we're in verify mode, install a custom diagnostic handling for
  // SourceMgr.
  if (VerifyMode)
    enableDiagnosticVerifier(CI.getSourceMgr());

  if (OptimizationGroup == OptGroup::Diagnostics) {
    runSILDiagnosticPasses(*CI.getSILModule());
  } else if (OptimizationGroup == OptGroup::Performance) {
    runSILOptimizationPasses(*CI.getSILModule());
  } else if (OptimizationGroup == OptGroup::Lowering) {
    runSILLoweringPasses(*CI.getSILModule());
  } else {
    auto *SILMod = CI.getSILModule();
    {
      auto T = irgen::createIRGenModule(SILMod, getGlobalLLVMContext());
      runCommandLineSelectedPasses(SILMod, T.second);
      irgen::deleteIRGenModule(T);
    }
  }

  if (EmitSIB) {
    llvm::SmallString<128> OutputFile;
    if (OutputFilename.size()) {
      OutputFile = OutputFilename;
    } else if (ModuleName.size()) {
      OutputFile = ModuleName;
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    } else {
      OutputFile = CI.getMainModule()->getName().str();
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    }

    SerializationOptions serializationOpts;
    serializationOpts.OutputPath = OutputFile.c_str();
    serializationOpts.SerializeAllSIL = true;
    serializationOpts.IsSIB = true;

    serialize(CI.getMainModule(), serializationOpts, CI.getSILModule());
  } else {
    const StringRef OutputFile = OutputFilename.size() ?
                                   StringRef(OutputFilename) : "-";

    if (OutputFile == "-") {
      CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    } else {
      std::error_code EC;
      llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
      if (EC) {
        llvm::errs() << "while opening '" << OutputFile << "': "
                     << EC.message() << '\n';
        return 1;
      }
      CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    }
  }

  bool HadError = CI.getASTContext().hadError();

  // If we're in -verify mode, we've buffered up all of the generated
  // diagnostics.  Check now to ensure that they meet our expectations.
  if (VerifyMode) {
    HadError = verifyDiagnostics(CI.getSourceMgr(), CI.getInputBufferIDs(),
                                 /*autoApplyFixes*/false,
                                 /*ignoreUnknown*/false);
    DiagnosticEngine &diags = CI.getDiags();
    if (diags.hasFatalErrorOccurred() &&
        !Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) {
      diags.resetHadAnyError();
      diags.diagnose(SourceLoc(), diag::verify_encountered_fatal);
      HadError = true;
    }
  }

  return HadError;
}
Esempio n. 18
0
int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM IR Generator\n");

  if (PrintStats)
    llvm::EnableStatistics();

  CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(llvm::sys::fs::getMainExecutable(
      argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  // Give the context the list of search paths to use for modules.
  Invocation.setImportSearchPaths(ImportPaths);
  Invocation.setFrameworkSearchPaths(FrameworkPaths);
  // Set the SDK path and target if given.
  if (SDKPath.getNumOccurrences() == 0) {
    const char *SDKROOT = getenv("SDKROOT");
    if (SDKROOT)
      SDKPath = SDKROOT;
  }
  if (!SDKPath.empty())
    Invocation.setSDKPath(SDKPath);
  if (!Target.empty())
    Invocation.setTargetTriple(Target);
  if (!ResourceDir.empty())
    Invocation.setRuntimeResourcePath(ResourceDir);
  // Set the module cache path. If not passed in we use the default swift module
  // cache.
  Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
  Invocation.setParseStdlib();

  // Setup the language options
  auto &LangOpts = Invocation.getLangOptions();
  LangOpts.DisableAvailabilityChecking = true;
  LangOpts.EnableAccessControl = false;
  LangOpts.EnableObjCAttrRequiresFoundation = false;
  LangOpts.EnableObjCInterop = LangOpts.Target.isOSDarwin();

  // Setup the SIL Options.
  SILOptions &SILOpts = Invocation.getSILOptions();
  SILOpts.AssumeUnqualifiedOwnershipWhenParsing =
      AssumeUnqualifiedOwnershipWhenParsing;

  // Setup the IRGen Options.
  IRGenOptions &Opts = Invocation.getIRGenOptions();
  Opts.MainInputFilename = InputFilename;
  Opts.OutputFilenames.push_back(OutputFilename);
  Opts.OutputKind = OutputKind;

  // Load the input file.
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
      llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (!FileBufOrErr) {
    fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str());
    exit(-1);
  }

  // If it looks like we have an AST, set the source file kind to SIL and the
  // name of the module to the file's name.
  Invocation.addInputBuffer(FileBufOrErr.get().get());

  serialization::ExtendedValidationInfo extendedInfo;
  auto result = serialization::validateSerializedAST(
      FileBufOrErr.get()->getBuffer(), &extendedInfo);
  bool HasSerializedAST = result.status == serialization::Status::Valid;

  if (HasSerializedAST) {
    const StringRef Stem = ModuleName.size()
                               ? StringRef(ModuleName)
                               : llvm::sys::path::stem(InputFilename);
    Invocation.setModuleName(Stem);
    Invocation.setInputKind(InputFileKind::IFK_Swift_Library);
  } else {
    const StringRef Name = ModuleName.size() ? StringRef(ModuleName) : "main";
    Invocation.setModuleName(Name);
    Invocation.setInputKind(InputFileKind::IFK_SIL);
  }

  CompilerInstance CI;
  PrintingDiagnosticConsumer PrintDiags;
  CI.addDiagnosticConsumer(&PrintDiags);

  if (!PerformWMO) {
    auto &FrontendOpts = Invocation.getFrontendOptions();
    if (!InputFilename.empty() && InputFilename != "-") {
      FrontendOpts.PrimaryInput =
          SelectedInput(FrontendOpts.InputFilenames.size());
    } else {
      FrontendOpts.PrimaryInput = SelectedInput(
          FrontendOpts.InputBuffers.size(), SelectedInput::InputKind::Buffer);
    }
  }

  if (CI.setup(Invocation))
    return 1;

  CI.performSema();

  // If parsing produced an error, don't run any passes.
  if (CI.getASTContext().hadError())
    return 1;

  // Load the SIL if we have a module. We have to do this after SILParse
  // creating the unfortunate double if statement.
  if (HasSerializedAST) {
    assert(!CI.hasSILModule() &&
           "performSema() should not create a SILModule.");
    CI.setSILModule(SILModule::createEmptyModule(
        CI.getMainModule(), CI.getSILOptions(), PerformWMO));
    std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create(
        CI.getASTContext(), CI.getSILModule(), nullptr);

    if (extendedInfo.isSIB())
      SL->getAllForModule(CI.getMainModule()->getName(), nullptr);
    else
      SL->getAll();
  }

  std::unique_ptr<llvm::Module> Mod = performIRGeneration(
      Opts, CI.getMainModule(), CI.takeSILModule(),
      CI.getMainModule()->getName().str(), getGlobalLLVMContext());
  return CI.getASTContext().hadError();
}
Esempio n. 19
0
int main(int argc, char *argv[]) {
  llvm::cl::SetVersionPrinter(PrintVersion);
  llvm::cl::ParseCommandLineOptions(argc, argv, "CFG to LLVM");

  auto context = llvm::make_unique<llvm::LLVMContext>();

  if (OS.empty()) {
    if (ListSupported || ListUnsupported) {
      OS = "linux"; // just need something
    }
    else {
      std::cerr << "-os must be specified" << std::endl;
      return EXIT_FAILURE;
    }
  }

  if (!(ListSupported || ListUnsupported || ListCFGFunctions) && EntryPoints.empty()) {
    std::cerr
        << "-entrypoint must be specified" << std::endl;
        return EXIT_FAILURE;
  }

  if (!InitArch(context.get(), OS, Arch)) {
    std::cerr
        << "Cannot initialize for arch " << Arch
        << " and OS " << OS << std::endl;
    return EXIT_FAILURE;
  }

  auto M = CreateModule(context.get());
  if (!M) {
    return EXIT_FAILURE;
  }

  auto triple = M->getTargetTriple();

  if (ListSupported || ListUnsupported) {
    ListArchSupportedInstructions(triple, llvm::outs(), ListSupported, ListUnsupported);
    return EXIT_SUCCESS;
  }

  if (InputFilename.empty()) {
    std::cerr
        << "Must specify an input file." << std::endl;
    return EXIT_FAILURE;
  }

  //reproduce NativeModule from CFG input argument
  try {
    std::unique_ptr<NativeModule> mod(ReadProtoBuf(InputFilename));
    if (!mod) {
      std::cerr << "Unable to read module from CFG" << std::endl;
      return EXIT_FAILURE;
    }

    if (ListCFGFunctions) {
      PrintCFGFunctionList(mod.get(), Arch);
      return EXIT_SUCCESS;
    }

    //make sure the entry point list is correct before we start lifting the code
    const std::vector<NativeEntrySymbol> &module_entry_points = mod->getEntryPoints();

    for (const auto &entry_point : EntryPoints) {
      auto it = std::find_if(
        module_entry_points.begin(),
        module_entry_points.end(),

        [&entry_point](const NativeEntrySymbol &symbol) -> bool {
          return (symbol.getName() == entry_point);
        }
      );

      if (it == module_entry_points.end()) {
          std::cerr << "The following entry point could not be found: \"" << entry_point << "\". Aborting..." << std::endl;
          return EXIT_FAILURE;
      }
    }

    //now, convert it to an LLVM module
    ArchInitAttachDetach(M);

    if (!LiftCodeIntoModule(mod.get(), M)) {
      std::cerr << "Failure to convert to LLVM module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::set<VA> entry_point_pcs;
    for (const auto &entry_point_name : EntryPoints) {
      auto entry_pc = FindSymbolInModule(mod.get(), entry_point_name);
      assert(entry_pc != static_cast<VA>( -1));

      std::cerr << "Adding entry point: " << entry_point_name << std::endl
                << entry_point_name << " is implemented by sub_" << std::hex
                << entry_pc << std::endl;

      if ( !ArchAddEntryPointDriver(M, entry_point_name, entry_pc)) {
        return EXIT_FAILURE;
      }

      entry_point_pcs.insert(entry_pc);
    }

    RenameLiftedFunctions(mod.get(), M, entry_point_pcs);

    // will abort if verification fails
    if (llvm::verifyModule( *M, &llvm::errs())) {
      std::cerr << "Could not verify module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::error_code ec;
    llvm::tool_output_file Out(OutputFilename.c_str(), ec,
                               llvm::sys::fs::F_None);
    llvm::WriteBitcodeToFile(M, Out.os());
    Out.keep();

  } catch (std::exception &e) {
    std::cerr << "error: " << std::endl << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
Esempio n. 20
0
int main(int argc, char **argv) {
    llvm::llvm_shutdown_obj shutdown;  // calls llvm_shutdown() on exit
    llvm::cl::ParseCommandLineOptions(argc, argv, "llvm2bpl - LLVM bitcode to Boogie transformation\n");

    llvm::sys::PrintStackTraceOnErrorSignal();
    llvm::PrettyStackTraceProgram PSTP(argc, argv);
    llvm::EnableDebugBuffering = true;

    llvm::SMDiagnostic err;
    std::unique_ptr<llvm::Module> module = llvm::parseIRFile(InputFilename, err, llvm::getGlobalContext());
    if (!err.getMessage().empty())
        check("Problem reading input bitcode/IR: " + err.getMessage().str());

    auto &L = module.get()->getDataLayoutStr();
    if (L.empty())
        module.get()->setDataLayout(DefaultDataLayout);

    ///////////////////////////////
    // initialise and run passes //
    ///////////////////////////////

    llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
    llvm::initializeAnalysis(Registry);

    llvm::legacy::PassManager pass_manager;

    pass_manager.add(llvm::createLowerSwitchPass());
    //pass_manager.add(llvm::createCFGSimplificationPass());
    pass_manager.add(llvm::createInternalizePass());
    pass_manager.add(llvm::createPromoteMemoryToRegisterPass());

    if (StaticUnroll) {
        pass_manager.add(llvm::createLoopSimplifyPass());
        pass_manager.add(llvm::createLoopRotatePass());
        //pass_manager.add(llvm::createIndVarSimplifyPass());
        pass_manager.add(llvm::createLoopUnrollPass(32767));
    }

    pass_manager.add(new llvm::StructRet());
    pass_manager.add(new llvm::SimplifyEV());
    pass_manager.add(new llvm::SimplifyIV());
    pass_manager.add(new smack::ExtractContracts());
    pass_manager.add(llvm::createDeadCodeEliminationPass());
    pass_manager.add(new smack::CodifyStaticInits());
    pass_manager.add(new smack::RemoveDeadDefs());
    pass_manager.add(new llvm::MergeArrayGEP());
    // pass_manager.add(new smack::SimplifyLibCalls());
    pass_manager.add(new llvm::Devirtualize());

    if (smack::SmackOptions::MemorySafety) {
        pass_manager.add(new smack::MemorySafetyChecker());
    }

    if (SignedIntegerOverflow)
        pass_manager.add(new smack::SignedIntegerOverflowChecker());

    std::vector<tool_output_file*> files;

    if (!FinalIrFilename.empty()) {
        std::error_code EC;
        auto F = new tool_output_file(FinalIrFilename.c_str(), EC, sys::fs::F_None);
        if (EC) check(EC.message());
        F->keep();
        files.push_back(F);
        pass_manager.add(llvm::createPrintModulePass(F->os()));
    }

    if (!OutputFilename.empty()) {
        std::error_code EC;
        auto F = new tool_output_file(OutputFilename.c_str(), EC, sys::fs::F_None);
        if (EC) check(EC.message());
        F->keep();
        files.push_back(F);
        pass_manager.add(new smack::SmackModuleGenerator());
        pass_manager.add(new smack::BplFilePrinter(F->os()));
    }

    pass_manager.run(*module.get());

    for (auto F : files)
        delete F;

    return 0;
}
int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  Transforms TransformManager;
  ReplacementHandling ReplacementHandler;

  TransformManager.registerTransforms();

  // Hide all options we don't define ourselves. Move pre-defined 'help',
  // 'help-list', and 'version' to our general category.
  llvm::StringMap<cl::Option*> Options;
  cl::getRegisteredOptions(Options);
  const cl::OptionCategory **CategoryEnd =
      VisibleCategories + llvm::array_lengthof(VisibleCategories);
  for (llvm::StringMap<cl::Option *>::iterator I = Options.begin(),
                                               E = Options.end();
       I != E; ++I) {
    if (I->first() == "help" || I->first() == "version" ||
        I->first() == "help-list")
      I->second->setCategory(GeneralCategory);
    else if (std::find(VisibleCategories, CategoryEnd, I->second->Category) ==
             CategoryEnd)
      I->second->setHiddenFlag(cl::ReallyHidden);
  }
  cl::SetVersionPrinter(&printVersion);

  // Parse options and generate compilations.
  std::unique_ptr<CompilationDatabase> Compilations(
      FixedCompilationDatabase::loadFromCommandLine(argc, argv));
  cl::ParseCommandLineOptions(argc, argv);

  // Populate the ModifiableFiles structure.
  GlobalOptions.ModifiableFiles.readListFromString(IncludePaths, ExcludePaths);
  GlobalOptions.ModifiableFiles.readListFromFile(IncludeFromFile,
                                                 ExcludeFromFile);

  if (!Compilations) {
    std::string ErrorMessage;
    Compilations.reset(autoDetectCompilations(ErrorMessage));
    if (!Compilations) {
      llvm::errs() << llvm::sys::path::filename(argv[0]) << ": " << ErrorMessage
                   << "\n";
      return 1;
    }
  }

  // Populate source files.
  std::vector<std::string> Sources;
  if (!SourcePaths.empty()) {
    // Use only files that are not explicitly excluded.
    std::remove_copy_if(SourcePaths.begin(), SourcePaths.end(),
                        std::back_inserter(Sources),
                        isFileExplicitlyExcludedPredicate);
  } else {
    if (GlobalOptions.ModifiableFiles.isIncludeListEmpty()) {
      llvm::errs() << llvm::sys::path::filename(argv[0])
                   << ": Use -include to indicate which files of "
                   << "the compilatiion database to transform.\n";
      return 1;
    }
    // Use source paths from the compilation database.
    // We only transform files that are explicitly included.
    Sources = Compilations->getAllFiles();
    std::vector<std::string>::iterator E = std::remove_if(
        Sources.begin(), Sources.end(), isFileNotIncludedPredicate);
    Sources.erase(E, Sources.end());
  }

  // check if line ranges are just applyed to single files
  if ( !LineRanges.empty() && Sources.size() > 1 ){
     llvm::errs() << "error: -line can only be used for single file.\n";
     return 1;
  }

  // add the line ranges to the sources 
  if ( !LineRanges.empty() ){
  }

  if (Sources.empty()) {
    llvm::errs() << llvm::sys::path::filename(argv[0])
                 << ": Could not determine sources to transform.\n";
    return 1;
  }

  // Enable timming.
  GlobalOptions.EnableTiming = TimingDirectoryName.getNumOccurrences() > 0;

  bool CmdSwitchError = false;
  CompilerVersions RequiredVersions =
      handleSupportedCompilers(argv[0], CmdSwitchError);
  if (CmdSwitchError)
    return 1;

  TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);

  if (TransformManager.begin() == TransformManager.end()) {
    if (SupportedCompilers.empty())
      llvm::errs() << llvm::sys::path::filename(argv[0])
                   << ": no selected transforms\n";
    else
      llvm::errs() << llvm::sys::path::filename(argv[0])
                   << ": no transforms available for specified compilers\n";
    return 1;
  }

  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
      new DiagnosticOptions());
  DiagnosticsEngine Diagnostics(
      llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
      DiagOpts.getPtr());

  // FIXME: Make this DiagnosticsEngine available to all Transforms probably via
  // GlobalOptions.

  // If SerializeReplacements is requested, then code reformatting must be
  // turned off and only one transform should be requested.
  if (SerializeOnly &&
      (std::distance(TransformManager.begin(), TransformManager.end()) > 1 ||
       DoFormat)) {
    llvm::errs() << "Serialization of replacements requested for multiple "
                    "transforms.\nChanges from only one transform can be "
                    "serialized.\n";
    return 1;
  }

  // If we're asked to apply changes to files on disk, need to locate
  // clang-apply-replacements.
  if (!SerializeOnly) {
    if (!ReplacementHandler.findClangApplyReplacements(argv[0])) {
      llvm::errs() << "Could not find clang-apply-replacements\n";
      return 1;
    }

    if (DoFormat)
      ReplacementHandler.enableFormatting(FormatStyleOpt, FormatStyleConfig);
  }

  StringRef TempDestinationDir;
  if (SerializeLocation.getNumOccurrences() > 0)
    ReplacementHandler.setDestinationDir(SerializeLocation);
  else
    TempDestinationDir = ReplacementHandler.useTempDestinationDir();

  SourcePerfData PerfData;

  for (Transforms::const_iterator I = TransformManager.begin(),
                                  E = TransformManager.end();
       I != E; ++I) {
    Transform *T = *I;

    if (T->apply(*Compilations, Sources,LineRanges) != 0) {
      // FIXME: Improve ClangTool to not abort if just one file fails.
      return 1;
    }

    if (GlobalOptions.EnableTiming)
      collectSourcePerfData(*T, PerfData);

    if (SummaryMode) {
      llvm::outs() << "Transform: " << T->getName()
                   << " - Accepted: " << T->getAcceptedChanges();
      if (T->getChangesNotMade()) {
        llvm::outs() << " - Rejected: " << T->getRejectedChanges()
                     << " - Deferred: " << T->getDeferredChanges();
      }
      llvm::outs() << "\n";
    }

    if (!ReplacementHandler.serializeReplacements(T->getAllReplacements()))
      return 1;

    if (!SerializeOnly)
      if (!ReplacementHandler.applyReplacements())
        return 1;
  }

  // Let the user know which temporary directory the replacements got written
  // to.
  if (SerializeOnly && !TempDestinationDir.empty())
    llvm::errs() << "Replacements serialized to: " << TempDestinationDir << "\n";

  if (FinalSyntaxCheck) {
    ClangTool SyntaxTool(*Compilations, SourcePaths);
    if (SyntaxTool.run(newFrontendActionFactory<SyntaxOnlyAction>().get()) != 0)
      return 1;
  }

  // Report execution times.
  if (GlobalOptions.EnableTiming && !PerfData.empty()) {
    std::string DirectoryName = TimingDirectoryName;
    // Use default directory name.
    if (DirectoryName.empty())
      DirectoryName = "./migrate_perf";
    writePerfDataJSON(DirectoryName, PerfData);
  }

  return 0;
}
Esempio n. 22
0
int createStaticLibrary() {
  Logger::println("*** Creating static library ***");

  const bool isTargetMSVC =
      global.params.targetTriple->isWindowsMSVCEnvironment();

#if LDC_LLVM_VER >= 309
  const bool useInternalArchiver = ar.empty();
#else
  const bool useInternalArchiver = false;
#endif

  // find archiver
  std::string tool;
  if (useInternalArchiver) {
    tool = isTargetMSVC ? "llvm-lib.exe" : "llvm-ar";
  } else {
#ifdef _WIN32
    if (isTargetMSVC)
      windows::setupMsvcEnvironment();
#endif

    tool = getProgram(isTargetMSVC ? "lib.exe" : "ar", &ar);
  }

  // build arguments
  std::vector<std::string> args;

  // ask ar to create a new library
  if (!isTargetMSVC) {
    args.push_back("rcs");
  }

  // ask lib to be quiet
  if (isTargetMSVC) {
    args.push_back("/NOLOGO");
  }

  // output filename
  std::string libName;
  if (global.params.libname) { // explicit
    // DMD adds the default extension if there is none
    libName = opts::invokedByLDMD
                  ? FileName::defaultExt(global.params.libname, global.lib_ext)
                  : global.params.libname;
  } else { // infer from first object file
    libName = global.params.objfiles->dim
                  ? FileName::removeExt((*global.params.objfiles)[0])
                  : "a.out";
    libName += '.';
    libName += global.lib_ext;
  }

  // DMD creates static libraries in the objects directory (unless using an
  // absolute output path via `-of`).
  if (opts::invokedByLDMD && global.params.objdir &&
      !FileName::absolute(libName.c_str())) {
    libName = FileName::combine(global.params.objdir, libName.c_str());
  }

  if (isTargetMSVC) {
    args.push_back("/OUT:" + libName);
  } else {
    args.push_back(libName);
  }

  appendObjectFiles(args);

  // create path to the library
  CreateDirectoryOnDisk(libName);

#if LDC_LLVM_VER >= 309
  if (useInternalArchiver) {
    std::vector<const char *> fullArgs;
    fullArgs.reserve(1 + args.size());
    fullArgs.push_back(tool.c_str());
    for (const auto &arg : args)
      fullArgs.push_back(arg.c_str());

    if (global.params.verbose) {
      for (auto arg : fullArgs) {
        fprintf(global.stdmsg, "%s ", arg);
      }
      fprintf(global.stdmsg, "\n");
      fflush(global.stdmsg);
    }

    const int exitCode = isTargetMSVC ? ldc::lib(fullArgs) : ldc::ar(fullArgs);
    if (exitCode)
      error(Loc(), "%s failed with status: %d", tool.c_str(), exitCode);

    return exitCode;
  }
#endif

  // try to call archiver
  return executeToolAndWait(tool, args, global.params.verbose);
}
Esempio n. 23
0
int main(int argc, char **argv) {
  llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
  std::vector<ASTUnit*> ASTUnits;

  Program Prog;
  Indexer Idxer(Prog);

  if (InputFilenames.empty())
    return 0;

  DiagnosticOptions DiagOpts;
  llvm::IntrusiveRefCntPtr<Diagnostic> Diags
    = CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
    const std::string &InFile = InputFilenames[i];
    llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags));
    if (!AST)
      return 1;

    ASTUnits.push_back(AST.take());
  }

  if (ViewCallGraph) {
    llvm::OwningPtr<CallGraph> CG;
    CG.reset(new CallGraph(Prog));

    for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
      CG->addTU(ASTUnits[i]->getASTContext());

    CG->ViewCallGraph();
    return 0;
  }

  if (AnalyzeFunction.empty())
    return 0;

  // Feed all ASTUnits to the Indexer.
  for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) {
    ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]);
    Idxer.IndexAST(TU);
  }

  Entity Ent = Entity::get(AnalyzeFunction, Prog);
  FunctionDecl *FD;
  TranslationUnit *TU;
  llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);

  if (!FD)
    return 0;

  // Create an analysis engine.
  Preprocessor &PP = TU->getPreprocessor();

  // Hard code options for now.
  AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(),
                       PP.getLangOptions(), /* PathDiagnostic */ 0,
                       CreateRegionStoreManager,
                       CreateRangeConstraintManager, &Idxer,
                       /* MaxNodes */ 300000, /* MaxLoop */ 3,
                       /* VisualizeEG */ false, /* VisualizeEGUbi */ false,
                       /* PurgeDead */ true, /* EagerlyAssume */ false,
                       /* TrimGraph */ false, /* InlineCall */ true, 
                       /* UseUnoptimizedCFG */ false);

  GRTransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false,
                                         AMgr.getLangOptions());
  GRExprEngine Eng(AMgr, TF);

  Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes());
  
  return 0;
}
Esempio n. 24
0
int main(int argc, char **argv) {
  llvm::llvm_shutdown_obj shutdown;  // calls llvm_shutdown() on exit
  llvm::cl::ParseCommandLineOptions(argc, argv, "llvm2bpl - LLVM bitcode to Boogie transformation\n");

  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram PSTP(argc, argv);
  llvm::EnableDebugBuffering = true;

  llvm::SMDiagnostic err;
  llvm::LLVMContext Context;

  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();

  std::unique_ptr<llvm::Module> module = llvm::parseIRFile(InputFilename, err, Context);
  if (!err.getMessage().empty())
    check("Problem reading input bitcode/IR: " + err.getMessage().str());

  auto &L = module.get()->getDataLayoutStr();
  if (L.empty())
    module.get()->setDataLayout(DefaultDataLayout);

  ///////////////////////////////
  // initialise and run passes //
  ///////////////////////////////

  llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
  llvm::initializeAnalysis(Registry);

  llvm::legacy::PassManager pass_manager;

  pass_manager.add(llvm::createLowerSwitchPass());
  //pass_manager.add(llvm::createCFGSimplificationPass());
  pass_manager.add(llvm::createInternalizePass());
  pass_manager.add(llvm::createPromoteMemoryToRegisterPass());

  if (StaticUnroll) {
    pass_manager.add(llvm::createLoopSimplifyPass());
    pass_manager.add(llvm::createLoopRotatePass());
    //pass_manager.add(llvm::createIndVarSimplifyPass());
    pass_manager.add(llvm::createLoopUnrollPass(32767));
  }

  pass_manager.add(new llvm::StructRet());
  pass_manager.add(new llvm::SimplifyEV());
  pass_manager.add(new llvm::SimplifyIV());
  pass_manager.add(new smack::ExtractContracts());
  pass_manager.add(new smack::VerifierCodeMetadata());
  pass_manager.add(llvm::createDeadCodeEliminationPass());
  pass_manager.add(new smack::CodifyStaticInits());
  if (!Modular) {
    pass_manager.add(new smack::RemoveDeadDefs());
  }
  pass_manager.add(new llvm::MergeArrayGEP());
  // pass_manager.add(new smack::SimplifyLibCalls());
  pass_manager.add(new llvm::Devirtualize());

  if (SplitStructs)
    pass_manager.add(new smack::SplitAggregateLoadStore());

  if (smack::SmackOptions::MemorySafety) {
    pass_manager.add(new smack::MemorySafetyChecker());
  }

  if (SignedIntegerOverflow)
    pass_manager.add(new smack::SignedIntegerOverflowChecker());


  if(smack::SmackOptions::AddTiming){
    Triple ModuleTriple(module->getTargetTriple());
    assert (ModuleTriple.getArch() && "Module has no defined architecture: unable to add timing annotations");

    const TargetOptions Options; /* = InitTargetOptionsFromCodeGenFlags();*/
    std::string CPUStr = ""; /*getCPUStr();*/
    std::string FeaturesStr = ""; /*getFeaturesStr();*/
    TargetMachine *Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);

    assert(Machine && "Module did not have a Target Machine: Cannot set up timing pass");
    // Add an appropriate TargetLibraryInfo pass for the module's triple.
    TargetLibraryInfoImpl TLII(ModuleTriple);
    pass_manager.add(new TargetLibraryInfoWrapperPass(TLII));

    // Add internal analysis passes from the target machine.
    pass_manager.add(createTargetTransformInfoWrapperPass(Machine->getTargetIRAnalysis()));
    pass_manager.add(new smack::AddTiming());
  }

  std::vector<tool_output_file*> files;

  if (!FinalIrFilename.empty()) {
    std::error_code EC;
    auto F = new tool_output_file(FinalIrFilename.c_str(), EC, sys::fs::F_None);
    if (EC) check(EC.message());
    F->keep();
    files.push_back(F);
    pass_manager.add(llvm::createPrintModulePass(F->os()));
  }

  if (!OutputFilename.empty()) {
    std::error_code EC;
    auto F = new tool_output_file(OutputFilename.c_str(), EC, sys::fs::F_None);
    if (EC) check(EC.message());
    F->keep();
    files.push_back(F);
    pass_manager.add(new smack::SmackModuleGenerator());
    pass_manager.add(new smack::BplFilePrinter(F->os()));
  }

  pass_manager.run(*module.get());

  for (auto F : files)
    delete F;

  return 0;
}
Esempio n. 25
0
int main(int argc, char **argv) {
  llvm::llvm_shutdown_obj shutdown;  // calls llvm_shutdown() on exit
  llvm::cl::ParseCommandLineOptions(argc, argv, "SMACK - LLVM bitcode to Boogie transformation\n");

  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram PSTP(argc, argv);
  llvm::EnableDebugBuffering = true;

  if (OutputFilename.empty()) {
//    OutputFilename = getFileName(InputFilename) + ".bpl";
    OutputFilename = "a.bpl";
  }
 
  std::string error_msg;
  llvm::SMDiagnostic err;
  llvm::LLVMContext &context = llvm::getGlobalContext();  
  std::unique_ptr<llvm::Module> module;
  std::unique_ptr<llvm::tool_output_file> output;
 
  module.reset(llvm::ParseIRFile(InputFilename, err, context));
  if (module.get() == 0) {
    if (llvm::errs().has_colors()) llvm::errs().changeColor(llvm::raw_ostream::RED);
    llvm::errs() << "error: " << "Bitcode was not properly read; " << err.getMessage() << "\n";
    if (llvm::errs().has_colors()) llvm::errs().resetColor();
    return 1;
  }
 
  output.reset(new llvm::tool_output_file(OutputFilename.c_str(), error_msg, llvm::sys::fs::F_None));
  if (!error_msg.empty()) {
    if (llvm::errs().has_colors()) llvm::errs().changeColor(llvm::raw_ostream::RED);
    llvm::errs() << "error: " << error_msg << "\n";
    if (llvm::errs().has_colors()) llvm::errs().resetColor();
    return 1;
  }
 
  ///////////////////////////////
  // initialise and run passes //
  ///////////////////////////////

  llvm::PassManager pass_manager;
  llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
  llvm::initializeAnalysis(Registry);
 
  // add an appropriate DataLayout instance for the module
  const llvm::DataLayout *dl = 0;
  const std::string &moduleDataLayout = module.get()->getDataLayoutStr();
  if (!moduleDataLayout.empty())
    dl = new llvm::DataLayout(moduleDataLayout);
  else if (!DefaultDataLayout.empty())
    dl = new llvm::DataLayout(moduleDataLayout);
  if (dl) pass_manager.add(new llvm::DataLayoutPass(*dl));

  pass_manager.add(llvm::createLowerSwitchPass());
  pass_manager.add(llvm::createCFGSimplificationPass());
  pass_manager.add(llvm::createInternalizePass());
  pass_manager.add(llvm::createPromoteMemoryToRegisterPass());
  pass_manager.add(new llvm::StructRet());
  pass_manager.add(new llvm::SimplifyEV());
  pass_manager.add(new llvm::SimplifyIV());
  pass_manager.add(new smack::SmackModuleGenerator());
  pass_manager.add(new smack::BplFilePrinter(output->os()));
  pass_manager.run(*module.get());

  output->keep();

  return 0;
}
Esempio n. 26
0
static int
do_assemble(SourceManager& source_mgr, DiagnosticsEngine& diags)
{
    // Apply warning settings
    ApplyWarningSettings(diags);

    // Determine objfmt_bits based on -32 and -64 options
    std::string objfmt_bits = GetBitsSetting();

    FileManager& file_mgr = source_mgr.getFileManager();
    Assembler assembler("x86", YGAS_OBJFMT_BASE + objfmt_bits, diags,
                        dump_object);
    HeaderSearch headers(file_mgr);

    if (diags.hasFatalErrorOccurred())
        return EXIT_FAILURE;

    // Set object filename if specified.
    if (!obj_filename.empty())
        assembler.setObjectFilename(obj_filename);

    // Set parser.
    assembler.setParser("gas", diags);

    if (diags.hasFatalErrorOccurred())
        return EXIT_FAILURE;

    // Set debug format to dwarf2pass if it's legal for this object format.
    if (assembler.isOkDebugFormat("dwarf2pass"))
    {
        assembler.setDebugFormat("dwarf2pass", diags);
        if (diags.hasFatalErrorOccurred())
            return EXIT_FAILURE;
    }

    // open the input file or STDIN (for filename of "-")
    if (in_filename == "-")
    {
        OwningPtr<MemoryBuffer> my_stdin;
        if (llvm::error_code err = MemoryBuffer::getSTDIN(my_stdin))
        {
            diags.Report(SourceLocation(), diag::fatal_file_open)
                << in_filename << err.message();
            return EXIT_FAILURE;
        }
        source_mgr.createMainFileIDForMemBuffer(my_stdin.take());
    }
    else
    {
        const FileEntry* in = file_mgr.getFile(in_filename);
        if (!in)
        {
            diags.Report(SourceLocation(), diag::fatal_file_open)
                << in_filename;
            return EXIT_FAILURE;
        }
        source_mgr.createMainFileID(in);
    }

    // Initialize the object.
    if (!assembler.InitObject(source_mgr, diags))
        return EXIT_FAILURE;

    // Configure object per command line parameters.
    ConfigureObject(*assembler.getObject());

    // Predefine symbols.
    for (std::vector<std::string>::const_iterator i=defsym.begin(),
         end=defsym.end(); i != end; ++i)
    {
        StringRef str(*i);
        size_t equalpos = str.find('=');
        if (equalpos == StringRef::npos)
        {
            diags.Report(diag::fatal_bad_defsym) << str;
            continue;
        }
        StringRef name = str.slice(0, equalpos);
        StringRef vstr = str.slice(equalpos+1, StringRef::npos);

        IntNum value;
        if (!vstr.empty())
        {
            // determine radix
            unsigned int radix;
            if (vstr[0] == '0' && vstr.size() > 1 &&
                (vstr[1] == 'x' || vstr[1] == 'X'))
            {
                vstr = vstr.substr(2);
                radix = 16;
            }
            else if (vstr[0] == '0')
            {
                vstr = vstr.substr(1);
                radix = 8;
            }
            else
                radix = 10;

            // check validity
            const char* ptr = vstr.begin();
            const char* end = vstr.end();
            if (radix == 16)
            {
                while (ptr != end && isxdigit(*ptr))
                    ++ptr;
            }
            else if (radix == 8)
            {
                while (ptr != end && (*ptr >= '0' && *ptr <= '7'))
                    ++ptr;
            }
            else
            {
                while (ptr != end && isdigit(*ptr))
                    ++ptr;
            }
            if (ptr != end)
            {
                diags.Report(diag::fatal_bad_defsym) << name;
                continue;
            }
            value.setStr(vstr, radix);
        }

        // define equ
        assembler.getObject()->getSymbol(name)->DefineEqu(Expr(value));
    }

    if (diags.hasFatalErrorOccurred())
        return EXIT_FAILURE;

    // Initialize the parser.
    assembler.InitParser(source_mgr, diags, headers);

    // Assemble the input.
    if (!assembler.Assemble(source_mgr, diags))
    {
        // An error occurred during assembly.
        return EXIT_FAILURE;
    }

    // open the object file for output
    std::string err;
    raw_fd_ostream out(assembler.getObjectFilename().str().c_str(),
                       err, raw_fd_ostream::F_Binary);
    if (!err.empty())
    {
        diags.Report(SourceLocation(), diag::err_cannot_open_file)
            << obj_filename << err;
        return EXIT_FAILURE;
    }

    if (!assembler.Output(out, diags))
    {
        // An error occurred during output.
        // If we had an error at this point, we also need to delete the output
        // object file (to make sure it's not left newer than the source).
        out.close();
        remove(assembler.getObjectFilename().str().c_str());
        return EXIT_FAILURE;
    }

    // close object file
    out.close();
    return EXIT_SUCCESS;
}
Esempio n. 27
0
int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);
  // For codegen passes, only passes that do IR to IR transformation are
  // supported.
  initializeCodeGenPreparePass(Registry);
  initializeAtomicExpandPass(Registry);
  initializeRewriteSymbolsPass(Registry);
  initializeWinEHPreparePass(Registry);
  initializeDwarfEHPreparePass(Registry);
  initializeSjLjEHPreparePass(Registry);

  // Register Swift Only Passes.
  initializeSwiftAAWrapperPassPass(Registry);
  initializeSwiftRCIdentityPass(Registry);
  initializeSwiftARCOptPass(Registry);
  initializeSwiftARCContractPass(Registry);
  initializeSwiftStackPromotionPass(Registry);
  initializeInlineTreePrinterPass(Registry);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n");

  if (PrintStats)
    llvm::EnableStatistics();

  llvm::SMDiagnostic Err;

  // Load the input module...
  std::unique_ptr<Module> M =
      parseIRFile(InputFilename, Err, getGlobalContext());

  if (!M) {
    Err.print(argv[0], errs());
    return 1;
  }

  if (verifyModule(*M, &errs())) {
    errs() << argv[0] << ": " << InputFilename
           << ": error: input module is broken!\n";
    return 1;
  }

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    M->setTargetTriple(llvm::Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<llvm::tool_output_file> Out;
  // Default to standard output.
  if (OutputFilename.empty())
    OutputFilename = "-";

  std::error_code EC;
  Out.reset(
      new llvm::tool_output_file(OutputFilename, EC, llvm::sys::fs::F_None));
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  llvm::Triple ModuleTriple(M->getTargetTriple());
  std::string CPUStr, FeaturesStr;
  llvm::TargetMachine *Machine = nullptr;
  const llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();

  if (ModuleTriple.getArch()) {
    CPUStr = getCPUStr();
    FeaturesStr = getFeaturesStr();
    Machine = getTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);
  }

  std::unique_ptr<llvm::TargetMachine> TM(Machine);

  // Override function attributes based on CPUStr, FeaturesStr, and command line
  // flags.
  setFunctionAttributes(CPUStr, FeaturesStr, *M);

  if (Optimized) {
    IRGenOptions Opts;
    Opts.Optimize = true;

    // Then perform the optimizations.
    performLLVMOptimizations(Opts, M.get(), TM.get());
  } else {
    runSpecificPasses(argv[0], M.get(), TM.get(), ModuleTriple);
  }

  // Finally dump the output.
  dumpOutput(*M, Out->os());

  return 0;
}
Esempio n. 28
0
int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift SIL Extractor\n");

  CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(llvm::sys::fs::getMainExecutable(
      argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  // Give the context the list of search paths to use for modules.
  Invocation.setImportSearchPaths(ImportPaths);
  // Set the SDK path and target if given.
  if (SDKPath.getNumOccurrences() == 0) {
    const char *SDKROOT = getenv("SDKROOT");
    if (SDKROOT)
      SDKPath = SDKROOT;
  }
  if (!SDKPath.empty())
    Invocation.setSDKPath(SDKPath);
  if (!Triple.empty())
    Invocation.setTargetTriple(Triple);
  if (!ResourceDir.empty())
    Invocation.setRuntimeResourcePath(ResourceDir);
  Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
  Invocation.setParseStdlib();
  Invocation.getLangOptions().DisableAvailabilityChecking = true;
  Invocation.getLangOptions().EnableAccessControl = false;
  Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;

  // Load the input file.
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
      llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (!FileBufOrErr) {
    fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str());
    exit(-1);
  }

  // If it looks like we have an AST, set the source file kind to SIL and the
  // name of the module to the file's name.
  Invocation.addInputBuffer(FileBufOrErr.get().get());

  serialization::ExtendedValidationInfo extendedInfo;
  auto result = serialization::validateSerializedAST(
      FileBufOrErr.get()->getBuffer(), &extendedInfo);
  bool HasSerializedAST = result.status == serialization::Status::Valid;

  if (HasSerializedAST) {
    const StringRef Stem = ModuleName.size()
                               ? StringRef(ModuleName)
                               : llvm::sys::path::stem(InputFilename);
    Invocation.setModuleName(Stem);
    Invocation.setInputKind(InputFileKind::IFK_Swift_Library);
  } else {
    Invocation.setModuleName("main");
    Invocation.setInputKind(InputFileKind::IFK_SIL);
  }

  SILOptions &SILOpts = Invocation.getSILOptions();
  SILOpts.AssumeUnqualifiedOwnershipWhenParsing =
      AssumeUnqualifiedOwnershipWhenParsing;

  CompilerInstance CI;
  PrintingDiagnosticConsumer PrintDiags;
  CI.addDiagnosticConsumer(&PrintDiags);

  if (CI.setup(Invocation))
    return 1;
  CI.performSema();

  // If parsing produced an error, don't run any passes.
  if (CI.getASTContext().hadError())
    return 1;

  // Load the SIL if we have a module. We have to do this after SILParse
  // creating the unfortunate double if statement.
  if (HasSerializedAST) {
    assert(!CI.hasSILModule() &&
           "performSema() should not create a SILModule.");
    CI.setSILModule(
        SILModule::createEmptyModule(CI.getMainModule(), CI.getSILOptions()));
    std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create(
        CI.getASTContext(), CI.getSILModule(), nullptr);

    if (extendedInfo.isSIB())
      SL->getAllForModule(CI.getMainModule()->getName(), nullptr);
    else
      SL->getAll();
  }

  if (CommandLineFunctionNames.empty() && FunctionNameFile.empty())
    return CI.getASTContext().hadError();

  // For efficient usage, we separate our names into two separate sorted
  // lists, one of managled names, and one of unmangled names.
  std::vector<std::string> Names;
  getFunctionNames(Names);

  // First partition our function names into mangled/demangled arrays.
  auto FirstDemangledName = std::partition(
      Names.begin(), Names.end(), [](const std::string &Name) -> bool {
        StringRef NameRef(Name);
        return NameRef.startswith("_T") ||
               NameRef.startswith(MANGLING_PREFIX_STR);
      });

  // Then grab offsets to avoid any issues with iterator invalidation when we
  // sort.
  unsigned NumMangled = std::distance(Names.begin(), FirstDemangledName);
  unsigned NumNames = Names.size();

  // Then sort the two partitioned arrays.
  std::sort(Names.begin(), FirstDemangledName);
  std::sort(FirstDemangledName, Names.end());

  // Finally construct our ArrayRefs into the sorted std::vector for our
  // mangled and demangled names.
  ArrayRef<std::string> MangledNames(&*Names.begin(), NumMangled);
  ArrayRef<std::string> DemangledNames(&*std::next(Names.begin(), NumMangled),
                                       NumNames - NumMangled);

  DEBUG(llvm::errs() << "MangledNames to keep:\n";
        std::for_each(MangledNames.begin(), MangledNames.end(),
                      [](const std::string &str) {
                        llvm::errs() << "    " << str << '\n';
                      }));
  DEBUG(llvm::errs() << "DemangledNames to keep:\n";
        std::for_each(DemangledNames.begin(), DemangledNames.end(),
                      [](const std::string &str) {
                        llvm::errs() << "    " << str << '\n';
                      }));

  removeUnwantedFunctions(CI.getSILModule(), MangledNames, DemangledNames);

  if (EmitSIB) {
    llvm::SmallString<128> OutputFile;
    if (OutputFilename.size()) {
      OutputFile = OutputFilename;
    } else if (ModuleName.size()) {
      OutputFile = ModuleName;
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    } else {
      OutputFile = CI.getMainModule()->getName().str();
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    }

    SerializationOptions serializationOpts;
    serializationOpts.OutputPath = OutputFile.c_str();
    serializationOpts.SerializeAllSIL = true;
    serializationOpts.IsSIB = true;

    serialize(CI.getMainModule(), serializationOpts, CI.getSILModule());
  } else {
    const StringRef OutputFile =
        OutputFilename.size() ? StringRef(OutputFilename) : "-";

    if (OutputFile == "-") {
      CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    } else {
      std::error_code EC;
      llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
      if (EC) {
        llvm::errs() << "while opening '" << OutputFile << "': " << EC.message()
                     << '\n';
        return 1;
      }
      CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    }
  }
}