[llvm] r276461 - GlobalISel: implement legalization pass, with just one transformation.

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 23 00:57:37 PDT 2016


On Fri, Jul 22, 2016 at 10:36 PM Chandler Carruth <chandlerc at google.com>
wrote:

> 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?
>

To avoid leaving the build broken for GCC over the weekend or trying to
unwind the very large series of global isel patches, I've hacked around it
by renaming the member in r276522.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160723/a6f5d292/attachment-0001.html>


More information about the llvm-commits mailing list