xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- XtensaTargetMachine.cpp - Define TargetMachine for Xtensa ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 // See https://llvm.org/LICENSE.txt for license information.
7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // Implements the info about Xtensa target spec.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "XtensaTargetMachine.h"
16 #include "TargetInfo/XtensaTargetInfo.h"
17 #include "XtensaMachineFunctionInfo.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
20 #include "llvm/CodeGen/TargetPassConfig.h"
21 #include "llvm/MC/TargetRegistry.h"
22 #include "llvm/PassRegistry.h"
23 #include "llvm/Transforms/Scalar.h"
24 #include <optional>
25 
26 using namespace llvm;
27 
LLVMInitializeXtensaTarget()28 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTarget() {
29   // Register the target.
30   RegisterTargetMachine<XtensaTargetMachine> A(getTheXtensaTarget());
31   PassRegistry &PR = *PassRegistry::getPassRegistry();
32   initializeXtensaAsmPrinterPass(PR);
33 }
34 
computeDataLayout(const Triple & TT,StringRef CPU,const TargetOptions & Options,bool IsLittle)35 static std::string computeDataLayout(const Triple &TT, StringRef CPU,
36                                      const TargetOptions &Options,
37                                      bool IsLittle) {
38   std::string Ret = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32";
39   return Ret;
40 }
41 
getEffectiveRelocModel(bool JIT,std::optional<Reloc::Model> RM)42 static Reloc::Model getEffectiveRelocModel(bool JIT,
43                                            std::optional<Reloc::Model> RM) {
44   if (!RM || JIT)
45      return Reloc::Static;
46   return *RM;
47 }
48 
XtensaTargetMachine(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,bool IsLittle)49 XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT,
50                                          StringRef CPU, StringRef FS,
51                                          const TargetOptions &Options,
52                                          std::optional<Reloc::Model> RM,
53                                          std::optional<CodeModel::Model> CM,
54                                          CodeGenOptLevel OL, bool JIT,
55                                          bool IsLittle)
56     : CodeGenTargetMachineImpl(T, computeDataLayout(TT, CPU, Options, IsLittle),
57                                TT, CPU, FS, Options,
58                                getEffectiveRelocModel(JIT, RM),
59                                getEffectiveCodeModel(CM, CodeModel::Small), OL),
60       TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
61   initAsmInfo();
62 }
63 
XtensaTargetMachine(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)64 XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT,
65                                          StringRef CPU, StringRef FS,
66                                          const TargetOptions &Options,
67                                          std::optional<Reloc::Model> RM,
68                                          std::optional<CodeModel::Model> CM,
69                                          CodeGenOptLevel OL, bool JIT)
70     : XtensaTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
71 
72 const XtensaSubtarget *
getSubtargetImpl(const Function & F) const73 XtensaTargetMachine::getSubtargetImpl(const Function &F) const {
74   Attribute CPUAttr = F.getFnAttribute("target-cpu");
75   Attribute FSAttr = F.getFnAttribute("target-features");
76 
77   auto CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
78   auto FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
79 
80   auto &I = SubtargetMap[CPU + FS];
81   if (!I) {
82     // This needs to be done before we create a new subtarget since any
83     // creation will depend on the TM and the code generation flags on the
84     // function that reside in TargetOptions.
85     resetTargetOptions(F);
86     I = std::make_unique<XtensaSubtarget>(TargetTriple, CPU, FS, *this);
87   }
88   return I.get();
89 }
90 
createMachineFunctionInfo(BumpPtrAllocator & Allocator,const Function & F,const TargetSubtargetInfo * STI) const91 MachineFunctionInfo *XtensaTargetMachine::createMachineFunctionInfo(
92     BumpPtrAllocator &Allocator, const Function &F,
93     const TargetSubtargetInfo *STI) const {
94   return XtensaMachineFunctionInfo::create<XtensaMachineFunctionInfo>(Allocator,
95                                                                       F, STI);
96 }
97 
98 namespace {
99 /// Xtensa Code Generator Pass Configuration Options.
100 class XtensaPassConfig : public TargetPassConfig {
101 public:
XtensaPassConfig(XtensaTargetMachine & TM,PassManagerBase & PM)102   XtensaPassConfig(XtensaTargetMachine &TM, PassManagerBase &PM)
103       : TargetPassConfig(TM, PM) {}
104 
getXtensaTargetMachine() const105   XtensaTargetMachine &getXtensaTargetMachine() const {
106     return getTM<XtensaTargetMachine>();
107   }
108 
109   bool addInstSelector() override;
110   void addPreEmitPass() override;
111 };
112 } // end anonymous namespace
113 
addInstSelector()114 bool XtensaPassConfig::addInstSelector() {
115   addPass(createXtensaISelDag(getXtensaTargetMachine(), getOptLevel()));
116   return false;
117 }
118 
addPreEmitPass()119 void XtensaPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
120 
createPassConfig(PassManagerBase & PM)121 TargetPassConfig *XtensaTargetMachine::createPassConfig(PassManagerBase &PM) {
122   return new XtensaPassConfig(*this, PM);
123 }
124