[llvm] r276461 - GlobalISel: implement legalization pass, with just one transformation.
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 22 22:36:45 PDT 2016
On Fri, Jul 22, 2016 at 1:11 PM Tim Northover via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: tnorthover
> Date: Fri Jul 22 15:03:43 2016
> New Revision: 276461
>
> URL: http://llvm.org/viewvc/llvm-project?rev=276461&view=rev
> Log:
> GlobalISel: implement legalization pass, with just one transformation.
>
> This adds the actual MachineLegalizeHelper to do the work and a trivial
> pass
> wrapper that legalizes all instructions in a MachineFunction. Currently the
> only transformation supported is splitting up a vector G_ADD into one
> acting on
> smaller vectors.
>
> Added:
> llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
> llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h
> llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
> llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp
> llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp
> llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.h
> llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir
> Modified:
> llvm/trunk/include/llvm/CodeGen/GlobalISel/GISelAccessor.h
> llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
> llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
> llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h
> llvm/trunk/include/llvm/InitializePasses.h
> llvm/trunk/include/llvm/Target/GenericOpcodes.td
> llvm/trunk/include/llvm/Target/TargetOpcodes.def
> llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h
> llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt
> llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp
> llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
> llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
> llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
> llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp
> llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h
> llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp
> llvm/trunk/lib/Target/AArch64/CMakeLists.txt
> llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/GISelAccessor.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/GISelAccessor.h?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/GISelAccessor.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/GISelAccessor.h Fri Jul 22
> 15:03:43 2016
> @@ -17,6 +17,7 @@
>
> namespace llvm {
> class CallLowering;
> +class MachineLegalizer;
> class RegisterBankInfo;
>
> /// The goal of this helper class is to gather the accessor to all
> @@ -27,6 +28,9 @@ class RegisterBankInfo;
> struct GISelAccessor {
> virtual ~GISelAccessor() {}
> virtual const CallLowering *getCallLowering() const { return nullptr;}
> + virtual const MachineLegalizer *getMachineLegalizer() const {
> + return nullptr;
> + }
> virtual const RegisterBankInfo *getRegBankInfo() const { return
> nullptr;}
> };
> } // End namespace llvm;
>
> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
> (original)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Fri Jul
> 22 15:03:43 2016
> @@ -80,7 +80,7 @@ public:
> /// Set the insertion point to before (\p Before = true) or after
> /// (\p Before = false) \p MI.
> /// \pre MI must be in getMF().
> - void setInstr(MachineInstr &MI, bool Before = false);
> + void setInstr(MachineInstr &MI, bool Before = true);
> /// @}
>
> /// Set the debug location to \p DL for all the next build instructions.
> @@ -152,6 +152,37 @@ public:
> /// \return The newly created instruction.
> MachineInstr *buildFrameIndex(LLT Ty, unsigned Res, int Idx);
>
> + /// Build and insert \p Res<def> = G_ADD \p Ty \p Op0, \p Op1
> + ///
> + /// G_ADD sets \p Res to the sum of integer parameters \p Op0 and \p
> Op1,
> + /// truncated to their width.
> + ///
> + /// \pre setBasicBlock or setMI must have been called.
> + ///
> + /// \return The newly created instruction.
> + MachineInstr *buildAdd(LLT Ty, unsigned Res, unsigned Op0, unsigned
> Op1);
> +
> + /// Build and insert `Res0<def>, ... = G_EXTRACT Ty Src, Idx0, ...`.
> + ///
> + /// If \p Ty has size N bits, G_EXTRACT sets \p Res[0] to bits
> `[Idxs[0],
> + /// Idxs[0] + N)` of \p Src and similarly for subsequent bit-indexes.
> + ///
> + /// \pre setBasicBlock or setMI must have been called.
> + ///
> + /// \return The newly created instruction.
> + MachineInstr *buildExtract(LLT Ty, ArrayRef<unsigned> Results, unsigned
> Src,
> + ArrayRef<unsigned> Indexes);
> +
> + /// Build and insert \p Res<def> = G_SEQUENCE \p Ty \p Ops[0], ...
> + ///
> + /// G_SEQUENCE concatenates each element in Ops into a single register,
> where
> + /// Ops[0] starts at bit 0 of \p Res.
> + ///
> + /// \pre setBasicBlock or setMI must have been called.
> + /// \pre The sum of the input sizes must equal the result's size.
> + ///
> + /// \return The newly created instruction.
> + MachineInstr *buildSequence(LLT Ty, unsigned Res, ArrayRef<unsigned>
> Ops);
> };
>
> } // End namespace llvm.
>
> Added: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h?rev=276461&view=auto
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
> (added)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h Fri
> Jul 22 15:03:43 2016
> @@ -0,0 +1,92 @@
> +//== llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h ----------- -*- C++
> -*-==//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file A pass to convert the target-illegal operations created by IR
> -> MIR
> +/// translation into ones the target expects to be able to select. This
> may
> +/// occur in multiple phases, for example G_ADD <2 x i8> -> G_ADD <2 x
> i16> ->
> +/// G_ADD <4 x i16>.
> +///
> +/// The MachineLegalizeHelper class is where most of the work happens,
> and is
> +/// designed to be callable from other passes that find themselves with an
> +/// illegal instruction.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
> +#define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
> +
> +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
> +#include "llvm/CodeGen/MachineFunctionPass.h"
> +#include "llvm/CodeGen/LowLevelType.h"
> +
> +namespace llvm {
> +// Forward declarations.
> +class MachineLegalizeInfo;
> +class MachineLegalizer;
> +class MachineRegisterInfo;
> +
> +class MachineLegalizeHelper {
> +public:
> + enum LegalizeResult {
> + /// Instruction was already legal and no change was made to the
> + /// MachineFunction.
> + AlreadyLegal,
> +
> + /// Instruction has been legalized and the MachineFunction changed.
> + Legalized,
> +
> + /// Some kind of error has occurred and we could not legalize this
> + /// instruction.
> + UnableToLegalize,
> + };
> +
> + MachineLegalizeHelper(MachineFunction &MF);
> +
> + /// Replace \p MI by a sequence of legal instructions that can
> implement the
> + /// same operation. Note that this means \p MI may be deleted, so any
> iterator
> + /// steps should be performed before calling this function. \p Helper
> should
> + /// be initialized to the MachineFunction containing \p MI.
> + ///
> + /// Considered as an opaque blob, the legal code will use and define
> the same
> + /// registers as \p MI.
> + LegalizeResult legalizeInstr(MachineInstr &MI,
> + const MachineLegalizer &Legalizer);
> +
> + /// Legalize an instruction by reducing the width of the underlying
> scalar
> + /// type.
> + LegalizeResult narrowScalar(MachineInstr &MI, LLT NarrowTy);
> +
> + /// Legalize an instruction by performing the operation on a wider
> scalar type
> + /// (for example a 16-bit addition can be safely performed at 32-bits
> + /// precision, ignoring the unused bits).
> + LegalizeResult widenScalar(MachineInstr &MI, LLT WideTy);
> +
> + /// Legalize a vector instruction by splitting into multiple
> components, each
> + /// acting on the same scalar type as the original but with fewer
> elements.
> + LegalizeResult fewerElementsVector(MachineInstr &MI, LLT NarrowTy);
> +
> + /// Legalize a vector instruction by increasing the number of vector
> elements
> + /// involved and ignoring the added elements later.
> + LegalizeResult moreElementsVector(MachineInstr &MI, LLT WideTy);
> +
> +private:
> +
> + /// Helper function to split a wide generic register into bitwise
> blocks with
> + /// the given Type (which implies the number of blocks needed). The
> generic
> + /// registers created are appended to Ops, starting at bit 0 of Reg.
> + void extractParts(unsigned Reg, LLT Ty, int NumParts,
> + SmallVectorImpl<unsigned> &Ops);
> +
> + MachineIRBuilder MIRBuilder;
> + MachineRegisterInfo &MRI;
> +};
> +
> +} // End namespace llvm.
> +
> +#endif
>
> Added: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h?rev=276461&view=auto
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h
> (added)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h Fri
> Jul 22 15:03:43 2016
> @@ -0,0 +1,50 @@
> +//== llvm/CodeGen/GlobalISel/MachineLegalizePass.h ------------- -*- C++
> -*-==//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file A pass to convert the target-illegal operations created by IR
> -> MIR
> +/// translation into ones the target expects to be able to select. This
> may
> +/// occur in multiple phases, for example G_ADD <2 x i8> -> G_ADD <2 x
> i16> ->
> +/// G_ADD <4 x i16>.
> +///
> +/// The LegalizeHelper class is where most of the work happens, and is
> designed
> +/// to be callable from other passes that find themselves with an illegal
> +/// instruction.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZEMACHINEIRPASS_H
> +#define LLVM_CODEGEN_GLOBALISEL_LEGALIZEMACHINEIRPASS_H
> +
> +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
> +#include "llvm/CodeGen/MachineFunctionPass.h"
> +
> +namespace llvm {
> +
> +class MachineLegalizePass : public MachineFunctionPass {
> +public:
> + static char ID;
> +
> +private:
> +
> + /// Initialize the field members using \p MF.
> + void init(MachineFunction &MF);
> +
> +public:
> + // Ctor, nothing fancy.
> + MachineLegalizePass();
> +
> + const char *getPassName() const override {
> + return "MachineLegalizePass";
> + }
> +
> + bool runOnMachineFunction(MachineFunction &MF) override;
> +};
> +} // End namespace llvm.
> +
> +#endif
>
> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
> (original)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h Fri Jul
> 22 15:03:43 2016
> @@ -71,17 +71,6 @@ public:
>
> MachineLegalizer();
>
> - /// Replace \p MI by a sequence of legal instructions that can
> implement the
> - /// same operation. Note that this means \p MI may be deleted, so any
> iterator
> - /// steps should be performed before calling this function.
> - ///
> - /// Considered as an opaque blob, the legal code will use and define
> the same
> - /// registers as \p MI.
> - ///
> - /// \returns true if the function is modified, false if the instruction
> was
> - /// already legal.
> - bool legalizeInstr(MachineInstr &MI) const;
> -
> /// Compute any ancillary tables needed to quickly decide how an
> operation
> /// should be handled. This must be called after all
> "set*Action"methods but
> /// before any query is made or incorrect results may be returned.
>
> Modified: llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h Fri Jul 22 15:03:43
> 2016
> @@ -218,6 +218,14 @@ public:
> virtual bool addIRTranslator() { return true; }
>
> /// This method may be implemented by targets that want to run passes
> + /// immediately before legalization.
> + virtual void addPreLegalizeMachineIR() {}
> +
> + /// This method should install a legalize pass, which converts the
> instruction
> + /// sequence into one that can be selected by the target.
> + virtual bool addLegalizeMachineIR() { return true; }
> +
> + /// This method may be implemented by targets that want to run passes
> /// immediately before the register bank selection.
> virtual void addPreRegBankSelect() {}
>
>
> Modified: llvm/trunk/include/llvm/InitializePasses.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/InitializePasses.h (original)
> +++ llvm/trunk/include/llvm/InitializePasses.h Fri Jul 22 15:03:43 2016
> @@ -214,6 +214,7 @@ void initializeMachineCopyPropagationPas
> void initializeMachineDominanceFrontierPass(PassRegistry&);
> void initializeMachineDominatorTreePass(PassRegistry&);
> void initializeMachineFunctionPrinterPassPass(PassRegistry&);
> +void initializeMachineLegalizePassPass(PassRegistry&);
> void initializeMachineLICMPass(PassRegistry&);
> void initializeMachineLoopInfoPass(PassRegistry&);
> void initializeMachineModuleInfoPass(PassRegistry&);
>
> Modified: llvm/trunk/include/llvm/Target/GenericOpcodes.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/GenericOpcodes.td?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/GenericOpcodes.td (original)
> +++ llvm/trunk/include/llvm/Target/GenericOpcodes.td Fri Jul 22 15:03:43
> 2016
> @@ -58,6 +58,27 @@ def G_OR : Instruction {
> }
>
>
> //------------------------------------------------------------------------------
> +// Variadic ops
>
> +//------------------------------------------------------------------------------
> +
> +// Extract multiple registers specified size, starting from blocks given
> by
> +// indexes. This will almost certainly be mapped to sub-register COPYs
> after
> +// register banks have been selected.
> +def G_EXTRACT : Instruction {
> + let OutOperandList = (outs variable_ops);
> + let InOperandList = (ins variable_ops);
> + let hasSideEffects = 0;
> +}
> +
> +// Combine a sequence of generic vregs into a single larger value
> (starting at
> +// bit 0).
> +def G_SEQUENCE : Instruction {
> + let OutOperandList = (outs unknown:$dst);
> + let InOperandList = (ins variable_ops);
> + let hasSideEffects = 0;
> +}
> +
>
> +//------------------------------------------------------------------------------
> // Branches.
>
> //------------------------------------------------------------------------------
> // Generic unconditional branch.
>
> Modified: llvm/trunk/include/llvm/Target/TargetOpcodes.def
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOpcodes.def?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/TargetOpcodes.def (original)
> +++ llvm/trunk/include/llvm/Target/TargetOpcodes.def Fri Jul 22 15:03:43
> 2016
> @@ -172,6 +172,14 @@ HANDLE_TARGET_OPCODE(G_OR)
> /// stack-based object.
> HANDLE_TARGET_OPCODE(G_FRAME_INDEX)
>
> +/// Generic instruction to extract blocks of bits from the register given
> +/// (typically a sub-register COPY after instruction selection).
> +HANDLE_TARGET_OPCODE(G_EXTRACT)
> +
> +/// Generic instruction to paste a variable number of components together
> into a
> +/// larger register.
> +HANDLE_TARGET_OPCODE(G_SEQUENCE)
> +
> /// Generic BRANCH instruction. This is an unconditional branch.
> HANDLE_TARGET_OPCODE(G_BR)
>
>
> Modified: llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h Fri Jul 22
> 15:03:43 2016
> @@ -27,6 +27,7 @@ class CallLowering;
> class DataLayout;
> class MachineFunction;
> class MachineInstr;
> +class MachineLegalizer;
> class RegisterBankInfo;
> class SDep;
> class SUnit;
> @@ -94,6 +95,10 @@ public:
> return nullptr;
> }
>
> + virtual const MachineLegalizer *getMachineLegalizer() const {
> + return nullptr;
> + }
> +
> /// getRegisterInfo - If register information is available, return it.
> If
> /// not, return null.
> ///
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/CMakeLists.txt Fri Jul 22 15:03:43
> 2016
> @@ -2,6 +2,8 @@
> set(GLOBAL_ISEL_FILES
> IRTranslator.cpp
> MachineIRBuilder.cpp
> + MachineLegalizeHelper.cpp
> + MachineLegalizePass.cpp
> MachineLegalizer.cpp
> RegBankSelect.cpp
> RegisterBank.cpp
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/GlobalISel.cpp Fri Jul 22 15:03:43
> 2016
> @@ -25,6 +25,7 @@ void llvm::initializeGlobalISel(PassRegi
>
> void llvm::initializeGlobalISel(PassRegistry &Registry) {
> initializeIRTranslatorPass(Registry);
> + initializeMachineLegalizePassPass(Registry);
> initializeRegBankSelectPass(Registry);
> }
> #endif // LLVM_BUILD_GLOBAL_ISEL
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Fri Jul 22
> 15:03:43 2016
> @@ -110,3 +110,35 @@ MachineInstr *MachineIRBuilder::buildFra
> MIB.addImm(Idx);
> return NewMI;
> }
> +
> +MachineInstr *MachineIRBuilder::buildAdd(LLT Ty, unsigned Res, unsigned
> Op0,
> + unsigned Op1) {
> + return buildInstr(TargetOpcode::G_ADD, Ty, Res, Op0, Op1);
> +}
> +
> +MachineInstr *MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned>
> Results,
> + unsigned Src,
> + ArrayRef<unsigned> Indexes) {
> + assert(Results.size() == Indexes.size() && "inconsistent number of
> regs");
> +
> + MachineInstr *NewMI = buildInstr(TargetOpcode::G_EXTRACT, Ty);
> + auto MIB = MachineInstrBuilder(getMF(), NewMI);
> + for (auto Res : Results)
> + MIB.addReg(Res, RegState::Define);
> +
> + MIB.addReg(Src);
> +
> + for (auto Idx : Indexes)
> + MIB.addImm(Idx);
> + return NewMI;
> +}
> +
> +MachineInstr *MachineIRBuilder::buildSequence(LLT Ty, unsigned Res,
> + ArrayRef<unsigned> Ops) {
> + MachineInstr *NewMI = buildInstr(TargetOpcode::G_SEQUENCE, Ty);
> + auto MIB = MachineInstrBuilder(getMF(), NewMI);
> + MIB.addReg(Res, RegState::Define);
> + for (auto Op : Ops)
> + MIB.addReg(Op);
> + return NewMI;
> +}
>
> Added: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp?rev=276461&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp (added)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp Fri Jul 22
> 15:03:43 2016
> @@ -0,0 +1,98 @@
> +//===-- llvm/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
> -----------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file This file implements the MachineLegalizeHelper class to legalize
> +/// individual instructions and the LegalizeMachineIR wrapper pass for the
> +/// primary legalization.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h"
> +#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/Target/TargetSubtargetInfo.h"
> +
> +#include <sstream>
> +
> +#define DEBUG_TYPE "legalize-mir"
> +
> +using namespace llvm;
> +
> +MachineLegalizeHelper::MachineLegalizeHelper(MachineFunction &MF)
> + : MRI(MF.getRegInfo()) {
> + MIRBuilder.setMF(MF);
> +}
> +
> +MachineLegalizeHelper::LegalizeResult
> MachineLegalizeHelper::legalizeInstr(
> + MachineInstr &MI, const MachineLegalizer &Legalizer) {
> + auto Action = Legalizer.getAction(MI);
> + switch (Action.first) {
> + case MachineLegalizer::Legal:
> + return AlreadyLegal;
> + case MachineLegalizer::NarrowScalar:
> + return narrowScalar(MI, Action.second);
> + case MachineLegalizer::WidenScalar:
> + return widenScalar(MI, Action.second);
> + case MachineLegalizer::FewerElements:
> + return fewerElementsVector(MI, Action.second);
> + default:
> + return UnableToLegalize;
> + }
> +}
> +
> +void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int
> NumParts,
> + SmallVectorImpl<unsigned>
> &VRegs) {
> + unsigned Size = Ty.getSizeInBits();
> + SmallVector<unsigned, 4> Indexes;
> + for (int i = 0; i < NumParts; ++i) {
> + VRegs.push_back(MRI.createGenericVirtualRegister(Size));
> + Indexes.push_back(i * Size);
> + }
> + MIRBuilder.buildExtract(Ty, VRegs, Reg, Indexes);
> +}
> +
> +MachineLegalizeHelper::LegalizeResult
> +MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) {
> + return UnableToLegalize;
> +}
> +
> +MachineLegalizeHelper::LegalizeResult
> +MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
> + return UnableToLegalize;
> +}
> +
> +MachineLegalizeHelper::LegalizeResult
> +MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, LLT
> NarrowTy) {
> + switch (MI.getOpcode()) {
> + default:
> + return UnableToLegalize;
> + case TargetOpcode::G_ADD: {
> + unsigned NarrowSize = NarrowTy.getSizeInBits();
> + int NumParts = MI.getType().getSizeInBits() / NarrowSize;
> +
> + MIRBuilder.setInstr(MI);
> +
> + SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
> + extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
> + extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
> +
> + for (int i = 0; i < NumParts; ++i) {
> + unsigned DstReg = MRI.createGenericVirtualRegister(NarrowSize);
> + MIRBuilder.buildAdd(NarrowTy, DstReg, Src1Regs[i], Src2Regs[i]);
> + DstRegs.push_back(DstReg);
> + }
> +
> + MIRBuilder.buildSequence(MI.getType(), MI.getOperand(0).getReg(),
> DstRegs);
> + MI.eraseFromParent();
> + return Legalized;
> + }
> + }
> +}
>
> Added: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp?rev=276461&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp (added)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp Fri Jul 22
> 15:03:43 2016
> @@ -0,0 +1,72 @@
> +//===-- llvm/CodeGen/GlobalISel/MachineLegalizePass.cpp
> -------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file This file implements the LegalizeHelper class to legalize
> individual
> +/// instructions and the MachineLegalizePass wrapper pass for the primary
> +/// legalization.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/CodeGen/GlobalISel/MachineLegalizePass.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h"
> +#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Target/TargetSubtargetInfo.h"
> +
> +#define DEBUG_TYPE "legalize-mir"
> +
> +using namespace llvm;
> +
> +char MachineLegalizePass::ID = 0;
> +INITIALIZE_PASS(MachineLegalizePass, DEBUG_TYPE,
> + "Legalize the Machine IR a function's Machine IR", false,
> + false);
> +
> +MachineLegalizePass::MachineLegalizePass() : MachineFunctionPass(ID) {
> + initializeMachineLegalizePassPass(*PassRegistry::getPassRegistry());
> +}
> +
> +void MachineLegalizePass::init(MachineFunction &MF) {
> +}
> +
> +bool MachineLegalizePass::runOnMachineFunction(MachineFunction &MF) {
> + DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
> + init(MF);
> + const MachineLegalizer &Legalizer =
> *MF.getSubtarget().getMachineLegalizer();
> + MachineLegalizeHelper Helper(MF);
> +
> + // FIXME: an instruction may need more than one pass before it is
> legal. For
> + // example on most architectures <3 x i3> is doubly-illegal. It would
> + // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x
> i8>. We
> + // probably want a worklist of instructions rather than naive iterate
> until
> + // convergence for performance reasons.
> + bool Changed = false;
> + MachineBasicBlock::iterator NextMI;
> + for (auto &MBB : MF)
> + for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
> + // Get the next Instruction before we try to legalize, because
> there's a
> + // good chance MI will be deleted.
> + NextMI = std::next(MI);
> + auto Res = Helper.legalizeInstr(*MI, Legalizer);
> +
> + // Error out if we couldn't legalize this instruction. We may want
> to fall
> + // back to DAG ISel instead in the future.
> + if (Res == MachineLegalizeHelper::UnableToLegalize) {
> + std::string Msg;
> + raw_string_ostream OS(Msg);
> + OS << "unable to legalize instruction: ";
> + MI->print(OS);
> + report_fatal_error(OS.str());
> + }
> +
> + Changed |= Res == MachineLegalizeHelper::Legalized;
> + }
> + return Changed;
> +}
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp Fri Jul 22
> 15:03:43 2016
> @@ -28,10 +28,6 @@ MachineLegalizer::MachineLegalizer() : T
> DefaultActions[TargetOpcode::G_ADD] = NarrowScalar;
> }
>
> -bool MachineLegalizer::legalizeInstr(MachineInstr &MI) const {
> - llvm_unreachable("Unimplemented functionality");
> -}
> -
> void MachineLegalizer::computeTables() {
> for (auto &Op : Actions) {
> LLT Ty = Op.first.second;
> @@ -56,6 +52,11 @@ MachineLegalizer::getAction(unsigned Opc
> // These *have* to be implemented for now, they're the fundamental
> basis of
> // how everything else is transformed.
>
> + // FIXME: the long-term plan calls for expansion in terms of load/store
> (if
> + // they're not legal).
> + if (Opcode == TargetOpcode::G_SEQUENCE || Opcode ==
> TargetOpcode::G_EXTRACT)
> + return std::make_pair(Legal, Ty);
> +
> auto ActionIt = Actions.find(std::make_pair(Opcode, Ty));
> if (ActionIt != Actions.end())
> return findLegalAction(Opcode, Ty, ActionIt->second);
>
> Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Fri Jul 22 15:03:43 2016
> @@ -165,6 +165,11 @@ addPassesToGenerateCode(LLVMTargetMachin
> if (PassConfig->addIRTranslator())
> return nullptr;
>
> + PassConfig->addPreLegalizeMachineIR();
> +
> + if (PassConfig->addLegalizeMachineIR())
> + return nullptr;
> +
> // Before running the register bank selector, ask the target if it
> // wants to run some passes.
> PassConfig->addPreRegBankSelect();
>
> Added: llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp?rev=276461&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp (added)
> +++ llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp Fri Jul 22
> 15:03:43 2016
> @@ -0,0 +1,30 @@
> +//===- AArch64MachineLegalizer.cpp -------------------------------*- C++
> -*-==//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +/// \file
> +/// This file implements the targeting of the Machinelegalizer class for
> +/// AArch64.
> +/// \todo This should be generated by TableGen.
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AArch64MachineLegalizer.h"
> +#include "llvm/CodeGen/ValueTypes.h"
> +#include "llvm/IR/Type.h"
> +#include "llvm/IR/DerivedTypes.h"
> +#include "llvm/Target/TargetOpcodes.h"
> +
> +using namespace llvm;
> +
> +#ifndef LLVM_BUILD_GLOBAL_ISEL
> +#error "You shouldn't build this"
> +#endif
> +
> +AArch64MachineLegalizer::AArch64MachineLegalizer() {
> + setAction(TargetOpcode::G_ADD, LLT::vector(2, 64), Legal);
> + computeTables();
> +}
>
> Added: llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.h?rev=276461&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.h (added)
> +++ llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.h Fri Jul 22
> 15:03:43 2016
> @@ -0,0 +1,30 @@
> +//===- AArch64Machinelegalizer --------------------------------*- C++
> -*-==//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +/// \file
> +/// This file declares the targeting of the Machinelegalizer class for
> +/// AArch64.
> +/// \todo This should be generated by TableGen.
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64MACHINELEGALIZER_H
> +#define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINELEGALIZER_H
> +
> +#include "llvm/CodeGen/GlobalISel/Machinelegalizer.h"
> +
> +namespace llvm {
> +
> +class LLVMContext;
> +
> +/// This class provides the information for the target register banks.
> +class AArch64MachineLegalizer : public MachineLegalizer {
> +public:
> + AArch64MachineLegalizer();
> +};
> +} // End llvm namespace.
> +#endif
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp Fri Jul 22 15:03:43
> 2016
> @@ -98,6 +98,11 @@ const CallLowering *AArch64Subtarget::ge
> return GISel->getCallLowering();
> }
>
> +const MachineLegalizer *AArch64Subtarget::getMachineLegalizer() const {
> + assert(GISel && "Access to GlobalISel APIs not set");
> + return GISel->getMachineLegalizer();
> +}
> +
> const RegisterBankInfo *AArch64Subtarget::getRegBankInfo() const {
> assert(GISel && "Access to GlobalISel APIs not set");
> return GISel->getRegBankInfo();
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Fri Jul 22 15:03:43
> 2016
> @@ -147,6 +147,7 @@ public:
> return &getInstrInfo()->getRegisterInfo();
> }
> const CallLowering *getCallLowering() const override;
> + const MachineLegalizer *getMachineLegalizer() const override;
> const RegisterBankInfo *getRegBankInfo() const override;
> const Triple &getTargetTriple() const { return TargetTriple; }
> bool enableMachineScheduler() const override { return true; }
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=276461&r1=276460&r2=276461&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp Fri Jul 22
> 15:03:43 2016
> @@ -12,11 +12,13 @@
>
> #include "AArch64.h"
> #include "AArch64CallLowering.h"
> +#include "AArch64MachineLegalizer.h"
> #include "AArch64RegisterBankInfo.h"
> #include "AArch64TargetMachine.h"
> #include "AArch64TargetObjectFile.h"
> #include "AArch64TargetTransformInfo.h"
> #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
> +#include "llvm/CodeGen/GlobalISel/MachineLegalizePass.h"
> #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
> #include "llvm/CodeGen/Passes.h"
> #include "llvm/CodeGen/RegAllocRegistry.h"
> @@ -196,10 +198,14 @@ AArch64TargetMachine::~AArch64TargetMach
> namespace {
> struct AArch64GISelActualAccessor : public GISelAccessor {
> std::unique_ptr<CallLowering> CallLoweringInfo;
> + std::unique_ptr<MachineLegalizer> MachineLegalizer;
>
This doesn't compile with GCC 4.9 because the member is the same name as
the type.
Suggestions?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160723/04bd89a0/attachment.html>
More information about the llvm-commits
mailing list