[llvm] r301750 - [globalisel][tablegen] Compute available feature bits correctly.

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 29 10:30:09 PDT 2017


Author: dsanders
Date: Sat Apr 29 12:30:09 2017
New Revision: 301750

URL: http://llvm.org/viewvc/llvm-project?rev=301750&view=rev
Log:
[globalisel][tablegen] Compute available feature bits correctly.

Summary:
Predicate<> now has a field to indicate how often it must be recomputed.
Currently, there are two frequencies, per-module (RecomputePerFunction==0)
and per-function (RecomputePerFunction==1). Per-function predicates are
currently recomputed more frequently than necessary since the only predicate
in this category is cheap to test. Per-module predicates are now computed in
getSubtargetImpl() while per-function predicates are computed in selectImpl().

Tablegen now manages the PredicateBitset internally. It should only be
necessary to add the required includes.

Also fixed a problem revealed by the test case where
constrainSelectedInstRegOperands() would attempt to tie operands that
BuildMI had already tied.

Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar

Reviewed By: rovka

Subscribers: kristof.beyls, igorb, llvm-commits

Differential Revision: https://reviews.llvm.org/D32491

Added:
    llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir
Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
    llvm/trunk/include/llvm/Target/Target.td
    llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
    llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp
    llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h
    llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
    llvm/trunk/lib/Target/X86/X86Subtarget.cpp
    llvm/trunk/lib/Target/X86/X86Subtarget.h
    llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
    llvm/trunk/test/TableGen/GlobalISelEmitter.td
    llvm/trunk/unittests/Target/AArch64/InstSizes.cpp
    llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
    llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp
    llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h Sat Apr 29 12:30:09 2017
@@ -61,9 +61,6 @@ class InstructionSelector {
 public:
   virtual ~InstructionSelector() {}
 
-  /// This is executed before selecting a function.
-  virtual void beginFunction(const MachineFunction &MF) {}
-
   /// Select the (possibly generic) instruction \p I to only use target-specific
   /// opcodes. It is OK to insert multiple instructions, but they cannot be
   /// generic pre-isel instructions.

Modified: llvm/trunk/include/llvm/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/Target.td (original)
+++ llvm/trunk/include/llvm/Target/Target.td Sat Apr 29 12:30:09 2017
@@ -530,6 +530,12 @@ class Predicate<string cond> {
   /// PredicateName - User-level name to use for the predicate. Mainly for use
   /// in diagnostics such as missing feature errors in the asm matcher.
   string PredicateName = "";
+
+  /// Setting this to '1' indicates that the predicate must be recomputed on
+  /// every function change. Most predicates can leave this at '0'.
+  ///
+  /// Ignored by SelectionDAG, it always recomputes the predicate on every use.
+  bit RecomputePerFunction = 0;
 }
 
 /// NoHonorSignDependentRounding - This predicate is true if support for

Modified: llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelector.cpp Sat Apr 29 12:30:09 2017
@@ -58,10 +58,11 @@ bool InstructionSelector::constrainSelec
     MO.setReg(constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(),
                                        Reg, OpI));
 
-    // Tie uses to defs as indicated in MCInstrDesc.
+    // Tie uses to defs as indicated in MCInstrDesc if this hasn't already been
+    // done.
     if (MO.isUse()) {
       int DefIdx = I.getDesc().getOperandConstraint(OpI, MCOI::TIED_TO);
-      if (DefIdx != -1)
+      if (DefIdx != -1 && !I.isRegTiedToUseOperand(DefIdx))
         I.tieOperands(DefIdx, OpI);
     }
   }

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td Sat Apr 29 12:30:09 2017
@@ -314,8 +314,8 @@ def AArch64umaxv    : SDNode<"AArch64ISD
 // AArch64 Instruction Predicate Definitions.
 def IsDarwin  : Predicate<"Subtarget->isTargetDarwin()">;
 def IsNotDarwin: Predicate<"!Subtarget->isTargetDarwin()">;
