blob: bd8374cb6b05cb8e76733449f68a1616085022f4 [file] [log] [blame]
Tim Northover33b07d62016-07-22 20:03:43 +00001//===-- llvm/CodeGen/GlobalISel/MachineLegalizeHelper.cpp -----------------===//
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/// \file This file implements the MachineLegalizeHelper class to legalize
11/// individual instructions and the LegalizeMachineIR wrapper pass for the
12/// primary legalization.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h"
17#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
18#include "llvm/CodeGen/MachineRegisterInfo.h"
19#include "llvm/Support/Debug.h"
20#include "llvm/Support/raw_ostream.h"
21#include "llvm/Target/TargetSubtargetInfo.h"
22
23#include <sstream>
24
25#define DEBUG_TYPE "legalize-mir"
26
27using namespace llvm;
28
29MachineLegalizeHelper::MachineLegalizeHelper(MachineFunction &MF)
30 : MRI(MF.getRegInfo()) {
31 MIRBuilder.setMF(MF);
32}
33
34MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::legalizeInstr(
35 MachineInstr &MI, const MachineLegalizer &Legalizer) {
36 auto Action = Legalizer.getAction(MI);
Tim Northovera01bece2016-08-23 19:30:42 +000037 switch (std::get<0>(Action)) {
Tim Northover33b07d62016-07-22 20:03:43 +000038 case MachineLegalizer::Legal:
39 return AlreadyLegal;
40 case MachineLegalizer::NarrowScalar:
Tim Northovera01bece2016-08-23 19:30:42 +000041 return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
Tim Northover33b07d62016-07-22 20:03:43 +000042 case MachineLegalizer::WidenScalar:
Tim Northovera01bece2016-08-23 19:30:42 +000043 return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
Tim Northover33b07d62016-07-22 20:03:43 +000044 case MachineLegalizer::FewerElements:
Tim Northovera01bece2016-08-23 19:30:42 +000045 return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action));
Tim Northover33b07d62016-07-22 20:03:43 +000046 default:
47 return UnableToLegalize;
48 }
49}
50
51void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int NumParts,
52 SmallVectorImpl<unsigned> &VRegs) {
53 unsigned Size = Ty.getSizeInBits();
Tim Northover6f80b082016-08-19 17:47:05 +000054 SmallVector<uint64_t, 4> Indexes;
Tim Northover26b76f22016-08-19 18:32:14 +000055 SmallVector<LLT, 4> ResTys;
Tim Northover33b07d62016-07-22 20:03:43 +000056 for (int i = 0; i < NumParts; ++i) {
57 VRegs.push_back(MRI.createGenericVirtualRegister(Size));
58 Indexes.push_back(i * Size);
Tim Northover26b76f22016-08-19 18:32:14 +000059 ResTys.push_back(Ty);
Tim Northover33b07d62016-07-22 20:03:43 +000060 }
Tim Northover26b76f22016-08-19 18:32:14 +000061 MIRBuilder.buildExtract(ResTys, VRegs, Indexes,
62 LLT::scalar(Ty.getSizeInBits() * NumParts), Reg);
Tim Northover33b07d62016-07-22 20:03:43 +000063}
64
65MachineLegalizeHelper::LegalizeResult
Tim Northovera01bece2016-08-23 19:30:42 +000066MachineLegalizeHelper::narrowScalar(MachineInstr &MI, unsigned TypeIdx,
67 LLT NarrowTy) {
68 assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
Tim Northover9656f142016-08-04 20:54:13 +000069 switch (MI.getOpcode()) {
70 default:
71 return UnableToLegalize;
72 case TargetOpcode::G_ADD: {
73 // Expand in terms of carry-setting/consuming G_ADDE instructions.
74 unsigned NarrowSize = NarrowTy.getSizeInBits();
75 int NumParts = MI.getType().getSizeInBits() / NarrowSize;
76
77 MIRBuilder.setInstr(MI);
78
Tim Northover91c81732016-08-19 17:17:06 +000079 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs, Indexes;
Tim Northover9656f142016-08-04 20:54:13 +000080 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
81 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
82
83 unsigned CarryIn = MRI.createGenericVirtualRegister(1);
84 MIRBuilder.buildConstant(LLT::scalar(1), CarryIn, 0);
85
Tim Northover26b76f22016-08-19 18:32:14 +000086 SmallVector<LLT, 2> DstTys;
Tim Northover9656f142016-08-04 20:54:13 +000087 for (int i = 0; i < NumParts; ++i) {
88 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowSize);
89 unsigned CarryOut = MRI.createGenericVirtualRegister(1);
90
Tim Northover91c81732016-08-19 17:17:06 +000091 MIRBuilder.buildUAdde(NarrowTy, DstReg, CarryOut, Src1Regs[i],
92 Src2Regs[i], CarryIn);
Tim Northover9656f142016-08-04 20:54:13 +000093
Tim Northover26b76f22016-08-19 18:32:14 +000094 DstTys.push_back(NarrowTy);
Tim Northover9656f142016-08-04 20:54:13 +000095 DstRegs.push_back(DstReg);
Tim Northover91c81732016-08-19 17:17:06 +000096 Indexes.push_back(i * NarrowSize);
Tim Northover9656f142016-08-04 20:54:13 +000097 CarryIn = CarryOut;
98 }
Tim Northover26b76f22016-08-19 18:32:14 +000099 MIRBuilder.buildSequence(MI.getType(), MI.getOperand(0).getReg(), DstTys,
100 DstRegs, Indexes);
Tim Northover9656f142016-08-04 20:54:13 +0000101 MI.eraseFromParent();
102 return Legalized;
103 }
104 }
Tim Northover33b07d62016-07-22 20:03:43 +0000105}
106
107MachineLegalizeHelper::LegalizeResult
Tim Northovera01bece2016-08-23 19:30:42 +0000108MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
109 LLT WideTy) {
110 assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
111
Tim Northoverea904f92016-08-19 22:40:00 +0000112 unsigned WideSize = WideTy.getSizeInBits();
Tim Northover3c73e362016-08-23 18:20:09 +0000113 MIRBuilder.setInstr(MI);
114
Tim Northover32335812016-08-04 18:35:11 +0000115 switch (MI.getOpcode()) {
116 default:
117 return UnableToLegalize;
Tim Northover61c16142016-08-04 21:39:49 +0000118 case TargetOpcode::G_ADD:
119 case TargetOpcode::G_AND:
120 case TargetOpcode::G_MUL:
121 case TargetOpcode::G_OR:
122 case TargetOpcode::G_XOR:
123 case TargetOpcode::G_SUB: {
Tim Northover32335812016-08-04 18:35:11 +0000124 // Perform operation at larger width (any extension is fine here, high bits
125 // don't affect the result) and then truncate the result back to the
126 // original type.
Tim Northover32335812016-08-04 18:35:11 +0000127 unsigned Src1Ext = MRI.createGenericVirtualRegister(WideSize);
128 unsigned Src2Ext = MRI.createGenericVirtualRegister(WideSize);
129 MIRBuilder.buildAnyExtend(WideTy, Src1Ext, MI.getOperand(1).getReg());
130 MIRBuilder.buildAnyExtend(WideTy, Src2Ext, MI.getOperand(2).getReg());
131
132 unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
Tim Northover61c16142016-08-04 21:39:49 +0000133 MIRBuilder.buildInstr(MI.getOpcode(), WideTy)
134 .addDef(DstExt).addUse(Src1Ext).addUse(Src2Ext);
Tim Northover32335812016-08-04 18:35:11 +0000135
136 MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
137 MI.eraseFromParent();
138 return Legalized;
139 }
Tim Northover3c73e362016-08-23 18:20:09 +0000140 case TargetOpcode::G_LOAD: {
141 assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
142 "illegal to increase number of bytes loaded");
143
144 unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
145 MIRBuilder.buildLoad(WideTy, MI.getType(1), DstExt,
146 MI.getOperand(1).getReg(), **MI.memoperands_begin());
147 MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
148 MI.eraseFromParent();
149 return Legalized;
150 }
151 case TargetOpcode::G_STORE: {
152 assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
153 "illegal to increase number of bytes modified by a store");
154
155 unsigned SrcExt = MRI.createGenericVirtualRegister(WideSize);
156 MIRBuilder.buildAnyExtend(WideTy, SrcExt, MI.getOperand(0).getReg());
157 MIRBuilder.buildStore(WideTy, MI.getType(1), SrcExt,
158 MI.getOperand(1).getReg(), **MI.memoperands_begin());
159 MI.eraseFromParent();
160 return Legalized;
161 }
Tim Northoverea904f92016-08-19 22:40:00 +0000162 case TargetOpcode::G_CONSTANT: {
Tim Northoverea904f92016-08-19 22:40:00 +0000163 unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
164 MIRBuilder.buildConstant(WideTy, DstExt, MI.getOperand(1).getImm());
165 MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
166 MI.eraseFromParent();
167 return Legalized;
168 }
Tim Northovera11be042016-08-19 22:40:08 +0000169 case TargetOpcode::G_FCONSTANT: {
Tim Northovera11be042016-08-19 22:40:08 +0000170 unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
171 MIRBuilder.buildFConstant(WideTy, DstExt, *MI.getOperand(1).getFPImm());
172 MIRBuilder.buildFPTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
173 MI.eraseFromParent();
174 return Legalized;
175 }
Tim Northover32335812016-08-04 18:35:11 +0000176 }
Tim Northover33b07d62016-07-22 20:03:43 +0000177}
178
179MachineLegalizeHelper::LegalizeResult
Tim Northovera01bece2016-08-23 19:30:42 +0000180MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
181 LLT NarrowTy) {
182 assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
Tim Northover33b07d62016-07-22 20:03:43 +0000183 switch (MI.getOpcode()) {
184 default:
185 return UnableToLegalize;
186 case TargetOpcode::G_ADD: {
187 unsigned NarrowSize = NarrowTy.getSizeInBits();
188 int NumParts = MI.getType().getSizeInBits() / NarrowSize;
189
190 MIRBuilder.setInstr(MI);
191
Tim Northover91c81732016-08-19 17:17:06 +0000192 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs, Indexes;
Tim Northover33b07d62016-07-22 20:03:43 +0000193 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
194 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
195
Tim Northover26b76f22016-08-19 18:32:14 +0000196 SmallVector<LLT, 2> DstTys;
Tim Northover33b07d62016-07-22 20:03:43 +0000197 for (int i = 0; i < NumParts; ++i) {
198 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowSize);
199 MIRBuilder.buildAdd(NarrowTy, DstReg, Src1Regs[i], Src2Regs[i]);
Tim Northover26b76f22016-08-19 18:32:14 +0000200 DstTys.push_back(NarrowTy);
Tim Northover33b07d62016-07-22 20:03:43 +0000201 DstRegs.push_back(DstReg);
Tim Northover91c81732016-08-19 17:17:06 +0000202 Indexes.push_back(i * NarrowSize);
Tim Northover33b07d62016-07-22 20:03:43 +0000203 }
204
Tim Northover26b76f22016-08-19 18:32:14 +0000205 MIRBuilder.buildSequence(MI.getType(), MI.getOperand(0).getReg(), DstTys,
206 DstRegs, Indexes);
Tim Northover33b07d62016-07-22 20:03:43 +0000207 MI.eraseFromParent();
208 return Legalized;
209 }
210 }
211}