llvm.org GIT mirror llvm / d80222a
[tablegen] Add !listconcat operator with the similar semantics as !strconcat Summary: It concatenates two or more lists. In addition to the !strconcat semantics the lists must have the same element type. My overall aim is to make it easy to append to Instruction.Predicates rather than override it. This can be done by concatenating lists passed as arguments, or by concatenating lists passed in additional fields. Reviewers: dsanders Reviewed By: dsanders Subscribers: hfinkel, llvm-commits Differential Revision: http://reviews.llvm.org/D3506 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208183 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 5 years ago
8 changed file(s) with 63 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
158158 a dag value. The first element is required to be a record definition, the
159159 remaining elements in the list may be arbitrary other values, including
160160 nested ```dag``' values.
161
162 ``!listconcat(a, b, ...)``
163 A list value that is the result of concatenating the 'a' and 'b' lists.
164 The lists must have the same element type.
165 More than two arguments are accepted with the result being the concatenation
166 of all the lists given.
161167
162168 ``!strconcat(a, b, ...)``
163169 A string value that is the result of concatenating the 'a' and 'b' strings.
9292 BangOperator: one of
9393 :!eq !if !head !tail !con
9494 :!add !shl !sra !srl
95 :!cast !empty !subst !foreach !strconcat
95 :!cast !empty !subst !foreach !listconcat !strconcat
9696
9797 Syntax
9898 ======
928928 ///
929929 class BinOpInit : public OpInit {
930930 public:
931 enum BinaryOp { ADD, SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
931 enum BinaryOp { ADD, SHL, SRA, SRL, LISTCONCAT, STRCONCAT, CONCAT, EQ };
932
932933 private:
933934 BinaryOp Opc;
934935 Init *LHS, *RHS;
917917 }
918918 break;
919919 }
920 case LISTCONCAT: {
921 ListInit *LHSs = dyn_cast(LHS);
922 ListInit *RHSs = dyn_cast(RHS);
923 if (LHSs && RHSs) {
924 std::vector Args;
925 Args.insert(Args.end(), LHSs->begin(), LHSs->end());
926 Args.insert(Args.end(), RHSs->begin(), RHSs->end());
927 return ListInit::get(
928 Args, static_cast(LHSs->getType())->getElementType());
929 }
930 break;
931 }
920932 case STRCONCAT: {
921933 StringInit *LHSs = dyn_cast(LHS);
922934 StringInit *RHSs = dyn_cast(RHS);
986998 case SRA: Result = "!sra"; break;
987999 case SRL: Result = "!srl"; break;
9881000 case EQ: Result = "!eq"; break;
1001 case LISTCONCAT: Result = "!listconcat"; break;
9891002 case STRCONCAT: Result = "!strconcat"; break;
9901003 }
9911004 return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
477477 .Case("empty", tgtok::XEmpty)
478478 .Case("subst", tgtok::XSubst)
479479 .Case("foreach", tgtok::XForEach)
480 .Case("listconcat", tgtok::XListConcat)
480481 .Case("strconcat", tgtok::XStrConcat)
481482 .Default(tgtok::Error);
482483
4646 MultiClass, String,
4747
4848 // !keywords.
49 XConcat, XADD, XSRA, XSRL, XSHL, XStrConcat, XCast, XSubst,
49 XConcat, XADD, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, XSubst,
5050 XForEach, XHead, XTail, XEmpty, XIf, XEq,
5151
5252 // Integer value.
902902 case tgtok::XSRL:
903903 case tgtok::XSHL:
904904 case tgtok::XEq:
905 case tgtok::XListConcat:
905906 case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')'
906907 tgtok::TokKind OpTok = Lex.getCode();
907908 SMLoc OpLoc = Lex.getLoc();
918919 case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break;
919920 case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break;
920921 case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break;
922 case tgtok::XListConcat:
923 Code = BinOpInit::LISTCONCAT;
924 // We don't know the list type until we parse the first argument
925 break;
921926 case tgtok::XStrConcat:
922927 Code = BinOpInit::STRCONCAT;
923928 Type = StringRecTy::get();
948953 }
949954 Lex.Lex(); // eat the ')'
950955
956 // If we are doing !listconcat, we should know the type by now
957 if (OpTok == tgtok::XListConcat) {
958 if (VarInit *Arg0 = dyn_cast(InitList[0]))
959 Type = Arg0->getType();
960 else if (ListInit *Arg0 = dyn_cast(InitList[0]))
961 Type = Arg0->getType();
962 else {
963 InitList[0]->dump();
964 Error(OpLoc, "expected a list");
965 return nullptr;
966 }
967 }
968
951969 // We allow multiple operands to associative operators like !strconcat as
952970 // shorthand for nesting them.
953 if (Code == BinOpInit::STRCONCAT) {
971 if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT) {
954972 while (InitList.size() > 2) {
955973 Init *RHS = InitList.pop_back_val();
956974 RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))
11331151 /// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
11341152 /// SimpleValue ::= SRATOK '(' Value ',' Value ')'
11351153 /// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
1154 /// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
11361155 /// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
11371156 ///
11381157 Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
14161435 case tgtok::XSRL:
14171436 case tgtok::XSHL:
14181437 case tgtok::XEq:
1438 case tgtok::XListConcat:
14191439 case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')'
14201440 case tgtok::XIf:
14211441 case tgtok::XForEach:
0 // RUN: llvm-tblgen %s | FileCheck %s
1
2 // CHECK: class Y Y:S = ?> {
3 // CHECK: list T1 = !listconcat(Y:S, ["foo"]);
4 // CHECK: list T2 = !listconcat(Y:S, !listconcat(["foo"], !listconcat(Y:S, ["bar", "baz"])));
5 // CHECK: }
6
7 // CHECK: def Z {
8 // CHECK: list T1 = ["fu", "foo"];
9 // CHECK: list T2 = ["fu", "foo", "fu", "bar", "baz"];
10 // CHECK: }
11
12 class Y S> {
13 list T1 = !listconcat(S, ["foo"]);
14 list T2 = !listconcat(S, ["foo"], S, ["bar", "baz"]);
15 }
16
17 def Z : Y<["fu"]>;