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

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 17:16:57 PDT 2017


>
>
> An important aspect of this is that predicates are evaluated at the lowest
> frequency possible. Ideally, predicates should be evaluated once per module
> and retained for each function/bb/instruction but this is not always
> possible. Fortunately this is mitigated by the existence of multiple
> <Target>Subtarget instances. The target-features attribute for example
> would have required most predicates to be re-computed on a per-function
> basis if there were a single <Target>Subtarget instance but the
> implementation of getSubtargetImpl() allows us to reduce this to once per
> subtarget-instance which is nearly as good. Similarly,
> ForCodeSize/NotForCodeSize in AArch64 and
> OptForSize/OptForMinSize/OptForSpeed in X86 are examples of function-level
> predicates that can be computed once per subtarget using the same technique
> and they have been added to the key to take advantage of this. We could
> evaluate them using Function directly but this comes at the cost of having
> to re-evaluate them on a per-function basis.
>
> The only predicate that genuinely needs to be calculated on a per-function
> basis so far is NotWin64WithoutFP on X86 which needs the MachineFunction to
> determine whether the frame pointer is available.
>
> 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.
>
>
> The main cost of taking it from the Function directly is the increased
> frequency with which we need to re-evaluate the predicate. Instead of being
> once per unique subtarget, it would be once per function*. I'd expect
> per-unique subtarget to be a win in the general case because most codebases
> have a single subtarget for all functions.
>
>
I think that this is a lot of premature optimization for an area that
doesn't need it. There's no compelling use case in the change from what was
there setting it during instruction selection versus otherwise and it
complicates the definition of the subtarget in ways that don't need to
happen. In addition, you're still doing the same lookup, you're just doing
it via getSubtargetImpl on every call rather than once during instruction
selection.

-eric


> * It's actually worse than this right now, it's once per instruction.
> However, that's just a case not having fully implemented the per-function
> frequency yet.
>
> On 3 May 2017, at 00:26, Quentin Colombet <qcolombet at apple.com> wrote:
>
> Hi Daniel,
>
> We’ve talked with Eric on IRC and we agreed that this part of the patch is
> not needed for now.
>
> 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.
>
> Cheers,
> -Quentin
>
> On May 2, 2017, at 11:50 AM, Eric Christopher <echristo at gmail.com> wrote:
>
> 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/20170504/136e3532/attachment-0001.html>


More information about the llvm-commits mailing list