diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2018-03-19 14:44:43 +0100 |
---|---|---|
committer | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2018-03-19 14:44:43 +0100 |
commit | 443c0b3809d6942fc9745b2d016d5654b4bdfd11 (patch) | |
tree | 58800a05d53b5c28b36d7f981fa00f92db3c5bab | |
parent | f6fb9af3a84f05a60b3e84bbce8333fc03c318b4 (diff) |
INCOMPLETE TableGen: Streamline NAME resolutiontablegen-name-resolution
Change-Id: I5133fae81f090ac6a014b2ed1ed6ce6e37d2e4cb
-rw-r--r-- | include/llvm/TableGen/Record.h | 18 | ||||
-rw-r--r-- | lib/TableGen/Record.cpp | 8 | ||||
-rw-r--r-- | lib/TableGen/TGParser.cpp | 60 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrAVX512.td | 42 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrSSE.td | 24 |
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; } |