LLVM  4.0.0
LegalizerInfo.h
Go to the documentation of this file.
1 //==-- llvm/CodeGen/GlobalISel/LegalizerInfo.h -------------------*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// Interface for Targets to specify which operations they can successfully
11 /// select and how the others should be expanded most efficiently.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZER_H
16 #define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZER_H
17 
18 #include "llvm/ADT/DenseMap.h"
21 
22 #include <cstdint>
23 #include <functional>
24 
25 namespace llvm {
26 class LLVMContext;
27 class MachineInstr;
28 class MachineRegisterInfo;
29 class Type;
30 class VectorType;
31 
32 /// Legalization is decided based on an instruction's opcode, which type slot
33 /// we're considering, and what the existing type is. These aspects are gathered
34 /// together for convenience in the InstrAspect class.
35 struct InstrAspect {
36  unsigned Opcode;
37  unsigned Idx;
39 
40  InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Idx(0), Type(Type) {}
41  InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
42  : Opcode(Opcode), Idx(Idx), Type(Type) {}
43 
44  bool operator==(const InstrAspect &RHS) const {
45  return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
46  }
47 };
48 
50 public:
51  enum LegalizeAction : std::uint8_t {
52  /// The operation is expected to be selectable directly by the target, and
53  /// no transformation is necessary.
55 
56  /// The operation should be synthesized from multiple instructions acting on
57  /// a narrower scalar base-type. For example a 64-bit add might be
58  /// implemented in terms of 32-bit add-with-carry.
60 
61  /// The operation should be implemented in terms of a wider scalar
62  /// base-type. For example a <2 x s8> add could be implemented as a <2
63  /// x s32> add (ignoring the high bits).
65 
66  /// The (vector) operation should be implemented by splitting it into
67  /// sub-vectors where the operation is legal. For example a <8 x s64> add
68  /// might be implemented as 4 separate <2 x s64> adds.
70 
71  /// The (vector) operation should be implemented by widening the input
72  /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
73  /// rarely legal, but you might perform an <8 x i8> and then only look at
74  /// the first two results.
76 
77  /// The operation itself must be expressed in terms of simpler actions on
78  /// this target. E.g. a SREM replaced by an SDIV and subtraction.
80 
81  /// The operation should be implemented as a call to some kind of runtime
82  /// support library. For example this usually happens on machines that don't
83  /// support floating-point operations natively.
85 
86  /// The target wants to do something special with this combination of
87  /// operand and type. A callback will be issued when it is needed.
89 
90  /// This operation is completely unsupported on the target. A programming
91  /// error has occurred.
93 
94  /// Sentinel value for when no action was found in the specified table.
96  };
97 
98  LegalizerInfo();
99 
100  /// Compute any ancillary tables needed to quickly decide how an operation
101  /// should be handled. This must be called after all "set*Action"methods but
102  /// before any query is made or incorrect results may be returned.
103  void computeTables();
104 
105  /// More friendly way to set an action for common types that have an LLT
106  /// representation.
107  void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
108  TablesInitialized = false;
109  unsigned Opcode = Aspect.Opcode - FirstOp;
110  if (Actions[Opcode].size() <= Aspect.Idx)
111  Actions[Opcode].resize(Aspect.Idx + 1);
112  Actions[Aspect.Opcode - FirstOp][Aspect.Idx][Aspect.Type] = Action;
113  }
114 
115  /// If an operation on a given vector type (say <M x iN>) isn't explicitly
116  /// specified, we proceed in 2 stages. First we legalize the underlying scalar
117  /// (so that there's at least one legal vector with that scalar), then we
118  /// adjust the number of elements in the vector so that it is legal. The
119  /// desired action in the first step is controlled by this function.
120  void setScalarInVectorAction(unsigned Opcode, LLT ScalarTy,
121  LegalizeAction Action) {
122  assert(!ScalarTy.isVector());
123  ScalarInVectorActions[std::make_pair(Opcode, ScalarTy)] = Action;
124  }
125 
126 
127  /// Determine what action should be taken to legalize the given generic
128  /// instruction opcode, type-index and type. Requires computeTables to have
129  /// been called.
130  ///
131  /// \returns a pair consisting of the kind of legalization that should be
132  /// performed and the destination type.
133  std::pair<LegalizeAction, LLT> getAction(const InstrAspect &Aspect) const;
134 
135  /// Determine what action should be taken to legalize the given generic
136  /// instruction.
137  ///
138  /// \returns a tuple consisting of the LegalizeAction that should be
139  /// performed, the type-index it should be performed on and the destination
140  /// type.
141  std::tuple<LegalizeAction, unsigned, LLT>
142  getAction(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
143 
144  /// Iterate the given function (typically something like doubling the width)
145  /// on Ty until we find a legal type for this operation.
147  std::function<LLT(LLT)> NextType) const {
148  LegalizeAction Action;
149  const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
150  LLT Ty = Aspect.Type;
151  do {
152  Ty = NextType(Ty);
153  auto ActionIt = Map.find(Ty);
154  if (ActionIt == Map.end())
155  Action = DefaultActions.find(Aspect.Opcode)->second;
156  else
157  Action = ActionIt->second;
158  } while(Action != Legal);
159  return Ty;
160  }
161 
162  /// Find what type it's actually OK to perform the given operation on, given
163  /// the general approach we've decided to take.
164  LLT findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const;
165 
166  std::pair<LegalizeAction, LLT> findLegalAction(const InstrAspect &Aspect,
167  LegalizeAction Action) const {
168  return std::make_pair(Action, findLegalType(Aspect, Action));
169  }
170 
171  /// Find the specified \p Aspect in the primary (explicitly set) Actions
172  /// table. Returns either the action the target requested or NotFound if there
173  /// was no setAction call.
174  LegalizeAction findInActions(const InstrAspect &Aspect) const {
175  if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
176  return NotFound;
177  if (Aspect.Idx >= Actions[Aspect.Opcode - FirstOp].size())
178  return NotFound;
179  const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
180  auto ActionIt = Map.find(Aspect.Type);
181  if (ActionIt == Map.end())
182  return NotFound;
183 
184  return ActionIt->second;
185  }
186 
187  bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
188 
189 private:
190  static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
191  static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
192 
193  typedef DenseMap<LLT, LegalizeAction> TypeMap;
194  typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> SIVActionMap;
195 
196  SmallVector<TypeMap, 1> Actions[LastOp - FirstOp + 1];
197  SIVActionMap ScalarInVectorActions;
198  DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts;
199  DenseMap<unsigned, LegalizeAction> DefaultActions;
200 
201  bool TablesInitialized;
202 };
203 
204 
205 } // End namespace llvm.
206 
207 #endif
InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
Definition: LegalizerInfo.h:41
bool operator==(const InstrAspect &RHS) const
Definition: LegalizerInfo.h:44
std::pair< LegalizeAction, LLT > getAction(const InstrAspect &Aspect) const
Determine what action should be taken to legalize the given generic instruction opcode, type-index and type.
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:95
InstrAspect(unsigned Opcode, LLT Type)
Definition: LegalizerInfo.h:40
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
The target wants to do something special with this combination of operand and type.
Definition: LegalizerInfo.h:88
unsigned const MachineRegisterInfo * MRI
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:69
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
Definition: LegalizerInfo.h:75
std::pair< LegalizeAction, LLT > findLegalAction(const InstrAspect &Aspect, LegalizeAction Action) const
Legalization is decided based on an instruction's opcode, which type slot we're considering, and what the existing type is.
Definition: LegalizerInfo.h:35
LLT findLegalType(const InstrAspect &Aspect, std::function< LLT(LLT)> NextType) const
Iterate the given function (typically something like doubling the width) on Ty until we find a legal ...
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type...
Definition: LegalizerInfo.h:59
The operation should be implemented as a call to some kind of runtime support library.
Definition: LegalizerInfo.h:84
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:64
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:79
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:54
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:52
iterator end()
Definition: DenseMap.h:69
iterator find(const KeyT &Val)
Definition: DenseMap.h:127
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:92
print Print MemDeps of function
IRTranslator LLVM IR MI
LegalizeAction findInActions(const InstrAspect &Aspect) const
Find the specified Aspect in the primary (explicitly set) Actions table.
bool isVector() const
Definition: LowLevelType.h:94
void setScalarInVectorAction(unsigned Opcode, LLT ScalarTy, LegalizeAction Action)
If an operation on a given vector type (say <M x="" in>="">) isn't explicitly specified, we proceed in 2 stages.
bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const
void setAction(const InstrAspect &Aspect, LegalizeAction Action)
More friendly way to set an action for common types that have an LLT representation.