blob: b52cb103cebfe2b336cfe9d2b005b2fa87e9f26f [file] [log] [blame]
Tim Northover33b07d62016-07-22 20:03:43 +00001//===-- llvm/CodeGen/GlobalISel/MachineLegalizePass.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 LegalizeHelper class to legalize individual
11/// instructions and the MachineLegalizePass wrapper pass for the primary
12/// legalization.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/CodeGen/GlobalISel/MachineLegalizePass.h"
Tim Northover33b07d62016-07-22 20:03:43 +000017#include "llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h"
18#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000019#include "llvm/CodeGen/MachineRegisterInfo.h"
20#include "llvm/CodeGen/TargetPassConfig.h"
Tim Northover33b07d62016-07-22 20:03:43 +000021#include "llvm/Support/Debug.h"
Tim Northover991b12b2016-08-30 20:51:25 +000022#include "llvm/Target/TargetInstrInfo.h"
Tim Northover33b07d62016-07-22 20:03:43 +000023#include "llvm/Target/TargetSubtargetInfo.h"
24
25#define DEBUG_TYPE "legalize-mir"
26
27using namespace llvm;
28
29char MachineLegalizePass::ID = 0;
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000030INITIALIZE_PASS_BEGIN(MachineLegalizePass, DEBUG_TYPE,
31 "Legalize the Machine IR a function's Machine IR", false,
32 false)
33INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
34INITIALIZE_PASS_END(MachineLegalizePass, DEBUG_TYPE,
35 "Legalize the Machine IR a function's Machine IR", false,
36 false)
Tim Northover33b07d62016-07-22 20:03:43 +000037
38MachineLegalizePass::MachineLegalizePass() : MachineFunctionPass(ID) {
39 initializeMachineLegalizePassPass(*PassRegistry::getPassRegistry());
40}
41
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000042void MachineLegalizePass::getAnalysisUsage(AnalysisUsage &AU) const {
43 AU.addRequired<TargetPassConfig>();
44 MachineFunctionPass::getAnalysisUsage(AU);
45}
46
Tim Northover33b07d62016-07-22 20:03:43 +000047void MachineLegalizePass::init(MachineFunction &MF) {
48}
49
Tim Northover991b12b2016-08-30 20:51:25 +000050bool MachineLegalizePass::combineExtracts(MachineInstr &MI,
51 MachineRegisterInfo &MRI,
52 const TargetInstrInfo &TII) {
53 bool Changed = false;
54 if (MI.getOpcode() != TargetOpcode::G_EXTRACT)
55 return Changed;
56
57 unsigned NumDefs = (MI.getNumOperands() - 1) / 2;
58 unsigned SrcReg = MI.getOperand(NumDefs).getReg();
59 MachineInstr &SeqI = *MRI.def_instr_begin(SrcReg);
60 if (SeqI.getOpcode() != TargetOpcode::G_SEQUENCE)
61 return Changed;
62
63 unsigned NumSeqSrcs = (SeqI.getNumOperands() - 1) / 2;
64 bool AllDefsReplaced = true;
65
66 // Try to match each register extracted with a corresponding insertion formed
67 // by the G_SEQUENCE.
68 for (unsigned Idx = 0, SeqIdx = 0; Idx < NumDefs; ++Idx) {
69 MachineOperand &ExtractMO = MI.getOperand(Idx);
70 assert(ExtractMO.isReg() && ExtractMO.isDef() &&
71 "unexpected extract operand");
72
73 unsigned ExtractReg = ExtractMO.getReg();
74 unsigned ExtractPos = MI.getOperand(NumDefs + Idx + 1).getImm();
75
76 while (SeqIdx < NumSeqSrcs &&
77 SeqI.getOperand(2 * SeqIdx + 2).getImm() < ExtractPos)
78 ++SeqIdx;
79
Tim Northover0f140c72016-09-09 11:46:34 +000080 if (SeqIdx == NumSeqSrcs) {
Tim Northover991b12b2016-08-30 20:51:25 +000081 AllDefsReplaced = false;
82 continue;
83 }
84
85 unsigned OrigReg = SeqI.getOperand(2 * SeqIdx + 1).getReg();
Tim Northover0f140c72016-09-09 11:46:34 +000086 if (SeqI.getOperand(2 * SeqIdx + 2).getImm() != ExtractPos ||
87 MRI.getType(OrigReg) != MRI.getType(ExtractReg)) {
88 AllDefsReplaced = false;
89 continue;
90 }
91
Tim Northover991b12b2016-08-30 20:51:25 +000092 assert(!TargetRegisterInfo::isPhysicalRegister(OrigReg) &&
93 "unexpected physical register in G_SEQUENCE");
94
95 // Finally we can replace the uses.
96 for (auto &Use : MRI.use_operands(ExtractReg)) {
97 Changed = true;
98 Use.setReg(OrigReg);
99 }
100 }
101
102 if (AllDefsReplaced) {
103 // If SeqI was the next instruction in the BB and we removed it, we'd break
104 // the outer iteration.
105 assert(std::next(MachineBasicBlock::iterator(MI)) != SeqI &&
106 "G_SEQUENCE does not dominate G_EXTRACT");
107
108 MI.eraseFromParent();
109
110 if (MRI.use_empty(SrcReg))
111 SeqI.eraseFromParent();
112 Changed = true;
113 }
114
115 return Changed;
116}
117
Tim Northover33b07d62016-07-22 20:03:43 +0000118bool MachineLegalizePass::runOnMachineFunction(MachineFunction &MF) {
Quentin Colombet60495242016-08-27 00:18:24 +0000119 // If the ISel pipeline failed, do not bother running that pass.
120 if (MF.getProperties().hasProperty(
121 MachineFunctionProperties::Property::FailedISel))
122 return false;
Tim Northover33b07d62016-07-22 20:03:43 +0000123 DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
124 init(MF);
Quentin Colombet5e60bcd2016-08-27 02:38:21 +0000125 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
Tim Northover33b07d62016-07-22 20:03:43 +0000126 const MachineLegalizer &Legalizer = *MF.getSubtarget().getMachineLegalizer();
127 MachineLegalizeHelper Helper(MF);
128
129 // FIXME: an instruction may need more than one pass before it is legal. For
130 // example on most architectures <3 x i3> is doubly-illegal. It would
131 // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x i8>. We
132 // probably want a worklist of instructions rather than naive iterate until
133 // convergence for performance reasons.
134 bool Changed = false;
135 MachineBasicBlock::iterator NextMI;
136 for (auto &MBB : MF)
137 for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
138 // Get the next Instruction before we try to legalize, because there's a
139 // good chance MI will be deleted.
140 NextMI = std::next(MI);
Ahmed Bougachafaf8e9f2016-08-02 11:41:09 +0000141
142 // Only legalize pre-isel generic instructions: others don't have types
143 // and are assumed to be legal.
144 if (!isPreISelGenericOpcode(MI->getOpcode()))
145 continue;
146
Tim Northover33b07d62016-07-22 20:03:43 +0000147 auto Res = Helper.legalizeInstr(*MI, Legalizer);
148
149 // Error out if we couldn't legalize this instruction. We may want to fall
150 // back to DAG ISel instead in the future.
151 if (Res == MachineLegalizeHelper::UnableToLegalize) {
Quentin Colombet5e60bcd2016-08-27 02:38:21 +0000152 if (!TPC.isGlobalISelAbortEnabled()) {
153 MF.getProperties().set(
154 MachineFunctionProperties::Property::FailedISel);
155 return false;
156 }
Tim Northover33b07d62016-07-22 20:03:43 +0000157 std::string Msg;
158 raw_string_ostream OS(Msg);
159 OS << "unable to legalize instruction: ";
160 MI->print(OS);
161 report_fatal_error(OS.str());
162 }
163
164 Changed |= Res == MachineLegalizeHelper::Legalized;
165 }
Tim Northover991b12b2016-08-30 20:51:25 +0000166
167
168 MachineRegisterInfo &MRI = MF.getRegInfo();
169 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
170 for (auto &MBB : MF) {
171 for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
172 // Get the next Instruction before we try to legalize, because there's a
173 // good chance MI will be deleted.
174 NextMI = std::next(MI);
175
176 Changed |= combineExtracts(*MI, MRI, TII);
177 }
178 }
179
Tim Northover33b07d62016-07-22 20:03:43 +0000180 return Changed;
181}