implement __builtin_expect, fix _Bool in ast2firm, improve declaration counting ...
authorMatthias Braun <matze@braunis.de>
Wed, 5 Dec 2007 17:04:42 +0000 (17:04 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 5 Dec 2007 17:04:42 +0000 (17:04 +0000)
[r18612]

ast.c
ast2firm.c
ast_t.h
parser.c

diff --git a/ast.c b/ast.c
index 08499d7..f8a1c18 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -140,6 +140,15 @@ static void print_call_expression(const call_expression_t *call)
 
 static void print_binary_expression(const binary_expression_t *binexpr)
 {
+       if(binexpr->expression.type == EXPR_BINARY_BUILTIN_EXPECT) {
+               fputs("__builtin_expect(", out);
+               print_expression(binexpr->left);
+               fputs(", ", out);
+               print_expression(binexpr->right);
+               fputs(")", out);
+               return;
+       }
+
        fprintf(out, "(");
        print_expression(binexpr->left);
        fprintf(out, " ");
@@ -812,6 +821,7 @@ bool is_constant_expression(const expression_t *expression)
        case EXPR_BINARY_LOGICAL_OR:
        case EXPR_BINARY_SHIFTLEFT:
        case EXPR_BINARY_SHIFTRIGHT:
+       case EXPR_BINARY_BUILTIN_EXPECT:
        case EXPR_BINARY_ISGREATER:
        case EXPR_BINARY_ISGREATEREQUAL:
        case EXPR_BINARY_ISLESS:
index 56757d2..9ac4b0f 100644 (file)
@@ -223,6 +223,7 @@ static void init_atomic_modes(void) {
        _atomic_modes[ATOMIC_TYPE_FLOAT]       = mode_F;
        _atomic_modes[ATOMIC_TYPE_DOUBLE]      = mode_D;
        _atomic_modes[ATOMIC_TYPE_LONG_DOUBLE] = mode_E;
+       _atomic_modes[ATOMIC_TYPE_BOOL]        = get_umode(int_size);
 
 #ifdef PROVIDE_COMPLEX
        _atomic_modes[ATOMIC_TYPE_BOOL]                  = _atomic_modes[ATOMIC_TYPE_INT];
@@ -1590,6 +1591,8 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
        case EXPR_BINARY_SHIFTLEFT_ASSIGN:
        case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
                return create_arithmetic_assign_shift(expression);
+       case EXPR_BINARY_BUILTIN_EXPECT:
+               return expression_to_firm(expression->left);
        default:
                panic("TODO binexpr type");
        }
@@ -2880,7 +2883,9 @@ static void case_label_to_firm(const case_label_statement_t *statement)
        add_immBlock_pred(block, proj);
        mature_immBlock(block);
 
-       statement_to_firm(statement->label_statement);
+       if(statement->label_statement != NULL) {
+               statement_to_firm(statement->label_statement);
+       }
 }
 
 static ir_node *get_label_block(declaration_t *label)
@@ -2916,7 +2921,9 @@ static void label_to_firm(const label_statement_t *statement)
        set_cur_block(block);
        keep_alive(block);
 
-       statement_to_firm(statement->label_statement);
+       if(statement->label_statement != NULL) {
+               statement_to_firm(statement->label_statement);
+       }
 }
 
 static void goto_to_firm(const goto_statement_t *statement)
@@ -3101,9 +3108,27 @@ static int count_local_declarations(const declaration_t *      decl,
        return count;
 }
 
