Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- llvm/CodeGen/TargetSubtargetInfo.h - Target Information --*- C++ -*-===// |
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-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // This file describes the subtarget options of a Target machine. |
||
10 | // |
||
11 | //===----------------------------------------------------------------------===// |
||
12 | |||
13 | #ifndef LLVM_CODEGEN_TARGETSUBTARGETINFO_H |
||
14 | #define LLVM_CODEGEN_TARGETSUBTARGETINFO_H |
||
15 | |||
16 | #include "llvm/ADT/ArrayRef.h" |
||
17 | #include "llvm/ADT/SmallVector.h" |
||
18 | #include "llvm/ADT/StringRef.h" |
||
19 | #include "llvm/CodeGen/PBQPRAConstraint.h" |
||
20 | #include "llvm/CodeGen/SchedulerRegistry.h" |
||
21 | #include "llvm/IR/GlobalValue.h" |
||
22 | #include "llvm/MC/MCSubtargetInfo.h" |
||
23 | #include "llvm/Support/CodeGen.h" |
||
24 | #include <memory> |
||
25 | #include <vector> |
||
26 | |||
27 | namespace llvm { |
||
28 | |||
29 | class APInt; |
||
30 | class MachineFunction; |
||
31 | class ScheduleDAGMutation; |
||
32 | class CallLowering; |
||
33 | class GlobalValue; |
||
34 | class InlineAsmLowering; |
||
35 | class InstrItineraryData; |
||
36 | struct InstrStage; |
||
37 | class InstructionSelector; |
||
38 | class LegalizerInfo; |
||
39 | class MachineInstr; |
||
40 | struct MachineSchedPolicy; |
||
41 | struct MCReadAdvanceEntry; |
||
42 | struct MCWriteLatencyEntry; |
||
43 | struct MCWriteProcResEntry; |
||
44 | class RegisterBankInfo; |
||
45 | class SDep; |
||
46 | class SelectionDAGTargetInfo; |
||
47 | class SUnit; |
||
48 | class TargetFrameLowering; |
||
49 | class TargetInstrInfo; |
||
50 | class TargetLowering; |
||
51 | class TargetRegisterClass; |
||
52 | class TargetRegisterInfo; |
||
53 | class TargetSchedModel; |
||
54 | class Triple; |
||
55 | |||
56 | //===----------------------------------------------------------------------===// |
||
57 | /// |
||
58 | /// TargetSubtargetInfo - Generic base class for all target subtargets. All |
||
59 | /// Target-specific options that control code generation and printing should |
||
60 | /// be exposed through a TargetSubtargetInfo-derived class. |
||
61 | /// |
||
62 | class TargetSubtargetInfo : public MCSubtargetInfo { |
||
63 | protected: // Can only create subclasses... |
||
64 | TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU, |
||
65 | StringRef FS, ArrayRef<SubtargetFeatureKV> PF, |
||
66 | ArrayRef<SubtargetSubTypeKV> PD, |
||
67 | const MCWriteProcResEntry *WPR, |
||
68 | const MCWriteLatencyEntry *WL, |
||
69 | const MCReadAdvanceEntry *RA, const InstrStage *IS, |
||
70 | const unsigned *OC, const unsigned *FP); |
||
71 | |||
72 | public: |
||
73 | // AntiDepBreakMode - Type of anti-dependence breaking that should |
||
74 | // be performed before post-RA scheduling. |
||
75 | using AntiDepBreakMode = enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL }; |
||
76 | using RegClassVector = SmallVectorImpl<const TargetRegisterClass *>; |
||
77 | |||
78 | TargetSubtargetInfo() = delete; |
||
79 | TargetSubtargetInfo(const TargetSubtargetInfo &) = delete; |
||
80 | TargetSubtargetInfo &operator=(const TargetSubtargetInfo &) = delete; |
||
81 | ~TargetSubtargetInfo() override; |
||
82 | |||
83 | virtual bool isXRaySupported() const { return false; } |
||
84 | |||
85 | // Interfaces to the major aspects of target machine information: |
||
86 | // |
||
87 | // -- Instruction opcode and operand information |
||
88 | // -- Pipelines and scheduling information |
||
89 | // -- Stack frame information |
||
90 | // -- Selection DAG lowering information |
||
91 | // -- Call lowering information |
||
92 | // |
||
93 | // N.B. These objects may change during compilation. It's not safe to cache |
||
94 | // them between functions. |
||
95 | virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; } |
||
96 | virtual const TargetFrameLowering *getFrameLowering() const { |
||
97 | return nullptr; |
||
98 | } |
||
99 | virtual const TargetLowering *getTargetLowering() const { return nullptr; } |
||
100 | virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const { |
||
101 | return nullptr; |
||
102 | } |
||
103 | virtual const CallLowering *getCallLowering() const { return nullptr; } |
||
104 | |||
105 | virtual const InlineAsmLowering *getInlineAsmLowering() const { |
||
106 | return nullptr; |
||
107 | } |
||
108 | |||
109 | // FIXME: This lets targets specialize the selector by subtarget (which lets |
||
110 | // us do things like a dedicated avx512 selector). However, we might want |
||
111 | // to also specialize selectors by MachineFunction, which would let us be |
||
112 | // aware of optsize/optnone and such. |
||
113 | virtual InstructionSelector *getInstructionSelector() const { |
||
114 | return nullptr; |
||
115 | } |
||
116 | |||
117 | /// Target can subclass this hook to select a different DAG scheduler. |
||
118 | virtual RegisterScheduler::FunctionPassCtor |
||
119 | getDAGScheduler(CodeGenOpt::Level) const { |
||
120 | return nullptr; |
||
121 | } |
||
122 | |||
123 | virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; } |
||
124 | |||
125 | /// getRegisterInfo - If register information is available, return it. If |
||
126 | /// not, return null. |
||
127 | virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; } |
||
128 | |||
129 | /// If the information for the register banks is available, return it. |
||
130 | /// Otherwise return nullptr. |
||
131 | virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; } |
||
132 | |||
133 | /// getInstrItineraryData - Returns instruction itinerary data for the target |
||
134 | /// or specific subtarget. |
||
135 | virtual const InstrItineraryData *getInstrItineraryData() const { |
||
136 | return nullptr; |
||
137 | } |
||
138 | |||
139 | /// Resolve a SchedClass at runtime, where SchedClass identifies an |
||
140 | /// MCSchedClassDesc with the isVariant property. This may return the ID of |
||
141 | /// another variant SchedClass, but repeated invocation must quickly terminate |
||
142 | /// in a nonvariant SchedClass. |
||
143 | virtual unsigned resolveSchedClass(unsigned SchedClass, |
||
144 | const MachineInstr *MI, |
||
145 | const TargetSchedModel *SchedModel) const { |
||
146 | return 0; |
||
147 | } |
||
148 | |||
149 | /// Returns true if MI is a dependency breaking zero-idiom instruction for the |
||
150 | /// subtarget. |
||
151 | /// |
||
152 | /// This function also sets bits in Mask related to input operands that |
||
153 | /// are not in a data dependency relationship. There is one bit for each |
||
154 | /// machine operand; implicit operands follow explicit operands in the bit |
||
155 | /// representation used for Mask. An empty (i.e. a mask with all bits |
||
156 | /// cleared) means: data dependencies are "broken" for all the explicit input |
||
157 | /// machine operands of MI. |
||
158 | virtual bool isZeroIdiom(const MachineInstr *MI, APInt &Mask) const { |
||
159 | return false; |
||
160 | } |
||
161 | |||
162 | /// Returns true if MI is a dependency breaking instruction for the subtarget. |
||
163 | /// |
||
164 | /// Similar in behavior to `isZeroIdiom`. However, it knows how to identify |
||
165 | /// all dependency breaking instructions (i.e. not just zero-idioms). |
||
166 | /// |
||
167 | /// As for `isZeroIdiom`, this method returns a mask of "broken" dependencies. |
||
168 | /// (See method `isZeroIdiom` for a detailed description of Mask). |
||
169 | virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const { |
||
170 | return isZeroIdiom(MI, Mask); |
||
171 | } |
||
172 | |||
173 | /// Returns true if MI is a candidate for move elimination. |
||
174 | /// |
||
175 | /// A candidate for move elimination may be optimized out at register renaming |
||
176 | /// stage. Subtargets can specify the set of optimizable moves by |
||
177 | /// instantiating tablegen class `IsOptimizableRegisterMove` (see |
||
178 | /// llvm/Target/TargetInstrPredicate.td). |
||
179 | /// |
||
180 | /// SubtargetEmitter is responsible for processing all the definitions of class |
||
181 | /// IsOptimizableRegisterMove, and auto-generate an override for this method. |
||
182 | virtual bool isOptimizableRegisterMove(const MachineInstr *MI) const { |
||
183 | return false; |
||
184 | } |
||
185 | |||
186 | /// True if the subtarget should run MachineScheduler after aggressive |
||
187 | /// coalescing. |
||
188 | /// |
||
189 | /// This currently replaces the SelectionDAG scheduler with the "source" order |
||
190 | /// scheduler (though see below for an option to turn this off and use the |
||
191 | /// TargetLowering preference). It does not yet disable the postRA scheduler. |
||
192 | virtual bool enableMachineScheduler() const; |
||
193 | |||
194 | /// True if the machine scheduler should disable the TLI preference |
||
195 | /// for preRA scheduling with the source level scheduler. |
||
196 | virtual bool enableMachineSchedDefaultSched() const { return true; } |
||
197 | |||
198 | /// True if the subtarget should run MachinePipeliner |
||
199 | virtual bool enableMachinePipeliner() const { return true; }; |
||
200 | |||
201 | /// True if the subtarget should enable joining global copies. |
||
202 | /// |
||
203 | /// By default this is enabled if the machine scheduler is enabled, but |
||
204 | /// can be overridden. |
||
205 | virtual bool enableJoinGlobalCopies() const; |
||
206 | |||
207 | /// True if the subtarget should run a scheduler after register allocation. |
||
208 | /// |
||
209 | /// By default this queries the PostRAScheduling bit in the scheduling model |
||
210 | /// which is the preferred way to influence this. |
||
211 | virtual bool enablePostRAScheduler() const; |
||
212 | |||
213 | /// True if the subtarget should run a machine scheduler after register |
||
214 | /// allocation. |
||
215 | virtual bool enablePostRAMachineScheduler() const; |
||
216 | |||
217 | /// True if the subtarget should run the atomic expansion pass. |
||
218 | virtual bool enableAtomicExpand() const; |
||
219 | |||
220 | /// True if the subtarget should run the indirectbr expansion pass. |
||
221 | virtual bool enableIndirectBrExpand() const; |
||
222 | |||
223 | /// Override generic scheduling policy within a region. |
||
224 | /// |
||
225 | /// This is a convenient way for targets that don't provide any custom |
||
226 | /// scheduling heuristics (no custom MachineSchedStrategy) to make |
||
227 | /// changes to the generic scheduling policy. |
||
228 | virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, |
||
229 | unsigned NumRegionInstrs) const {} |
||
230 | |||
231 | // Perform target-specific adjustments to the latency of a schedule |
||
232 | // dependency. |
||
233 | // If a pair of operands is associated with the schedule dependency, DefOpIdx |
||
234 | // and UseOpIdx are the indices of the operands in Def and Use, respectively. |
||
235 | // Otherwise, either may be -1. |
||
236 | virtual void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, |
||
237 | int UseOpIdx, SDep &Dep) const {} |
||
238 | |||
239 | // For use with PostRAScheduling: get the anti-dependence breaking that should |
||
240 | // be performed before post-RA scheduling. |
||
241 | virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; } |
||
242 | |||
243 | // For use with PostRAScheduling: in CriticalPathRCs, return any register |
||
244 | // classes that should only be considered for anti-dependence breaking if they |
||
245 | // are on the critical path. |
||
246 | virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { |
||
247 | return CriticalPathRCs.clear(); |
||
248 | } |
||
249 | |||
250 | // Provide an ordered list of schedule DAG mutations for the post-RA |
||
251 | // scheduler. |
||
252 | virtual void getPostRAMutations( |
||
253 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
||
254 | } |
||
255 | |||
256 | // Provide an ordered list of schedule DAG mutations for the machine |
||
257 | // pipeliner. |
||
258 | virtual void getSMSMutations( |
||
259 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
||
260 | } |
||
261 | |||
262 | /// Default to DFA for resource management, return false when target will use |
||
263 | /// ProcResource in InstrSchedModel instead. |
||
264 | virtual bool useDFAforSMS() const { return true; } |
||
265 | |||
266 | // For use with PostRAScheduling: get the minimum optimization level needed |
||
267 | // to enable post-RA scheduling. |
||
268 | virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { |
||
269 | return CodeGenOpt::Default; |
||
270 | } |
||
271 | |||
272 | /// True if the subtarget should run the local reassignment |
||
273 | /// heuristic of the register allocator. |
||
274 | /// This heuristic may be compile time intensive, \p OptLevel provides |
||
275 | /// a finer grain to tune the register allocator. |
||
276 | virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const; |
||
277 | |||
278 | /// Enable use of alias analysis during code generation (during MI |
||
279 | /// scheduling, DAGCombine, etc.). |
||
280 | virtual bool useAA() const; |
||
281 | |||
282 | /// \brief Sink addresses into blocks using GEP instructions rather than |
||
283 | /// pointer casts and arithmetic. |
||
284 | virtual bool addrSinkUsingGEPs() const { |
||
285 | return useAA(); |
||
286 | } |
||
287 | |||
288 | /// Enable the use of the early if conversion pass. |
||
289 | virtual bool enableEarlyIfConversion() const { return false; } |
||
290 | |||
291 | /// Return PBQPConstraint(s) for the target. |
||
292 | /// |
||
293 | /// Override to provide custom PBQP constraints. |
||
294 | virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const { |
||
295 | return nullptr; |
||
296 | } |
||
297 | |||
298 | /// Enable tracking of subregister liveness in register allocator. |
||
299 | /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where |
||
300 | /// possible. |
||
301 | virtual bool enableSubRegLiveness() const { return false; } |
||
302 | |||
303 | /// This is called after a .mir file was loaded. |
||
304 | virtual void mirFileLoaded(MachineFunction &MF) const; |
||
305 | |||
306 | /// True if the register allocator should use the allocation orders exactly as |
||
307 | /// written in the tablegen descriptions, false if it should allocate |
||
308 | /// the specified physical register later if is it callee-saved. |
||
309 | virtual bool ignoreCSRForAllocationOrder(const MachineFunction &MF, |
||
310 | unsigned PhysReg) const { |
||
311 | return false; |
||
312 | } |
||
313 | |||
314 | /// Classify a global function reference. This mainly used to fetch target |
||
315 | /// special flags for lowering a function address. For example mark a function |
||
316 | /// call should be plt or pc-related addressing. |
||
317 | virtual unsigned char |
||
318 | classifyGlobalFunctionReference(const GlobalValue *GV) const { |
||
319 | return 0; |
||
320 | } |
||
321 | }; |
||
322 | |||
323 | } // end namespace llvm |
||
324 | |||
325 | #endif // LLVM_CODEGEN_TARGETSUBTARGETINFO_H |