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