143 lines · cpp
1//===-- AVRTargetMachine.cpp - Define TargetMachine for AVR ---------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the AVR specific subclass of TargetMachine.10//11//===----------------------------------------------------------------------===//12 13#include "AVRTargetMachine.h"14 15#include "llvm/CodeGen/Passes.h"16#include "llvm/CodeGen/TargetPassConfig.h"17#include "llvm/MC/TargetRegistry.h"18#include "llvm/Support/Compiler.h"19 20#include "AVR.h"21#include "AVRMachineFunctionInfo.h"22#include "AVRTargetObjectFile.h"23#include "AVRTargetTransformInfo.h"24#include "MCTargetDesc/AVRMCTargetDesc.h"25#include "TargetInfo/AVRTargetInfo.h"26 27#include <optional>28 29namespace llvm {30 31/// Processes a CPU name.32static StringRef getCPU(StringRef CPU) {33 if (CPU.empty() || CPU == "generic") {34 return "avr2";35 }36 37 return CPU;38}39 40static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {41 return RM.value_or(Reloc::Static);42}43 44AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT,45 StringRef CPU, StringRef FS,46 const TargetOptions &Options,47 std::optional<Reloc::Model> RM,48 std::optional<CodeModel::Model> CM,49 CodeGenOptLevel OL, bool JIT)50 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, getCPU(CPU), FS,51 Options, getEffectiveRelocModel(RM),52 getEffectiveCodeModel(CM, CodeModel::Small), OL),53 SubTarget(TT, std::string(getCPU(CPU)), std::string(FS), *this) {54 this->TLOF = std::make_unique<AVRTargetObjectFile>();55 initAsmInfo();56}57 58namespace {59/// AVR Code Generator Pass Configuration Options.60class AVRPassConfig : public TargetPassConfig {61public:62 AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM)63 : TargetPassConfig(TM, PM) {64 EnableLoopTermFold = true;65 }66 67 AVRTargetMachine &getAVRTargetMachine() const {68 return getTM<AVRTargetMachine>();69 }70 71 void addIRPasses() override;72 bool addInstSelector() override;73 void addPreSched2() override;74 void addPreEmitPass() override;75};76} // namespace77 78TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) {79 return new AVRPassConfig(*this, PM);80}81 82void AVRPassConfig::addIRPasses() {83 // Expand instructions like84 // %result = shl i32 %n, %amount85 // to a loop so that library calls are avoided.86 addPass(createAVRShiftExpandPass());87 88 TargetPassConfig::addIRPasses();89}90 91extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRTarget() {92 // Register the target.93 RegisterTargetMachine<AVRTargetMachine> X(getTheAVRTarget());94 95 auto &PR = *PassRegistry::getPassRegistry();96 initializeAVRAsmPrinterPass(PR);97 initializeAVRExpandPseudoPass(PR);98 initializeAVRShiftExpandPass(PR);99 initializeAVRDAGToDAGISelLegacyPass(PR);100}101 102const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const {103 return &SubTarget;104}105 106const AVRSubtarget *AVRTargetMachine::getSubtargetImpl(const Function &) const {107 return &SubTarget;108}109 110TargetTransformInfo111AVRTargetMachine::getTargetTransformInfo(const Function &F) const {112 return TargetTransformInfo(std::make_unique<AVRTTIImpl>(this, F));113}114 115MachineFunctionInfo *AVRTargetMachine::createMachineFunctionInfo(116 BumpPtrAllocator &Allocator, const Function &F,117 const TargetSubtargetInfo *STI) const {118 return AVRMachineFunctionInfo::create<AVRMachineFunctionInfo>(Allocator, F,119 STI);120}121 122//===----------------------------------------------------------------------===//123// Pass Pipeline Configuration124//===----------------------------------------------------------------------===//125 126bool AVRPassConfig::addInstSelector() {127 // Install an instruction selector.128 addPass(createAVRISelDag(getAVRTargetMachine(), getOptLevel()));129 // Create the frame analyzer pass used by the PEI pass.130 addPass(createAVRFrameAnalyzerPass());131 132 return false;133}134 135void AVRPassConfig::addPreSched2() { addPass(createAVRExpandPseudoPass()); }136 137void AVRPassConfig::addPreEmitPass() {138 // Must run branch selection immediately preceding the asm printer.139 addPass(&BranchRelaxationPassID);140}141 142} // end of namespace llvm143