Skip to content

Commit

Permalink
TableGen: Add !size operation
Browse files Browse the repository at this point in the history
Summary:
Returns the size of a list. I have found this to be rather useful in some
development for the AMDGPU backend where we could simplify our .td files
by concatenating list<LLVMType> for complex intrinsics. Doing so requires
us to compute the position argument for LLVMMatchType.

Basically, the usage is in a pattern that looks somewhat like this:

    list<LLVMType> argtypes =
        !listconcat(base,
                    [llvm_any_ty, LLVMMatchType<!size(base)>]);

Change-Id: I360a0b000fd488d18bea412228230fd93722bd2c

Reviewers: arsenm, craig.topper, tra, MartinO

Subscribers: wdng, llvm-commits, tpr

Differential Revision: https://reviews.llvm.org/D43553

llvm-svn: 325883
  • Loading branch information
nhaehnle committed Feb 23, 2018
1 parent 6cf306d commit 0243aaf
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 4 deletions.
3 changes: 3 additions & 0 deletions llvm/docs/TableGen/LangIntro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ supported include:
``!empty(a)``
An integer {0,1} indicating whether list 'a' is empty.

``!size(a)``
An integer indicating the number of elements in list 'a'.

``!if(a,b,c)``
'b' if the result of 'int' or 'bit' operator 'a' is nonzero, 'c' otherwise.

Expand Down
2 changes: 1 addition & 1 deletion llvm/docs/TableGen/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ wide variety of meanings:
:!eq !if !head !tail !con
:!add !shl !sra !srl !and
:!or !empty !subst !foreach !strconcat
:!cast !listconcat
:!cast !listconcat !size


Syntax
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/TableGen/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ class OpInit : public TypedInit {
///
class UnOpInit : public OpInit, public FoldingSetNode {
public:
enum UnaryOp : uint8_t { CAST, HEAD, TAIL, EMPTY };
enum UnaryOp : uint8_t { CAST, HEAD, TAIL, SIZE, EMPTY };

private:
Init *LHS;
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/TableGen/Record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,11 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
}
break;

case SIZE:
if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
return IntInit::get(LHSl->size());
break;

case EMPTY:
if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
return IntInit::get(LHSl->empty());
Expand All @@ -746,6 +751,7 @@ std::string UnOpInit::getAsString() const {
case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
case HEAD: Result = "!head"; break;
case TAIL: Result = "!tail"; break;
case SIZE: Result = "!size"; break;
case EMPTY: Result = "!empty"; break;
}
return Result + "(" + LHS->getAsString() + ")";
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/TableGen/TGLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("if", tgtok::XIf)
.Case("head", tgtok::XHead)
.Case("tail", tgtok::XTail)
.Case("size", tgtok::XSize)
.Case("con", tgtok::XConcat)
.Case("add", tgtok::XADD)
.Case("and", tgtok::XAND)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/TableGen/TGLexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace tgtok {

// !keywords.
XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast,
XSubst, XForEach, XHead, XTail, XEmpty, XIf, XEq,
XSubst, XForEach, XHead, XTail, XSize, XEmpty, XIf, XEq,

// Integer value.
IntVal,
Expand Down
12 changes: 11 additions & 1 deletion llvm/lib/TableGen/TGParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
return nullptr;
case tgtok::XHead:
case tgtok::XTail:
case tgtok::XSize:
case tgtok::XEmpty:
case tgtok::XCast: { // Value ::= !unop '(' Value ')'
UnOpInit::UnaryOp Code;
Expand Down Expand Up @@ -808,6 +809,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
Lex.Lex(); // eat the operation
Code = UnOpInit::TAIL;
break;
case tgtok::XSize:
Lex.Lex();
Code = UnOpInit::SIZE;
Type = IntRecTy::get();
break;
case tgtok::XEmpty:
Lex.Lex(); // eat the operation
Code = UnOpInit::EMPTY;
Expand Down Expand Up @@ -842,12 +848,15 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
}
}

if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) {
if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL ||
Code == UnOpInit::SIZE) {
if (!LHSl && !LHSt) {
TokError("expected list type argument in unary operator");
return nullptr;
}
}

if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) {
if (LHSl && LHSl->empty()) {
TokError("empty list argument in unary operator");
return nullptr;
Expand Down Expand Up @@ -1453,6 +1462,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,

case tgtok::XHead:
case tgtok::XTail:
case tgtok::XSize:
case tgtok::XEmpty:
case tgtok::XCast: // Value ::= !unop '(' Value ')'
case tgtok::XConcat:
Expand Down
34 changes: 34 additions & 0 deletions llvm/test/TableGen/size.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// RUN: llvm-tblgen %s | FileCheck %s
// XFAIL: vg_leak

// CHECK: --- Defs ---

// CHECK: def A1 {
// CHECK: int Val = 0;
// CHECK: }

// CHECK: def A2 {
// CHECK: int Val = 3;
// CHECK: }

// CHECK: def B1 {
// CHECK: int Val = 0;
// CHECK: }

// CHECK: def B2 {
// CHECK: int Val = 2;
// CHECK: }

class A<list<int> L> {
int Val = !size(L);
}

class B<list<string> L> {
int Val = !size(L);
}

def A1 : A<[]>;
def A2 : A<[1, 1, 2]>;

def B1 : B<[]>;
def B2 : B<["a", "b"]>;

0 comments on commit 0243aaf

Please sign in to comment.