blob: b0de76d075fbc4782760b3cc31d2584aea566c17 [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
80 if (SeqIdx == NumSeqSrcs ||
81 SeqI.getOperand(2 * SeqIdx + 2).getImm() != ExtractPos ||
82 SeqI.getType(SeqIdx + 1) != MI.getType(Idx)) {
83 AllDefsReplaced = false;
84 continue;
85 }
86
87 unsigned OrigReg = SeqI.getOperand(2 * SeqIdx + 1).getReg();
88 assert(!TargetRegisterInfo::isPhysicalRegister(OrigReg) &&
89 "unexpected physical register in G_SEQUENCE");
90
91 // Finally we can replace the uses.
92 for (auto &Use : MRI.use_operands(ExtractReg)) {
93 Changed = true;
94 Use.setReg(OrigReg);
95 }
96 }
97
98 if (AllDefsReplaced) {
99 // If SeqI was the next instruction in the BB and we removed it, we'd break
100 // the outer iteration.
101 assert(std::next(MachineBasicBlock::iterator(MI)) != SeqI &&
102 "G_SEQUENCE does not dominate G_EXTRACT");
103
104 MI.eraseFromParent();
105
106 if (MRI.use_empty(SrcReg))
107 SeqI.eraseFromParent();
108 Changed = true;
109 }
110
111 return Changed;
112}
113
Tim Northover33b07d62016-07-22 20:03:43 +0000114bool MachineLegalizePass::runOnMachineFunction(MachineFunction &MF) {
Quentin Colombet60495242016-08-27 00:18:24 +0000115 // If the ISel pipeline failed, do not bother running that pass.
116 if (MF.getProperties().hasProperty(
117 MachineFunctionProperties::Property::FailedISel))
118 return false;
Tim Northover33b07d62016-07-22 20:03:43 +0000119 DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
120 init(MF);
Quentin Colombet5e60bcd2016-08-27 02:38:21 +0000121 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
Tim Northover33b07d62016-07-22 20:03:43 +0000122 const MachineLegalizer &Legalizer = *MF.getSubtarget().getMachineLegalizer();
123 MachineLegalizeHelper Helper(MF);
124
125 // FIXME: an instruction may need more than one pass before it is legal. For
126 // example on most architectures <3 x i3> is doubly-illegal. It would
127 // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x i8>. We
128 // probably want a worklist of instructions rather than naive iterate until
129 // convergence for performance reasons.
130 bool Changed = false;
131 MachineBasicBlock::iterator NextMI;
132 for (auto &MBB : MF)
133 for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
134 // Get the next Instruction before we try to legalize, because there's a
135 // good chance MI will be deleted.
136 NextMI = std::next(MI);
Ahmed Bougachafaf8e9f2016-08-02 11:41:09 +0000137
138 // Only legalize pre-isel generic instructions: others don't have types
139 // and are assumed to be legal.
140 if (!isPreISelGenericOpcode(MI->getOpcode()))
141 continue;
142
Tim Northover33b07d62016-07-22 20:03:43 +0000143 auto Res = Helper.legalizeInstr(*MI, Legalizer);
144
145 // Error out if we couldn't legalize this instruction. We may want to fall
146 // back to DAG ISel instead in the future.
147 if (Res == MachineLegalizeHelper::UnableToLegalize) {
Quentin Colombet5e60bcd2016-08-27 02:38:21 +0000148 if (!TPC.isGlobalISelAbortEnabled()) {
149 MF.getProperties().set(
150 MachineFunctionProperties::Property::FailedISel);
151 return false;
152 }
Tim Northover33b07d62016-07-22 20:03:43 +0000153 std::string Msg;
154 raw_string_ostream OS(Msg);
155 OS << "unable to legalize instruction: ";
156 MI->print(OS);
157 report_fatal_error(OS.str());
158 }
159
160 Changed |= Res == MachineLegalizeHelper::Legalized;
161 }
Tim Northover991b12b2016-08-30 20:51:25 +0000162
163
164 MachineRegisterInfo &MRI = MF.getRegInfo();
165 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
166 for (auto &MBB : MF) {
167 for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
168 // Get the next Instruction before we try to legalize, because there's a
169 // good chance MI will be deleted.
170 NextMI = std::next(MI);
171
172 Changed |= combineExtracts(*MI, MRI, TII);
173 }
174 }
175
Tim Northover33b07d62016-07-22 20:03:43 +0000176 return Changed;
177}