10b57cec5SDimitry Andric //===- ARCTargetMachine.cpp - Define TargetMachine for ARC ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // 100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "ARCTargetMachine.h" 130b57cec5SDimitry Andric #include "ARC.h" 14bdd1243dSDimitry Andric #include "ARCMachineFunctionInfo.h" 150b57cec5SDimitry Andric #include "ARCTargetTransformInfo.h" 160b57cec5SDimitry Andric #include "TargetInfo/ARCTargetInfo.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 20349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 21bdd1243dSDimitry Andric #include <optional> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric using namespace llvm; 240b57cec5SDimitry Andric 25bdd1243dSDimitry Andric static Reloc::Model getRelocModel(std::optional<Reloc::Model> RM) { 2681ad6265SDimitry Andric return RM.value_or(Reloc::Static); 270b57cec5SDimitry Andric } 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric /// ARCTargetMachine ctor - Create an ILP32 architecture model 300b57cec5SDimitry Andric ARCTargetMachine::ARCTargetMachine(const Target &T, const Triple &TT, 310b57cec5SDimitry Andric StringRef CPU, StringRef FS, 320b57cec5SDimitry Andric const TargetOptions &Options, 33bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 34bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 355f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT) 360b57cec5SDimitry Andric : LLVMTargetMachine(T, 370b57cec5SDimitry Andric "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 380b57cec5SDimitry Andric "f32:32:32-i64:32-f64:32-a:0:32-n32", 390b57cec5SDimitry Andric TT, CPU, FS, Options, getRelocModel(RM), 400b57cec5SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL), 418bcb0991SDimitry Andric TLOF(std::make_unique<TargetLoweringObjectFileELF>()), 425ffd83dbSDimitry Andric Subtarget(TT, std::string(CPU), std::string(FS), *this) { 430b57cec5SDimitry Andric initAsmInfo(); 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric ARCTargetMachine::~ARCTargetMachine() = default; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric namespace { 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /// ARC Code Generator Pass Configuration Options. 510b57cec5SDimitry Andric class ARCPassConfig : public TargetPassConfig { 520b57cec5SDimitry Andric public: 530b57cec5SDimitry Andric ARCPassConfig(ARCTargetMachine &TM, PassManagerBase &PM) 540b57cec5SDimitry Andric : TargetPassConfig(TM, PM) {} 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric ARCTargetMachine &getARCTargetMachine() const { 570b57cec5SDimitry Andric return getTM<ARCTargetMachine>(); 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 601db9f3b2SDimitry Andric void addIRPasses() override; 610b57cec5SDimitry Andric bool addInstSelector() override; 620b57cec5SDimitry Andric void addPreEmitPass() override; 630b57cec5SDimitry Andric void addPreRegAlloc() override; 640b57cec5SDimitry Andric }; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric } // end anonymous namespace 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric TargetPassConfig *ARCTargetMachine::createPassConfig(PassManagerBase &PM) { 690b57cec5SDimitry Andric return new ARCPassConfig(*this, PM); 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 721db9f3b2SDimitry Andric void ARCPassConfig::addIRPasses() { 73*0fca6ea1SDimitry Andric addPass(createAtomicExpandLegacyPass()); 741db9f3b2SDimitry Andric 751db9f3b2SDimitry Andric TargetPassConfig::addIRPasses(); 761db9f3b2SDimitry Andric } 771db9f3b2SDimitry Andric 780b57cec5SDimitry Andric bool ARCPassConfig::addInstSelector() { 790b57cec5SDimitry Andric addPass(createARCISelDag(getARCTargetMachine(), getOptLevel())); 800b57cec5SDimitry Andric return false; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric void ARCPassConfig::addPreEmitPass() { addPass(createARCBranchFinalizePass()); } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric void ARCPassConfig::addPreRegAlloc() { 860b57cec5SDimitry Andric addPass(createARCExpandPseudosPass()); 870b57cec5SDimitry Andric addPass(createARCOptAddrMode()); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 90bdd1243dSDimitry Andric MachineFunctionInfo *ARCTargetMachine::createMachineFunctionInfo( 91bdd1243dSDimitry Andric BumpPtrAllocator &Allocator, const Function &F, 92bdd1243dSDimitry Andric const TargetSubtargetInfo *STI) const { 93bdd1243dSDimitry Andric return ARCFunctionInfo::create<ARCFunctionInfo>(Allocator, F, STI); 94bdd1243dSDimitry Andric } 95bdd1243dSDimitry Andric 960b57cec5SDimitry Andric // Force static initialization. 97480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARCTarget() { 980b57cec5SDimitry Andric RegisterTargetMachine<ARCTargetMachine> X(getTheARCTarget()); 99bdd1243dSDimitry Andric PassRegistry &PR = *PassRegistry::getPassRegistry(); 100*0fca6ea1SDimitry Andric initializeARCDAGToDAGISelLegacyPass(PR); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric TargetTransformInfo 10481ad6265SDimitry Andric ARCTargetMachine::getTargetTransformInfo(const Function &F) const { 1050b57cec5SDimitry Andric return TargetTransformInfo(ARCTTIImpl(this, F)); 1060b57cec5SDimitry Andric } 107