xref: /llvm-project/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp (revision eec21ccee0950d52926a79685573db1996e3ba5b)
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/Transforms/Scalar.h"
23 #include <optional>
24 
25 using namespace llvm;
26 
27 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTarget() {
28   // Register the target.
29   RegisterTargetMachine<XtensaTargetMachine> A(getTheXtensaTarget());
30 }
31 
32 static std::string computeDataLayout(const Triple &TT, StringRef CPU,
33                                      const TargetOptions &Options,
34                                      bool IsLittle) {
35   std::string Ret = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32";
36   return Ret;
37 }
38 
39 static Reloc::Model getEffectiveRelocModel(bool JIT,
40                                            std::optional<Reloc::Model> RM) {
41   if (!RM || JIT)
42      return Reloc::Static;
43   return *RM;
44 }
45 
46 XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT,
47                                          StringRef CPU, StringRef FS,
48                                          const TargetOptions &Options,
49                                          std::optional<Reloc::Model> RM,
50                                          std::optional<CodeModel::Model> CM,
51                                          CodeGenOptLevel OL, bool JIT,
52                                          bool IsLittle)
53     : CodeGenTargetMachineImpl(T, computeDataLayout(TT, CPU, Options, IsLittle),
54                                TT, CPU, FS, Options,
55                                getEffectiveRelocModel(JIT, RM),
56                                getEffectiveCodeModel(CM, CodeModel::Small), OL),
57       TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
58   initAsmInfo();
59 }
60 
61 XtensaTargetMachine::XtensaTargetMachine(const Target &T, const Triple &TT,
62                                          StringRef CPU, StringRef FS,
63                                          const TargetOptions &Options,
64                                          std::optional<Reloc::Model> RM,
65                                          std::optional<CodeModel::Model> CM,
66                                          CodeGenOptLevel OL, bool JIT)
67     : XtensaTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
68 
69 const XtensaSubtarget *
70 XtensaTargetMachine::getSubtargetImpl(const Function &F) const {
71   Attribute CPUAttr = F.getFnAttribute("target-cpu");
72   Attribute FSAttr = F.getFnAttribute("target-features");
73 
74   auto CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
75   auto FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
76 
77   auto &I = SubtargetMap[CPU + FS];
78   if (!I) {
79     // This needs to be done before we create a new subtarget since any
80     // creation will depend on the TM and the code generation flags on the
81     // function that reside in TargetOptions.
82     resetTargetOptions(F);
83     I = std::make_unique<XtensaSubtarget>(TargetTriple, CPU, FS, *this);
84   }
85   return I.get();
86 }
87 
88 MachineFunctionInfo *XtensaTargetMachine::createMachineFunctionInfo(
89     BumpPtrAllocator &Allocator, const Function &F,
90     const TargetSubtargetInfo *STI) const {
91   return XtensaMachineFunctionInfo::create<XtensaMachineFunctionInfo>(Allocator,
92                                                                       F, STI);
93 }
94 
95 namespace {
96 /// Xtensa Code Generator Pass Configuration Options.
97 class XtensaPassConfig : public TargetPassConfig {
98 public:
99   XtensaPassConfig(XtensaTargetMachine &TM, PassManagerBase &PM)
100       : TargetPassConfig(TM, PM) {}
101 
102   XtensaTargetMachine &getXtensaTargetMachine() const {
103     return getTM<XtensaTargetMachine>();
104   }
105 
106   bool addInstSelector() override;
107   void addPreEmitPass() override;
108 };
109 } // end anonymous namespace
110 
111 bool XtensaPassConfig::addInstSelector() {
112   addPass(createXtensaISelDag(getXtensaTargetMachine(), getOptLevel()));
113   return false;
114 }
115 
116 void XtensaPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
117 
118 TargetPassConfig *XtensaTargetMachine::createPassConfig(PassManagerBase &PM) {
119   return new XtensaPassConfig(*this, PM);
120 }
121