[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