<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Daniel,<div class=""><br class=""></div><div class="">We’ve talked with Eric on IRC and we agreed that this part of the patch is not needed for now.</div><div class=""><br class=""></div><div class="">I am actually supportive of this kind of approach where we could derive different selector/legalizer/etc. based on this “attribute”. E.g., we could have a NeonInstructionSelector and a CodeSizeSelector. However, Eric pointed out that this feature is not used right now and thus, we should postpone the design of such approach whenever we need it.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">-Quentin</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On May 2, 2017, at 11:50 AM, Eric Christopher <<a href="mailto:echristo@gmail.com" class="">echristo@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi Daniel,<div class=""><br class=""></div><div class="">I don't see a reason to pass whether or not we're optimizing for size through the subtarget constructor - it's not being used to initialize anything in the subtarget and it can be gotten from the function directly. I think this is the wrong direction to take this and would prefer that we use the function attributes in places that we need them.</div><div class=""><br class=""></div><div class="">That said, there could be something I've missed. Can you explain this patch much more thoroughly? The subtarget change is even missing from your patch description.</div><div class=""><br class=""></div><div class="">-eric<br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Sat, Apr 29, 2017 at 10:43 AM Daniel Sanders via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dsanders<br class="">
Date: Sat Apr 29 12:30:09 2017<br class="">
New Revision: 301750<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=301750&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=301750&view=rev</a><br class="">
Log:<br class="">
[globalisel][tablegen] Compute available feature bits correctly.<br class="">
<br class="">
Summary:<br class="">
Predicate<> now has a field to indicate how often it must be recomputed.<br class="">
Currently, there are two frequencies, per-module (RecomputePerFunction==0)<br class="">
and per-function (RecomputePerFunction==1). Per-function predicates are<br class="">
currently recomputed more frequently than necessary since the only predicate<br class="">
in this category is cheap to test. Per-module predicates are now computed in<br class="">
getSubtargetImpl() while per-function predicates are computed in selectImpl().<br class="">
<br class="">
Tablegen now manages the PredicateBitset internally. It should only be<br class="">
necessary to add the required includes.<br class="">
<br class="">
Also fixed a problem revealed by the test case where<br class="">
constrainSelectedInstRegOperands() would attempt to tie operands that<br class="">
BuildMI had already tied.<br class="">
<br class="">
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar<br class="">
<br class="">
Reviewed By: rovka<br class="">
<br class="">
Subscribers: kristof.beyls, igorb, llvm-commits<br class="">
<br class="">
Differential Revision: <a href="https://reviews.llvm.org/D32491" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/D32491</a><br class="">
<br class="">
Added:<br class="">
    llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir<br class="">
Modified:<br class="">
    llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h<br class="">
    llvm/trunk/include/llvm/Target/Target.td<br class="">
    llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp<br class="">
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td<br class="">
    llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp<br class="">
    llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp<br class="">
    llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br class="">
    llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp<br class="">
    llvm/trunk/lib/Target/X86/X86InstrInfo.td<br class="">
    llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp<br class="">
    llvm/trunk/lib/Target/X86/X86Subtarget.cpp<br class="">
    llvm/trunk/lib/Target/X86/X86Subtarget.h<br class="">
    llvm/trunk/lib/Target/X86/X86TargetMachine.cpp<br class="">
    llvm/trunk/test/TableGen/GlobalISelEmitter.td<br class="">
    llvm/trunk/unittests/Target/AArch64/InstSizes.cpp<br class="">
    llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp<br class="">
    llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp<br class="">
    llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h<br class="">
<br class="">
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h (original)<br class="">
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h Sat Apr 29 12:30:09 2017<br class="">
@@ -61,9 +61,6 @@ class InstructionSelector {<br class="">
 public:<br class="">
   virtual ~InstructionSelector() {}<br class="">
<br class="">
-  /// This is executed before selecting a function.<br class="">
-  virtual void beginFunction(const MachineFunction &MF) {}<br class="">
-<br class="">
   /// Select the (possibly generic) instruction \p I to only use target-specific<br class="">
   /// opcodes. It is OK to insert multiple instructions, but they cannot be<br class="">
   /// generic pre-isel instructions.<br class="">
<br class="">
Modified: llvm/trunk/include/llvm/Target/Target.td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/include/llvm/Target/Target.td (original)<br class="">
+++ llvm/trunk/include/llvm/Target/Target.td Sat Apr 29 12:30:09 2017<br class="">
@@ -530,6 +530,12 @@ class Predicate<string cond> {<br class="">
   /// PredicateName - User-level name to use for the predicate. Mainly for use<br class="">
   /// in diagnostics such as missing feature errors in the asm matcher.<br class="">
   string PredicateName = "";<br class="">
+<br class="">
+  /// Setting this to '1' indicates that the predicate must be recomputed on<br class="">
+  /// every function change. Most predicates can leave this at '0'.<br class="">
+  ///<br class="">
+  /// Ignored by SelectionDAG, it always recomputes the predicate on every use.<br class="">
+  bit RecomputePerFunction = 0;<br class="">
 }<br class="">
<br class="">
 /// NoHonorSignDependentRounding - This predicate is true if support for<br class="">
<br class="">
Modified: llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp (original)<br class="">
+++ llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -58,10 +58,11 @@ bool InstructionSelector::constrainSelec<br class="">
     MO.setReg(constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(),<br class="">
                                        Reg, OpI));<br class="">
