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
LLVMInitializeLanaiTarget()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
computeDataLayout()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
getEffectiveRelocModel(std::optional<Reloc::Model> RM)54bdd1243dSDimitry Andric static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
5581ad6265SDimitry Andric return RM.value_or(Reloc::PIC_);
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric
LanaiTargetMachine(const Target & T,const Triple & TT,StringRef Cpu,StringRef FeatureString,const TargetOptions & Options,std::optional<Reloc::Model> RM,std::optional<CodeModel::Model> CodeModel,CodeGenOptLevel OptLevel,bool JIT)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
getTargetTransformInfo(const Function & F) const7481ad6265SDimitry Andric LanaiTargetMachine::getTargetTransformInfo(const Function &F) const {
750b57cec5SDimitry Andric return TargetTransformInfo(LanaiTTIImpl(this, F));
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric
createMachineFunctionInfo(BumpPtrAllocator & Allocator,const Function & F,const TargetSubtargetInfo * STI) const78bdd1243dSDimitry 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:
LanaiPassConfig(LanaiTargetMachine & TM,PassManagerBase * PassManager)890b57cec5SDimitry Andric LanaiPassConfig(LanaiTargetMachine &TM, PassManagerBase *PassManager)
900b57cec5SDimitry Andric : TargetPassConfig(TM, *PassManager) {}
910b57cec5SDimitry Andric
getLanaiTargetMachine() const920b57cec5SDimitry 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 *
createPassConfig(PassManagerBase & PassManager)1040b57cec5SDimitry Andric LanaiTargetMachine::createPassConfig(PassManagerBase &PassManager) {
1050b57cec5SDimitry Andric return new LanaiPassConfig(*this, &PassManager);
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric
addIRPasses()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.
addInstSelector()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.
addPreEmitPass()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.
addPreSched2()1280b57cec5SDimitry Andric void LanaiPassConfig::addPreSched2() {
1290b57cec5SDimitry Andric addPass(createLanaiMemAluCombinerPass());
1300b57cec5SDimitry Andric }
131