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 
getRelocModel(std::optional<Reloc::Model> RM)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
ARCTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,std::optional<Reloc::Model> RM,std::optional<CodeModel::Model> CM,CodeGenOptLevel OL,bool JIT)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:
ARCPassConfig(ARCTargetMachine & TM,PassManagerBase & PM)530b57cec5SDimitry Andric   ARCPassConfig(ARCTargetMachine &TM, PassManagerBase &PM)
540b57cec5SDimitry Andric       : TargetPassConfig(TM, PM) {}
550b57cec5SDimitry Andric 
getARCTargetMachine() const560b57cec5SDimitry 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 
createPassConfig(PassManagerBase & PM)680b57cec5SDimitry Andric TargetPassConfig *ARCTargetMachine::createPassConfig(PassManagerBase &PM) {
690b57cec5SDimitry Andric   return new ARCPassConfig(*this, PM);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
addIRPasses()721db9f3b2SDimitry Andric void ARCPassConfig::addIRPasses() {
731db9f3b2SDimitry Andric   addPass(createAtomicExpandPass());
741db9f3b2SDimitry Andric 
751db9f3b2SDimitry Andric   TargetPassConfig::addIRPasses();
761db9f3b2SDimitry Andric }
771db9f3b2SDimitry Andric 
addInstSelector()780b57cec5SDimitry Andric bool ARCPassConfig::addInstSelector() {
790b57cec5SDimitry Andric   addPass(createARCISelDag(getARCTargetMachine(), getOptLevel()));
800b57cec5SDimitry Andric   return false;
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric 
addPreEmitPass()830b57cec5SDimitry Andric void ARCPassConfig::addPreEmitPass() { addPass(createARCBranchFinalizePass()); }
840b57cec5SDimitry Andric 
addPreRegAlloc()850b57cec5SDimitry Andric void ARCPassConfig::addPreRegAlloc() {
860b57cec5SDimitry Andric     addPass(createARCExpandPseudosPass());
870b57cec5SDimitry Andric     addPass(createARCOptAddrMode());
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
createMachineFunctionInfo(BumpPtrAllocator & Allocator,const Function & F,const TargetSubtargetInfo * STI) const90bdd1243dSDimitry 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.
LLVMInitializeARCTarget()97480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARCTarget() {
980b57cec5SDimitry Andric   RegisterTargetMachine<ARCTargetMachine> X(getTheARCTarget());
99bdd1243dSDimitry Andric   PassRegistry &PR = *PassRegistry::getPassRegistry();
100bdd1243dSDimitry Andric   initializeARCDAGToDAGISelPass(PR);
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F) const10481ad6265SDimitry Andric ARCTargetMachine::getTargetTransformInfo(const Function &F) const {
1050b57cec5SDimitry Andric   return TargetTransformInfo(ARCTTIImpl(this, F));
1060b57cec5SDimitry Andric }
107