xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- LanaiTargetMachine.cpp - Define TargetMachine for Lanai ---------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Implements the info about Lanai target spec.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "LanaiTargetMachine.h"
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "Lanai.h"
16bdd1243dSDimitry Andric #include "LanaiMachineFunctionInfo.h"
170b57cec5SDimitry Andric #include "LanaiTargetObjectFile.h"
180b57cec5SDimitry Andric #include "LanaiTargetTransformInfo.h"
190b57cec5SDimitry Andric #include "TargetInfo/LanaiTargetInfo.h"
200b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
24349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
250b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h"
260b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
27bdd1243dSDimitry Andric #include <optional>
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric using namespace llvm;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric namespace llvm {
320b57cec5SDimitry Andric void initializeLanaiMemAluCombinerPass(PassRegistry &);
330b57cec5SDimitry Andric } // namespace llvm
340b57cec5SDimitry Andric 
35480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiTarget() {
360b57cec5SDimitry Andric   // Register the target.
370b57cec5SDimitry Andric   RegisterTargetMachine<LanaiTargetMachine> registered_target(
380b57cec5SDimitry Andric       getTheLanaiTarget());
39bdd1243dSDimitry Andric   PassRegistry &PR = *PassRegistry::getPassRegistry();
40*0fca6ea1SDimitry Andric   initializeLanaiDAGToDAGISelLegacyPass(PR);
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric static std::string computeDataLayout() {
440b57cec5SDimitry Andric   // Data layout (keep in sync with clang/lib/Basic/Targets.cpp)
450b57cec5SDimitry Andric   return "E"        // Big endian
460b57cec5SDimitry Andric          "-m:e"     // ELF name manging
470b57cec5SDimitry Andric          "-p:32:32" // 32-bit pointers, 32 bit aligned
480b57cec5SDimitry Andric          "-i64:64"  // 64 bit integers, 64 bit aligned
490b57cec5SDimitry Andric          "-a:0:32"  // 32 bit alignment of objects of aggregate type
500b57cec5SDimitry Andric          "-n32"     // 32 bit native integer width
510b57cec5SDimitry Andric          "-S64";    // 64 bit natural stack alignment
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
54bdd1243dSDimitry Andric static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
5581ad6265SDimitry Andric   return RM.value_or(Reloc::PIC_);
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
58bdd1243dSDimitry Andric LanaiTargetMachine::LanaiTargetMachine(
59bdd1243dSDimitry Andric     const Target &T, const Triple &TT, StringRef Cpu, StringRef FeatureString,
60bdd1243dSDimitry Andric     const TargetOptions &Options, std::optional<Reloc::Model> RM,
615f757f3fSDimitry Andric     std::optional<CodeModel::Model> CodeModel, CodeGenOptLevel OptLevel,
62bdd1243dSDimitry Andric     bool JIT)
630b57cec5SDimitry Andric     : LLVMTargetMachine(T, computeDataLayout(), TT, Cpu, FeatureString, Options,
640b57cec5SDimitry Andric                         getEffectiveRelocModel(RM),
650b57cec5SDimitry Andric                         getEffectiveCodeModel(CodeModel, CodeModel::Medium),
660b57cec5SDimitry Andric                         OptLevel),
670b57cec5SDimitry Andric       Subtarget(TT, Cpu, FeatureString, *this, Options, getCodeModel(),
680b57cec5SDimitry Andric                 OptLevel),
690b57cec5SDimitry Andric       TLOF(new LanaiTargetObjectFile()) {
700b57cec5SDimitry Andric   initAsmInfo();
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric TargetTransformInfo
7481ad6265SDimitry Andric LanaiTargetMachine::getTargetTransformInfo(const Function &F) const {
750b57cec5SDimitry Andric   return TargetTransformInfo(LanaiTTIImpl(this, F));
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
78bdd1243dSDimitry Andric MachineFunctionInfo *LanaiTargetMachine::createMachineFunctionInfo(
79bdd1243dSDimitry Andric     BumpPtrAllocator &Allocator, const Function &F,
80bdd1243dSDimitry Andric     const TargetSubtargetInfo *STI) const {
81bdd1243dSDimitry Andric   return LanaiMachineFunctionInfo::create<LanaiMachineFunctionInfo>(Allocator,
82bdd1243dSDimitry Andric                                                                     F, STI);
83bdd1243dSDimitry Andric }
84bdd1243dSDimitry Andric 
850b57cec5SDimitry Andric namespace {
860b57cec5SDimitry Andric // Lanai Code Generator Pass Configuration Options.
870b57cec5SDimitry Andric class LanaiPassConfig : public TargetPassConfig {
880b57cec5SDimitry Andric public:
890b57cec5SDimitry Andric   LanaiPassConfig(LanaiTargetMachine &TM, PassManagerBase *PassManager)
900b57cec5SDimitry Andric       : TargetPassConfig(TM, *PassManager) {}
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   LanaiTargetMachine &getLanaiTargetMachine() const {
930b57cec5SDimitry Andric     return getTM<LanaiTargetMachine>();
940b57cec5SDimitry Andric   }
950b57cec5SDimitry Andric 
961db9f3b2SDimitry Andric   void addIRPasses() override;
970b57cec5SDimitry Andric   bool addInstSelector() override;
980b57cec5SDimitry Andric   void addPreSched2() override;
990b57cec5SDimitry Andric   void addPreEmitPass() override;
1000b57cec5SDimitry Andric };
1010b57cec5SDimitry Andric } // namespace
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric TargetPassConfig *
1040b57cec5SDimitry Andric LanaiTargetMachine::createPassConfig(PassManagerBase &PassManager) {
1050b57cec5SDimitry Andric   return new LanaiPassConfig(*this, &PassManager);
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1081db9f3b2SDimitry Andric void LanaiPassConfig::addIRPasses() {
109*0fca6ea1SDimitry Andric   addPass(createAtomicExpandLegacyPass());
1101db9f3b2SDimitry Andric 
1111db9f3b2SDimitry Andric   TargetPassConfig::addIRPasses();
1121db9f3b2SDimitry Andric }
1131db9f3b2SDimitry Andric 
1140b57cec5SDimitry Andric // Install an instruction selector pass.
1150b57cec5SDimitry Andric bool LanaiPassConfig::addInstSelector() {
1160b57cec5SDimitry Andric   addPass(createLanaiISelDag(getLanaiTargetMachine()));
1170b57cec5SDimitry Andric   return false;
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric // Implemented by targets that want to run passes immediately before
1210b57cec5SDimitry Andric // machine code is emitted.
1220b57cec5SDimitry Andric void LanaiPassConfig::addPreEmitPass() {
1230b57cec5SDimitry Andric   addPass(createLanaiDelaySlotFillerPass(getLanaiTargetMachine()));
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric // Run passes after prolog-epilog insertion and before the second instruction
1270b57cec5SDimitry Andric // scheduling pass.
1280b57cec5SDimitry Andric void LanaiPassConfig::addPreSched2() {
1290b57cec5SDimitry Andric   addPass(createLanaiMemAluCombinerPass());
1300b57cec5SDimitry Andric }
131