<br class="">
-    // Tie uses to defs as indicated in MCInstrDesc.<br class="">
+    // Tie uses to defs as indicated in MCInstrDesc if this hasn't already been<br class="">
+    // done.<br class="">
     if (MO.isUse()) {<br class="">
       int DefIdx = I.getDesc().getOperandConstraint(OpI, MCOI::TIED_TO);<br class="">
-      if (DefIdx != -1)<br class="">
+      if (DefIdx != -1 && !I.isRegTiedToUseOperand(DefIdx))<br class="">
         I.tieOperands(DefIdx, OpI);<br class="">
     }<br class="">
   }<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td (original)<br class="">
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td Sat Apr 29 12:30:09 2017<br class="">
@@ -314,8 +314,8 @@ def AArch64umaxv    : SDNode<"AArch64ISD<br class="">
 // AArch64 Instruction Predicate Definitions.<br class="">
 def IsDarwin  : Predicate<"Subtarget->isTargetDarwin()">;<br class="">
 def IsNotDarwin: Predicate<"!Subtarget->isTargetDarwin()">;<br class="">
-def ForCodeSize   : Predicate<"ForCodeSize">;<br class="">
-def NotForCodeSize   : Predicate<"!ForCodeSize">;<br class="">
+def ForCodeSize   : Predicate<"Subtarget->getForCodeSize()">;<br class="">
+def NotForCodeSize   : Predicate<"!Subtarget->getForCodeSize()">;<br class="">
<br class="">
 include "AArch64InstrFormats.td"<br class="">
<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)<br class="">
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -51,7 +51,6 @@ public:<br class="">
                              const AArch64Subtarget &STI,<br class="">
                              const AArch64RegisterBankInfo &RBI);<br class="">
<br class="">
-  void beginFunction(const MachineFunction &MF) override;<br class="">
   bool select(MachineInstr &I) const override;<br class="">
<br class="">
 private:<br class="">
@@ -74,12 +73,10 @@ private:<br class="">
   const AArch64InstrInfo &TII;<br class="">
   const AArch64RegisterInfo &TRI;<br class="">
   const AArch64RegisterBankInfo &RBI;<br class="">
-  bool ForCodeSize;<br class="">
<br class="">
-  PredicateBitset AvailableFeatures;<br class="">
-  PredicateBitset<br class="">
-  computeAvailableFeatures(const MachineFunction *MF,<br class="">
-                           const AArch64Subtarget *Subtarget) const;<br class="">
+#define GET_GLOBALISEL_PREDICATES_DECL<br class="">
+#include "AArch64GenGlobalISel.inc"<br class="">
+#undef GET_GLOBALISEL_PREDICATES_DECL<br class="">
<br class="">
 // We declare the temporaries used by selectImpl() in the class to minimize the<br class="">
 // cost of constructing placeholder values.<br class="">
@@ -98,7 +95,10 @@ AArch64InstructionSelector::AArch64Instr<br class="">
     const AArch64TargetMachine &TM, const AArch64Subtarget &STI,<br class="">
     const AArch64RegisterBankInfo &RBI)<br class="">
     : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),<br class="">
-      TRI(*STI.getRegisterInfo()), RBI(RBI), ForCodeSize(), AvailableFeatures()<br class="">
+      TRI(*STI.getRegisterInfo()), RBI(RBI),<br class="">
+#define GET_GLOBALISEL_PREDICATES_INIT<br class="">
+#include "AArch64GenGlobalISel.inc"<br class="">
+#undef GET_GLOBALISEL_PREDICATES_INIT<br class="">
 #define GET_GLOBALISEL_TEMPORARIES_INIT<br class="">
 #include "AArch64GenGlobalISel.inc"<br class="">
 #undef GET_GLOBALISEL_TEMPORARIES_INIT<br class="">
@@ -577,12 +577,6 @@ bool AArch64InstructionSelector::selectV<br class="">
   return true;<br class="">
 }<br class="">
<br class="">
-void AArch64InstructionSelector::beginFunction(<br class="">
-    const MachineFunction &MF) {<br class="">
-  ForCodeSize = MF.getFunction()->optForSize();<br class="">
-  AvailableFeatures = computeAvailableFeatures(&MF, &STI);<br class="">
-}<br class="">
-<br class="">
 bool AArch64InstructionSelector::select(MachineInstr &I) const {<br class="">
   assert(I.getParent() && "Instruction should be in a basic block!");<br class="">
   assert(I.getParent()->getParent() && "Instruction should be in a function!");<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp (original)<br class="">
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -113,11 +113,12 @@ void AArch64Subtarget::initializePropert<br class="">
<br class="">
 AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,<br class="">
                                    const std::string &FS,<br class="">
-                                   const TargetMachine &TM, bool LittleEndian)<br class="">
+                                   const TargetMachine &TM, bool LittleEndian,<br class="">
+                                   bool ForCodeSize)<br class="">
     : AArch64GenSubtargetInfo(TT, CPU, FS), ReserveX18(TT.isOSDarwin()),<br class="">
       IsLittle(LittleEndian), TargetTriple(TT), FrameLowering(),<br class="">
       InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),<br class="">
-      TLInfo(TM, *this), GISel() {}<br class="">
+      TLInfo(TM, *this), GISel(), ForCodeSize(ForCodeSize) {}<br class="">
<br class="">
 const CallLowering *AArch64Subtarget::getCallLowering() const {<br class="">
   assert(GISel && "Access to GlobalISel APIs not set");<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (original)<br class="">
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Sat Apr 29 12:30:09 2017<br class="">
@@ -124,6 +124,8 @@ protected:<br class="">
   /// an optional library.<br class="">
   std::unique_ptr<GISelAccessor> GISel;<br class="">
<br class="">
+  bool ForCodeSize;<br class="">
+<br class="">
 private:<br class="">
   /// initializeSubtargetDependencies - Initializes using CPUString and the<br class="">
   /// passed in feature string so that we can use initializer lists for<br class="">
@@ -139,7 +141,7 @@ public:<br class="">
   /// of the specified triple.<br class="">
   AArch64Subtarget(const Triple &TT, const std::string &CPU,<br class="">
                    const std::string &FS, const TargetMachine &TM,<br class="">
-                   bool LittleEndian);<br class="">
+                   bool LittleEndian, bool ForCodeSize);<br class="">
<br class="">
   /// This object will take onwership of \p GISelAccessor.<br class="">
   void setGISelAccessor(GISelAccessor &GISel) {<br class="">
@@ -262,6 +264,8 @@ public:<br class="">
     }<br class="">
   }<br class="">
