LLVM  4.0.0
LegalizerInfo.cpp
Go to the documentation of this file.
1 //===---- lib/CodeGen/GlobalISel/LegalizerInfo.cpp - Legalizer -------==//
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 // Implement an interface to specify and query how an illegal operation on a
11 // given type should be expanded.
12 //
13 // Issues to be resolved:
14 // + Make it fast.
15 // + Support weird types like i3, <7 x i3>, ...
16 // + Operations with more than one type (ICMP, CMPXCHG, intrinsics, ...)
17 //
18 //===----------------------------------------------------------------------===//
19 
21 
26 #include "llvm/IR/Type.h"
28 using namespace llvm;
29 
30 LegalizerInfo::LegalizerInfo() : TablesInitialized(false) {
31  // FIXME: these two can be legalized to the fundamental load/store Jakob
32  // proposed. Once loads & stores are supported.
33  DefaultActions[TargetOpcode::G_ANYEXT] = Legal;
34  DefaultActions[TargetOpcode::G_TRUNC] = Legal;
35 
36  DefaultActions[TargetOpcode::G_INTRINSIC] = Legal;
37  DefaultActions[TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS] = Legal;
38 
39  DefaultActions[TargetOpcode::G_ADD] = NarrowScalar;
40  DefaultActions[TargetOpcode::G_LOAD] = NarrowScalar;
41  DefaultActions[TargetOpcode::G_STORE] = NarrowScalar;
42 
43  DefaultActions[TargetOpcode::G_BRCOND] = WidenScalar;
44 }
45 
47  for (unsigned Opcode = 0; Opcode <= LastOp - FirstOp; ++Opcode) {
48  for (unsigned Idx = 0; Idx != Actions[Opcode].size(); ++Idx) {
49  for (auto &Action : Actions[Opcode][Idx]) {
50  LLT Ty = Action.first;
51  if (!Ty.isVector())
52  continue;
53 
54  auto &Entry = MaxLegalVectorElts[std::make_pair(Opcode + FirstOp,
55  Ty.getElementType())];
56  Entry = std::max(Entry, Ty.getNumElements());
57  }
58  }
59  }
60 
61  TablesInitialized = true;
62 }
63 
64 // FIXME: inefficient implementation for now. Without ComputeValueVTs we're
65 // probably going to need specialized lookup structures for various types before
66 // we have any hope of doing well with something like <13 x i3>. Even the common
67 // cases should do better than what we have now.
68 std::pair<LegalizerInfo::LegalizeAction, LLT>
69 LegalizerInfo::getAction(const InstrAspect &Aspect) const {
70  assert(TablesInitialized && "backend forgot to call computeTables");
71  // These *have* to be implemented for now, they're the fundamental basis of
72  // how everything else is transformed.
73 
74  // Nothing is going to go well with types that aren't a power of 2 yet, so
75  // don't even try because we might make things worse.
76  if (!isPowerOf2_64(Aspect.Type.getSizeInBits()))
77  return std::make_pair(Unsupported, LLT());
78 
79  // FIXME: the long-term plan calls for expansion in terms of load/store (if
80  // they're not legal).
81  if (Aspect.Opcode == TargetOpcode::G_SEQUENCE ||
82  Aspect.Opcode == TargetOpcode::G_EXTRACT)
83  return std::make_pair(Legal, Aspect.Type);
84 
85  LegalizeAction Action = findInActions(Aspect);
86  if (Action != NotFound)
87  return findLegalAction(Aspect, Action);
88 
89  unsigned Opcode = Aspect.Opcode;
90  LLT Ty = Aspect.Type;
91  if (!Ty.isVector()) {
92  auto DefaultAction = DefaultActions.find(Aspect.Opcode);
93  if (DefaultAction != DefaultActions.end() && DefaultAction->second == Legal)
94  return std::make_pair(Legal, Ty);
95 
96  if (DefaultAction == DefaultActions.end() ||
97  DefaultAction->second != NarrowScalar)
98  return std::make_pair(Unsupported, LLT());
99  return findLegalAction(Aspect, NarrowScalar);
100  }
101 
102  LLT EltTy = Ty.getElementType();
103  int NumElts = Ty.getNumElements();
104 
105  auto ScalarAction = ScalarInVectorActions.find(std::make_pair(Opcode, EltTy));
106  if (ScalarAction != ScalarInVectorActions.end() &&
107  ScalarAction->second != Legal)
108  return findLegalAction(Aspect, ScalarAction->second);
109 
110  // The element type is legal in principle, but the number of elements is
111  // wrong.
112  auto MaxLegalElts = MaxLegalVectorElts.lookup(std::make_pair(Opcode, EltTy));
113  if (MaxLegalElts > NumElts)
114  return findLegalAction(Aspect, MoreElements);
115 
116  if (MaxLegalElts == 0) {
117  // Scalarize if there's no legal vector type, which is just a special case
118  // of FewerElements.
119  return std::make_pair(FewerElements, EltTy);
120  }
121 
122  return findLegalAction(Aspect, FewerElements);
123 }
124 
125 std::tuple<LegalizerInfo::LegalizeAction, unsigned, LLT>
127  const MachineRegisterInfo &MRI) const {
128  SmallBitVector SeenTypes(8);
129  const MCOperandInfo *OpInfo = MI.getDesc().OpInfo;
130  for (unsigned i = 0; i < MI.getDesc().getNumOperands(); ++i) {
131  if (!OpInfo[i].isGenericType())
132  continue;
133 
134  // We don't want to repeatedly check the same operand index, that
135  // could get expensive.
136  unsigned TypeIdx = OpInfo[i].getGenericTypeIndex();
137  if (SeenTypes[TypeIdx])
138  continue;
139 
140  SeenTypes.set(TypeIdx);
141 
142  LLT Ty = MRI.getType(MI.getOperand(i).getReg());
143  auto Action = getAction({MI.getOpcode(), TypeIdx, Ty});
144  if (Action.first != Legal)
145  return std::make_tuple(Action.first, TypeIdx, Action.second);
146  }
147  return std::make_tuple(Legal, 0, LLT{});
148 }
149 
151  const MachineRegisterInfo &MRI) const {
152  return std::get<0>(getAction(MI, MRI)) == Legal;
153 }
154 
156  LegalizeAction Action) const {
157  switch(Action) {
158  default:
159  llvm_unreachable("Cannot find legal type");
160  case Legal:
161  case Lower:
162  case Libcall:
163  return Aspect.Type;
164  case NarrowScalar: {
165  return findLegalType(Aspect,
166  [&](LLT Ty) -> LLT { return Ty.halfScalarSize(); });
167  }
168  case WidenScalar: {
169  return findLegalType(Aspect, [&](LLT Ty) -> LLT {
170  return Ty.getSizeInBits() < 8 ? LLT::scalar(8) : Ty.doubleScalarSize();
171  });
172  }
173  case FewerElements: {
174  return findLegalType(Aspect,
175  [&](LLT Ty) -> LLT { return Ty.halfElements(); });
176  }
177  case MoreElements: {
178  return findLegalType(Aspect,
179  [&](LLT Ty) -> LLT { return Ty.doubleElements(); });
180  }
181  }
182 }
LLT doubleElements() const
Get a low-level type with twice the size of the original, by doubling the number of vector elements o...
Definition: LowLevelType.h:160
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
size_t i
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.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:270
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:95
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
Function Alias Analysis false
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:51
LLT doubleScalarSize() const
Get a low-level type with twice the size of the original, by doubling the size of the scalar type inv...
Definition: LowLevelType.h:137
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
unsigned const MachineRegisterInfo * MRI
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:69
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
unsigned getGenericTypeIndex() const
Definition: MCInstrDesc.h:106
constexpr bool isPowerOf2_64(uint64_t Value)
isPowerOf2_64 - This function returns true if the argument is a power of two 0 (64 bit edition...
Definition: MathExtras.h:405
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 ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelType.h:98
SmallBitVector & set()
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
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
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelType.h:120
LLT halfScalarSize() const
Get a low-level type with half the size of the original, by halving the size of the scalar type invol...
Definition: LowLevelType.h:128
LLT halfElements() const
Get a low-level type with half the size of the original, by halving the number of vector elements of ...
Definition: LowLevelType.h:146
iterator end()
Definition: DenseMap.h:69
iterator find(const KeyT &Val)
Definition: DenseMap.h:127
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:92
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:210
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:174
IRTranslator LLVM IR MI
LegalizeAction findInActions(const InstrAspect &Aspect) const
Find the specified Aspect in the primary (explicitly set) Actions table.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:104
bool isVector() const
Definition: LowLevelType.h:94
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:70
bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const