-def ForCodeSize   : Predicate<"ForCodeSize">;
-def NotForCodeSize   : Predicate<"!ForCodeSize">;
+def ForCodeSize   : Predicate<"Subtarget->getForCodeSize()">;
+def NotForCodeSize   : Predicate<"!Subtarget->getForCodeSize()">;
 
 include "AArch64InstrFormats.td"
 

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Sat Apr 29 12:30:09 2017
@@ -51,7 +51,6 @@ public:
                              const AArch64Subtarget &STI,
                              const AArch64RegisterBankInfo &RBI);
 
-  void beginFunction(const MachineFunction &MF) override;
   bool select(MachineInstr &I) const override;
 
 private:
@@ -74,12 +73,10 @@ private:
   const AArch64InstrInfo &TII;
   const AArch64RegisterInfo &TRI;
   const AArch64RegisterBankInfo &RBI;
-  bool ForCodeSize;
 
-  PredicateBitset AvailableFeatures;
-  PredicateBitset
-  computeAvailableFeatures(const MachineFunction *MF,
-                           const AArch64Subtarget *Subtarget) const;
+#define GET_GLOBALISEL_PREDICATES_DECL
+#include "AArch64GenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_DECL
 
 // We declare the temporaries used by selectImpl() in the class to minimize the
 // cost of constructing placeholder values.
@@ -98,7 +95,10 @@ AArch64InstructionSelector::AArch64Instr
     const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
     const AArch64RegisterBankInfo &RBI)
     : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
-      TRI(*STI.getRegisterInfo()), RBI(RBI), ForCodeSize(), AvailableFeatures()
+      TRI(*STI.getRegisterInfo()), RBI(RBI),
+#define GET_GLOBALISEL_PREDICATES_INIT
+#include "AArch64GenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_INIT
 #define GET_GLOBALISEL_TEMPORARIES_INIT
 #include "AArch64GenGlobalISel.inc"
 #undef GET_GLOBALISEL_TEMPORARIES_INIT
@@ -577,12 +577,6 @@ bool AArch64InstructionSelector::selectV
   return true;
 }
 
-void AArch64InstructionSelector::beginFunction(
-    const MachineFunction &MF) {
-  ForCodeSize = MF.getFunction()->optForSize();
-  AvailableFeatures = computeAvailableFeatures(&MF, &STI);
-}
-
 bool AArch64InstructionSelector::select(MachineInstr &I) const {
   assert(I.getParent() && "Instruction should be in a basic block!");
   assert(I.getParent()->getParent() && "Instruction should be in a function!");

Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp Sat Apr 29 12:30:09 2017
@@ -113,11 +113,12 @@ void AArch64Subtarget::initializePropert
 
 AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
                                    const std::string &FS,
-                                   const TargetMachine &TM, bool LittleEndian)
+                                   const TargetMachine &TM, bool LittleEndian,
+                                   bool ForCodeSize)
     : AArch64GenSubtargetInfo(TT, CPU, FS), ReserveX18(TT.isOSDarwin()),
       IsLittle(LittleEndian), TargetTriple(TT), FrameLowering(),
       InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
-      TLInfo(TM, *this), GISel() {}
+      TLInfo(TM, *this), GISel(), ForCodeSize(ForCodeSize) {}
 
 const CallLowering *AArch64Subtarget::getCallLowering() const {
   assert(GISel && "Access to GlobalISel APIs not set");

Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Sat Apr 29 12:30:09 2017
@@ -124,6 +124,8 @@ protected:
   /// an optional library.
   std::unique_ptr<GISelAccessor> GISel;
 
+  bool ForCodeSize;
+
 private:
   /// initializeSubtargetDependencies - Initializes using CPUString and the
   /// passed in feature string so that we can use initializer lists for
@@ -139,7 +141,7 @@ public:
   /// of the specified triple.
   AArch64Subtarget(const Triple &TT, const std::string &CPU,
                    const std::string &FS, const TargetMachine &TM,
-                   bool LittleEndian);
+                   bool LittleEndian, bool ForCodeSize);
 
   /// This object will take onwership of \p GISelAccessor.
   void setGISelAccessor(GISelAccessor &GISel) {
@@ -262,6 +264,8 @@ public:
     }
   }
 
+  bool getForCodeSize() const { return ForCodeSize; }
+
   /// ParseSubtargetFeatures - Parses features string setting specified
   /// subtarget options.  Definition of function is auto generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);

Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp Sat Apr 29 12:30:09 2017
@@ -255,6 +255,7 @@ const AArch64Subtarget *
 AArch64TargetMachine::getSubtargetImpl(const Function &F) const {
   Attribute CPUAttr = F.getFnAttribute("target-cpu");
   Attribute FSAttr = F.getFnAttribute("target-features");
+  bool ForCodeSize = F.optForSize();
 
   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
                         ? CPUAttr.getValueAsString().str()
@@ -262,15 +263,17 @@ AArch64TargetMachine::getSubtargetImpl(c
   std::string FS = !FSAttr.hasAttribute(Attribute::None)
                        ? FSAttr.getValueAsString().str()
                        : TargetFS;
+  std::string ForCodeSizeStr =
+      std::string(ForCodeSize ? "+" : "-") + "forcodesize";
 
-  auto &I = SubtargetMap[CPU + FS];
+  auto &I = SubtargetMap[CPU + FS + ForCodeSizeStr];
   if (!I) {
     // This needs to be done before we create a new subtarget since any
     // creation will depend on the TM and the code generation flags on the
     // function that reside in TargetOptions.
     resetTargetOptions(F);
     I = llvm::make_unique<AArch64Subtarget>(TargetTriple, CPU, FS, *this,
-                                            isLittle);
+                                            isLittle, ForCodeSize);
 #ifndef LLVM_BUILD_GLOBAL_ISEL
     GISelAccessor *GISel = new GISelAccessor();
 #else

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Apr 29 12:30:09 2017
@@ -877,7 +877,9 @@ def In32BitMode  : Predicate<"Subtarget-
 def IsWin64      : Predicate<"Subtarget->isTargetWin64()">;
 def NotWin64     : Predicate<"!Subtarget->isTargetWin64()">;
 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
-                                  "Subtarget->getFrameLowering()->hasFP(*MF)">;
+                                  "Subtarget->getFrameLowering()->hasFP(*MF)"> {
+  let RecomputePerFunction = 1;
+}
 def IsPS4        : Predicate<"Subtarget->isTargetPS4()">;
 def NotPS4       : Predicate<"!Subtarget->isTargetPS4()">;
 def IsNaCl       : Predicate<"Subtarget->isTargetNaCl()">;
@@ -887,9 +889,9 @@ def KernelCode   : Predicate<"TM.getCode
 def NearData     : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
                              "TM.getCodeModel() == CodeModel::Kernel">;
 def IsNotPIC     : Predicate<"!TM.isPositionIndependent()">;
-def OptForSize   : Predicate<"OptForSize">;
-def OptForMinSize : Predicate<"OptForMinSize">;
-def OptForSpeed  : Predicate<"!OptForSize">;
+def OptForSize   : Predicate<"Subtarget->getOptForSize()">;
+def OptForMinSize : Predicate<"Subtarget->getOptForMinSize()">;
+def OptForSpeed  : Predicate<"!Subtarget->getOptForSize()">;
 def FastBTMem    : Predicate<"!Subtarget->isBTMemSlow()">;
 def CallImmAddr  : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
 def FavorMemIndirectCall  : Predicate<"!Subtarget->callRegIndirect()">;

Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Sat Apr 29 12:30:09 2017
@@ -48,7 +48,6 @@ public:
   X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
                          const X86RegisterBankInfo &RBI);
 
-  void beginFunction(const MachineFunction &MF) override;
   bool select(MachineInstr &I) const override;
 
 private:
@@ -80,12 +79,10 @@ private:
   const X86InstrInfo &TII;
   const X86RegisterInfo &TRI;
   const X86RegisterBankInfo &RBI;
-  bool OptForSize;
-  bool OptForMinSize;
 
-  PredicateBitset AvailableFeatures;
-  PredicateBitset computeAvailableFeatures(const MachineFunction *MF,
-                                           const X86Subtarget *Subtarget) const;
+#define GET_GLOBALISEL_PREDICATES_DECL
+#include "X86GenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_DECL
 
 #define GET_GLOBALISEL_TEMPORARIES_DECL
 #include "X86GenGlobalISel.inc"
@@ -102,8 +99,10 @@ X86InstructionSelector::X86InstructionSe
                                                const X86Subtarget &STI,
                                                const X86RegisterBankInfo &RBI)
     : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
-      TRI(*STI.getRegisterInfo()), RBI(RBI), OptForSize(false),
-      OptForMinSize(false), AvailableFeatures()
+      TRI(*STI.getRegisterInfo()), RBI(RBI),
+#define GET_GLOBALISEL_PREDICATES_INIT
+#include "X86GenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_INIT
 #define GET_GLOBALISEL_TEMPORARIES_INIT
 #include "X86GenGlobalISel.inc"
 #undef GET_GLOBALISEL_TEMPORARIES_INIT
@@ -206,12 +205,6 @@ static bool selectCopy(MachineInstr &I,
   return true;
 }
 
-void X86InstructionSelector::beginFunction(const MachineFunction &MF) {
-  OptForSize = MF.getFunction()->optForSize();
-  OptForMinSize = MF.getFunction()->optForMinSize();
-  AvailableFeatures = computeAvailableFeatures(&MF, &STI);
-}
-
 bool X86InstructionSelector::select(MachineInstr &I) const {
   assert(I.getParent() && "Instruction should be in a basic block!");
   assert(I.getParent()->getParent() && "Instruction should be in a function!");

Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Sat Apr 29 12:30:09 2017
@@ -326,7 +326,8 @@ X86Subtarget &X86Subtarget::initializeSu
 
 X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
                            const X86TargetMachine &TM,
-                           unsigned StackAlignOverride)
+                           unsigned StackAlignOverride, bool OptForSize,
+                           bool OptForMinSize)
     : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others),
       PICStyle(PICStyles::None), TM(TM), TargetTriple(TT),
       StackAlignOverride(StackAlignOverride),
@@ -335,8 +336,9 @@ X86Subtarget::X86Subtarget(const Triple
                   TargetTriple.getEnvironment() != Triple::CODE16),
       In16BitMode(TargetTriple.getArch() == Triple::x86 &&
                   TargetTriple.getEnvironment() == Triple::CODE16),
-      InstrInfo(initializeSubtargetDependencies(CPU, FS)),
-      TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {
+      InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
+      FrameLowering(*this, getStackAlignment()), OptForSize(OptForSize),
+      OptForMinSize(OptForMinSize) {
   // Determine the PICStyle based on the target selected.
   if (!isPositionIndependent())
     setPICStyle(PICStyles::None);

Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Subtarget.h (original)
+++ llvm/trunk/lib/Target/X86/X86Subtarget.h Sat Apr 29 12:30:09 2017
@@ -328,12 +328,16 @@ private:
   X86TargetLowering TLInfo;
   X86FrameLowering FrameLowering;
 
+  bool OptForSize;
+  bool OptForMinSize;
+
 public:
   /// This constructor initializes the data members to match that
   /// of the specified triple.
   ///
   X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
-               const X86TargetMachine &TM, unsigned StackAlignOverride);
+               const X86TargetMachine &TM, unsigned StackAlignOverride,
+               bool OptForSize, bool OptForMinSize);
 
   /// This object will take onwership of \p GISelAccessor.
   void setGISelAccessor(GISelAccessor &GISel) { this->GISel.reset(&GISel); }
@@ -499,6 +503,9 @@ public:
   bool isSLM() const { return X86ProcFamily == IntelSLM; }
   bool useSoftFloat() const { return UseSoftFloat; }
 
+  bool getOptForSize() const { return OptForSize; }
+  bool getOptForMinSize() const { return OptForMinSize; }
+
   /// Use mfence if we have SSE2 or we're on x86-64 (even if we asked for
   /// no-sse2). There isn't any reason to disable it if the target processor
   /// supports it.

Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Sat Apr 29 12:30:09 2017
@@ -268,6 +268,12 @@ X86TargetMachine::getSubtargetImpl(const
 
   FS = Key.substr(CPU.size());
 
+  bool OptForSize = F.optForSize();
+  bool OptForMinSize = F.optForMinSize();
+
+  Key += std::string(OptForSize ? "+" : "-") + "optforsize";
+  Key += std::string(OptForMinSize ? "+" : "-") + "optforminsize";
+
   auto &I = SubtargetMap[Key];
   if (!I) {
     // This needs to be done before we create a new subtarget since any
@@ -275,7 +281,8 @@ X86TargetMachine::getSubtargetImpl(const
     // function that reside in TargetOptions.
     resetTargetOptions(F);
     I = llvm::make_unique<X86Subtarget>(TargetTriple, CPU, FS, *this,
-                                        Options.StackAlignmentOverride);
+                                        Options.StackAlignmentOverride,
+                                        OptForSize, OptForMinSize);
 #ifndef LLVM_BUILD_GLOBAL_ISEL
     GISelAccessor *GISel = new GISelAccessor();
 #else
@@ -286,7 +293,8 @@ X86TargetMachine::getSubtargetImpl(const
 
     auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
     GISel->RegBankInfo.reset(RBI);
-    GISel->InstSelector.reset(createX86InstructionSelector(*this, *I, *RBI));
+    GISel->InstSelector.reset(createX86InstructionSelector(
+        *this, *I, *RBI));
 #endif
     I->setGISelAccessor(*GISel);
   }

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir?rev=301750&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-inc.mir Sat Apr 29 12:30:09 2017
@@ -0,0 +1,37 @@
+# RUN: llc -mtriple=x86_64-linux-gnu                     -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=ALL,INC
+# 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
+
+--- |
+  define i8 @test_add_i8(i8 %arg1) {
+    %ret = add i8 %arg1, 1
+    ret i8 %ret
+  }
+...
+
+---
+name:            test_add_i8
+legalized:       true
+regBankSelected: true
+# ALL:      registers:
+# ALL-NEXT:  - { id: 0, class: gr8 }
+# INC-NEXT:  - { id: 1, class: gpr }
+# ADD-NEXT:  - { id: 1, class: gr8 }
+# ALL-NEXT:  - { id: 2, class: gr8 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: gpr }
+# ALL:      %0 = COPY %al
+# INC-NEXT: %2 = INC8r %0
+# ADD-NEXT: %1 = MOV8ri 1
+# ADD-NEXT: %2 = ADD8rr %0, %1
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %al
+
+    %0(s8) = COPY %al
+    %1(s8) = G_CONSTANT i8 1
+    %2(s8) = G_ADD %0, %1
+    %al = COPY %2(s8)
+
+...

Modified: llvm/trunk/test/TableGen/GlobalISelEmitter.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/test/TableGen/GlobalISelEmitter.td (original)
+++ llvm/trunk/test/TableGen/GlobalISelEmitter.td Sat Apr 29 12:30:09 2017
@@ -32,22 +32,25 @@ def m1Z : OperandWithDefaultOps <i32, (o
 
 def HasA : Predicate<"Subtarget->hasA()">;
 def HasB : Predicate<"Subtarget->hasB()">;
+def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
 
 //===- Test the function boilerplate. -------------------------------------===//
 
 // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
 // CHECK-NEXT:    Feature_HasABit = 0,
 // CHECK-NEXT:    Feature_HasBBit = 1,
+// CHECK-NEXT:    Feature_HasCBit = 2,
 // CHECK-NEXT:  };
 
 // CHECK-LABEL: static const char *SubtargetFeatureNames[] = {
 // CHECK-NEXT:    "Feature_HasA",
 // CHECK-NEXT:    "Feature_HasB",
+// CHECK-NEXT:    "Feature_HasC",
 // CHECK-NEXT:    nullptr
 // CHECK-NEXT:  };
 
 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
-// CHECK-NEXT:  computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {
+// CHECK-NEXT:  computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {
 // CHECK-NEXT:    PredicateBitset Features;
 // CHECK-NEXT:    if (Subtarget->hasA())
 // CHECK-NEXT:      Features[Feature_HasABit] = 1;
@@ -56,6 +59,14 @@ def HasB : Predicate<"Subtarget->hasB()"
 // CHECK-NEXT:    return Features;
 // CHECK-NEXT:  }
 
+// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
+// CHECK-NEXT:  computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {
+// CHECK-NEXT:    PredicateBitset Features;
+// CHECK-NEXT:    if (Subtarget->hasC())
+// CHECK-NEXT:      Features[Feature_HasCBit] = 1;
+// CHECK-NEXT:    return Features;
+// CHECK-NEXT:  }
+
 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
 // CHECK: MachineFunction &MF = *I.getParent()->getParent();
 // CHECK: const MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -216,7 +227,7 @@ def MULADD : I<(outs GPR32:$dst), (ins G
 //===- Test another simple pattern with regclass operands. ----------------===//
 
 // CHECK-LABEL: if ([&]() {
-// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit, Feature_HasCBit};
 // CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
 // CHECK-NEXT:      return false;
 // CHECK-NEXT:    MachineInstr &MI0 = I;
@@ -247,7 +258,7 @@ def MULADD : I<(outs GPR32:$dst), (ins G
 
 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
              [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
-          Requires<[HasA, HasB]>;
+          Requires<[HasA, HasB, HasC]>;
 
 //===- Test a pattern with ComplexPattern operands. -----------------------===//
 //

Modified: llvm/trunk/unittests/Target/AArch64/InstSizes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Target/AArch64/InstSizes.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/unittests/Target/AArch64/InstSizes.cpp (original)
+++ llvm/trunk/unittests/Target/AArch64/InstSizes.cpp Sat Apr 29 12:30:09 2017
@@ -30,7 +30,8 @@ std::unique_ptr<TargetMachine> createTar
 
 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
   AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
-                      TM->getTargetFeatureString(), *TM, /* isLittle */ false);
+                      TM->getTargetFeatureString(), *TM, /* isLittle */ false,
+                      /* ForCodeSize */ false);
   return llvm::make_unique<AArch64InstrInfo>(ST);
 }
 

Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Sat Apr 29 12:30:09 2017
@@ -199,21 +199,19 @@ public:
   void emitCxxCapturedInsnList(raw_ostream &OS);
   void emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr);
 
-  void emit(raw_ostream &OS,
-            std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
-                SubtargetFeatures);
+void emit(raw_ostream &OS, SubtargetFeatureInfoMap SubtargetFeatures);
 
-  /// Compare the priority of this object and B.
-  ///
-  /// Returns true if this object is more important than B.
-  bool isHigherPriorityThan(const RuleMatcher &B) const;
+/// Compare the priority of this object and B.
+///
+/// Returns true if this object is more important than B.
+bool isHigherPriorityThan(const RuleMatcher &B) const;
 
-  /// Report the maximum number of temporary operands needed by the rule
-  /// matcher.
-  unsigned countRendererFns() const;
+/// Report the maximum number of temporary operands needed by the rule
+/// matcher.
+unsigned countRendererFns() const;
 
-  // FIXME: Remove this as soon as possible
-  InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
+// FIXME: Remove this as soon as possible
+InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
 };
 
 template <class PredicateTy> class PredicateListMatcher {
@@ -951,6 +949,9 @@ private:
 
   /// True if the instruction can be built solely by mutating the opcode.
   bool canMutate() const {
+    if (OperandRenderers.size() != Matched.getNumOperands())
+      return false;
+
     for (const auto &Renderer : enumerate(OperandRenderers)) {
       if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
         const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName());
@@ -1072,8 +1073,7 @@ void RuleMatcher::emitCxxCaptureStmts(ra
 }
 
 void RuleMatcher::emit(raw_ostream &OS,
-                       std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
-                           SubtargetFeatures) {
+                       SubtargetFeatureInfoMap SubtargetFeatures) {
   if (Matchers.empty())
     llvm_unreachable("Unexpected empty matcher!");
 
@@ -1218,7 +1218,7 @@ private:
   DenseMap<const Record *, const Record *> ComplexPatternEquivs;
 
   // Map of predicates to their subtarget features.
-  std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
+  SubtargetFeatureInfoMap SubtargetFeatures;
 
   void gatherNodeEquivs();
   const CodeGenInstruction *findNodeEquiv(Record *N) const;
@@ -1713,14 +1713,36 @@ void GlobalISelEmitter::run(raw_ostream
   SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
                                                            OS);
   SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
+
+  // Separate subtarget features by how often they must be recomputed.
+  SubtargetFeatureInfoMap ModuleFeatures;
+  std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
+               std::inserter(ModuleFeatures, ModuleFeatures.end()),
+               [](const SubtargetFeatureInfoMap::value_type &X) {
+                 return !X.second.mustRecomputePerFunction();
+               });
+  SubtargetFeatureInfoMap FunctionFeatures;
+  std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
+               std::inserter(FunctionFeatures, FunctionFeatures.end()),
+               [](const SubtargetFeatureInfoMap::value_type &X) {
+                 return X.second.mustRecomputePerFunction();
+               });
+
   SubtargetFeatureInfo::emitComputeAvailableFeatures(
-      Target.getName(), "InstructionSelector", "computeAvailableFeatures",
-      SubtargetFeatures, OS);
+      Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
+      ModuleFeatures, OS);
+  SubtargetFeatureInfo::emitComputeAvailableFeatures(
+      Target.getName(), "InstructionSelector",
+      "computeAvailableFunctionFeatures", FunctionFeatures, OS,
+      "const MachineFunction *MF");
 
   OS << "bool " << Target.getName()
      << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
      << "  MachineFunction &MF = *I.getParent()->getParent();\n"
-     << "  const MachineRegisterInfo &MRI = MF.getRegInfo();\n";
+     << "  const MachineRegisterInfo &MRI = MF.getRegInfo();\n"
+     << "  // FIXME: This should be computed on a per-function basis rather than per-insn.\n"
+     << "  AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);\n"
+     << "  const PredicateBitset AvailableFeatures = getAvailableFeatures();\n";
 
   for (auto &Rule : Rules) {
     Rule.emit(OS, SubtargetFeatures);
@@ -1730,6 +1752,26 @@ void GlobalISelEmitter::run(raw_ostream
   OS << "  return false;\n"
      << "}\n"
      << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
+
+  OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
+     << "PredicateBitset AvailableModuleFeatures;\n"
+     << "mutable PredicateBitset AvailableFunctionFeatures;\n"
+     << "PredicateBitset getAvailableFeatures() const {\n"
+     << "  return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
+     << "}\n"
+     << "PredicateBitset\n"
+     << "computeAvailableModuleFeatures(const " << Target.getName()
+     << "Subtarget *Subtarget) const;\n"
+     << "PredicateBitset\n"
+     << "computeAvailableFunctionFeatures(const " << Target.getName()
+     << "Subtarget *Subtarget,\n"
+     << "                                 const MachineFunction *MF) const;\n"
+     << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
+
+  OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
+     << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
+     << "AvailableFunctionFeatures()\n"
+     << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
 }
 
 void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {

Modified: llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp Sat Apr 29 12:30:09 2017
@@ -45,8 +45,7 @@ SubtargetFeatureInfo::getAll(const Recor
 }
 
 void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
-    raw_ostream &OS) {
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
   OS << "// Flags for subtarget features that participate in "
      << "instruction matching.\n";
   OS << "enum SubtargetFeatureFlag : "
@@ -60,8 +59,7 @@ void SubtargetFeatureInfo::emitSubtarget
 }
 
 void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
-    raw_ostream &OS) {
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
   OS << "// Bits for subtarget features that participate in "
      << "instruction matching.\n";
   OS << "enum SubtargetFeatureBits : "
@@ -74,8 +72,7 @@ void SubtargetFeatureInfo::emitSubtarget
 }
 
 void SubtargetFeatureInfo::emitNameTable(
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
-    raw_ostream &OS) {
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
   // Need to sort the name table so that lookup by the log of the enum value
   // gives the proper name. More specifically, for a feature of value 1<<n,
   // SubtargetFeatureNames[n] should be the name of the feature.
@@ -102,11 +99,13 @@ void SubtargetFeatureInfo::emitNameTable
 
 void SubtargetFeatureInfo::emitComputeAvailableFeatures(
     StringRef TargetName, StringRef ClassName, StringRef FuncName,
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
-    raw_ostream &OS) {
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS,
+    StringRef ExtraParams) {
   OS << "PredicateBitset " << TargetName << ClassName << "::\n"
-     << FuncName << "(const MachineFunction *MF, const " << TargetName
-     << "Subtarget *Subtarget) const {\n";
+     << FuncName << "(const " << TargetName << "Subtarget *Subtarget";
+  if (!ExtraParams.empty())
+    OS << ", " << ExtraParams;
+  OS << ") const {\n";
   OS << "  PredicateBitset Features;\n";
   for (const auto &SF : SubtargetFeatures) {
     const SubtargetFeatureInfo &SFI = SF.second;
@@ -120,8 +119,7 @@ void SubtargetFeatureInfo::emitComputeAv
 
 void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
     StringRef TargetName, StringRef ClassName, StringRef FuncName,
-    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
-    raw_ostream &OS) {
+    SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
   OS << "uint64_t " << TargetName << ClassName << "::\n"
      << FuncName << "(const FeatureBitset& FB) const {\n";
   OS << "  uint64_t Features = 0;\n";

Modified: llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h?rev=301750&r1=301749&r2=301750&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h (original)
+++ llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h Sat Apr 29 12:30:09 2017
@@ -21,6 +21,9 @@ namespace llvm {
 class Record;
 class RecordKeeper;
 
+struct SubtargetFeatureInfo;
+using SubtargetFeatureInfoMap = std::map<Record *, SubtargetFeatureInfo, LessRecordByID>;
+
 /// Helper class for storing information on a subtarget feature which
 /// participates in instruction matching.
 struct SubtargetFeatureInfo {
@@ -43,6 +46,10 @@ struct SubtargetFeatureInfo {
     return "Feature_" + TheDef->getName().str() + "Bit";
   }
 
+  bool mustRecomputePerFunction() const {
+    return TheDef->getValueAsBit("RecomputePerFunction");
+  }
+
   void dump() const;
   static std::vector<std::pair<Record *, SubtargetFeatureInfo>>
   getAll(const RecordKeeper &Records);
@@ -52,21 +59,17 @@ struct SubtargetFeatureInfo {
   /// This version emits the bit value for the feature and is therefore limited
   /// to 64 feature bits.
   static void emitSubtargetFeatureFlagEnumeration(
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
-          &SubtargetFeatures,
-      raw_ostream &OS);
+      SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);
 
   /// Emit the subtarget feature flag definitions.
   ///
   /// This version emits the bit index for the feature and can therefore support
   /// more than 64 feature bits.
-  static void emitSubtargetFeatureBitEnumeration(
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
-          &SubtargetFeatures,
-      raw_ostream &OS);
+  static void
+  emitSubtargetFeatureBitEnumeration(SubtargetFeatureInfoMap &SubtargetFeatures,
+                                     raw_ostream &OS);
 
-  static void emitNameTable(std::map<Record *, SubtargetFeatureInfo,
-                                     LessRecordByID> &SubtargetFeatures,
+  static void emitNameTable(SubtargetFeatureInfoMap &SubtargetFeatures,
                             raw_ostream &OS);
 
   /// Emit the function to compute the list of available features given a
@@ -82,11 +85,12 @@ struct SubtargetFeatureInfo {
   /// \param FuncName   The name of the function to emit.
   /// \param SubtargetFeatures A map of TableGen records to the
   ///                          SubtargetFeatureInfo equivalent.
-  static void emitComputeAvailableFeatures(
-      StringRef TargetName, StringRef ClassName, StringRef FuncName,
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
-          &SubtargetFeatures,
-      raw_ostream &OS);
+  /// \param ExtraParams Additional arguments to the generated function.
+  static void
+  emitComputeAvailableFeatures(StringRef TargetName, StringRef ClassName,
+                               StringRef FuncName,
+                               SubtargetFeatureInfoMap &SubtargetFeatures,
+                               raw_ostream &OS, StringRef ExtraParams = "");
 
   /// Emit the function to compute the list of available features given a
   /// subtarget.
@@ -103,9 +107,7 @@ struct SubtargetFeatureInfo {
   ///                          SubtargetFeatureInfo equivalent.
   static void emitComputeAssemblerAvailableFeatures(
       StringRef TargetName, StringRef ClassName, StringRef FuncName,
-      std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
-          &SubtargetFeatures,
-      raw_ostream &OS);
+      SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);
 };
 } // end namespace llvm
 




More information about the llvm-commits mailing list