<br class="">
+  bool getForCodeSize() const { return ForCodeSize; }<br class="">
+<br class="">
   /// ParseSubtargetFeatures - Parses features string setting specified<br class="">
   /// subtarget options.  Definition of function is auto generated by tblgen.<br class="">
   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp (original)<br class="">
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -255,6 +255,7 @@ const AArch64Subtarget *<br class="">
 AArch64TargetMachine::getSubtargetImpl(const Function &F) const {<br class="">
   Attribute CPUAttr = F.getFnAttribute("target-cpu");<br class="">
   Attribute FSAttr = F.getFnAttribute("target-features");<br class="">
+  bool ForCodeSize = F.optForSize();<br class="">
<br class="">
   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)<br class="">
                         ? CPUAttr.getValueAsString().str()<br class="">
@@ -262,15 +263,17 @@ AArch64TargetMachine::getSubtargetImpl(c<br class="">
   std::string FS = !FSAttr.hasAttribute(Attribute::None)<br class="">
                        ? FSAttr.getValueAsString().str()<br class="">
                        : TargetFS;<br class="">
+  std::string ForCodeSizeStr =<br class="">
+      std::string(ForCodeSize ? "+" : "-") + "forcodesize";<br class="">
<br class="">
-  auto &I = SubtargetMap[CPU + FS];<br class="">
+  auto &I = SubtargetMap[CPU + FS + ForCodeSizeStr];<br class="">
   if (!I) {<br class="">
     // This needs to be done before we create a new subtarget since any<br class="">
     // creation will depend on the TM and the code generation flags on the<br class="">
     // function that reside in TargetOptions.<br class="">
     resetTargetOptions(F);<br class="">
     I = llvm::make_unique<AArch64Subtarget>(TargetTriple, CPU, FS, *this,<br class="">
-                                            isLittle);<br class="">
+                                            isLittle, ForCodeSize);<br class="">
 #ifndef LLVM_BUILD_GLOBAL_ISEL<br class="">
     GISelAccessor *GISel = new GISelAccessor();<br class="">
 #else<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)<br class="">
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Apr 29 12:30:09 2017<br class="">
@@ -877,7 +877,9 @@ def In32BitMode  : Predicate<"Subtarget-<br class="">
 def IsWin64      : Predicate<"Subtarget->isTargetWin64()">;<br class="">
 def NotWin64     : Predicate<"!Subtarget->isTargetWin64()">;<br class="">
 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"<br class="">
-                                  "Subtarget->getFrameLowering()->hasFP(*MF)">;<br class="">
+                                  "Subtarget->getFrameLowering()->hasFP(*MF)"> {<br class="">
+  let RecomputePerFunction = 1;<br class="">
+}<br class="">
 def IsPS4        : Predicate<"Subtarget->isTargetPS4()">;<br class="">
 def NotPS4       : Predicate<"!Subtarget->isTargetPS4()">;<br class="">
 def IsNaCl       : Predicate<"Subtarget->isTargetNaCl()">;<br class="">
@@ -887,9 +889,9 @@ def KernelCode   : Predicate<"TM.getCode<br class="">
 def NearData     : Predicate<"TM.getCodeModel() == CodeModel::Small ||"<br class="">
                              "TM.getCodeModel() == CodeModel::Kernel">;<br class="">
 def IsNotPIC     : Predicate<"!TM.isPositionIndependent()">;<br class="">
-def OptForSize   : Predicate<"OptForSize">;<br class="">
-def OptForMinSize : Predicate<"OptForMinSize">;<br class="">
-def OptForSpeed  : Predicate<"!OptForSize">;<br class="">
+def OptForSize   : Predicate<"Subtarget->getOptForSize()">;<br class="">
+def OptForMinSize : Predicate<"Subtarget->getOptForMinSize()">;<br class="">
+def OptForSpeed  : Predicate<"!Subtarget->getOptForSize()">;<br class="">
 def FastBTMem    : Predicate<"!Subtarget->isBTMemSlow()">;<br class="">
 def CallImmAddr  : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;<br class="">
 def FavorMemIndirectCall  : Predicate<"!Subtarget->callRegIndirect()">;<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)<br class="">
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -48,7 +48,6 @@ public:<br class="">
   X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,<br class="">
                          const X86RegisterBankInfo &RBI);<br class="">
<br class="">
-  void beginFunction(const MachineFunction &MF) override;<br class="">
   bool select(MachineInstr &I) const override;<br class="">
<br class="">
 private:<br class="">
@@ -80,12 +79,10 @@ private:<br class="">
   const X86InstrInfo &TII;<br class="">
   const X86RegisterInfo &TRI;<br class="">
   const X86RegisterBankInfo &RBI;<br class="">
