- implemented __builtin_prefetch()
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sun, 21 Dec 2008 14:54:46 +0000 (14:54 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sun, 21 Dec 2008 14:54:46 +0000 (14:54 +0000)
- __builtin_prefetch is now a builtin_symbol

[r24836]

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

diff --git a/ast.c b/ast.c
index b893bd3..1deb7bf 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -117,7 +117,6 @@ static unsigned get_expression_precedence(expression_kind_t kind)
                [EXPR_BUILTIN_SYMBOL]             = PREC_PRIMARY,
                [EXPR_BUILTIN_CONSTANT_P]         = PREC_PRIMARY,
                [EXPR_BUILTIN_TYPES_COMPATIBLE_P] = PREC_PRIMARY,
-               [EXPR_BUILTIN_PREFETCH]           = PREC_PRIMARY,
                [EXPR_OFFSETOF]                   = PREC_PRIMARY,
                [EXPR_VA_START]                   = PREC_PRIMARY,
                [EXPR_VA_ARG]                     = PREC_PRIMARY,
@@ -622,26 +621,6 @@ static void print_builtin_types_compatible(
        fputc(')', out);
 }
 
-/**
- * Prints a builtin prefetch expression.
- *
- * @param expression   the builtin prefetch expression
- */
-static void print_builtin_prefetch(const builtin_prefetch_expression_t *expression)
-{
-       fputs("__builtin_prefetch(", out);
-       print_assignment_expression(expression->adr);
-       if (expression->rw) {
-               fputc(',', out);
-               print_assignment_expression(expression->rw);
-       }
-       if (expression->locality) {
-               fputc(',', out);
-               print_assignment_expression(expression->locality);
-       }
-       fputc(')', out);
-}
-
 /**
  * Prints a conditional expression.
  *
@@ -842,9 +821,6 @@ static void print_expression_prec(const expression_t *expression, unsigned top_p
        case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
                print_builtin_types_compatible(&expression->builtin_types_compatible);
                break;
-       case EXPR_BUILTIN_PREFETCH:
-               print_builtin_prefetch(&expression->builtin_prefetch);
-               break;
        case EXPR_CONDITIONAL:
                print_conditional(&expression->conditional);
                break;
@@ -1884,7 +1860,6 @@ bool is_constant_expression(const expression_t *expression)
        }
 
        case EXPR_BUILTIN_SYMBOL:
-       case EXPR_BUILTIN_PREFETCH:
        case EXPR_SELECT:
        case EXPR_VA_START:
        case EXPR_VA_ARG:
diff --git a/ast.h b/ast.h
index 6ad6d84..bf200b2 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -51,7 +51,6 @@ typedef struct va_arg_expression_t                   va_arg_expression_t;
 typedef struct builtin_symbol_expression_t           builtin_symbol_expression_t;
 typedef struct builtin_constant_expression_t         builtin_constant_expression_t;
 typedef struct builtin_types_compatible_expression_t builtin_types_compatible_expression_t;
-typedef struct builtin_prefetch_expression_t         builtin_prefetch_expression_t;
 typedef struct classify_type_expression_t            classify_type_expression_t;
 typedef struct bitfield_extract_expression_t         bitfield_extract_expression_t;
 typedef struct label_address_expression_t            label_address_expression_t;
index c4edb5e..8865424 100644 (file)
@@ -1674,7 +1674,33 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_return_address, 2, in, tp);
                return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
        }
+       case T___builtin_prefetch: {
+               call_argument_t *const args = call->arguments;
+               expression_t *const addr    = args->expression;
+               ir_node *in[3];
 
+               in[0] = _expression_to_firm(addr);
+               if (args->next != NULL) {
+                       expression_t *const rw = args->next->expression;
+
+                       in[1] = _expression_to_firm(rw);
+
+                       if (args->next->next != NULL) {
+                               expression_t *const locality = args->next->next->expression;
+
+                               in[2] = _expression_to_firm(locality);
+                       } else {
+                               in[2] = new_Const_long(mode_int, 3);
+                       }
+               } else {
+                       in[1] = new_Const_long(mode_int, 0);
+                       in[2] = new_Const_long(mode_int, 3);
+               }
+               ir_type *tp  = get_ir_type((type_t*) function_type);
+               ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_prefetch, 3, in, tp);
+               set_store(new_Proj(irn, mode_M, pn_Builtin_M));
+               return NULL;
+       }
        default:
                panic("unsupported builtin found");
        }
@@ -3192,15 +3218,6 @@ static ir_node *builtin_types_compatible_to_firm(
        return new_Const_long(mode, value);
 }
 
-static ir_node *builtin_prefetch_to_firm(
-               const builtin_prefetch_expression_t *expression)
-{
-       ir_node *adr = expression_to_firm(expression->adr);
-       /* no Firm support for prefetch yet */
-       (void) adr;
-       return NULL;
-}
-
 static ir_node *get_label_block(label_t *label)
 {
        if (label->block != NULL)
@@ -3318,8 +3335,6 @@ static ir_node *_expression_to_firm(const expression_t *expression)
                return builtin_constant_to_firm(&expression->builtin_constant);
        case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
                return builtin_types_compatible_to_firm(&expression->builtin_types_compatible);
-       case EXPR_BUILTIN_PREFETCH:
-               return builtin_prefetch_to_firm(&expression->builtin_prefetch);
        case EXPR_OFFSETOF:
                return offsetof_to_firm(&expression->offsetofe);
        case EXPR_COMPOUND_LITERAL:
diff --git a/ast_t.h b/ast_t.h
index b859b2a..0a98d02 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -84,7 +84,6 @@ typedef enum expression_kind_t {
        EXPR_BUILTIN_SYMBOL,
        EXPR_BUILTIN_CONSTANT_P,
        EXPR_BUILTIN_TYPES_COMPATIBLE_P,
-       EXPR_BUILTIN_PREFETCH,
        EXPR_OFFSETOF,
        EXPR_VA_START,
        EXPR_VA_ARG,
@@ -290,13 +289,6 @@ struct builtin_types_compatible_expression_t {
        type_t            *right;
 };
 
-struct builtin_prefetch_expression_t {
-       expression_base_t  base;
-       expression_t      *adr;
-       expression_t      *rw;
-       expression_t      *locality;
-};
-
 struct reference_expression_t {
        expression_base_t  base;
        entity_t          *entity;
@@ -400,7 +392,6 @@ union expression_t {
        builtin_symbol_expression_t           builtin_symbol;
        builtin_constant_expression_t         builtin_constant;
        builtin_types_compatible_expression_t builtin_types_compatible;
-       builtin_prefetch_expression_t         builtin_prefetch;
        reference_expression_t                reference;
        call_expression_t                     call;
        unary_expression_t                    unary;
index 9d586b7..680d21c 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -431,7 +431,6 @@ static size_t get_expression_struct_size(expression_kind_t kind)
                [EXPR_BUILTIN_SYMBOL]             = sizeof(builtin_symbol_expression_t),
                [EXPR_BUILTIN_CONSTANT_P]         = sizeof(builtin_constant_expression_t),
                [EXPR_BUILTIN_TYPES_COMPATIBLE_P] = sizeof(builtin_types_compatible_expression_t),
-               [EXPR_BUILTIN_PREFETCH]           = sizeof(builtin_prefetch_expression_t),
                [EXPR_OFFSETOF]                   = sizeof(offsetof_expression_t),
                [EXPR_VA_START]                   = sizeof(va_start_expression_t),
                [EXPR_VA_ARG]                     = sizeof(va_arg_expression_t),
@@ -2141,7 +2140,6 @@ unary:
                case EXPR_BUILTIN_SYMBOL:
                case EXPR_BUILTIN_CONSTANT_P:
                case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
-               case EXPR_BUILTIN_PREFETCH:
                case EXPR_OFFSETOF:
                case EXPR_STATEMENT: // TODO
                case EXPR_LABEL_ADDRESS:
@@ -5752,7 +5750,6 @@ static bool expression_returns(expression_t const *const expr)
                case EXPR_BUILTIN_SYMBOL:
                case EXPR_BUILTIN_CONSTANT_P:
                case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
-               case EXPR_BUILTIN_PREFETCH:
                case EXPR_OFFSETOF:
                case EXPR_INVALID:
                        return true;
@@ -6908,6 +6905,19 @@ static type_t *make_function_1_type(type_t *return_type, type_t *argument_type)
        return identify_new_type(type);
 }
 
+static type_t *make_function_1_type_variadic(type_t *return_type, type_t *argument_type)
+{
+       type_t *res = make_function_1_type(return_type, argument_type);
+       res->function.variadic = 1;
+       return res;
+}
+
+/**
+ * Creates a return_type (func)(void) function type if not
+ * already exists.
+ *
+ * @param return_type    the return type
+ */
 static type_t *make_function_0_type(type_t *return_type)
 {
        type_t *type               = allocate_type_zero(TYPE_FUNCTION);
@@ -6948,6 +6958,8 @@ static type_t *get_builtin_symbol_type(symbol_t *symbol)
        case T___builtin_return_address:
        case T___builtin_frame_address:
                return make_function_1_type(type_void_ptr, type_unsigned_int);
+       case T___builtin_prefetch:
+               return make_function_1_type_variadic(type_float, type_void_ptr);
        default:
                internal_errorf(HERE, "not implemented builtin identifier found");
        }
@@ -7574,35 +7586,6 @@ end_error:
        return create_invalid_expression();
 }
 
-/**
- * Parses a __builtin_prefetch() expression.
- */
-static expression_t *parse_builtin_prefetch(void)
-{
-       expression_t *expression = allocate_expression_zero(EXPR_BUILTIN_PREFETCH);
-
-       eat(T___builtin_prefetch);
-
-       expect('(', end_error);
-       add_anchor_token(')');
-       expression->builtin_prefetch.adr = parse_assignment_expression();
-       if (token.type == ',') {
-               next_token();
-               expression->builtin_prefetch.rw = parse_assignment_expression();
-       }
-       if (token.type == ',') {
-               next_token();
-               expression->builtin_prefetch.locality = parse_assignment_expression();
-       }
-       rem_anchor_token(')');
-       expect(')', end_error);
-       expression->base.type = type_void;
-
-       return expression;
-end_error:
-       return create_invalid_expression();
-}
-
 /**
  * Parses a __builtin_is_*() compare expression.
  */
@@ -7843,7 +7826,8 @@ static expression_t *parse_primary_expression(void)
                case T___builtin_huge_val:
                case T___builtin_va_end:
                case T___builtin_return_address:
-               case T___builtin_frame_address:      return parse_builtin_symbol();
+               case T___builtin_frame_address:
+               case T___builtin_prefetch:           return parse_builtin_symbol();
                case T___builtin_isgreater:
                case T___builtin_isgreaterequal:
                case T___builtin_isless:
@@ -7851,7 +7835,6 @@ static expression_t *parse_primary_expression(void)
                case T___builtin_islessgreater:
                case T___builtin_isunordered:        return parse_compare_builtin();
                case T___builtin_constant_p:         return parse_builtin_constant();
-               case T___builtin_prefetch:           return parse_builtin_prefetch();
                case T___builtin_types_compatible_p: return parse_builtin_types_compatible();
                case T__assume:                      return parse_assume();
                case T_ANDAND:
@@ -8153,6 +8136,29 @@ static void handle_builtin_argument_restrictions(call_expression_t *call) {
                        }
                        break;
                }
+               case T___builtin_prefetch: {
+                       /* second and third argument must be constant if existant */
+                       call_argument_t *rw = call->arguments->next;
+                       call_argument_t *locality = NULL;
+
+                       if (rw != NULL) {
+                               if (! is_constant_expression(rw->expression)) {
+                                       errorf(&call->base.source_position,
+                                              "second argument of '%Y' must be a constant expression",
+                                              call->function->builtin_symbol.symbol);
+                               }
+                               locality = rw->next;
+                       }
+                       if (locality != NULL) {
+                               if (! is_constant_expression(locality->expression)) {
+                                       errorf(&call->base.source_position,
+                                              "third argument of '%Y' must be a constant expression",
+                                              call->function->builtin_symbol.symbol);
+                               }
+                               locality = rw->next;
+                       }
+                       break;
+               }
                default:
                        break;
        }
