parser support for array types
ADD
tests/unit/array/extractvalue1.opt
+Name: constant-folding-1
+%r = extractvalue [2 x i4] [i4 3, i4 poison], 0
+ =>
+%r = 3
+
+
+Name: constant-folding-2
+%r = extractvalue [4 x i64] [i64 3, i64 poison, i64 8, i64 16], 3
+ =>
+%r = 16
+
+
+Name: constant-folding-3
+%r = extractvalue [2 x i4] [i4 3, i4 undef], 1
+ =>
+%r = 5
+
+
+Name: constant-folding-4
+%r = extractvalue [2 x i4] [i4 3, i4 poison], 1
+ =>
+%r = 5
+
+
+Name: constant-folding-5
+%r = extractvalue [2 x float] [float 3.0, float 4.0], 0
+ =>
+%r = 3.0

MODIFY
tools/alive_lexer.re
tools/alive_lexer.re
@@ -110,6 +110,11 @@ space+ {
return VECTOR_TYPE_PREFIX;
}
+"[" space* @tag1 [0-9]+ space* "x" {
+ yylval.num = strtoull((char*)tag1, nullptr, 10);
+ return ARRAY_TYPE_PREFIX;
+}
+
[-+]? [0-9]* "." [0-9]+ ([eE] [-+]? [0-9]+)? {
yylval.fp_num = strtod((char*)YYTEXT, nullptr);
return FP_NUM;
@@ -177,6 +182,8 @@ space+ {
"<" { return CSLT; }
">u" { return CUGT; }
"<u" { return CULT; }
+"]" { return RSQBRACKET; }
+"[" { return LSQBRACKET; }
"true" { return TRUE; }
"false" { return FALSE; }

MODIFY
tools/alive_parser.cpp
tools/alive_parser.cpp
@@ -130,7 +130,7 @@ struct tokenizer_t {
bool isType() {
// TODO: support other aggregate types
- return isScalarType() || isVectorType();
+ return isScalarType() || isVectorType() || isArrayType();
}
bool isScalarType() {
@@ -142,6 +142,10 @@ struct tokenizer_t {
return peek() == VECTOR_TYPE_PREFIX;
}
+ bool isArrayType() {
+ return peek() == ARRAY_TYPE_PREFIX;
+ }
+
private:
token get_new_token() const {
try {
@@ -318,6 +322,8 @@ static Type& get_pointer_type(unsigned address_space_number) {
static unsigned vector_num;
static vector<unique_ptr<VectorType>> vector_types;
+static unsigned array_num;
+static vector<unique_ptr<ArrayType>> array_types;
static Type& parse_scalar_type() {
switch (*tokenizer) {
@@ -356,11 +362,17 @@ static Type& parse_vector_type() {
elements, elemTy)).get();
}
+static Type& parse_array_type();
+
static Type& parse_type(bool optional = true) {
if (tokenizer.isScalarType()) {
return parse_scalar_type();
}
+ if (tokenizer.isArrayType()) {
+ return parse_array_type();
+ }
+
if (tokenizer.isVectorType()) {
return parse_vector_type();
}
@@ -373,6 +385,17 @@ static Type& parse_type(bool optional = true) {
UNREACHABLE();
}
+static Type& parse_array_type() {
+ tokenizer.ensure(ARRAY_TYPE_PREFIX);
+ unsigned elements = yylval.num;
+
+ Type &elemTy = parse_type(false);
+ tokenizer.ensure(RSQBRACKET);
+ return *array_types.emplace_back(
+ make_unique<ArrayType>("aty_" + to_string(array_num++),
+ elements, elemTy)).get();
+}
+
static Type& try_parse_type(Type &default_type) {
if (tokenizer.isType())
return parse_type();
@@ -475,7 +498,7 @@ static Value& get_or_copy_instr(const string &name) {
return *ret;
}
-static Value& parse_vector_constant(Type &type) {
+static Value& parse_aggregate_constant(Type &type) {
std::vector<Value*> vals;
do {
Type &elemTy = parse_scalar_type();
@@ -483,7 +506,10 @@ static Value& parse_vector_constant(Type &type) {
vals.emplace_back(elem);
} while (tokenizer.consumeIf(COMMA));
- tokenizer.ensure(CSGT);
+ auto closingTk = *tokenizer;
+ if (closingTk != CSGT && closingTk != RSQBRACKET)
+ error(string("expected token: ") + token_name[CSGT] + " or " +
+ token_name[RSQBRACKET] + ", got: " + token_name[closingTk]);
auto c = make_unique<AggregateValue>(type, move(vals));
auto ret = c.get();
@@ -500,7 +526,8 @@ static Value& parse_operand(Type &type) {
case NUM_STR:
return get_num_constant(yylval.str, type);
case CSLT:
- return parse_vector_constant(type);
+ case LSQBRACKET:
+ return parse_aggregate_constant(type);
case TRUE:
return get_constant(1, type);
case FALSE:
@@ -1022,6 +1049,7 @@ static unique_ptr<Instr> parse_instr(string_view name) {
case UNDEF:
case POISON:
case REGISTER:
+ case ARRAY_TYPE_PREFIX:
return parse_copyop(name, t);
default:
tokenizer.unget(t);

MODIFY
tools/tokens.h
tools/tokens.h
TOKEN(END)
TOKEN(ADD)
TOKEN(AND)
+TOKEN(ARRAY_TYPE_PREFIX)
TOKEN(ARROW)
TOKEN(ASHR)
TOKEN(BAND)
@@ -50,10 +51,12 @@ TOKEN(HALF)
TOKEN(ICMP)
TOKEN(IDENTIFIER)
TOKEN(INSERTELEMENT)
+TOKEN(INSERTVALUE)
TOKEN(INT_TYPE)
TOKEN(LABEL)
TOKEN(LPAREN)
TOKEN(LSHR)
+TOKEN(LSQBRACKET)
TOKEN(MUL)
TOKEN(MALLOC)
TOKEN(NAME)
@@ -80,6 +83,7 @@ TOKEN(PTRTOINT)
TOKEN(REGISTER)
TOKEN(RETURN)
TOKEN(RPAREN)
+TOKEN(RSQBRACKET)
TOKEN(SADD_OVERFLOW)
TOKEN(SADD_SAT)
TOKEN(SDIV)

parser support for array types (#218)