brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · 92a9388 Raw
245 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// Implements the info about LoongArch target spec.10//11//===----------------------------------------------------------------------===//12 13#include "LoongArchTargetMachine.h"14#include "LoongArch.h"15#include "LoongArchMachineFunctionInfo.h"16#include "LoongArchTargetTransformInfo.h"17#include "MCTargetDesc/LoongArchBaseInfo.h"18#include "TargetInfo/LoongArchTargetInfo.h"19#include "llvm/Analysis/TargetTransformInfo.h"20#include "llvm/CodeGen/Passes.h"21#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"22#include "llvm/CodeGen/TargetPassConfig.h"23#include "llvm/MC/TargetRegistry.h"24#include "llvm/Support/CodeGen.h"25#include "llvm/Support/Compiler.h"26#include "llvm/Transforms/Scalar.h"27#include <optional>28 29using namespace llvm;30 31#define DEBUG_TYPE "loongarch"32 33extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void34LLVMInitializeLoongArchTarget() {35  // Register the target.36  RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target());37  RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target());38  auto *PR = PassRegistry::getPassRegistry();39  initializeLoongArchDeadRegisterDefinitionsPass(*PR);40  initializeLoongArchMergeBaseOffsetOptPass(*PR);41  initializeLoongArchOptWInstrsPass(*PR);42  initializeLoongArchPreRAExpandPseudoPass(*PR);43  initializeLoongArchExpandPseudoPass(*PR);44  initializeLoongArchDAGToDAGISelLegacyPass(*PR);45  initializeLoongArchExpandAtomicPseudoPass(*PR);46}47 48static cl::opt<bool> EnableLoongArchDeadRegisterElimination(49    "loongarch-enable-dead-defs", cl::Hidden,50    cl::desc("Enable the pass that removes dead"51             " definitons and replaces stores to"52             " them with stores to r0"),53    cl::init(true));54 55static cl::opt<bool>56    EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden,57                           cl::desc("Enable the loop data prefetch pass"),58                           cl::init(false));59 60static cl::opt<bool>61    EnableMergeBaseOffset("loongarch-enable-merge-offset",62                          cl::desc("Enable the merge base offset pass"),63                          cl::init(true), cl::Hidden);64 65static cl::opt<bool>66    EnableSinkFold("loongarch-enable-sink-fold",67                   cl::desc("Enable sinking and folding of instruction copies"),68                   cl::init(true), cl::Hidden);69 70static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {71  return RM.value_or(Reloc::Static);72}73 74static CodeModel::Model75getEffectiveLoongArchCodeModel(const Triple &TT,76                               std::optional<CodeModel::Model> CM) {77  if (!CM)78    return TT.isArch64Bit() ? CodeModel::Medium : CodeModel::Small;79 80  switch (*CM) {81  case CodeModel::Small:82    return *CM;83  case CodeModel::Medium:84  case CodeModel::Large:85    if (!TT.isArch64Bit())86      report_fatal_error("Medium/Large code model requires LA64");87    return *CM;88  default:89    report_fatal_error(90        "Only small, medium and large code models are allowed on LoongArch");91  }92}93 94LoongArchTargetMachine::LoongArchTargetMachine(95    const Target &T, const Triple &TT, StringRef CPU, StringRef FS,96    const TargetOptions &Options, std::optional<Reloc::Model> RM,97    std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)98    : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,99                               getEffectiveRelocModel(RM),100                               getEffectiveLoongArchCodeModel(TT, CM), OL),101      TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {102  initAsmInfo();103}104 105LoongArchTargetMachine::~LoongArchTargetMachine() = default;106 107const LoongArchSubtarget *108LoongArchTargetMachine::getSubtargetImpl(const Function &F) const {109  Attribute CPUAttr = F.getFnAttribute("target-cpu");110  Attribute TuneAttr = F.getFnAttribute("tune-cpu");111  Attribute FSAttr = F.getFnAttribute("target-features");112 113  std::string CPU =114      CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;115  std::string TuneCPU =116      TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;117  std::string FS =118      FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;119 120  std::string Key = CPU + TuneCPU + FS;121  auto &I = SubtargetMap[Key];122  if (!I) {123    // This needs to be done before we create a new subtarget since any124    // creation will depend on the TM and the code generation flags on the125    // function that reside in TargetOptions.126    resetTargetOptions(F);127    auto ABIName = Options.MCOptions.getABIName();128    if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(129            F.getParent()->getModuleFlag("target-abi"))) {130      auto TargetABI = LoongArchABI::getTargetABI(ABIName);131      if (TargetABI != LoongArchABI::ABI_Unknown &&132          ModuleTargetABI->getString() != ABIName) {133        report_fatal_error("-target-abi option != target-abi module flag");134      }135      ABIName = ModuleTargetABI->getString();136    }137    I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,138                                             ABIName, *this);139  }140  return I.get();141}142 143MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo(144    BumpPtrAllocator &Allocator, const Function &F,145    const TargetSubtargetInfo *STI) const {146  return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(147      Allocator, F, STI);148}149 150namespace {151class LoongArchPassConfig : public TargetPassConfig {152public:153  LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)154      : TargetPassConfig(TM, PM) {155    setEnableSinkAndFold(EnableSinkFold);156  }157 158  LoongArchTargetMachine &getLoongArchTargetMachine() const {159    return getTM<LoongArchTargetMachine>();160  }161 162  void addIRPasses() override;163  void addCodeGenPrepare() override;164  bool addInstSelector() override;165  void addPreEmitPass() override;166  void addPreEmitPass2() override;167  void addMachineSSAOptimization() override;168  void addPreRegAlloc() override;169  bool addRegAssignAndRewriteFast() override;170  bool addRegAssignAndRewriteOptimized() override;171};172} // end namespace173 174TargetPassConfig *175LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) {176  return new LoongArchPassConfig(*this, PM);177}178 179void LoongArchPassConfig::addIRPasses() {180  // Run LoopDataPrefetch181  //182  // Run this before LSR to remove the multiplies involved in computing the183  // pointer values N iterations ahead.184  if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch)185    addPass(createLoopDataPrefetchPass());186  addPass(createAtomicExpandLegacyPass());187 188  TargetPassConfig::addIRPasses();189}190 191void LoongArchPassConfig::addCodeGenPrepare() {192  if (getOptLevel() != CodeGenOptLevel::None)193    addPass(createTypePromotionLegacyPass());194  TargetPassConfig::addCodeGenPrepare();195}196 197bool LoongArchPassConfig::addInstSelector() {198  addPass(createLoongArchISelDag(getLoongArchTargetMachine(), getOptLevel()));199 200  return false;201}202 203TargetTransformInfo204LoongArchTargetMachine::getTargetTransformInfo(const Function &F) const {205  return TargetTransformInfo(std::make_unique<LoongArchTTIImpl>(this, F));206}207 208void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }209 210void LoongArchPassConfig::addPreEmitPass2() {211  addPass(createLoongArchExpandPseudoPass());212  // Schedule the expansion of AtomicPseudos at the last possible moment,213  // avoiding the possibility for other passes to break the requirements for214  // forward progress in the LL/SC block.215  addPass(createLoongArchExpandAtomicPseudoPass());216}217 218void LoongArchPassConfig::addMachineSSAOptimization() {219  TargetPassConfig::addMachineSSAOptimization();220 221  if (TM->getTargetTriple().isLoongArch64()) {222    addPass(createLoongArchOptWInstrsPass());223  }224}225 226void LoongArchPassConfig::addPreRegAlloc() {227  addPass(createLoongArchPreRAExpandPseudoPass());228  if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMergeBaseOffset)229    addPass(createLoongArchMergeBaseOffsetOptPass());230}231 232bool LoongArchPassConfig::addRegAssignAndRewriteFast() {233  if (TM->getOptLevel() != CodeGenOptLevel::None &&234      EnableLoongArchDeadRegisterElimination)235    addPass(createLoongArchDeadRegisterDefinitionsPass());236  return TargetPassConfig::addRegAssignAndRewriteFast();237}238 239bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {240  if (TM->getOptLevel() != CodeGenOptLevel::None &&241      EnableLoongArchDeadRegisterElimination)242    addPass(createLoongArchDeadRegisterDefinitionsPass());243  return TargetPassConfig::addRegAssignAndRewriteOptimized();244}245