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 "VETargetTransformInfo.h"
16 #include "llvm/CodeGen/Passes.h"
17 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
18 #include "llvm/CodeGen/TargetPassConfig.h"
19 #include "llvm/IR/LegacyPassManager.h"
20 #include "llvm/MC/TargetRegistry.h"
21
22 using namespace llvm;
23
24 #define DEBUG_TYPE "ve"
25
LLVMInitializeVETarget()26 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVETarget() {
27 // Register the target.
28 RegisterTargetMachine<VETargetMachine> X(getTheVETarget());
29 }
30
computeDataLayout(const Triple & T)31 static std::string computeDataLayout(const Triple &T) {
32 // Aurora VE is little endian
33 std::string Ret = "e";
34
35 // Use ELF mangling
36 Ret += "-m:e";
37
38 // Alignments for 64 bit integers.
39 Ret += "-i64:64";
40
41 // VE supports 32 bit and 64 bits integer on registers
42 Ret += "-n32:64";
43
44 // Stack alignment is 128 bits
45 Ret += "-S128";
46
47 // Vector alignments are 64 bits
48 // Need to define all of them. Otherwise, each alignment becomes
49 // the size of each data by default.
50 Ret += "-v64:64:64"; // for v2f32
51 Ret += "-v128:64:64";
52 Ret += "-v256:64:64";
53 Ret += "-v512:64:64";
54 Ret += "-v1024:64:64";
55 Ret += "-v2048:64:64";
56 Ret += "-v4096:64:64";
57 Ret += "-v8192:64:64";
58 Ret += "-v16384:64:64"; // for v256f64
59
60 return Ret;
61 }
62
getEffectiveRelocModel(Optional<Reloc::Model> RM)63 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
64 return RM.value_or(Reloc::Static);
65 }
66
67 class VEELFTargetObjectFile : public TargetLoweringObjectFileELF {
Initialize(MCContext & Ctx,const TargetMachine & TM)68 void Initialize(MCContext &Ctx, const TargetMachine &TM) override {
69 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
70 InitializeELF(TM.Options.UseInitArray);
71 }
72 };
73
createTLOF()74 static std::unique_ptr<TargetLoweringObjectFile> createTLOF() {
75 return std::make_unique<VEELFTargetObjectFile>();
76 }
77
78 /// Create an Aurora VE architecture model
VETargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,Optional<CodeModel::Model> CM,CodeGenOpt::Level OL,bool JIT)79 VETargetMachine::VETargetMachine(const Target &T, const Triple &TT,
80 StringRef CPU, StringRef FS,
81 const TargetOptions &Options,
82 Optional<Reloc::Model> RM,
83 Optional<CodeModel::Model> CM,
84 CodeGenOpt::Level OL, bool JIT)
85 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
86 getEffectiveRelocModel(RM),
87 getEffectiveCodeModel(CM, CodeModel::Small), OL),
88 TLOF(createTLOF()),
89 Subtarget(TT, std::string(CPU), std::string(FS), *this) {
90 initAsmInfo();
91 }
92
93 VETargetMachine::~VETargetMachine() = default;
94
95 TargetTransformInfo
getTargetTransformInfo(const Function & F) const96 VETargetMachine::getTargetTransformInfo(const Function &F) const {
97 return TargetTransformInfo(VETTIImpl(this, F));
98 }
99
100 namespace {
101 /// VE Code Generator Pass Configuration Options.
102 class VEPassConfig : public TargetPassConfig {
103 public:
VEPassConfig(VETargetMachine & TM,PassManagerBase & PM)104 VEPassConfig(VETargetMachine &TM, PassManagerBase &PM)
105 : TargetPassConfig(TM, PM) {}
106
getVETargetMachine() const107 VETargetMachine &getVETargetMachine() const {
108 return getTM<VETargetMachine>();
109 }
110
111 void addIRPasses() override;
112 bool addInstSelector() override;
113 void addPreEmitPass() override;
114 };
115 } // namespace
116
createPassConfig(PassManagerBase & PM)117 TargetPassConfig *VETargetMachine::createPassConfig(PassManagerBase &PM) {
118 return new VEPassConfig(*this, PM);
119 }
120
addIRPasses()121 void VEPassConfig::addIRPasses() {
122 // VE requires atomic expand pass.
123 addPass(createAtomicExpandPass());
124 TargetPassConfig::addIRPasses();
125 }
126
addInstSelector()127 bool VEPassConfig::addInstSelector() {
128 addPass(createVEISelDag(getVETargetMachine()));
129 return false;
130 }
131
addPreEmitPass()132 void VEPassConfig::addPreEmitPass() {
133 // LVLGen should be called after scheduling and register allocation
134 addPass(createLVLGenPass());
135 }
136