Tim Northover | 33b07d6 | 2016-07-22 20:03:43 +0000 | [diff] [blame] | 1 | //===-- 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" |
| 17 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
| 18 | #include "llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h" |
| 19 | #include "llvm/CodeGen/GlobalISel/MachineLegalizer.h" |
| 20 | #include "llvm/Support/Debug.h" |
| 21 | #include "llvm/Target/TargetSubtargetInfo.h" |
| 22 | |
| 23 | #define DEBUG_TYPE "legalize-mir" |
| 24 | |
| 25 | using namespace llvm; |
| 26 | |
| 27 | char MachineLegalizePass::ID = 0; |
| 28 | INITIALIZE_PASS(MachineLegalizePass, DEBUG_TYPE, |
| 29 | "Legalize the Machine IR a function's Machine IR", false, |
Tim Northover | 884b47e | 2016-07-26 03:29:18 +0000 | [diff] [blame] | 30 | false) |
Tim Northover | 33b07d6 | 2016-07-22 20:03:43 +0000 | [diff] [blame] | 31 | |
| 32 | MachineLegalizePass::MachineLegalizePass() : MachineFunctionPass(ID) { |
| 33 | initializeMachineLegalizePassPass(*PassRegistry::getPassRegistry()); |
| 34 | } |
| 35 | |
| 36 | void MachineLegalizePass::init(MachineFunction &MF) { |
| 37 | } |
| 38 | |
| 39 | bool MachineLegalizePass::runOnMachineFunction(MachineFunction &MF) { |
| 40 | DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n'); |
| 41 | init(MF); |
| 42 | const MachineLegalizer &Legalizer = *MF.getSubtarget().getMachineLegalizer(); |
| 43 | MachineLegalizeHelper Helper(MF); |
| 44 | |
| 45 | // FIXME: an instruction may need more than one pass before it is legal. For |
| 46 | // example on most architectures <3 x i3> is doubly-illegal. It would |
| 47 | // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x i8>. We |
| 48 | // probably want a worklist of instructions rather than naive iterate until |
| 49 | // convergence for performance reasons. |
| 50 | bool Changed = false; |
| 51 | MachineBasicBlock::iterator NextMI; |
| 52 | for (auto &MBB : MF) |
| 53 | for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) { |
| 54 | // Get the next Instruction before we try to legalize, because there's a |
| 55 | // good chance MI will be deleted. |
| 56 | NextMI = std::next(MI); |
Ahmed Bougacha | faf8e9f | 2016-08-02 11:41:09 +0000 | [diff] [blame^] | 57 | |
| 58 | // Only legalize pre-isel generic instructions: others don't have types |
| 59 | // and are assumed to be legal. |
| 60 | if (!isPreISelGenericOpcode(MI->getOpcode())) |
| 61 | continue; |
| 62 | |
Tim Northover | 33b07d6 | 2016-07-22 20:03:43 +0000 | [diff] [blame] | 63 | auto Res = Helper.legalizeInstr(*MI, Legalizer); |
| 64 | |
| 65 | // Error out if we couldn't legalize this instruction. We may want to fall |
| 66 | // back to DAG ISel instead in the future. |
| 67 | if (Res == MachineLegalizeHelper::UnableToLegalize) { |
| 68 | std::string Msg; |
| 69 | raw_string_ostream OS(Msg); |
| 70 | OS << "unable to legalize instruction: "; |
| 71 | MI->print(OS); |
| 72 | report_fatal_error(OS.str()); |
| 73 | } |
| 74 | |
| 75 | Changed |= Res == MachineLegalizeHelper::Legalized; |
| 76 | } |
| 77 | return Changed; |
| 78 | } |