summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2018-03-19 14:44:43 +0100
committerNicolai Hähnle <nicolai.haehnle@amd.com>2018-03-19 14:44:43 +0100
commit443c0b3809d6942fc9745b2d016d5654b4bdfd11 (patch)
tree58800a05d53b5c28b36d7f981fa00f92db3c5bab
parentf6fb9af3a84f05a60b3e84bbce8333fc03c318b4 (diff)
INCOMPLETE TableGen: Streamline NAME resolutiontablegen-name-resolution
Change-Id: I5133fae81f090ac6a014b2ed1ed6ce6e37d2e4cb
-rw-r--r--include/llvm/TableGen/Record.h18
-rw-r--r--lib/TableGen/Record.cpp8
-rw-r--r--lib/TableGen/TGParser.cpp60
-rw-r--r--lib/Target/X86/X86InstrAVX512.td42
-rw-r--r--lib/Target/X86/X86InstrSSE.td24
5 files changed, 87 insertions, 65 deletions
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 3b2ebaa4af5..2b64d4d0288 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -1833,7 +1833,9 @@ class MapResolver final : public Resolver {
public:
explicit MapResolver(Record *CurRec = nullptr) : Resolver(CurRec) {}
- void set(Init *Key, Init *Value) { Map[Key] = {Value, false}; }
+ void set(Init *Key, Init *Value, bool Resolved = false) {
+ Map[Key] = {Value, Resolved};
+ }
Init *resolve(Init *VarName) override;
};
@@ -1905,6 +1907,20 @@ public:
Init *resolve(Init *VarName) override;
};
+/// Check whether an unresolved reference to a specific variable exists.
+class FindVariableResolver final : public Resolver {
+ Init *Name;
+ bool Found = false;
+
+public:
+ explicit FindVariableResolver(Init *VarName)
+ : Resolver(nullptr), Name(VarName) {}
+
+ bool found() const { return Found; }
+
+ Init *resolve(Init *VarName) override;
+};
+
} // end namespace llvm
#endif // LLVM_TABLEGEN_RECORD_H
diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp
index 30889b1e6e4..8dc9170e0b0 100644
--- a/lib/TableGen/Record.cpp
+++ b/lib/TableGen/Record.cpp
@@ -2164,7 +2164,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
/// GetNewAnonymousName - Generate a unique anonymous name that can be used as
/// an identifier.
Init *RecordKeeper::getNewAnonymousName() {
- return StringInit::get("anonymous_" + utostr(AnonCounter++));
+ return StringInit::get(".anonymous_" + utostr(AnonCounter++));
}
std::vector<Record *>
@@ -2257,3 +2257,9 @@ Init *TrackUnresolvedResolver::resolve(Init *VarName) {
FoundUnresolved = true;
return I;
}
+
+Init *FindVariableResolver::resolve(Init *VarName) {
+ if (VarName == Name)
+ Found = true;
+ return nullptr;
+}
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index e1b32d3829a..da17520e606 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -405,15 +405,6 @@ bool TGParser::addDefOne(std::unique_ptr<Record> Rec, Init *DefmName,
return false;
}
- // Name construction is an incoherent mess. Unfortunately, existing .td
- // files rely on pretty much all the quirks and implementation details of
- // this.
- if (DefmName) {
- MapResolver R(Rec.get());
- R.set(StringInit::get("NAME"), DefmName);
- Rec->resolveReferences(R);
- }
-
if (Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
if (!Rec->isAnonymous()) {
PrintError(Rec->getLoc(),
@@ -480,7 +471,19 @@ Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
if (CurMultiClass)
CurRec = &CurMultiClass->Rec;
- return ParseValue(CurRec, StringRecTy::get(), ParseNameMode);
+ Init *Name = ParseValue(CurRec, StringRecTy::get(), ParseNameMode);
+
+ if (CurMultiClass) {
+ Init *NameStr = StringInit::get("NAME");
+ FindVariableResolver R(NameStr);
+ Name->resolveReferences(R);
+ if (!R.found()) {
+ Name = BinOpInit::getStrConcat(VarInit::get(NameStr, StringRecTy::get()),
+ Name);
+ }
+ }
+
+ return Name;
}
/// ParseClassID - Parse and resolve a reference to a class name. This returns
@@ -2788,8 +2791,12 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
Init *DefmName = ParseObjectName(CurMultiClass);
if (!DefmName)
return true;
- if (isa<UnsetInit>(DefmName))
- DefmName = Records.getNewAnonymousName();
+ if (isa<UnsetInit>(DefmName)) {
+ if (!CurMultiClass)
+ DefmName = StringInit::get("");
+ else
+ DefmName = nullptr;
+ }
if (Lex.getCode() != tgtok::colon)
return TokError("expected ':' after defm identifier");
@@ -2841,39 +2848,22 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
// Loop over all the def's in the multiclass, instantiating each one.
for (const std::unique_ptr<Record> &DefProto : MC->DefPrototypes) {
- bool ResolveName = true;
auto CurRec = make_unique<Record>(*DefProto);
CurRec->appendLoc(SubClassLoc);
- if (StringInit *NameString =
- dyn_cast<StringInit>(CurRec->getNameInit())) {
- // We have a fully expanded string so there are no operators to
- // resolve. We should concatenate the given prefix and name.
- //
- // TODO: This MUST happen before template argument resolution. This
- // does not make sense and should be changed, but at the time of
- // writing, there are existing .td files which rely on this
- // implementation detail. It's a bad idea and should be fixed.
- CurRec->setName(BinOpInit::getStrConcat(DefmName, NameString));
- ResolveName = false;
- }
-
MapResolver R(CurRec.get());
- if (ResolveName) {
- // If the proto's name wasn't resolved, we probably have a reference to
- // NAME and need to replace it.
- //
- // TODO: Whether the name is resolved is basically determined by magic.
- // Unfortunately, existing .td files depend on it.
- R.set(StringInit::get("NAME"), DefmName);
- }
-
for (const auto &TArg : TemplateArgs)
R.set(TArg.first, TArg.second);
CurRec->resolveReferences(R);
+ if (DefmName) {
+ MapResolver R(CurRec.get());
+ R.set(StringInit::get("NAME"), DefmName, true);
+ CurRec->resolveReferences(R);
+ }
+
NewRecDefs.emplace_back(std::move(CurRec));
}
diff --git a/lib/Target/X86/X86InstrAVX512.td b/lib/Target/X86/X86InstrAVX512.td
index 663f2d17bfc..4826eb72532 100644
--- a/lib/Target/X86/X86InstrAVX512.td
+++ b/lib/Target/X86/X86InstrAVX512.td
@@ -1215,51 +1215,61 @@ multiclass avx512_broadcast_rm_split<bits<8> opc, string OpcodeStr,
multiclass avx512_broadcast_rm<bits<8> opc, string OpcodeStr,
SchedWrite SchedRR, SchedWrite SchedRM,
X86VectorVTInfo DestInfo,
- X86VectorVTInfo SrcInfo> :
+ X86VectorVTInfo SrcInfo, string BASENAME> :
avx512_broadcast_rm_split<opc, OpcodeStr, SchedRR, SchedRM,
- DestInfo, DestInfo, SrcInfo>;
+ DestInfo, DestInfo, SrcInfo, BASENAME>;
multiclass avx512_fp_broadcast_sd<bits<8> opc, string OpcodeStr,
- AVX512VLVectorVTInfo _> {
+ AVX512VLVectorVTInfo _, string BASENAME> {
let Predicates = [HasAVX512] in {
defm Z : avx512_broadcast_rm<opc, OpcodeStr, WriteFShuffle256,
- WriteFShuffle256Ld, _.info512, _.info128>,
- avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128>,
+ WriteFShuffle256Ld, _.info512, _.info128,
+ string BASENAME>,
+ avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128,
+ string BASENAME>,
EVEX_V512;
}
let Predicates = [HasVLX] in {
defm Z256 : avx512_broadcast_rm<opc, OpcodeStr, WriteFShuffle256,
- WriteFShuffle256Ld, _.info256, _.info128>,
- avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128>,
+ WriteFShuffle256Ld, _.info256, _.info128,
+ string BASENAME>,
+ avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128,
+ string BASENAME>,
EVEX_V256;
}
}
multiclass avx512_fp_broadcast_ss<bits<8> opc, string OpcodeStr,
- AVX512VLVectorVTInfo _> {
+ AVX512VLVectorVTInfo _, string BASENAME> {
let Predicates = [HasAVX512] in {
defm Z : avx512_broadcast_rm<opc, OpcodeStr, WriteFShuffle256,
- WriteFShuffle256Ld, _.info512, _.info128>,
- avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128>,
+ WriteFShuffle256Ld, _.info512, _.info128,
+ string BASENAME>,
+ avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128,
+ string BASENAME>,
EVEX_V512;
}
let Predicates = [HasVLX] in {
defm Z256 : avx512_broadcast_rm<opc, OpcodeStr, WriteFShuffle256,
- WriteFShuffle256Ld, _.info256, _.info128>,
- avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128>,
+ WriteFShuffle256Ld, _.info256, _.info128,
+ string BASENAME>,
+ avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128,
+ string BASENAME>,
EVEX_V256;
defm Z128 : avx512_broadcast_rm<opc, OpcodeStr, WriteFShuffle256,
- WriteFShuffle256Ld, _.info128, _.info128>,
- avx512_broadcast_scalar<opc, OpcodeStr, _.info128, _.info128>,
+ WriteFShuffle256Ld, _.info128, _.info128,
+ string BASENAME>,
+ avx512_broadcast_scalar<opc, OpcodeStr, _.info128, _.info128,
+ string BASENAME>,
EVEX_V128;
}
}
defm VBROADCASTSS : avx512_fp_broadcast_ss<0x18, "vbroadcastss",
- avx512vl_f32_info>;
+ avx512vl_f32_info, "VBROADCASTSS">;
defm VBROADCASTSD : avx512_fp_broadcast_sd<0x19, "vbroadcastsd",
- avx512vl_f64_info>, VEX_W;
+ avx512vl_f64_info, "VBROADCASTSD">, VEX_W;
def : Pat<(int_x86_avx512_vbroadcast_ss_512 addr:$src),
(VBROADCASTSSZm addr:$src)>;
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index 516504b712c..fdccc924c22 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -3141,7 +3141,7 @@ multiclass sse_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
Operand intmemop, ComplexPattern int_cpat,
Intrinsic Intr,
SDNode OpNode, Domain d, OpndItins itins,
- Predicate target, string Suffix> {
+ Predicate target> {
let hasSideEffects = 0 in {
def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1),
!strconcat(OpcodeStr, "\t{$src1, $dst|$dst, $src1}"),
@@ -3169,7 +3169,7 @@ multiclass sse_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
// These are unary operations, but they are modeled as having 2 source operands
// because the high elements of the destination are unchanged in SSE.
def : Pat<(Intr VR128:$src),
- (!cast<Instruction>(NAME#Suffix##r_Int) VR128:$src, VR128:$src)>;
+ (!cast<Instruction>(NAME#r_Int) VR128:$src, VR128:$src)>;
}
// We don't want to fold scalar loads into these instructions unless
// optimizing for size. This is because the folded instruction will have a
@@ -3180,7 +3180,7 @@ multiclass sse_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
// rcpss mem, %xmm0
let Predicates = [target, OptForSize] in {
def : Pat<(Intr int_cpat:$src2),
- (!cast<Instruction>(NAME#Suffix##m_Int)
+ (!cast<Instruction>(NAME#m_Int)
(vt (IMPLICIT_DEF)), addr:$src2)>;
}
}
@@ -3190,7 +3190,7 @@ multiclass avx_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
X86MemOperand x86memop,
Operand intmemop, ComplexPattern int_cpat,
Intrinsic Intr, SDNode OpNode, Domain d,
- OpndItins itins, Predicate target, string Suffix> {
+ OpndItins itins, Predicate target> {
let hasSideEffects = 0 in {
def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
!strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
@@ -3222,18 +3222,18 @@ multiclass avx_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
// TODO: In theory, we could fold the load, and avoid the stall caused by
// the partial register store, either in BreakFalseDeps or with smarter RA.
let Predicates = [target] in {
- def : Pat<(OpNode RC:$src), (!cast<Instruction>("V"#NAME#Suffix##r)
+ def : Pat<(OpNode RC:$src), (!cast<Instruction>(NAME#r)
(ScalarVT (IMPLICIT_DEF)), RC:$src)>;
def : Pat<(Intr VR128:$src),
- (!cast<Instruction>("V"#NAME#Suffix##r_Int) VR128:$src,
+ (!cast<Instruction>(NAME#r_Int) VR128:$src,
VR128:$src)>;
}
let Predicates = [target, OptForSize] in {
def : Pat<(Intr int_cpat:$src2),
- (!cast<Instruction>("V"#NAME#Suffix##m_Int)
+ (!cast<Instruction>(NAME#m_Int)
(vt (IMPLICIT_DEF)), addr:$src2)>;
def : Pat<(ScalarVT (OpNode (load addr:$src))),
- (!cast<Instruction>("V"#NAME#Suffix##m) (ScalarVT (IMPLICIT_DEF)),
+ (!cast<Instruction>(NAME#m) (ScalarVT (IMPLICIT_DEF)),
addr:$src)>;
}
}
@@ -3315,11 +3315,11 @@ multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
defm SS : sse_fp_unop_s<opc, OpcodeStr##ss, FR32, v4f32, f32, f32mem,
ssmem, sse_load_f32,
!cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss), OpNode,
- SSEPackedSingle, itins, UseSSE1, "SS">, XS;
+ SSEPackedSingle, itins, UseSSE1>, XS;
defm V#NAME#SS : avx_fp_unop_s<opc, "v"#OpcodeStr##ss, FR32, v4f32, f32,
f32mem, ssmem, sse_load_f32,
!cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss), OpNode,
- SSEPackedSingle, itins, AVXTarget, "SS">, XS, VEX_4V,
+ SSEPackedSingle, itins, AVXTarget>, XS, VEX_4V,
VEX_LIG, VEX_WIG, NotMemoryFoldable;
}
@@ -3328,11 +3328,11 @@ multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
defm SD : sse_fp_unop_s<opc, OpcodeStr##sd, FR64, v2f64, f64, f64mem,
sdmem, sse_load_f64,
!cast<Intrinsic>("int_x86_sse2_"##OpcodeStr##_sd),
- OpNode, SSEPackedDouble, itins, UseSSE2, "SD">, XD;
+ OpNode, SSEPackedDouble, itins, UseSSE2>, XD;
defm V#NAME#SD : avx_fp_unop_s<opc, "v"#OpcodeStr##sd, FR64, v2f64, f64,
f64mem, sdmem, sse_load_f64,
!cast<Intrinsic>("int_x86_sse2_"##OpcodeStr##_sd),
- OpNode, SSEPackedDouble, itins, AVXTarget, "SD">,
+ OpNode, SSEPackedDouble, itins, AVXTarget>,
XD, VEX_4V, VEX_LIG, VEX_WIG, NotMemoryFoldable;
}