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