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