llvm-as.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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())) {
  78. const ModuleSummaryIndex *IndexToWrite = nullptr;
  79. // Don't attempt to write a summary index unless it contains any entries or
  80. // has non-zero flags. The latter is used to assemble dummy index files for
  81. // skipping modules by distributed ThinLTO backends. Otherwise we get an empty
  82. // summary section.
  83. if (Index && (Index->begin() != Index->end() || Index->getFlags()))
  84. IndexToWrite = Index;
  85. if (!IndexToWrite || (M && (!M->empty() || !M->global_empty())))
  86. // If we have a non-empty Module, then we write the Module plus
  87. // any non-null Index along with it as a per-module Index.
  88. // If both are empty, this will give an empty module block, which is
  89. // the expected behavior.
  90. WriteBitcodeToFile(*M, Out->os(), PreserveBitcodeUseListOrder,
  91. IndexToWrite, EmitModuleHash);
  92. else
  93. // Otherwise, with an empty Module but non-empty Index, we write a
  94. // combined index.
  95. writeIndexToFile(*IndexToWrite, Out->os());
  96. }
  97. // Declare success.
  98. Out->keep();
  99. }
  100. int main(int argc, char **argv) {
  101. InitLLVM X(argc, argv);
  102. cl::HideUnrelatedOptions(AsCat);
  103. cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n");
  104. LLVMContext Context;
  105. // Parse the file now...
  106. SMDiagnostic Err;
  107. auto SetDataLayout = [](StringRef) -> Optional<std::string> {
  108. if (ClDataLayout.empty())
  109. return None;
  110. return ClDataLayout;
  111. };
  112. ParsedModuleAndIndex ModuleAndIndex;
  113. if (DisableVerify) {
  114. ModuleAndIndex = parseAssemblyFileWithIndexNoUpgradeDebugInfo(
  115. InputFilename, Err, Context, nullptr, SetDataLayout);
  116. } else {
  117. ModuleAndIndex = parseAssemblyFileWithIndex(InputFilename, Err, Context,
  118. nullptr, SetDataLayout);
  119. }
  120. std::unique_ptr<Module> M = std::move(ModuleAndIndex.Mod);
  121. if (!M.get()) {
  122. Err.print(argv[0], errs());
  123. return 1;
  124. }
  125. std::unique_ptr<ModuleSummaryIndex> Index = std::move(ModuleAndIndex.Index);
  126. if (!DisableVerify) {
  127. std::string ErrorStr;
  128. raw_string_ostream OS(ErrorStr);
  129. if (verifyModule(*M.get(), &OS)) {
  130. errs() << argv[0]
  131. << ": assembly parsed, but does not verify as correct!\n";
  132. errs() << OS.str();
  133. return 1;
  134. }
  135. // TODO: Implement and call summary index verifier.
  136. }
  137. if (DumpAsm) {
  138. errs() << "Here's the assembly:\n" << *M.get();
  139. if (Index.get() && Index->begin() != Index->end())
  140. Index->print(errs());
  141. }
  142. if (!DisableOutput)
  143. WriteOutputFile(M.get(), Index.get());
  144. return 0;
  145. }