-  bool OptForSize;<br class="">
-  bool OptForMinSize;<br class="">
<br class="">
-  PredicateBitset AvailableFeatures;<br class="">
-  PredicateBitset computeAvailableFeatures(const MachineFunction *MF,<br class="">
-                                           const X86Subtarget *Subtarget) const;<br class="">
+#define GET_GLOBALISEL_PREDICATES_DECL<br class="">
+#include "X86GenGlobalISel.inc"<br class="">
+#undef GET_GLOBALISEL_PREDICATES_DECL<br class="">
<br class="">
 #define GET_GLOBALISEL_TEMPORARIES_DECL<br class="">
 #include "X86GenGlobalISel.inc"<br class="">
@@ -102,8 +99,10 @@ X86InstructionSelector::X86InstructionSe<br class="">
                                                const X86Subtarget &STI,<br class="">
                                                const X86RegisterBankInfo &RBI)<br class="">
     : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),<br class="">
-      TRI(*STI.getRegisterInfo()), RBI(RBI), OptForSize(false),<br class="">
-      OptForMinSize(false), AvailableFeatures()<br class="">
+      TRI(*STI.getRegisterInfo()), RBI(RBI),<br class="">
+#define GET_GLOBALISEL_PREDICATES_INIT<br class="">
+#include "X86GenGlobalISel.inc"<br class="">
+#undef GET_GLOBALISEL_PREDICATES_INIT<br class="">
 #define GET_GLOBALISEL_TEMPORARIES_INIT<br class="">
 #include "X86GenGlobalISel.inc"<br class="">
 #undef GET_GLOBALISEL_TEMPORARIES_INIT<br class="">
@@ -206,12 +205,6 @@ static bool selectCopy(MachineInstr &I,<br class="">
   return true;<br class="">
 }<br class="">
<br class="">
-void X86InstructionSelector::beginFunction(const MachineFunction &MF) {<br class="">
-  OptForSize = MF.getFunction()->optForSize();<br class="">
-  OptForMinSize = MF.getFunction()->optForMinSize();<br class="">
-  AvailableFeatures = computeAvailableFeatures(&MF, &STI);<br class="">
-}<br class="">
-<br class="">
 bool X86InstructionSelector::select(MachineInstr &I) const {<br class="">
   assert(I.getParent() && "Instruction should be in a basic block!");<br class="">
   assert(I.getParent()->getParent() && "Instruction should be in a function!");<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)<br class="">
+++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -326,7 +326,8 @@ X86Subtarget &X86Subtarget::initializeSu<br class="">
<br class="">
 X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,<br class="">
                            const X86TargetMachine &TM,<br class="">
-                           unsigned StackAlignOverride)<br class="">
+                           unsigned StackAlignOverride, bool OptForSize,<br class="">
+                           bool OptForMinSize)<br class="">
     : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others),<br class="">
       PICStyle(PICStyles::None), TM(TM), TargetTriple(TT),<br class="">
       StackAlignOverride(StackAlignOverride),<br class="">
@@ -335,8 +336,9 @@ X86Subtarget::X86Subtarget(const Triple<br class="">
                   TargetTriple.getEnvironment() != Triple::CODE16),<br class="">
       In16BitMode(TargetTriple.getArch() == Triple::x86 &&<br class="">
                   TargetTriple.getEnvironment() == Triple::CODE16),<br class="">
-      InstrInfo(initializeSubtargetDependencies(CPU, FS)),<br class="">
-      TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {<br class="">
+      InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),<br class="">
+      FrameLowering(*this, getStackAlignment()), OptForSize(OptForSize),<br class="">
+      OptForMinSize(OptForMinSize) {<br class="">
   // Determine the PICStyle based on the target selected.<br class="">
   if (!isPositionIndependent())<br class="">
     setPICStyle(PICStyles::None);<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/X86/X86Subtarget.h (original)<br class="">
+++ llvm/trunk/lib/Target/X86/X86Subtarget.h Sat Apr 29 12:30:09 2017<br class="">
@@ -328,12 +328,16 @@ private:<br class="">
   X86TargetLowering TLInfo;<br class="">
   X86FrameLowering FrameLowering;<br class="">
<br class="">
+  bool OptForSize;<br class="">
+  bool OptForMinSize;<br class="">
+<br class="">
 public:<br class="">
   /// This constructor initializes the data members to match that<br class="">
   /// of the specified triple.<br class="">
   ///<br class="">
   X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,<br class="">
-               const X86TargetMachine &TM, unsigned StackAlignOverride);<br class="">
+               const X86TargetMachine &TM, unsigned StackAlignOverride,<br class="">
+               bool OptForSize, bool OptForMinSize);<br class="">
<br class="">
   /// This object will take onwership of \p GISelAccessor.<br class="">
   void setGISelAccessor(GISelAccessor &GISel) { this->GISel.reset(&GISel); }<br class="">
@@ -499,6 +503,9 @@ public:<br class="">
   bool isSLM() const { return X86ProcFamily == IntelSLM; }<br class="">
   bool useSoftFloat() const { return UseSoftFloat; }<br class="">
<br class="">
+  bool getOptForSize() const { return OptForSize; }<br class="">
+  bool getOptForMinSize() const { return OptForMinSize; }<br class="">
+<br class="">
   /// Use mfence if we have SSE2 or we're on x86-64 (even if we asked for<br class="">
   /// no-sse2). There isn't any reason to disable it if the target processor<br class="">
   /// supports it.<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original)<br class="">
