1480093f4SDimitry Andric //===-- VETargetMachine.cpp - Define TargetMachine for VE -----------------===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // 10480093f4SDimitry Andric //===----------------------------------------------------------------------===// 11480093f4SDimitry Andric 12480093f4SDimitry Andric #include "VETargetMachine.h" 135ffd83dbSDimitry Andric #include "TargetInfo/VETargetInfo.h" 14480093f4SDimitry Andric #include "VE.h" 15bdd1243dSDimitry Andric #include "VEMachineFunctionInfo.h" 16480093f4SDimitry Andric #include "VETargetTransformInfo.h" 17480093f4SDimitry Andric #include "llvm/CodeGen/Passes.h" 18480093f4SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 19480093f4SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 20480093f4SDimitry Andric #include "llvm/IR/LegacyPassManager.h" 21349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 22bdd1243dSDimitry Andric #include <optional> 23480093f4SDimitry Andric 24480093f4SDimitry Andric using namespace llvm; 25480093f4SDimitry Andric 26480093f4SDimitry Andric #define DEBUG_TYPE "ve" 27480093f4SDimitry Andric 28e8d8bef9SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVETarget() { 29480093f4SDimitry Andric // Register the target. 30480093f4SDimitry Andric RegisterTargetMachine<VETargetMachine> X(getTheVETarget()); 31bdd1243dSDimitry Andric 32bdd1243dSDimitry Andric PassRegistry &PR = *PassRegistry::getPassRegistry(); 33*0fca6ea1SDimitry Andric initializeVEDAGToDAGISelLegacyPass(PR); 34480093f4SDimitry Andric } 35480093f4SDimitry Andric 36480093f4SDimitry Andric static std::string computeDataLayout(const Triple &T) { 37480093f4SDimitry Andric // Aurora VE is little endian 38480093f4SDimitry Andric std::string Ret = "e"; 39480093f4SDimitry Andric 40480093f4SDimitry Andric // Use ELF mangling 41480093f4SDimitry Andric Ret += "-m:e"; 42480093f4SDimitry Andric 43480093f4SDimitry Andric // Alignments for 64 bit integers. 44480093f4SDimitry Andric Ret += "-i64:64"; 45480093f4SDimitry Andric 46480093f4SDimitry Andric // VE supports 32 bit and 64 bits integer on registers 47480093f4SDimitry Andric Ret += "-n32:64"; 48480093f4SDimitry Andric 495ffd83dbSDimitry Andric // Stack alignment is 128 bits 505ffd83dbSDimitry Andric Ret += "-S128"; 51480093f4SDimitry Andric 52e8d8bef9SDimitry Andric // Vector alignments are 64 bits 53e8d8bef9SDimitry Andric // Need to define all of them. Otherwise, each alignment becomes 54e8d8bef9SDimitry Andric // the size of each data by default. 55e8d8bef9SDimitry Andric Ret += "-v64:64:64"; // for v2f32 56e8d8bef9SDimitry Andric Ret += "-v128:64:64"; 57e8d8bef9SDimitry Andric Ret += "-v256:64:64"; 58e8d8bef9SDimitry Andric Ret += "-v512:64:64"; 59e8d8bef9SDimitry Andric Ret += "-v1024:64:64"; 60e8d8bef9SDimitry Andric Ret += "-v2048:64:64"; 61e8d8bef9SDimitry Andric Ret += "-v4096:64:64"; 62e8d8bef9SDimitry Andric Ret += "-v8192:64:64"; 63e8d8bef9SDimitry Andric Ret += "-v16384:64:64"; // for v256f64 64e8d8bef9SDimitry Andric 65480093f4SDimitry Andric return Ret; 66480093f4SDimitry Andric } 67480093f4SDimitry Andric 68bdd1243dSDimitry Andric static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { 6981ad6265SDimitry Andric return RM.value_or(Reloc::Static); 70480093f4SDimitry Andric } 71480093f4SDimitry Andric 72bdd1243dSDimitry Andric namespace { 73480093f4SDimitry Andric class VEELFTargetObjectFile : public TargetLoweringObjectFileELF { 74480093f4SDimitry Andric void Initialize(MCContext &Ctx, const TargetMachine &TM) override { 75480093f4SDimitry Andric TargetLoweringObjectFileELF::Initialize(Ctx, TM); 76480093f4SDimitry Andric InitializeELF(TM.Options.UseInitArray); 77480093f4SDimitry Andric } 78480093f4SDimitry Andric }; 79bdd1243dSDimitry Andric } // namespace 80480093f4SDimitry Andric 81480093f4SDimitry Andric static std::unique_ptr<TargetLoweringObjectFile> createTLOF() { 82480093f4SDimitry Andric return std::make_unique<VEELFTargetObjectFile>(); 83480093f4SDimitry Andric } 84480093f4SDimitry Andric 85480093f4SDimitry Andric /// Create an Aurora VE architecture model 86480093f4SDimitry Andric VETargetMachine::VETargetMachine(const Target &T, const Triple &TT, 87480093f4SDimitry Andric StringRef CPU, StringRef FS, 88480093f4SDimitry Andric const TargetOptions &Options, 89bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 90bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 915f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT) 92480093f4SDimitry Andric : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 93480093f4SDimitry Andric getEffectiveRelocModel(RM), 94480093f4SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL), 955ffd83dbSDimitry Andric TLOF(createTLOF()), 965ffd83dbSDimitry Andric Subtarget(TT, std::string(CPU), std::string(FS), *this) { 97480093f4SDimitry Andric initAsmInfo(); 98480093f4SDimitry Andric } 99480093f4SDimitry Andric 10081ad6265SDimitry Andric VETargetMachine::~VETargetMachine() = default; 101480093f4SDimitry Andric 10281ad6265SDimitry Andric TargetTransformInfo 10381ad6265SDimitry Andric VETargetMachine::getTargetTransformInfo(const Function &F) const { 104480093f4SDimitry Andric return TargetTransformInfo(VETTIImpl(this, F)); 105480093f4SDimitry Andric } 106480093f4SDimitry Andric 107bdd1243dSDimitry Andric MachineFunctionInfo *VETargetMachine::createMachineFunctionInfo( 108bdd1243dSDimitry Andric BumpPtrAllocator &Allocator, const Function &F, 109bdd1243dSDimitry Andric const TargetSubtargetInfo *STI) const { 110bdd1243dSDimitry Andric return VEMachineFunctionInfo::create<VEMachineFunctionInfo>(Allocator, F, 111bdd1243dSDimitry Andric STI); 112bdd1243dSDimitry Andric } 113bdd1243dSDimitry Andric 114480093f4SDimitry Andric namespace { 115480093f4SDimitry Andric /// VE Code Generator Pass Configuration Options. 116480093f4SDimitry Andric class VEPassConfig : public TargetPassConfig { 117480093f4SDimitry Andric public: 118480093f4SDimitry Andric VEPassConfig(VETargetMachine &TM, PassManagerBase &PM) 119480093f4SDimitry Andric : TargetPassConfig(TM, PM) {} 120480093f4SDimitry Andric 121480093f4SDimitry Andric VETargetMachine &getVETargetMachine() const { 122480093f4SDimitry Andric return getTM<VETargetMachine>(); 123480093f4SDimitry Andric } 124480093f4SDimitry Andric 125e8d8bef9SDimitry Andric void addIRPasses() override; 126480093f4SDimitry Andric bool addInstSelector() override; 127e8d8bef9SDimitry Andric void addPreEmitPass() override; 128480093f4SDimitry Andric }; 129480093f4SDimitry Andric } // namespace 130480093f4SDimitry Andric 131480093f4SDimitry Andric TargetPassConfig *VETargetMachine::createPassConfig(PassManagerBase &PM) { 132480093f4SDimitry Andric return new VEPassConfig(*this, PM); 133480093f4SDimitry Andric } 134480093f4SDimitry Andric 135e8d8bef9SDimitry Andric void VEPassConfig::addIRPasses() { 136e8d8bef9SDimitry Andric // VE requires atomic expand pass. 137*0fca6ea1SDimitry Andric addPass(createAtomicExpandLegacyPass()); 138e8d8bef9SDimitry Andric TargetPassConfig::addIRPasses(); 139e8d8bef9SDimitry Andric } 140e8d8bef9SDimitry Andric 141480093f4SDimitry Andric bool VEPassConfig::addInstSelector() { 142480093f4SDimitry Andric addPass(createVEISelDag(getVETargetMachine())); 143480093f4SDimitry Andric return false; 144480093f4SDimitry Andric } 145e8d8bef9SDimitry Andric 146e8d8bef9SDimitry Andric void VEPassConfig::addPreEmitPass() { 147e8d8bef9SDimitry Andric // LVLGen should be called after scheduling and register allocation 148e8d8bef9SDimitry Andric addPass(createLVLGenPass()); 149e8d8bef9SDimitry Andric } 150