blob: 6d2d1057a6b9bc6e35cfb45d22a6ba7b9056e8e2 [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);
37 switch (Action.first) {
38 case MachineLegalizer::Legal:
39 return AlreadyLegal;
40 case MachineLegalizer::NarrowScalar:
41 return narrowScalar(MI, Action.second);
42 case MachineLegalizer::WidenScalar:
43 return widenScalar(MI, Action.second);
44 case MachineLegalizer::FewerElements:
45 return fewerElementsVector(MI, Action.second);
46 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 Northover33b07d62016-07-22 20:03:43 +000055 for (int i = 0; i < NumParts; ++i) {
56 VRegs.push_back(MRI.createGenericVirtualRegister(Size));
57 Indexes.push_back(i * Size);
58 }
59 MIRBuilder.buildExtract(Ty, VRegs, Reg, Indexes);
60}
61
62MachineLegalizeHelper::LegalizeResult
63MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) {
Tim Northover9656f142016-08-04 20:54:13 +000064 switch (MI.getOpcode()) {
65 default:
66 return UnableToLegalize;
67 case TargetOpcode::G_ADD: {
68 // Expand in terms of carry-setting/consuming G_ADDE instructions.
69 unsigned NarrowSize = NarrowTy.getSizeInBits();
70 int NumParts = MI.getType().getSizeInBits() / NarrowSize;
71
72 MIRBuilder.setInstr(MI);
73
Tim Northover91c81732016-08-19 17:17:06 +000074 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs, Indexes;
Tim Northover9656f142016-08-04 20:54:13 +000075 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
76 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
77
78 unsigned CarryIn = MRI.createGenericVirtualRegister(1);
79 MIRBuilder.buildConstant(LLT::scalar(1), CarryIn, 0);
80
81 for (int i = 0; i < NumParts; ++i) {
82 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowSize);
83 unsigned CarryOut = MRI.createGenericVirtualRegister(1);
84
Tim Northover91c81732016-08-19 17:17:06 +000085 MIRBuilder.buildUAdde(NarrowTy, DstReg, CarryOut, Src1Regs[i],
86 Src2Regs[i], CarryIn);
Tim Northover9656f142016-08-04 20:54:13 +000087
88 DstRegs.push_back(DstReg);
Tim Northover91c81732016-08-19 17:17:06 +000089 Indexes.push_back(i * NarrowSize);
Tim Northover9656f142016-08-04 20:54:13 +000090 CarryIn = CarryOut;
91 }
Tim Northover91c81732016-08-19 17:17:06 +000092 MIRBuilder.buildSequence(MI.getType(), MI.getOperand(0).getReg(), DstRegs,
93 Indexes);
Tim Northover9656f142016-08-04 20:54:13 +000094 MI.eraseFromParent();
95 return Legalized;
96 }
97 }
Tim Northover33b07d62016-07-22 20:03:43 +000098}
99
100MachineLegalizeHelper::LegalizeResult
101MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
Tim Northover32335812016-08-04 18:35:11 +0000102 switch (MI.getOpcode()) {
103 default:
104 return UnableToLegalize;
Tim Northover61c16142016-08-04 21:39:49 +0000105 case TargetOpcode::G_ADD:
106 case TargetOpcode::G_AND:
107 case TargetOpcode::G_MUL:
108 case TargetOpcode::G_OR:
109 case TargetOpcode::G_XOR:
110 case TargetOpcode::G_SUB: {
Tim Northover32335812016-08-04 18:35:11 +0000111 // Perform operation at larger width (any extension is fine here, high bits
112 // don't affect the result) and then truncate the result back to the
113 // original type.
114 unsigned WideSize = WideTy.getSizeInBits();
115
116 MIRBuilder.setInstr(MI);
117
118 unsigned Src1Ext = MRI.createGenericVirtualRegister(WideSize);
119 unsigned Src2Ext = MRI.createGenericVirtualRegister(WideSize);
120 MIRBuilder.buildAnyExtend(WideTy, Src1Ext, MI.getOperand(1).getReg());
121 MIRBuilder.buildAnyExtend(WideTy, Src2Ext, MI.getOperand(2).getReg());
122
123 unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
Tim Northover61c16142016-08-04 21:39:49 +0000124 MIRBuilder.buildInstr(MI.getOpcode(), WideTy)
125 .addDef(DstExt).addUse(Src1Ext).addUse(Src2Ext);
Tim Northover32335812016-08-04 18:35:11 +0000126
127 MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
128 MI.eraseFromParent();
129 return Legalized;
130 }
131 }
Tim Northover33b07d62016-07-22 20:03:43 +0000132}
133
134MachineLegalizeHelper::LegalizeResult
135MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, LLT NarrowTy) {
136 switch (MI.getOpcode()) {
137 default:
138 return UnableToLegalize;
139 case TargetOpcode::G_ADD: {
140 unsigned NarrowSize = NarrowTy.getSizeInBits();
141 int NumParts = MI.getType().getSizeInBits() / NarrowSize;
142
143 MIRBuilder.setInstr(MI);
144
Tim Northover91c81732016-08-19 17:17:06 +0000145 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs, Indexes;
Tim Northover33b07d62016-07-22 20:03:43 +0000146 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
147 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
148
149 for (int i = 0; i < NumParts; ++i) {
150 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowSize);
151 MIRBuilder.buildAdd(NarrowTy, DstReg, Src1Regs[i], Src2Regs[i]);
152 DstRegs.push_back(DstReg);
Tim Northover91c81732016-08-19 17:17:06 +0000153 Indexes.push_back(i * NarrowSize);
Tim Northover33b07d62016-07-22 20:03:43 +0000154 }
155
Tim Northover91c81732016-08-19 17:17:06 +0000156 MIRBuilder.buildSequence(MI.getType(), MI.getOperand(0).getReg(), DstRegs,
157 Indexes);
Tim Northover33b07d62016-07-22 20:03:43 +0000158 MI.eraseFromParent();
159 return Legalized;
160 }
161 }
162}