+++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -268,6 +268,12 @@ X86TargetMachine::getSubtargetImpl(const<br class="">
<br class="">
   FS = Key.substr(CPU.size());<br class="">
<br class="">
+  bool OptForSize = F.optForSize();<br class="">
+  bool OptForMinSize = F.optForMinSize();<br class="">
+<br class="">
+  Key += std::string(OptForSize ? "+" : "-") + "optforsize";<br class="">
+  Key += std::string(OptForMinSize ? "+" : "-") + "optforminsize";<br class="">
+<br class="">
   auto &I = SubtargetMap[Key];<br class="">
   if (!I) {<br class="">
     // This needs to be done before we create a new subtarget since any<br class="">
@@ -275,7 +281,8 @@ X86TargetMachine::getSubtargetImpl(const<br class="">
     // function that reside in TargetOptions.<br class="">
     resetTargetOptions(F);<br class="">
     I = llvm::make_unique<X86Subtarget>(TargetTriple, CPU, FS, *this,<br class="">
-                                        Options.StackAlignmentOverride);<br class="">
+                                        Options.StackAlignmentOverride,<br class="">
+                                        OptForSize, OptForMinSize);<br class="">
 #ifndef LLVM_BUILD_GLOBAL_ISEL<br class="">
     GISelAccessor *GISel = new GISelAccessor();<br class="">
 #else<br class="">
@@ -286,7 +293,8 @@ X86TargetMachine::getSubtargetImpl(const<br class="">
<br class="">
     auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());<br class="">
     GISel->RegBankInfo.reset(RBI);<br class="">
-    GISel->InstSelector.reset(createX86InstructionSelector(*this, *I, *RBI));<br class="">
+    GISel->InstSelector.reset(createX86InstructionSelector(<br class="">
+        *this, *I, *RBI));<br class="">
 #endif<br class="">
     I->setGISelAccessor(*GISel);<br class="">
   }<br class="">
<br class="">
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir?rev=301750&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir?rev=301750&view=auto</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir (added)<br class="">
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir Sat Apr 29 12:30:09 2017<br class="">
@@ -0,0 +1,37 @@<br class="">
+# RUN: llc -mtriple=x86_64-linux-gnu                     -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=ALL,INC<br class="">
+# RUN: llc -mtriple=x86_64-linux-gnu -mattr=+slow-incdec -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=ALL,ADD<br class="">
+<br class="">
+--- |<br class="">
+  define i8 @test_add_i8(i8 %arg1) {<br class="">
+    %ret = add i8 %arg1, 1<br class="">
+    ret i8 %ret<br class="">
+  }<br class="">
+...<br class="">
+<br class="">
+---<br class="">
+name:            test_add_i8<br class="">
+legalized:       true<br class="">
+regBankSelected: true<br class="">
+# ALL:      registers:<br class="">
+# ALL-NEXT:  - { id: 0, class: gr8 }<br class="">
+# INC-NEXT:  - { id: 1, class: gpr }<br class="">
+# ADD-NEXT:  - { id: 1, class: gr8 }<br class="">
+# ALL-NEXT:  - { id: 2, class: gr8 }<br class="">
+registers:<br class="">
+  - { id: 0, class: gpr }<br class="">
+  - { id: 1, class: gpr }<br class="">
+  - { id: 2, class: gpr }<br class="">
+# ALL:      %0 = COPY %al<br class="">
+# INC-NEXT: %2 = INC8r %0<br class="">
+# ADD-NEXT: %1 = MOV8ri 1<br class="">
+# ADD-NEXT: %2 = ADD8rr %0, %1<br class="">
+body:             |<br class="">
+  bb.1 (%ir-block.0):<br class="">
+    liveins: %al<br class="">
+<br class="">
+    %0(s8) = COPY %al<br class="">
+    %1(s8) = G_CONSTANT i8 1<br class="">
+    %2(s8) = G_ADD %0, %1<br class="">
+    %al = COPY %2(s8)<br class="">
+<br class="">
+...<br class="">
<br class="">
Modified: llvm/trunk/test/TableGen/GlobalISelEmitter.td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/test/TableGen/GlobalISelEmitter.td (original)<br class="">
+++ llvm/trunk/test/TableGen/GlobalISelEmitter.td Sat Apr 29 12:30:09 2017<br class="">
@@ -32,22 +32,25 @@ def m1Z : OperandWithDefaultOps <i32, (o<br class="">
<br class="">
 def HasA : Predicate<"Subtarget->hasA()">;<br class="">
 def HasB : Predicate<"Subtarget->hasB()">;<br class="">
+def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }<br class="">
<br class="">
 //===- Test the function boilerplate. -------------------------------------===//<br class="">
<br class="">
 // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {<br class="">
 // CHECK-NEXT:    Feature_HasABit = 0,<br class="">
 // CHECK-NEXT:    Feature_HasBBit = 1,<br class="">
+// CHECK-NEXT:    Feature_HasCBit = 2,<br class="">
 // CHECK-NEXT:  };<br class="">
<br class="">
 // CHECK-LABEL: static const char *SubtargetFeatureNames[] = {<br class="">
 // CHECK-NEXT:    "Feature_HasA",<br class="">
 // CHECK-NEXT:    "Feature_HasB",<br class="">
+// CHECK-NEXT:    "Feature_HasC",<br class="">
 // CHECK-NEXT:    nullptr<br class="">
 // CHECK-NEXT:  };<br class="">
<br class="">
 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::<br class="">
-// CHECK-NEXT:  computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {<br class="">
+// CHECK-NEXT:  computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {<br class="">
 // CHECK-NEXT:    PredicateBitset Features;<br class="">
 // CHECK-NEXT:    if (Subtarget->hasA())<br class="">
 // CHECK-NEXT:      Features[Feature_HasABit] = 1;<br class="">
@@ -56,6 +59,14 @@ def HasB : Predicate<"Subtarget->hasB()"<br class="">
 // CHECK-NEXT:    return Features;<br class="">
 // CHECK-NEXT:  }<br class="">
<br class="">
+// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::<br class="">
+// CHECK-NEXT:  computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {<br class="">
+// CHECK-NEXT:    PredicateBitset Features;<br class="">
+// CHECK-NEXT:    if (Subtarget->hasC())<br class="">
+// CHECK-NEXT:      Features[Feature_HasCBit] = 1;<br class="">
+// CHECK-NEXT:    return Features;<br class="">
+// CHECK-NEXT:  }<br class="">
+<br class="">
 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {<br class="">
 // CHECK: MachineFunction &MF = *I.getParent()->getParent();<br class="">
 // CHECK: const MachineRegisterInfo &MRI = MF.getRegInfo();<br class="">
@@ -216,7 +227,7 @@ def MULADD : I<(outs GPR32:$dst), (ins G<br class="">
 //===- Test another simple pattern with regclass operands. ----------------===//<br class="">
<br class="">
 // CHECK-LABEL: if ([&]() {<br class="">
-// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};<br class="">
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit, Feature_HasCBit};<br class="">
 // CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)<br class="">
 // CHECK-NEXT:      return false;<br class="">
 // CHECK-NEXT:    MachineInstr &MI0 = I;<br class="">
@@ -247,7 +258,7 @@ def MULADD : I<(outs GPR32:$dst), (ins G<br class="">
<br class="">
 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),<br class="">
              [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,<br class="">
-          Requires<[HasA, HasB]>;<br class="">
+          Requires<[HasA, HasB, HasC]>;<br class="">
<br class="">
 //===- Test a pattern with ComplexPattern operands. -----------------------===//<br class="">
 //<br class="">
<br class="">
Modified: llvm/trunk/unittests/Target/AArch64/InstSizes.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Target/AArch64/InstSizes.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Target/AArch64/InstSizes.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/unittests/Target/AArch64/InstSizes.cpp (original)<br class="">
+++ llvm/trunk/unittests/Target/AArch64/InstSizes.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -30,7 +30,8 @@ std::unique_ptr<TargetMachine> createTar<br class="">
<br class="">
 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {<br class="">
   AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),<br class="">
-                      TM->getTargetFeatureString(), *TM, /* isLittle */ false);<br class="">
+                      TM->getTargetFeatureString(), *TM, /* isLittle */ false,<br class="">
+                      /* ForCodeSize */ false);<br class="">
   return llvm::make_unique<AArch64InstrInfo>(ST);<br class="">
 }<br class="">
