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