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