fix builting expect handling and implement taking address of builtin functions (produ...
authorMatthias Braun <matze@braunis.de>
Thu, 27 Nov 2008 09:43:04 +0000 (09:43 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 27 Nov 2008 09:43:04 +0000 (09:43 +0000)
[r24037]

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

diff --git a/ast.c b/ast.c
index 747d042..e68aa1c 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -168,7 +168,6 @@ static unsigned get_expression_precedence(expression_kind_t kind)
                [EXPR_BINARY_BITWISE_OR_ASSIGN]  = PREC_ASSIGNMENT,
                [EXPR_BINARY_COMMA]              = PREC_EXPRESSION,
 
-               [EXPR_BINARY_BUILTIN_EXPECT]     = PREC_PRIMARY,
                [EXPR_BINARY_ISGREATER]          = PREC_PRIMARY,
                [EXPR_BINARY_ISGREATEREQUAL]     = PREC_PRIMARY,
                [EXPR_BINARY_ISLESS]             = PREC_PRIMARY,
@@ -418,15 +417,6 @@ static void print_binary_expression(const binary_expression_t *binexpr)
        unsigned prec = get_expression_precedence(binexpr->base.kind);
        int      r2l  = right_to_left(prec);
 
-       if (binexpr->base.kind == EXPR_BINARY_BUILTIN_EXPECT) {
-               fputs("__builtin_expect(", out);
-               print_expression_prec(binexpr->left, prec);
-               fputs(", ", out);
-               print_expression_prec(binexpr->right, prec);
-               fputc(')', out);
-               return;
-       }
-
        print_expression_prec(binexpr->left, prec + r2l);
        char const* op;
        switch (binexpr->base.kind) {
@@ -1949,7 +1939,6 @@ 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 d6b8ad9..9bf9cae 100644 (file)
@@ -1592,6 +1592,10 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                ir_node *res  = new_d_Const(dbgi, mode, tv);
                return res;
        }
+       case T___builtin_expect: {
+               expression_t *argument = call->arguments->expression;
+               return _expression_to_firm(argument);
+       }
        case T___builtin_va_end:
                return NULL;
        default:
@@ -2484,8 +2488,6 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
        case EXPR_BINARY_SHIFTLEFT_ASSIGN:
        case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
                return create_assign_binop(expression);
-       case EXPR_BINARY_BUILTIN_EXPECT:
-               return _expression_to_firm(expression->left);
        default:
                panic("TODO binexpr type");
        }
@@ -3075,6 +3077,24 @@ static ir_node *label_address_to_firm(
        return new_SymConst(mode_P_code, value, symconst_label);
 }
 
+static ir_node *builtin_symbol_to_firm(
+               const builtin_symbol_expression_t *expression)
+{
+       /* for gcc compatibility we have to produce (dummy) addresses for some
+        * builtins */
+       if (warning.other) {
+               warningf(&expression->base.source_position,
+                                "taking address of builtin '%Y'", expression->symbol);
+       }
+
+       /* simply create a NULL pointer */
+       ir_mode  *mode = get_ir_mode(type_void_ptr);
+       tarval   *tv   = new_tarval_from_long(0, mode);
+       ir_node  *res  = new_Const(mode, tv);
+
+       return res;
+}
+
 /**
  * creates firm nodes for an expression. The difference between this function
  * and expression_to_firm is, that this version might produce mode_b nodes
@@ -3131,7 +3151,7 @@ static ir_node *_expression_to_firm(const expression_t *expression)
        case EXPR_VA_ARG:
                return va_arg_expression_to_firm(&expression->va_arge);
        case EXPR_BUILTIN_SYMBOL:
-               panic("unimplemented expression found");
+               return builtin_symbol_to_firm(&expression->builtin_symbol);
        case EXPR_BUILTIN_CONSTANT_P:
                return builtin_constant_to_firm(&expression->builtin_constant);
        case EXPR_BUILTIN_PREFETCH:
@@ -3150,6 +3170,20 @@ static ir_node *_expression_to_firm(const expression_t *expression)
        panic("invalid expression found");
 }
 
+static bool is_builtin_expect(const expression_t *expression)
+{
+       if (expression->kind != EXPR_CALL)
+               return false;
+
+       expression_t *function = expression->call.function;
+       if (function->kind != EXPR_BUILTIN_SYMBOL)
+               return false;
+       if (function->builtin_symbol.symbol->ID != T___builtin_expect)
+               return false;
+
+       return true;
+}
+
 static bool produces_mode_b(const expression_t *expression)
 {
        switch (expression->kind) {
@@ -3168,8 +3202,12 @@ static bool produces_mode_b(const expression_t *expression)
        case EXPR_UNARY_NOT:
                return true;
 
-       case EXPR_BINARY_BUILTIN_EXPECT:
-               return produces_mode_b(expression->binary.left);
+       case EXPR_CALL:
+               if (is_builtin_expect(expression)) {
+                       expression_t *argument = expression->call.arguments->expression;
+                       return produces_mode_b(argument);
+               }
+               return false;
        case EXPR_BINARY_COMMA:
                return produces_mode_b(expression->binary.right);
 
@@ -3257,16 +3295,19 @@ static ir_node *create_condition_evaluation(const expression_t *expression,
        ir_node  *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
 
        /* set branch prediction info based on __builtin_expect */
-       if (expression->kind == EXPR_BINARY_BUILTIN_EXPECT) {
-               long               cnst = fold_constant(expression->binary.right);
-               cond_jmp_predicate pred;
-
-               if (cnst == 0) {
-                       pred = COND_JMP_PRED_FALSE;
-               } else {
-                       pred = COND_JMP_PRED_TRUE;
+       if (is_builtin_expect(expression)) {
+               call_argument_t *argument = expression->call.arguments->next;
+               if (is_constant_expression(argument->expression)) {
+                       long               cnst = fold_constant(argument->expression);
+                       cond_jmp_predicate pred;
+
+                       if (cnst == 0) {
+                               pred = COND_JMP_PRED_FALSE;
+                       } else {
+                               pred = COND_JMP_PRED_TRUE;
+                       }
+                       set_Cond_jmp_pred(cond, pred);
                }
-               set_Cond_jmp_pred(cond, pred);
        }
 
        add_immBlock_pred(true_block, true_proj);
diff --git a/ast_t.h b/ast_t.h
index 332cc85..c0955ab 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -141,7 +141,6 @@ typedef enum expression_kind_t {
        EXPR_BINARY_BITWISE_OR_ASSIGN,
        EXPR_BINARY_COMMA,
 
-       EXPR_BINARY_BUILTIN_EXPECT,
        EXPR_BINARY_ISGREATER,
        EXPR_BINARY_ISGREATEREQUAL,
        EXPR_BINARY_ISLESS,
@@ -190,7 +189,6 @@ typedef enum funcname_kind_t {
        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 6b2e048..0eccfe0 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -2128,7 +2128,6 @@ unary:
                case EXPR_OFFSETOF:
                case EXPR_STATEMENT: // TODO
                case EXPR_LABEL_ADDRESS:
-               case EXPR_BINARY_BUILTIN_EXPECT:
                case EXPR_REFERENCE_ENUM_VALUE:
                        return;
        }
@@ -9221,7 +9220,6 @@ static bool expression_has_effect(const expression_t *const expr)
                case EXPR_BINARY_COMMA:
                        return expression_has_effect(expr->binary.right);
 
-               case EXPR_BINARY_BUILTIN_EXPECT:     return true;
                case EXPR_BINARY_ISGREATER:          return false;
                case EXPR_BINARY_ISGREATEREQUAL:     return false;
                case EXPR_BINARY_ISLESS:             return false;