blob: 1c474b9984601d1071843df3182a4d280f5a262c [file] [log] [blame]
Tim Northover69fa84a2016-10-14 22:18:18 +00001//===-- llvm/CodeGen/GlobalISel/Legalizer.cpp -----------------------------===//
Tim Northover33b07d62016-07-22 20:03:43 +00002//
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//
Tim Northover69fa84a2016-10-14 22:18:18 +000010/// \file This file implements the LegalizerHelper class to legalize individual
11/// instructions and the LegalizePass wrapper pass for the primary
Tim Northover33b07d62016-07-22 20:03:43 +000012/// legalization.
13//
14//===----------------------------------------------------------------------===//
15
Tim Northover69fa84a2016-10-14 22:18:18 +000016#include "llvm/CodeGen/GlobalISel/Legalizer.h"
Aditya Nandakumarc6615f52017-08-30 19:32:59 +000017#include "llvm/ADT/SetVector.h"
18#include "llvm/CodeGen/GlobalISel/LegalizerCombiner.h"
Tim Northover69fa84a2016-10-14 22:18:18 +000019#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
Ahmed Bougachaae9dade2017-02-23 21:05:42 +000020#include "llvm/CodeGen/GlobalISel/Utils.h"
21#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000022#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/CodeGen/TargetPassConfig.h"
Tim Northover33b07d62016-07-22 20:03:43 +000024#include "llvm/Support/Debug.h"
Tim Northover991b12b2016-08-30 20:51:25 +000025#include "llvm/Target/TargetInstrInfo.h"
Tim Northover33b07d62016-07-22 20:03:43 +000026#include "llvm/Target/TargetSubtargetInfo.h"
27
Daniel Sanders5377fb32017-04-20 15:46:12 +000028#include <iterator>
29
Tim Northover69fa84a2016-10-14 22:18:18 +000030#define DEBUG_TYPE "legalizer"
Tim Northover33b07d62016-07-22 20:03:43 +000031
32using namespace llvm;
33
Tim Northover69fa84a2016-10-14 22:18:18 +000034char Legalizer::ID = 0;
35INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000036 "Legalize the Machine IR a function's Machine IR", false,
37 false)
38INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
Tim Northover69fa84a2016-10-14 22:18:18 +000039INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000040 "Legalize the Machine IR a function's Machine IR", false,
41 false)
Tim Northover33b07d62016-07-22 20:03:43 +000042
Tim Northover69fa84a2016-10-14 22:18:18 +000043Legalizer::Legalizer() : MachineFunctionPass(ID) {
44 initializeLegalizerPass(*PassRegistry::getPassRegistry());
Tim Northover33b07d62016-07-22 20:03:43 +000045}
46
Tim Northover69fa84a2016-10-14 22:18:18 +000047void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000048 AU.addRequired<TargetPassConfig>();
49 MachineFunctionPass::getAnalysisUsage(AU);
50}
51
Tim Northover69fa84a2016-10-14 22:18:18 +000052void Legalizer::init(MachineFunction &MF) {
Tim Northover33b07d62016-07-22 20:03:43 +000053}
54
Tim Northover69fa84a2016-10-14 22:18:18 +000055bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
Quentin Colombet60495242016-08-27 00:18:24 +000056 // If the ISel pipeline failed, do not bother running that pass.
57 if (MF.getProperties().hasProperty(
58 MachineFunctionProperties::Property::FailedISel))
59 return false;
Tim Northover33b07d62016-07-22 20:03:43 +000060 DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
61 init(MF);
Quentin Colombet5e60bcd2016-08-27 02:38:21 +000062 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
Ahmed Bougachaae9dade2017-02-23 21:05:42 +000063 MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
Tim Northover69fa84a2016-10-14 22:18:18 +000064 LegalizerHelper Helper(MF);
Tim Northover33b07d62016-07-22 20:03:43 +000065
66 // FIXME: an instruction may need more than one pass before it is legal. For
67 // example on most architectures <3 x i3> is doubly-illegal. It would
68 // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x i8>. We
69 // probably want a worklist of instructions rather than naive iterate until
70 // convergence for performance reasons.
71 bool Changed = false;
72 MachineBasicBlock::iterator NextMI;
Daniel Sanders5377fb32017-04-20 15:46:12 +000073 for (auto &MBB : MF) {
Tim Northover33b07d62016-07-22 20:03:43 +000074 for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
75 // Get the next Instruction before we try to legalize, because there's a
76 // good chance MI will be deleted.
77 NextMI = std::next(MI);
Ahmed Bougachafaf8e9f2016-08-02 11:41:09 +000078
79 // Only legalize pre-isel generic instructions: others don't have types
80 // and are assumed to be legal.
81 if (!isPreISelGenericOpcode(MI->getOpcode()))
82 continue;
Daniel Sanders5377fb32017-04-20 15:46:12 +000083 unsigned NumNewInsns = 0;
Aditya Nandakumarc6615f52017-08-30 19:32:59 +000084 using VecType = SetVector<MachineInstr *, SmallVector<MachineInstr *, 8>>;
85 VecType WorkList;
86 VecType CombineList;
Daniel Sanders5377fb32017-04-20 15:46:12 +000087 Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) {
Aditya Nandakumar21d8d312017-05-04 22:00:42 +000088 // Only legalize pre-isel generic instructions.
89 // Legalization process could generate Target specific pseudo
90 // instructions with generic types. Don't record them
91 if (isPreISelGenericOpcode(MI->getOpcode())) {
92 ++NumNewInsns;
Aditya Nandakumarc6615f52017-08-30 19:32:59 +000093 WorkList.insert(MI);
94 CombineList.insert(MI);
Aditya Nandakumar21d8d312017-05-04 22:00:42 +000095 }
Daniel Sanders5377fb32017-04-20 15:46:12 +000096 });
Aditya Nandakumarc6615f52017-08-30 19:32:59 +000097 WorkList.insert(&*MI);
98 LegalizerCombiner C(Helper.MIRBuilder, MF.getRegInfo());
Daniel Sanders5377fb32017-04-20 15:46:12 +000099 bool Changed = false;
Aditya Nandakumareb80a512017-04-07 21:49:30 +0000100 LegalizerHelper::LegalizeResult Res;
Aditya Nandakumareb80a512017-04-07 21:49:30 +0000101 do {
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000102 assert(!WorkList.empty() && "Expecting illegal ops");
103 while (!WorkList.empty()) {
104 NumNewInsns = 0;
105 MachineInstr *CurrInst = WorkList.pop_back_val();
106 Res = Helper.legalizeInstrStep(*CurrInst);
107 // Error out if we couldn't legalize this instruction. We may want to
108 // fall back to DAG ISel instead in the future.
Aditya Nandakumareb80a512017-04-07 21:49:30 +0000109 if (Res == LegalizerHelper::UnableToLegalize) {
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000110 Helper.MIRBuilder.stopRecordingInsertions();
111 if (Res == LegalizerHelper::UnableToLegalize) {
112 reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
113 "unable to legalize instruction", *CurrInst);
114 return false;
115 }
Aditya Nandakumareb80a512017-04-07 21:49:30 +0000116 }
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000117 Changed |= Res == LegalizerHelper::Legalized;
118 // If CurrInst was legalized, there's a good chance that it might have
119 // been erased. So remove it from the Combine List.
120 if (Res == LegalizerHelper::Legalized)
121 CombineList.remove(CurrInst);
Daniel Sanders5377fb32017-04-20 15:46:12 +0000122
123#ifndef NDEBUG
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000124 if (NumNewInsns)
125 for (unsigned I = WorkList.size() - NumNewInsns,
126 E = WorkList.size();
127 I != E; ++I)
128 DEBUG(dbgs() << ".. .. New MI: " << *WorkList[I];);
Daniel Sanders5377fb32017-04-20 15:46:12 +0000129#endif
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000130 }
131 // Do the combines.
132 while (!CombineList.empty()) {
133 NumNewInsns = 0;
134 MachineInstr *CurrInst = CombineList.pop_back_val();
135 SmallVector<MachineInstr *, 4> DeadInstructions;
136 Changed |= C.tryCombineInstruction(*CurrInst, DeadInstructions);
137 for (auto *DeadMI : DeadInstructions) {
138 DEBUG(dbgs() << ".. Erasing Dead Instruction " << *DeadMI);
139 CombineList.remove(DeadMI);
140 WorkList.remove(DeadMI);
141 DeadMI->eraseFromParent();
142 }
143#ifndef NDEBUG
144 if (NumNewInsns)
145 for (unsigned I = CombineList.size() - NumNewInsns,
146 E = CombineList.size();
147 I != E; ++I)
148 DEBUG(dbgs() << ".. .. Combine New MI: " << *CombineList[I];);
149#endif
150 }
151 } while (!WorkList.empty());
Tim Northover33b07d62016-07-22 20:03:43 +0000152
Aditya Nandakumareb80a512017-04-07 21:49:30 +0000153 Helper.MIRBuilder.stopRecordingInsertions();
Tim Northover33b07d62016-07-22 20:03:43 +0000154 }
Daniel Sanders5377fb32017-04-20 15:46:12 +0000155 }
Tim Northover991b12b2016-08-30 20:51:25 +0000156
Tim Northover991b12b2016-08-30 20:51:25 +0000157 MachineRegisterInfo &MRI = MF.getRegInfo();
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000158 MachineIRBuilder MIRBuilder(MF);
159 LegalizerCombiner C(MIRBuilder, MRI);
Tim Northover991b12b2016-08-30 20:51:25 +0000160 for (auto &MBB : MF) {
161 for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
162 // Get the next Instruction before we try to legalize, because there's a
163 // good chance MI will be deleted.
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000164 // TOOD: Perhaps move this to a combiner pass later?.
Tim Northover991b12b2016-08-30 20:51:25 +0000165 NextMI = std::next(MI);
Aditya Nandakumarc6615f52017-08-30 19:32:59 +0000166 SmallVector<MachineInstr *, 4> DeadInsts;
167 Changed |= C.tryCombineMerges(*MI, DeadInsts);
168 for (auto *DeadMI : DeadInsts)
169 DeadMI->eraseFromParent();
Tim Northover991b12b2016-08-30 20:51:25 +0000170 }
171 }
172
Tim Northover33b07d62016-07-22 20:03:43 +0000173 return Changed;
174}