codegen.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/codegen/codegen.h"
  5. #include <cstdio>
  6. #include "llvm/IR/LegacyPassManager.h"
  7. #include "llvm/MC/TargetRegistry.h"
  8. #include "llvm/Support/FileSystem.h"
  9. #include "llvm/Support/TargetSelect.h"
  10. #include "llvm/Target/TargetMachine.h"
  11. #include "llvm/Target/TargetOptions.h"
  12. #include "llvm/TargetParser/Host.h"
  13. namespace Carbon {
  14. auto PrintAssemblyFromModule(llvm::Module& module,
  15. llvm::StringRef target_triple,
  16. llvm::raw_pwrite_stream& error_stream,
  17. llvm::raw_pwrite_stream& output_stream) -> bool {
  18. // Initialize the target registry etc.
  19. llvm::InitializeAllTargetInfos();
  20. llvm::InitializeAllTargets();
  21. llvm::InitializeAllTargetMCs();
  22. llvm::InitializeAllAsmParsers();
  23. llvm::InitializeAllAsmPrinters();
  24. std::string error;
  25. llvm::StringRef triple = target_triple;
  26. std::string host_triple;
  27. if (target_triple.empty()) {
  28. host_triple = llvm::sys::getDefaultTargetTriple();
  29. triple = host_triple;
  30. }
  31. const auto* target = llvm::TargetRegistry::lookupTarget(triple, error);
  32. if (!target) {
  33. error_stream << "ERROR: " << error << "\n";
  34. return false;
  35. }
  36. constexpr llvm::StringLiteral CPU = "generic";
  37. constexpr llvm::StringLiteral Features = "";
  38. llvm::TargetOptions target_opts;
  39. std::optional<llvm::Reloc::Model> reloc_model;
  40. auto* target_machine = target->createTargetMachine(
  41. target_triple, CPU, Features, target_opts, reloc_model);
  42. module.setDataLayout(target_machine->createDataLayout());
  43. module.setTargetTriple(target_triple);
  44. // Using the legacy PM to generate the assembly since the new PM
  45. // does not work with this yet.
  46. // TODO: make the new PM work with the codegen pipeline.
  47. llvm::legacy::PassManager pass;
  48. auto file_type = llvm::CGFT_AssemblyFile;
  49. if (target_machine->addPassesToEmitFile(pass, output_stream, nullptr,
  50. file_type)) {
  51. error_stream << "Nothing to write to object file\n";
  52. return false;
  53. }
  54. pass.run(module);
  55. delete target_machine;
  56. return true;
  57. }
  58. } // namespace Carbon