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