1//===-- VETargetMachine.cpp - Define TargetMachine for VE -----------------===//
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//
10//===----------------------------------------------------------------------===//
11
12#include "VETargetMachine.h"
13#include "TargetInfo/VETargetInfo.h"
14#include "VE.h"
15#include "VEMachineFunctionInfo.h"
16#include "VETargetTransformInfo.h"
17#include "llvm/CodeGen/Passes.h"
18#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
19#include "llvm/CodeGen/TargetPassConfig.h"
20#include "llvm/IR/LegacyPassManager.h"
21#include "llvm/MC/TargetRegistry.h"
22#include "llvm/Support/Compiler.h"
23#include <optional>
24
25using namespace llvm;
26
27#define DEBUG_TYPE "ve"
28
29extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVETarget() {
30 // Register the target.
31 RegisterTargetMachine<VETargetMachine> X(getTheVETarget());
32
33 PassRegistry &PR = *PassRegistry::getPassRegistry();
34 initializeVEAsmPrinterPass(PR);
35 initializeVEDAGToDAGISelLegacyPass(PR);
36}
37
38static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
39 return RM.value_or(u: Reloc::Static);
40}
41
42namespace {
43class VEELFTargetObjectFile : public TargetLoweringObjectFileELF {
44 void initialize(MCContext &Ctx, const TargetMachine &TM,
45 const Module &M) override {
46 TargetLoweringObjectFileELF::initialize(Ctx, TM, M);
47 InitializeELF(UseInitArray_: TM.Options.UseInitArray);
48 }
49};
50} // namespace
51
52static std::unique_ptr<TargetLoweringObjectFile> createTLOF() {
53 return std::make_unique<VEELFTargetObjectFile>();
54}
55
56/// Create an Aurora VE architecture model
57VETargetMachine::VETargetMachine(const Target &T, const Triple &TT,
58 StringRef CPU, StringRef FS,
59 const TargetOptions &Options,
60 std::optional<Reloc::Model> RM,
61 std::optional<CodeModel::Model> CM,
62 CodeGenOptLevel OL, bool JIT)
63 : CodeGenTargetMachineImpl(T, TT, CPU, FS, Options,
64 getEffectiveRelocModel(RM),
65 getEffectiveCodeModel(CM, Default: CodeModel::Small), OL),
66 TLOF(createTLOF()),
67 Subtarget(TT, std::string(CPU), std::string(FS), *this) {
68 initAsmInfo();
69}
70
71VETargetMachine::~VETargetMachine() = default;
72
73TargetTransformInfo
74VETargetMachine::getTargetTransformInfo(const Function &F) const {
75 return TargetTransformInfo(std::make_unique<VETTIImpl>(args: this, args: F));
76}
77
78MachineFunctionInfo *VETargetMachine::createMachineFunctionInfo(
79 BumpPtrAllocator &Allocator, const Function &F,
80 const TargetSubtargetInfo *STI) const {
81 return VEMachineFunctionInfo::create<VEMachineFunctionInfo>(Allocator, F,
82 STI);
83}
84
85namespace {
86/// VE Code Generator Pass Configuration Options.
87class VEPassConfig : public TargetPassConfig {
88public:
89 VEPassConfig(VETargetMachine &TM, PassManagerBase &PM)
90 : TargetPassConfig(TM, PM) {}
91
92 VETargetMachine &getVETargetMachine() const {
93 return getTM<VETargetMachine>();
94 }
95
96 void addIRPasses() override;
97 bool addInstSelector() override;
98 void addPreEmitPass() override;
99};
100} // namespace
101
102TargetPassConfig *VETargetMachine::createPassConfig(PassManagerBase &PM) {
103 return new VEPassConfig(*this, PM);
104}
105
106void VEPassConfig::addIRPasses() {
107 // VE requires atomic expand pass.
108 addPass(P: createAtomicExpandLegacyPass());
109 TargetPassConfig::addIRPasses();
110}
111
112bool VEPassConfig::addInstSelector() {
113 addPass(P: createVEISelDag(TM&: getVETargetMachine()));
114 return false;
115}
116
117void VEPassConfig::addPreEmitPass() {
118 // LVLGen should be called after scheduling and register allocation
119 addPass(P: createLVLGenPass());
120}
121