<br class="">
<br class="">
Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)<br class="">
+++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -199,21 +199,19 @@ public:<br class="">
   void emitCxxCapturedInsnList(raw_ostream &OS);<br class="">
   void emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr);<br class="">
<br class="">
-  void emit(raw_ostream &OS,<br class="">
-            std::map<Record *, SubtargetFeatureInfo, LessRecordByID><br class="">
-                SubtargetFeatures);<br class="">
+void emit(raw_ostream &OS, SubtargetFeatureInfoMap SubtargetFeatures);<br class="">
<br class="">
-  /// Compare the priority of this object and B.<br class="">
-  ///<br class="">
-  /// Returns true if this object is more important than B.<br class="">
-  bool isHigherPriorityThan(const RuleMatcher &B) const;<br class="">
+/// Compare the priority of this object and B.<br class="">
+///<br class="">
+/// Returns true if this object is more important than B.<br class="">
+bool isHigherPriorityThan(const RuleMatcher &B) const;<br class="">
<br class="">
-  /// Report the maximum number of temporary operands needed by the rule<br class="">
-  /// matcher.<br class="">
-  unsigned countRendererFns() const;<br class="">
+/// Report the maximum number of temporary operands needed by the rule<br class="">
+/// matcher.<br class="">
+unsigned countRendererFns() const;<br class="">
<br class="">
-  // FIXME: Remove this as soon as possible<br class="">
-  InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }<br class="">
+// FIXME: Remove this as soon as possible<br class="">
+InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }<br class="">
 };<br class="">
<br class="">
 template <class PredicateTy> class PredicateListMatcher {<br class="">
@@ -951,6 +949,9 @@ private:<br class="">
<br class="">
   /// True if the instruction can be built solely by mutating the opcode.<br class="">
   bool canMutate() const {<br class="">
+    if (OperandRenderers.size() != Matched.getNumOperands())<br class="">
+      return false;<br class="">
+<br class="">
     for (const auto &Renderer : enumerate(OperandRenderers)) {<br class="">
       if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {<br class="">
         const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName());<br class="">
@@ -1072,8 +1073,7 @@ void RuleMatcher::emitCxxCaptureStmts(ra<br class="">
 }<br class="">
<br class="">
 void RuleMatcher::emit(raw_ostream &OS,<br class="">
-                       std::map<Record *, SubtargetFeatureInfo, LessRecordByID><br class="">
-                           SubtargetFeatures) {<br class="">
+                       SubtargetFeatureInfoMap SubtargetFeatures) {<br class="">
   if (Matchers.empty())<br class="">
     llvm_unreachable("Unexpected empty matcher!");<br class="">
<br class="">
@@ -1218,7 +1218,7 @@ private:<br class="">
   DenseMap<const Record *, const Record *> ComplexPatternEquivs;<br class="">
<br class="">
   // Map of predicates to their subtarget features.<br class="">
-  std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;<br class="">
+  SubtargetFeatureInfoMap SubtargetFeatures;<br class="">
<br class="">
   void gatherNodeEquivs();<br class="">
   const CodeGenInstruction *findNodeEquiv(Record *N) const;<br class="">
@@ -1713,14 +1713,36 @@ void GlobalISelEmitter::run(raw_ostream<br class="">
   SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,<br class="">
                                                            OS);<br class="">
   SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);<br class="">
+<br class="">
+  // Separate subtarget features by how often they must be recomputed.<br class="">
+  SubtargetFeatureInfoMap ModuleFeatures;<br class="">
+  std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),<br class="">
+               std::inserter(ModuleFeatures, ModuleFeatures.end()),<br class="">
+               [](const SubtargetFeatureInfoMap::value_type &X) {<br class="">
+                 return !X.second.mustRecomputePerFunction();<br class="">
+               });<br class="">
+  SubtargetFeatureInfoMap FunctionFeatures;<br class="">
+  std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),<br class="">
+               std::inserter(FunctionFeatures, FunctionFeatures.end()),<br class="">
+               [](const SubtargetFeatureInfoMap::value_type &X) {<br class="">
+                 return X.second.mustRecomputePerFunction();<br class="">
+               });<br class="">
+<br class="">
   SubtargetFeatureInfo::emitComputeAvailableFeatures(<br class="">
-      Target.getName(), "InstructionSelector", "computeAvailableFeatures",<br class="">
-      SubtargetFeatures, OS);<br class="">
+      Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",<br class="">
+      ModuleFeatures, OS);<br class="">
+  SubtargetFeatureInfo::emitComputeAvailableFeatures(<br class="">
+      Target.getName(), "InstructionSelector",<br class="">
+      "computeAvailableFunctionFeatures", FunctionFeatures, OS,<br class="">
+      "const MachineFunction *MF");<br class="">
<br class="">
   OS << "bool " << Target.getName()<br class="">
      << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"<br class="">
      << "  MachineFunction &MF = *I.getParent()->getParent();\n"<br class="">
