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