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