-     << "  const MachineRegisterInfo &MRI = MF.getRegInfo();\n";<br class="">
+     << "  const MachineRegisterInfo &MRI = MF.getRegInfo();\n"<br class="">
+     << "  // FIXME: This should be computed on a per-function basis rather than per-insn.\n"<br class="">
+     << "  AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);\n"<br class="">
+     << "  const PredicateBitset AvailableFeatures = getAvailableFeatures();\n";<br class="">
<br class="">
   for (auto &Rule : Rules) {<br class="">
     Rule.emit(OS, SubtargetFeatures);<br class="">
@@ -1730,6 +1752,26 @@ void GlobalISelEmitter::run(raw_ostream<br class="">
   OS << "  return false;\n"<br class="">
      << "}\n"<br class="">
      << "#endif // ifdef GET_GLOBALISEL_IMPL\n";<br class="">
+<br class="">
+  OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"<br class="">
+     << "PredicateBitset AvailableModuleFeatures;\n"<br class="">
+     << "mutable PredicateBitset AvailableFunctionFeatures;\n"<br class="">
+     << "PredicateBitset getAvailableFeatures() const {\n"<br class="">
+     << "  return AvailableModuleFeatures | AvailableFunctionFeatures;\n"<br class="">
+     << "}\n"<br class="">
+     << "PredicateBitset\n"<br class="">
+     << "computeAvailableModuleFeatures(const " << Target.getName()<br class="">
+     << "Subtarget *Subtarget) const;\n"<br class="">
+     << "PredicateBitset\n"<br class="">
+     << "computeAvailableFunctionFeatures(const " << Target.getName()<br class="">
+     << "Subtarget *Subtarget,\n"<br class="">
+     << "                                 const MachineFunction *MF) const;\n"<br class="">
+     << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";<br class="">
+<br class="">
+  OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"<br class="">
+     << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"<br class="">
+     << "AvailableFunctionFeatures()\n"<br class="">
+     << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";<br class="">
 }<br class="">
<br class="">
 void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {<br class="">
<br class="">
Modified: llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp (original)<br class="">
+++ llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp Sat Apr 29 12:30:09 2017<br class="">
@@ -45,8 +45,7 @@ SubtargetFeatureInfo::getAll(const Recor<br class="">
 }<br class="">
<br class="">
 void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(<br class="">
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,<br class="">
-    raw_ostream &OS) {<br class="">
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {<br class="">
   OS << "// Flags for subtarget features that participate in "<br class="">
      << "instruction matching.\n";<br class="">
   OS << "enum SubtargetFeatureFlag : "<br class="">
@@ -60,8 +59,7 @@ void SubtargetFeatureInfo::emitSubtarget<br class="">
 }<br class="">
<br class="">
 void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(<br class="">
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,<br class="">
-    raw_ostream &OS) {<br class="">
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {<br class="">
   OS << "// Bits for subtarget features that participate in "<br class="">
      << "instruction matching.\n";<br class="">
   OS << "enum SubtargetFeatureBits : "<br class="">
@@ -74,8 +72,7 @@ void SubtargetFeatureInfo::emitSubtarget<br class="">
 }<br class="">
<br class="">
 void SubtargetFeatureInfo::emitNameTable(<br class="">
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,<br class="">
-    raw_ostream &OS) {<br class="">
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {<br class="">
   // Need to sort the name table so that lookup by the log of the enum value<br class="">
   // gives the proper name. More specifically, for a feature of value 1<<n,<br class="">
   // SubtargetFeatureNames[n] should be the name of the feature.<br class="">
@@ -102,11 +99,13 @@ void SubtargetFeatureInfo::emitNameTable<br class="">
<br class="">
 void SubtargetFeatureInfo::emitComputeAvailableFeatures(<br class="">
     StringRef TargetName, StringRef ClassName, StringRef FuncName,<br class="">
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,<br class="">
-    raw_ostream &OS) {<br class="">
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS,<br class="">
+    StringRef ExtraParams) {<br class="">
   OS << "PredicateBitset " << TargetName << ClassName << "::\n"<br class="">
-     << FuncName << "(const MachineFunction *MF, const " << TargetName<br class="">
-     << "Subtarget *Subtarget) const {\n";<br class="">
+     << FuncName << "(const " << TargetName << "Subtarget *Subtarget";<br class="">
+  if (!ExtraParams.empty())<br class="">
+    OS << ", " << ExtraParams;<br class="">
+  OS << ") const {\n";<br class="">
   OS << "  PredicateBitset Features;\n";<br class="">
   for (const auto &SF : SubtargetFeatures) {<br class="">
     const SubtargetFeatureInfo &SFI = SF.second;<br class="">
@@ -120,8 +119,7 @@ void SubtargetFeatureInfo::emitComputeAv<br class="">
<br class="">
 void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(<br class="">
     StringRef TargetName, StringRef ClassName, StringRef FuncName,<br class="">
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,<br class="">
-    raw_ostream &OS) {<br class="">
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {<br class="">
   OS << "uint64_t " << TargetName << ClassName << "::\n"<br class="">
      << FuncName << "(const FeatureBitset& FB) const {\n";<br class="">
   OS << "  uint64_t Features = 0;\n";<br class="">
<br class="">
Modified: llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h?rev=301750&r1=301749&r2=301750&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h?rev=301750&r1=301749&r2=301750&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h (original)<br class="">
+++ llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h Sat Apr 29 12:30:09 2017<br class="">
@@ -21,6 +21,9 @@ namespace llvm {<br class="">
 class Record;<br class="">
 class RecordKeeper;<br class="">
<br class="">
+struct SubtargetFeatureInfo;<br class="">
+using SubtargetFeatureInfoMap = std::map<Record *, SubtargetFeatureInfo, LessRecordByID>;<br class="">
+<br class="">
 /// Helper class for storing information on a subtarget feature which<br class="">
 /// participates in instruction matching.<br class="">
 struct SubtargetFeatureInfo {<br class="">
@@ -43,6 +46,10 @@ struct SubtargetFeatureInfo {<br class="">
     return "Feature_" + TheDef->getName().str() + "Bit";<br class="">
   }<br class="">
<br class="">
+  bool mustRecomputePerFunction() const {<br class="">
+    return TheDef->getValueAsBit("RecomputePerFunction");<br class="">
+  }<br class="">
+<br class="">
   void dump() const;<br class="">
   static std::vector<std::pair<Record *, SubtargetFeatureInfo>><br class="">
   getAll(const RecordKeeper &Records);<br class="">
@@ -52,21 +59,17 @@ struct SubtargetFeatureInfo {<br class="">
   /// This version emits the bit value for the feature and is therefore limited<br class="">
   /// to 64 feature bits.<br class="">
   static void emitSubtargetFeatureFlagEnumeration(<br class="">
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID><br class="">
-          &SubtargetFeatures,<br class="">
-      raw_ostream &OS);<br class="">
+      SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);<br class="">
<br class="">
   /// Emit the subtarget feature flag definitions.<br class="">
   ///<br class="">
   /// This version emits the bit index for the feature and can therefore support<br class="">
   /// more than 64 feature bits.<br class="">
-  static void emitSubtargetFeatureBitEnumeration(<br class="">
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID><br class="">
-          &SubtargetFeatures,<br class="">
-      raw_ostream &OS);<br class="">
+  static void<br class="">
+  emitSubtargetFeatureBitEnumeration(SubtargetFeatureInfoMap &SubtargetFeatures,<br class="">
+                                     raw_ostream &OS);<br class="">
<br class="">
-  static void emitNameTable(std::map<Record *, SubtargetFeatureInfo,<br class="">
-                                     LessRecordByID> &SubtargetFeatures,<br class="">
+  static void emitNameTable(SubtargetFeatureInfoMap &SubtargetFeatures,<br class="">
                             raw_ostream &OS);<br class="">
<br class="">
   /// Emit the function to compute the list of available features given a<br class="">
@@ -82,11 +85,12 @@ struct SubtargetFeatureInfo {<br class="">
   /// \param FuncName   The name of the function to emit.<br class="">
   /// \param SubtargetFeatures A map of TableGen records to the<br class="">
   ///                          SubtargetFeatureInfo equivalent.<br class="">
-  static void emitComputeAvailableFeatures(<br class="">
-      StringRef TargetName, StringRef ClassName, StringRef FuncName,<br class="">
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID><br class="">
-          &SubtargetFeatures,<br class="">
-      raw_ostream &OS);<br class="">
+  /// \param ExtraParams Additional arguments to the generated function.<br class="">
+  static void<br class="">
+  emitComputeAvailableFeatures(StringRef TargetName, StringRef ClassName,<br class="">
+                               StringRef FuncName,<br class="">
+                               SubtargetFeatureInfoMap &SubtargetFeatures,<br class="">
+                               raw_ostream &OS, StringRef ExtraParams = "");<br class="">
<br class="">
   /// Emit the function to compute the list of available features given a<br class="">
   /// subtarget.<br class="">
@@ -103,9 +107,7 @@ struct SubtargetFeatureInfo {<br class="">
   ///                          SubtargetFeatureInfo equivalent.<br class="">
   static void emitComputeAssemblerAvailableFeatures(<br class="">
       StringRef TargetName, StringRef ClassName, StringRef FuncName,<br class="">
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID><br class="">
-          &SubtargetFeatures,<br class="">
-      raw_ostream &OS);<br class="">
+      SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);<br class="">
 };<br class="">
 } // end namespace llvm<br class="">
<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="">
</blockquote></div></div></div>
</div></blockquote></div><br class=""></div></body></html>