Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame^] | 1 | //== llvm/CodeGen/GlobalISel/LegalizerHelper.h ---------------- -*- C++ -*-==// |
| 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 A pass to convert the target-illegal operations created by IR -> MIR |
| 11 | /// translation into ones the target expects to be able to select. This may |
| 12 | /// occur in multiple phases, for example G_ADD <2 x i8> -> G_ADD <2 x i16> -> |
| 13 | /// G_ADD <4 x i16>. |
| 14 | /// |
| 15 | /// The LegalizerHelper class is where most of the work happens, and is |
| 16 | /// designed to be callable from other passes that find themselves with an |
| 17 | /// illegal instruction. |
| 18 | // |
| 19 | //===----------------------------------------------------------------------===// |
| 20 | |
| 21 | #ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H |
| 22 | #define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H |
| 23 | |
| 24 | #include "llvm/CodeGen/GlobalISel/CallLowering.h" |
| 25 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" |
| 26 | #include "llvm/CodeGen/LowLevelType.h" |
| 27 | #include "llvm/CodeGen/MachineFunctionPass.h" |
| 28 | #include "llvm/CodeGen/RuntimeLibcalls.h" |
| 29 | |
| 30 | namespace llvm { |
| 31 | // Forward declarations. |
| 32 | class LegalizerInfo; |
| 33 | class Legalizer; |
| 34 | class MachineRegisterInfo; |
| 35 | |
| 36 | class LegalizerHelper { |
| 37 | public: |
| 38 | enum LegalizeResult { |
| 39 | /// Instruction was already legal and no change was made to the |
| 40 | /// MachineFunction. |
| 41 | AlreadyLegal, |
| 42 | |
| 43 | /// Instruction has been legalized and the MachineFunction changed. |
| 44 | Legalized, |
| 45 | |
| 46 | /// Some kind of error has occurred and we could not legalize this |
| 47 | /// instruction. |
| 48 | UnableToLegalize, |
| 49 | }; |
| 50 | |
| 51 | LegalizerHelper(MachineFunction &MF); |
| 52 | |
| 53 | /// Replace \p MI by a sequence of legal instructions that can implement the |
| 54 | /// same operation. Note that this means \p MI may be deleted, so any iterator |
| 55 | /// steps should be performed before calling this function. \p Helper should |
| 56 | /// be initialized to the MachineFunction containing \p MI. |
| 57 | /// |
| 58 | /// Considered as an opaque blob, the legal code will use and define the same |
| 59 | /// registers as \p MI. |
| 60 | LegalizeResult legalizeInstrStep(MachineInstr &MI); |
| 61 | |
| 62 | /// Legalize an instruction by emiting a runtime library call instead. |
| 63 | LegalizeResult libcall(MachineInstr &MI); |
| 64 | |
| 65 | /// Legalize an instruction by reducing the width of the underlying scalar |
| 66 | /// type. |
| 67 | LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); |
| 68 | |
| 69 | /// Legalize an instruction by performing the operation on a wider scalar type |
| 70 | /// (for example a 16-bit addition can be safely performed at 32-bits |
| 71 | /// precision, ignoring the unused bits). |
| 72 | LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); |
| 73 | |
| 74 | /// Legalize an instruction by splitting it into simpler parts, hopefully |
| 75 | /// understood by the target. |
| 76 | LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty); |
| 77 | |
| 78 | /// Legalize a vector instruction by splitting into multiple components, each |
| 79 | /// acting on the same scalar type as the original but with fewer elements. |
| 80 | LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, |
| 81 | LLT NarrowTy); |
| 82 | |
| 83 | /// Legalize a vector instruction by increasing the number of vector elements |
| 84 | /// involved and ignoring the added elements later. |
| 85 | LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx, |
| 86 | LLT WideTy); |
| 87 | |
| 88 | /// Expose MIRBuilder so clients can set their own RecordInsertInstruction |
| 89 | /// functions |
| 90 | MachineIRBuilder MIRBuilder; |
| 91 | |
| 92 | /// Expose LegalizerInfo so the clients can re-use. |
| 93 | const LegalizerInfo &getLegalizerInfo() const { return LI; } |
| 94 | |
| 95 | private: |
| 96 | |
| 97 | /// Helper function to split a wide generic register into bitwise blocks with |
| 98 | /// the given Type (which implies the number of blocks needed). The generic |
| 99 | /// registers created are appended to Ops, starting at bit 0 of Reg. |
| 100 | void extractParts(unsigned Reg, LLT Ty, int NumParts, |
| 101 | SmallVectorImpl<unsigned> &Ops); |
| 102 | |
| 103 | MachineRegisterInfo &MRI; |
| 104 | const LegalizerInfo &LI; |
| 105 | }; |
| 106 | |
| 107 | /// Helper function that creates the given libcall. |
| 108 | LegalizerHelper::LegalizeResult |
| 109 | createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, |
| 110 | const CallLowering::ArgInfo &Result, |
| 111 | ArrayRef<CallLowering::ArgInfo> Args); |
| 112 | |
| 113 | } // End namespace llvm. |
| 114 | |
| 115 | #endif |