LoongArchTargetMachine.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //===-- LoongArchTargetMachine.cpp - Define TargetMachine for LoongArch ---===//
  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. // Implements the info about LoongArch target spec.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "LoongArchTargetMachine.h"
  13. #include "LoongArch.h"
  14. #include "LoongArchMachineFunctionInfo.h"
  15. #include "MCTargetDesc/LoongArchBaseInfo.h"
  16. #include "TargetInfo/LoongArchTargetInfo.h"
  17. #include "llvm/CodeGen/Passes.h"
  18. #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
  19. #include "llvm/CodeGen/TargetPassConfig.h"
  20. #include "llvm/MC/TargetRegistry.h"
  21. #include <optional>
  22. using namespace llvm;
  23. #define DEBUG_TYPE "loongarch"
  24. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() {
  25. // Register the target.
  26. RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target());
  27. RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target());
  28. auto *PR = PassRegistry::getPassRegistry();
  29. initializeLoongArchPreRAExpandPseudoPass(*PR);
  30. initializeLoongArchDAGToDAGISelPass(*PR);
  31. }
  32. static std::string computeDataLayout(const Triple &TT) {
  33. if (TT.isArch64Bit())
  34. return "e-m:e-p:64:64-i64:64-i128:128-n64-S128";
  35. assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported");
  36. return "e-m:e-p:32:32-i64:64-n32-S128";
  37. }
  38. static Reloc::Model getEffectiveRelocModel(const Triple &TT,
  39. std::optional<Reloc::Model> RM) {
  40. return RM.value_or(Reloc::Static);
  41. }
  42. LoongArchTargetMachine::LoongArchTargetMachine(
  43. const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
  44. const TargetOptions &Options, std::optional<Reloc::Model> RM,
  45. std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
  46. : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
  47. getEffectiveRelocModel(TT, RM),
  48. getEffectiveCodeModel(CM, CodeModel::Small), OL),
  49. TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
  50. initAsmInfo();
  51. }
  52. LoongArchTargetMachine::~LoongArchTargetMachine() = default;
  53. const LoongArchSubtarget *
  54. LoongArchTargetMachine::getSubtargetImpl(const Function &F) const {
  55. Attribute CPUAttr = F.getFnAttribute("target-cpu");
  56. Attribute TuneAttr = F.getFnAttribute("tune-cpu");
  57. Attribute FSAttr = F.getFnAttribute("target-features");
  58. std::string CPU =
  59. CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
  60. std::string TuneCPU =
  61. TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
  62. std::string FS =
  63. FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
  64. std::string Key = CPU + TuneCPU + FS;
  65. auto &I = SubtargetMap[Key];
  66. if (!I) {
  67. // This needs to be done before we create a new subtarget since any
  68. // creation will depend on the TM and the code generation flags on the
  69. // function that reside in TargetOptions.
  70. resetTargetOptions(F);
  71. auto ABIName = Options.MCOptions.getABIName();
  72. if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
  73. F.getParent()->getModuleFlag("target-abi"))) {
  74. auto TargetABI = LoongArchABI::getTargetABI(ABIName);
  75. if (TargetABI != LoongArchABI::ABI_Unknown &&
  76. ModuleTargetABI->getString() != ABIName) {
  77. report_fatal_error("-target-abi option != target-abi module flag");
  78. }
  79. ABIName = ModuleTargetABI->getString();
  80. }
  81. I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
  82. ABIName, *this);
  83. }
  84. return I.get();
  85. }
  86. MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo(
  87. BumpPtrAllocator &Allocator, const Function &F,
  88. const TargetSubtargetInfo *STI) const {
  89. return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(
  90. Allocator, F, STI);
  91. }
  92. namespace {
  93. class LoongArchPassConfig : public TargetPassConfig {
  94. public:
  95. LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
  96. : TargetPassConfig(TM, PM) {}
  97. LoongArchTargetMachine &getLoongArchTargetMachine() const {
  98. return getTM<LoongArchTargetMachine>();
  99. }
  100. void addIRPasses() override;
  101. bool addInstSelector() override;
  102. void addPreEmitPass() override;
  103. void addPreEmitPass2() override;
  104. void addPreRegAlloc() override;
  105. };
  106. } // end namespace
  107. TargetPassConfig *
  108. LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) {
  109. return new LoongArchPassConfig(*this, PM);
  110. }
  111. void LoongArchPassConfig::addIRPasses() {
  112. addPass(createAtomicExpandPass());
  113. TargetPassConfig::addIRPasses();
  114. }
  115. bool LoongArchPassConfig::addInstSelector() {
  116. addPass(createLoongArchISelDag(getLoongArchTargetMachine()));
  117. return false;
  118. }
  119. void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
  120. void LoongArchPassConfig::addPreEmitPass2() {
  121. // Schedule the expansion of AtomicPseudos at the last possible moment,
  122. // avoiding the possibility for other passes to break the requirements for
  123. // forward progress in the LL/SC block.
  124. addPass(createLoongArchExpandAtomicPseudoPass());
  125. }
  126. void LoongArchPassConfig::addPreRegAlloc() {
  127. addPass(createLoongArchPreRAExpandPseudoPass());
  128. }