@@ -9400,8 +9406,9 @@ static bool expression_has_effect(const expression_t *const expr)
                                return true;
 
                        switch (call->function->builtin_symbol.symbol->ID) {
-                               case T___builtin_va_end: return true;
-                               default:                 return false;
+                               case T___builtin_prefetch:
+                               case T___builtin_va_end:   return true;
+                               default:                   return false;
                        }
                }
 
@@ -9425,7 +9432,6 @@ static bool expression_has_effect(const expression_t *const expr)
                case EXPR_BUILTIN_SYMBOL:             break; /* handled in EXPR_CALL */
                case EXPR_BUILTIN_CONSTANT_P:         return false;
                case EXPR_BUILTIN_TYPES_COMPATIBLE_P: return false;
-               case EXPR_BUILTIN_PREFETCH:           return true;
                case EXPR_OFFSETOF:                   return false;
                case EXPR_VA_START:                   return true;
                case EXPR_VA_ARG:                     return true;
index 18cf602..ff26889 100644 (file)
@@ -49,17 +49,6 @@ static void walk_expression(expression_t const *const expr,
                walk_expression(expr->conditional.false_expression, callback, env);
                return;
 
-       case EXPR_BUILTIN_PREFETCH: {
-               builtin_prefetch_expression_t const *const pf = &expr->builtin_prefetch;
-               walk_expression(pf->adr, callback, env);
-               if (pf->rw != NULL) {
-                       walk_expression(pf->rw, callback, env);
-                       if (pf->locality != NULL)
-                               walk_expression(pf->locality, callback, env);
-               }
-               return;
-       }
-
        case EXPR_BUILTIN_CONSTANT_P:
                walk_expression(expr->builtin_constant.value, callback, env);
                return;