-static int count_decls_in_expr(const expression_t *expr) {
-       if (expr != NULL && expr->base.type == EXPR_STATEMENT)
-               return count_decls_in_stmts(expr->statement.statement);
+static int count_decls_in_expression(const expression_t *expression) {
+       if(expression == NULL)
+               return 0;
+
+       switch(expression->base.type) {
+       case EXPR_STATEMENT:
+               return count_decls_in_stmts(expression->statement.statement);
+       EXPR_BINARY_CASES
+               return count_decls_in_expression(expression->binary.left)
+                       + count_decls_in_expression(expression->binary.right);
+       EXPR_UNARY_CASES
+               return count_decls_in_expression(expression->unary.value);
+
+       default:
+               break;
+       }
+
+       /* TODO FIXME: finish/fix that firm patch that allows dynamic value numbers
+        * (or implement all the missing expressions here/implement a walker)
+        */
+
        return 0;
 }
 
@@ -3128,7 +3153,7 @@ static int count_decls_in_stmts(const statement_t *stmt)
 
                        case STATEMENT_IF: {
                                const if_statement_t *const if_stmt = &stmt->ifs;
-                               count += count_decls_in_expr(if_stmt->condition);
+                               count += count_decls_in_expression(if_stmt->condition);
                                count += count_decls_in_stmts(if_stmt->true_statement);
                                count += count_decls_in_stmts(if_stmt->false_statement);
                                break;
@@ -3136,7 +3161,7 @@ static int count_decls_in_stmts(const statement_t *stmt)
 
                        case STATEMENT_SWITCH: {
                                const switch_statement_t *const switch_stmt = &stmt->switchs;
-                               count += count_decls_in_expr(switch_stmt->expression);
+                               count += count_decls_in_expression(switch_stmt->expression);
                                count += count_decls_in_stmts(switch_stmt->body);
                                break;
                        }
@@ -3149,14 +3174,14 @@ static int count_decls_in_stmts(const statement_t *stmt)
 
                        case STATEMENT_WHILE: {
                                const while_statement_t *const while_stmt = &stmt->whiles;
-                               count += count_decls_in_expr(while_stmt->condition);
+                               count += count_decls_in_expression(while_stmt->condition);
                                count += count_decls_in_stmts(while_stmt->body);
                                break;
                        }
 
                        case STATEMENT_DO_WHILE: {
                                const do_while_statement_t *const do_while_stmt = &stmt->do_while;
-                               count += count_decls_in_expr(do_while_stmt->condition);
+                               count += count_decls_in_expression(do_while_stmt->condition);
                                count += count_decls_in_stmts(do_while_stmt->body);
                                break;
                        }
@@ -3164,22 +3189,28 @@ static int count_decls_in_stmts(const statement_t *stmt)
                        case STATEMENT_FOR: {
                                const for_statement_t *const for_stmt = &stmt->fors;
                                count += count_local_declarations(for_stmt->context.declarations, NULL);
-                               count += count_decls_in_expr(for_stmt->initialisation);
-                               count += count_decls_in_expr(for_stmt->condition);
-                               count += count_decls_in_expr(for_stmt->step);
+                               count += count_decls_in_expression(for_stmt->initialisation);
+                               count += count_decls_in_expression(for_stmt->condition);
+                               count += count_decls_in_expression(for_stmt->step);
                                count += count_decls_in_stmts(for_stmt->body);
                                break;
                        }
 
+                       case STATEMENT_CASE_LABEL: {
+                               const case_label_statement_t *label = &stmt->case_label;
+                               count += count_decls_in_expression(label->expression);
+                               count += count_decls_in_stmts(label->label_statement);
+                               break;
+                       }
+
                        case STATEMENT_ASM:
                        case STATEMENT_BREAK:
-                       case STATEMENT_CASE_LABEL:
                        case STATEMENT_CONTINUE:
                                break;
 
                        case STATEMENT_EXPRESSION: {
                                const expression_statement_t *expr_stmt = &stmt->expression;
-                               count += count_decls_in_expr(expr_stmt->expression);
+                               count += count_decls_in_expression(expr_stmt->expression);
                                break;
                        }
 
@@ -3189,7 +3220,7 @@ static int count_decls_in_stmts(const statement_t *stmt)
 
                        case STATEMENT_RETURN: {
                                const return_statement_t *ret_stmt = &stmt->returns;
-                               count += count_decls_in_expr(ret_stmt->return_value);
+                               count += count_decls_in_expression(ret_stmt->return_value);
                                break;
                        }
                }
diff --git a/ast_t.h b/ast_t.h
index 77b6860..bbabdca 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -81,6 +81,7 @@ typedef enum {
        EXPR_BINARY_BITWISE_OR_ASSIGN,
        EXPR_BINARY_COMMA,
 
+       EXPR_BINARY_BUILTIN_EXPECT,
        EXPR_BINARY_ISGREATER,
        EXPR_BINARY_ISGREATEREQUAL,
        EXPR_BINARY_ISLESS,
@@ -122,6 +123,7 @@ typedef enum {
        case EXPR_BINARY_BITWISE_XOR_ASSIGN:   \
        case EXPR_BINARY_BITWISE_OR_ASSIGN:    \
        case EXPR_BINARY_COMMA:                \
+       case EXPR_BINARY_BUILTIN_EXPECT:       \
        case EXPR_BINARY_ISGREATER:            \
        case EXPR_BINARY_ISGREATEREQUAL:       \
        case EXPR_BINARY_ISLESS:               \
index 48ca810..18e4285 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -3413,6 +3413,24 @@ static expression_t *parse_compare_builtin(void)
        return expression;
 }
 
+static expression_t *parse_builtin_expect(void)
+{
+       eat(T___builtin_expect);
+
+       expression_t *expression
+               = allocate_expression_zero(EXPR_BINARY_BUILTIN_EXPECT);
+
+       expect('(');
+       expression->binary.left = parse_assignment_expression();
+       expect(',');
+       expression->binary.right = parse_constant_expression();
+       expect(')');
+
+       expression->base.datatype = expression->binary.left->base.datatype;
+
+       return expression;
+}
+
 static expression_t *parse_primary_expression(void)
 {
        switch(token.type) {
@@ -3437,9 +3455,10 @@ static expression_t *parse_primary_expression(void)
                return parse_va_start();
        case T___builtin_va_arg:
                return parse_va_arg();
+       case T___builtin_expect:
+               return parse_builtin_expect();
        case T___builtin_nanf:
        case T___builtin_alloca:
-       case T___builtin_expect:
        case T___builtin_va_end:
                return parse_builtin_symbol();
        case T___builtin_isgreater: