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

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Tue May 2 11:50:38 PDT 2017


Hi Daniel,

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.

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.

-eric

On Sat, Apr 29, 2017 at 10:43 AM Daniel Sanders via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> 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
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170502/a7eeb671/attachment.html>


More information about the llvm-commits mailing list