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