llvm-as.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This utility may be invoked in the following manner:
  10. // llvm-as --help - Output information about command line switches
  11. // llvm-as [options] - Read LLVM asm from stdin, write bitcode to stdout
  12. // llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bitcode
  13. // to the x.bc file.
  14. //
  15. //===----------------------------------------------------------------------===//
  16. #include "llvm/AsmParser/Parser.h"
  17. #include "llvm/Bitcode/BitcodeWriter.h"
  18. #include "llvm/IR/LLVMContext.h"
  19. #include "llvm/IR/Module.h"
  20. #include "llvm/IR/ModuleSummaryIndex.h"
  21. #include "llvm/IR/Verifier.h"
  22. #include "llvm/Support/CommandLine.h"
  23. #include "llvm/Support/FileSystem.h"
  24. #include "llvm/Support/InitLLVM.h"
  25. #include "llvm/Support/ManagedStatic.h"
  26. #include "llvm/Support/SourceMgr.h"
  27. #include "llvm/Support/SystemUtils.h"
  28. #include "llvm/Support/ToolOutputFile.h"
  29. #include <memory>
  30. using namespace llvm;
  31. cl::OptionCategory AsCat("llvm-as Options");
  32. static cl::opt<std::string> InputFilename(cl::Positional,
  33. cl::desc("<input .llvm file>"),
  34. cl::init("-"));
  35. static cl::opt<std::string> OutputFilename("o",
  36. cl::desc("Override output filename"),
  37. cl::value_desc("filename"),
  38. cl::cat(AsCat));
  39. static cl::opt<bool> Force("f", cl::desc("Enable binary output on terminals"),
  40. cl::cat(AsCat));
  41. static cl::opt<bool> DisableOutput("disable-output", cl::desc("Disable output"),
  42. cl::init(false), cl::cat(AsCat));
  43. static cl::opt<bool> EmitModuleHash("module-hash", cl::desc("Emit module hash"),
  44. cl::init(false), cl::cat(AsCat));
  45. static cl::opt<bool> DumpAsm("d", cl::desc("Print assembly as parsed"),
  46. cl::Hidden, cl::cat(AsCat));
  47. static cl::opt<bool>
  48. DisableVerify("disable-verify", cl::Hidden,
  49. cl::desc("Do not run verifier on input LLVM (dangerous!)"),
  50. cl::cat(AsCat));
  51. static cl::opt<bool> PreserveBitcodeUseListOrder(
  52. "preserve-bc-uselistorder",
  53. cl::desc("Preserve use-list order when writing LLVM bitcode."),
  54. cl::init(true), cl::Hidden, cl::cat(AsCat));
  55. static cl::opt<std::string> ClDataLayout("data-layout",
  56. cl::desc("data layout string to use"),
  57. cl::value_desc("layout-string"),
  58. cl::init(""), cl::cat(AsCat));
  59. static void WriteOutputFile(const Module *M, const ModuleSummaryIndex *Index) {
  60. // Infer the output filename if needed.
  61. if (OutputFilename.empty()) {
  62. if (InputFilename == "-") {
  63. OutputFilename = "-";
  64. } else {
  65. StringRef IFN = InputFilename;
  66. OutputFilename = (IFN.endswith(".ll") ? IFN.drop_back(3) : IFN).str();
  67. OutputFilename += ".bc";
  68. }
  69. }
  70. std::error_code EC;
  71. std::unique_ptr<ToolOutputFile> Out(
  72. new ToolOutputFile(OutputFilename, EC, sys::fs::OF_None));
  73. if (EC) {
  74. errs() << EC.message() << '\n';
  75. exit(1);
  76. }
  77. if (Force || !CheckBitcodeOutputToConsole(Out->os(), true)) {
  78. const ModuleSummaryIndex *IndexToWrite = nullptr;
  79. // Don't attempt to write a summary index unless it contains any entries.
  80. // Otherwise we get an empty summary section.
  81. if (Index && Index->begin() != Index->end())
  82. IndexToWrite = Index;
  83. if (!IndexToWrite || (M && (!M->empty() || !M->global_empty())))
  84. // If we have a non-empty Module, then we write the Module plus
  85. // any non-null Index along with it as a per-module Index.
  86. // If both are empty, this will give an empty module block, which is
  87. // the expected behavior.
  88. WriteBitcodeToFile(*M, Out->os(), PreserveBitcodeUseListOrder,
  89. IndexToWrite, EmitModuleHash);
  90. else
  91. // Otherwise, with an empty Module but non-empty Index, we write a
  92. // combined index.
  93. WriteIndexToFile(*IndexToWrite, Out->os());
  94. }
  95. // Declare success.
  96. Out->keep();
  97. }
  98. int main(int argc, char **argv) {
  99. InitLLVM X(argc, argv);
  100. LLVMContext Context;
  101. cl::HideUnrelatedOptions(AsCat);
  102. cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n");
  103. // Parse the file now...
  104. SMDiagnostic Err;
  105. auto ModuleAndIndex = parseAssemblyFileWithIndex(
  106. InputFilename, Err, Context, nullptr, !DisableVerify, ClDataLayout);
  107. std::unique_ptr<Module> M = std::move(ModuleAndIndex.Mod);
  108. if (!M.get()) {
  109. Err.print(argv[0], errs());
  110. return 1;
  111. }
  112. std::unique_ptr<ModuleSummaryIndex> Index = std::move(ModuleAndIndex.Index);
  113. if (!DisableVerify) {
  114. std::string ErrorStr;
  115. raw_string_ostream OS(ErrorStr);
  116. if (verifyModule(*M.get(), &OS)) {
  117. errs() << argv[0]
  118. << ": assembly parsed, but does not verify as correct!\n";
  119. errs() << OS.str();
  120. return 1;
  121. }
  122. // TODO: Implement and call summary index verifier.
  123. }
  124. if (DumpAsm) {
  125. errs() << "Here's the assembly:\n" << *M.get();
  126. if (Index.get() && Index->begin() != Index->end())
  127. Index->print(errs());
  128. }
  129. if (!DisableOutput)
  130. WriteOutputFile(M.get(), Index.get());
  131. return 0;
  132. }