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/Support/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.getValueOr(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
~VETargetMachine()93 VETargetMachine::~VETargetMachine() {}
94
getTargetTransformInfo(const Function & F)95 TargetTransformInfo VETargetMachine::getTargetTransformInfo(const Function &F) {
96 return TargetTransformInfo(VETTIImpl(this, F));
97 }
98
99 namespace {
100 /// VE Code Generator Pass Configuration Options.
101 class VEPassConfig : public TargetPassConfig {
102 public:
VEPassConfig(VETargetMachine & TM,PassManagerBase & PM)103 VEPassConfig(VETargetMachine &TM, PassManagerBase &PM)
104 : TargetPassConfig(TM, PM) {}
105
getVETargetMachine() const106 VETargetMachine &getVETargetMachine() const {
107 return getTM<VETargetMachine>();
108 }
109
110 void addIRPasses() override;
111 bool addInstSelector() override;
112 void addPreEmitPass() override;
113 };
114 } // namespace
115
createPassConfig(PassManagerBase & PM)116 TargetPassConfig *VETargetMachine::createPassConfig(PassManagerBase &PM) {
117 return new VEPassConfig(*this, PM);
118 }
119
addIRPasses()120 void VEPassConfig::addIRPasses() {
121 // VE requires atomic expand pass.
122 addPass(createAtomicExpandPass());
123 TargetPassConfig::addIRPasses();
124 }
125
addInstSelector()126 bool VEPassConfig::addInstSelector() {
127 addPass(createVEISelDag(getVETargetMachine()));
128 return false;
129 }
130
addPreEmitPass()131 void VEPassConfig::addPreEmitPass() {
132 // LVLGen should be called after scheduling and register allocation
133 addPass(createLVLGenPass());
134 }
135