blob: 600f7bc5973c8b0814b73c1815b6e7b58acf1cba [file] [log] [blame]
Tim Northover75ad0772016-07-20 21:13:29 +00001//===---- lib/CodeGen/GlobalISel/MachineLegalizer.cpp - IRTranslator -------==//
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
20#include "llvm/CodeGen/MachineInstr.h"
21#include "llvm/CodeGen/ValueTypes.h"
22#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
23#include "llvm/IR/Type.h"
24#include "llvm/Target/TargetOpcodes.h"
25using namespace llvm;
26
27MachineLegalizer::MachineLegalizer() : TablesInitialized(false) {
28 DefaultActions[TargetOpcode::G_ADD] = NarrowScalar;
29}
30
Tim Northover75ad0772016-07-20 21:13:29 +000031void MachineLegalizer::computeTables() {
32 for (auto &Op : Actions) {
33 LLT Ty = Op.first.second;
34 if (!Ty.isVector())
35 continue;
36
37 auto &Entry =
38 MaxLegalVectorElts[std::make_pair(Op.first.first, Ty.getElementType())];
39 Entry = std::max(Entry, Ty.getNumElements());
40 }
41
42 TablesInitialized = true;
43}
44
45// FIXME: inefficient implementation for now. Without ComputeValueVTs we're
46// probably going to need specialized lookup structures for various types before
47// we have any hope of doing well with something like <13 x i3>. Even the common
48// cases should do better than what we have now.
49std::pair<MachineLegalizer::LegalizeAction, LLT>
50MachineLegalizer::getAction(unsigned Opcode, LLT Ty) const {
51 assert(TablesInitialized && "backend forgot to call computeTables");
52 // These *have* to be implemented for now, they're the fundamental basis of
53 // how everything else is transformed.
54
Tim Northover33b07d62016-07-22 20:03:43 +000055 // FIXME: the long-term plan calls for expansion in terms of load/store (if
56 // they're not legal).
57 if (Opcode == TargetOpcode::G_SEQUENCE || Opcode == TargetOpcode::G_EXTRACT)
58 return std::make_pair(Legal, Ty);
59
Tim Northover75ad0772016-07-20 21:13:29 +000060 auto ActionIt = Actions.find(std::make_pair(Opcode, Ty));
61 if (ActionIt != Actions.end())
62 return findLegalAction(Opcode, Ty, ActionIt->second);
63
64 if (!Ty.isVector()) {
65 auto DefaultAction = DefaultActions.find(Opcode);
66 if (DefaultAction != DefaultActions.end() && DefaultAction->second == Legal)
67 return std::make_pair(Legal, Ty);
68
69 assert(DefaultAction->second == NarrowScalar && "unexpected default");
70 return findLegalAction(Opcode, Ty, NarrowScalar);
71 }
72
73 LLT EltTy = Ty.getElementType();
74 int NumElts = Ty.getNumElements();
75
76 auto ScalarAction = ScalarInVectorActions.find(std::make_pair(Opcode, EltTy));
77 if (ScalarAction != ScalarInVectorActions.end() &&
78 ScalarAction->second != Legal)
79 return findLegalAction(Opcode, EltTy, ScalarAction->second);
80
81 // The element type is legal in principle, but the number of elements is
82 // wrong.
83 auto MaxLegalElts = MaxLegalVectorElts.lookup(std::make_pair(Opcode, EltTy));
84 if (MaxLegalElts > NumElts)
85 return findLegalAction(Opcode, Ty, MoreElements);
86
87 if (MaxLegalElts == 0) {
88 // Scalarize if there's no legal vector type, which is just a special case
89 // of FewerElements.
90 return std::make_pair(FewerElements, EltTy);
91 }
92
93 return findLegalAction(Opcode, Ty, FewerElements);
94}
95
96std::pair<MachineLegalizer::LegalizeAction, LLT>
97MachineLegalizer::getAction(MachineInstr &MI) const {
98 return getAction(MI.getOpcode(), MI.getType());
99}
100
101bool MachineLegalizer::isLegal(MachineInstr &MI) const {
102 return getAction(MI).first == Legal;
103}
104
105LLT MachineLegalizer::findLegalType(unsigned Opcode, LLT Ty,
106 LegalizeAction Action) const {
107 switch(Action) {
108 default:
109 llvm_unreachable("Cannot find legal type");
110 case Legal:
111 return Ty;
112 case NarrowScalar: {
113 return findLegalType(Opcode, Ty,
114 [&](LLT Ty) -> LLT { return Ty.halfScalarSize(); });
115 }
116 case WidenScalar: {
117 return findLegalType(Opcode, Ty,
118 [&](LLT Ty) -> LLT { return Ty.doubleScalarSize(); });
119 }
120 case FewerElements: {
121 return findLegalType(Opcode, Ty,
122 [&](LLT Ty) -> LLT { return Ty.halfElements(); });
123 }
124 case MoreElements: {
125 return findLegalType(
126 Opcode, Ty, [&](LLT Ty) -> LLT { return Ty.doubleElements(); });
127 }
128 }
129}