From 7f9f6b5425a6eff9bc419aaa5054275597ea4994 Mon Sep 17 00:00:00 2001 From: Moritz Kroll Date: Sat, 21 Feb 2009 14:49:38 +0000 Subject: [PATCH] irio: Fixed handling of frame types and value types [r25539] --- include/libfirm/typerep.h | 17 ++- ir/ir/irio.c | 293 +++++++++++++++++++++++++------------- ir/tr/type.c | 20 +++ ir/tr/typewalk.c | 4 + 4 files changed, 229 insertions(+), 105 deletions(-) diff --git a/include/libfirm/typerep.h b/include/libfirm/typerep.h index 5dbc3fb84..3e916c57e 100644 --- a/include/libfirm/typerep.h +++ b/include/libfirm/typerep.h @@ -1858,6 +1858,10 @@ void set_method_param_type(ir_type *method, int pos, ir_type *tp); /** Returns an entity that represents the copied value argument. Only necessary for compounds passed by value. This information is constructed only on demand. */ ir_entity *get_method_value_param_ent(ir_type *method, int pos); +/** + * Sets the type that represents the copied value arguments. + */ +void set_method_value_param_type(ir_type *method, ir_type *tp); /** * Returns a type that represents the copied value arguments if one * was allocated, else NULL. @@ -2373,6 +2377,13 @@ int is_value_param_type(const ir_type *tp); */ int is_lowered_type(const ir_type *tp); +/** + * Makes a new value type. Value types are struct types, + * so all struct access functions work. + * Value types are not in the global list of types. + */ +ir_type *new_type_value(ident *name); + /** * Makes a new frame type. Frame types are class types, * so all class access functions work. @@ -2559,10 +2570,8 @@ typedef void class_walk_func(ir_type *clss, void *env); * Does not touch frame types or types for value params ... */ void type_walk(type_walk_func *pre, type_walk_func *post, void *env); -/** Touches every type, entity, and frame types in unspecified order. If new - * types/entities are created during the traversal these will - * be visited, too. - * Does not touch types for value params ... (??) */ +/** Touches every type, entity, frame type, and value param type in + * unspecified order. */ void type_walk_plus_frames(type_walk_func *pre, type_walk_func *post, void *env); /** Walks over all type information reachable from an ir graph. diff --git a/ir/ir/irio.c b/ir/ir/irio.c index 85c21c5ce..d524faa56 100644 --- a/ir/ir/irio.c +++ b/ir/ir/irio.c @@ -65,6 +65,7 @@ typedef enum typetag_t tt_builtin, tt_initializer, tt_iro, + tt_keyword, tt_peculiarity, tt_pin_state, tt_tpo, @@ -74,6 +75,17 @@ typedef enum typetag_t tt_volatility } typetag_t; +typedef enum keyword_t +{ + kw_constirg, + kw_entity, + kw_frametype, + kw_irg, + kw_valuetype, + kw_type, + kw_typegraph +} keyword_t; + typedef struct symbol_t { const char *str; /**< The name of this symbol. */ @@ -139,6 +151,7 @@ static void symtbl_init(void) set_insert(symtbl, &key, sizeof(key), string_hash(s, sizeof(s)-1) + tt * 17) #define INSERTENUM(tt, e) INSERT(#e, tt, e) +#define INSERTKEYWORD(k) INSERT(#k, tt_keyword, kw_##k) INSERT("array", tt_tpo, tpo_array); INSERT("class", tt_tpo, tpo_class); @@ -149,6 +162,14 @@ static void symtbl_init(void) INSERT("union", tt_tpo, tpo_union); INSERT("Unknown", tt_tpo, tpo_unknown); + INSERTKEYWORD(constirg); + INSERTKEYWORD(entity); + INSERTKEYWORD(frametype); + INSERTKEYWORD(irg); + INSERTKEYWORD(valuetype); + INSERTKEYWORD(type); + INSERTKEYWORD(typegraph); + #include "gen_irio_lex.inl" INSERTENUM(tt_align, align_non_aligned); @@ -326,7 +347,8 @@ static void export_type(io_env_t *env, ir_type *tp) { FILE *f = env->file; int i; - fprintf(f, "\ttype %ld %s \"%s\" %u %u %s %s ", + fprintf(f, "\t%s %ld %s \"%s\" %u %u %s %s ", + is_frame_type(tp) ? "frametype" : is_value_param_type(tp) ? "valuetype" : "type", get_type_nr(tp), get_type_tpop_name(tp), get_type_name(tp), @@ -528,8 +550,11 @@ void ir_export(const char *filename) for(i = 0; i < n_irgs; i++) { ir_graph *irg = get_irp_irg(i); + ir_type *valuetype = get_irg_value_param_type(irg); - fprintf(env.file, "}\n\nirg %ld {\n", get_entity_nr(get_irg_entity(irg))); + fprintf(env.file, "}\n\nirg %ld %ld %ld {\n", get_entity_nr(get_irg_entity(irg)), + get_type_nr(get_irg_frame_type(irg)), + valuetype == NULL ? -1 : get_type_nr(valuetype)); env.ignoreblocks = 0; irg_block_walk_graph(irg, NULL, export_node, &env); @@ -924,7 +949,7 @@ static ir_initializer_t *read_initializer(io_env_t *env) /** Reads a type description and remembers it by its id. */ -static void import_type(io_env_t *env) +static void import_type(io_env_t *env, keyword_t kwkind) { char buf[1024]; int i; @@ -939,101 +964,135 @@ static void import_type(io_env_t *env) ident *id = new_id_from_str(name); - switch(symbol(tpop, tt_tpo)) + const char *kindstr; + + if(kwkind == kw_frametype) { - case tpo_array: + if(symbol(tpop, tt_tpo) != tpo_class) { - int ndims = (int) read_long(env); - long elemtypenr = read_long(env); - ir_type *elemtype = get_type(env, elemtypenr); - - type = new_type_array(id, ndims, elemtype); - for(i = 0; i < ndims; i++) - { - const char *str = read_str(env); - if(strcmp(str, "unknown")) - { - long lowerbound = strtol(str, NULL, 0); - set_array_lower_bound_int(type, i, lowerbound); - } - str = read_str(env); - if(strcmp(str, "unknown")) - { - long upperbound = strtol(str, NULL, 0); - set_array_upper_bound_int(type, i, upperbound); - } - } - set_type_size_bytes(type, size); - break; + printf("Frame type must be a class type in line %i:%i\n", env->line, env->col); + skip_to(env, '\n'); + return; } - case tpo_class: - type = new_type_class(id); - set_type_size_bytes(type, size); - break; + type = new_type_frame(id); + set_type_size_bytes(type, size); - case tpo_method: + kindstr = "frametype"; + } + else if(kwkind == kw_valuetype) + { + if(symbol(tpop, tt_tpo) != tpo_struct) { - unsigned callingconv = (unsigned) read_long(env); - unsigned addprops = (unsigned) read_long(env); - int nparams = (int) read_long(env); - int nresults = (int) read_long(env); + printf("Value type must be a struct type in line %i:%i\n", env->line, env->col); + skip_to(env, '\n'); + return; + } - type = new_type_method(id, nparams, nresults); + type = new_type_value(id); + set_type_size_bytes(type, size); - for(i = 0; i < nparams; i++) + kindstr = "valuetype"; + } + else + { + switch(symbol(tpop, tt_tpo)) + { + case tpo_array: { - long typenr = read_long(env); - ir_type *paramtype = get_type(env, typenr); + int ndims = (int) read_long(env); + long elemtypenr = read_long(env); + ir_type *elemtype = get_type(env, elemtypenr); - set_method_param_type(type, i, paramtype); + type = new_type_array(id, ndims, elemtype); + for(i = 0; i < ndims; i++) + { + const char *str = read_str(env); + if(strcmp(str, "unknown")) + { + long lowerbound = strtol(str, NULL, 0); + set_array_lower_bound_int(type, i, lowerbound); + } + str = read_str(env); + if(strcmp(str, "unknown")) + { + long upperbound = strtol(str, NULL, 0); + set_array_upper_bound_int(type, i, upperbound); + } + } + set_type_size_bytes(type, size); + break; } - for(i = 0; i < nresults; i++) + + case tpo_class: + type = new_type_class(id); + set_type_size_bytes(type, size); + break; + + case tpo_method: { - long typenr = read_long(env); - ir_type *restype = get_type(env, typenr); + unsigned callingconv = (unsigned) read_long(env); + unsigned addprops = (unsigned) read_long(env); + int nparams = (int) read_long(env); + int nresults = (int) read_long(env); - set_method_res_type(type, i, restype); - } + type = new_type_method(id, nparams, nresults); - set_method_calling_convention(type, callingconv); - set_method_additional_properties(type, addprops); - break; - } + for(i = 0; i < nparams; i++) + { + long typenr = read_long(env); + ir_type *paramtype = get_type(env, typenr); - case tpo_pointer: - { - ir_mode *mode = read_mode(env); - ir_type *pointsto = get_type(env, read_long(env)); - type = new_type_pointer(id, pointsto, mode); - break; - } + set_method_param_type(type, i, paramtype); + } + for(i = 0; i < nresults; i++) + { + long typenr = read_long(env); + ir_type *restype = get_type(env, typenr); - case tpo_primitive: - { - ir_mode *mode = read_mode(env); - type = new_type_primitive(id, mode); - break; - } + set_method_res_type(type, i, restype); + } - case tpo_struct: - type = new_type_struct(id); - set_type_size_bytes(type, size); - break; + set_method_calling_convention(type, callingconv); + set_method_additional_properties(type, addprops); + break; + } - case tpo_union: - type = new_type_union(id); - set_type_size_bytes(type, size); - break; + case tpo_pointer: + { + ir_mode *mode = read_mode(env); + ir_type *pointsto = get_type(env, read_long(env)); + type = new_type_pointer(id, pointsto, mode); + break; + } - case tpo_unknown: - return; // ignore unknown type + case tpo_primitive: + { + ir_mode *mode = read_mode(env); + type = new_type_primitive(id, mode); + break; + } - default: - if(typenr != 0) // ignore global type - printf("Unknown type kind: \"%s\" in line %i:%i\n", tpop, env->line, env->col); - skip_to(env, '\n'); - return; + case tpo_struct: + type = new_type_struct(id); + set_type_size_bytes(type, size); + break; + + case tpo_union: + type = new_type_union(id); + set_type_size_bytes(type, size); + break; + + case tpo_unknown: + return; // ignore unknown type + + default: + if(typenr != 0) // ignore global type + printf("Unknown type kind: \"%s\" in line %i:%i\n", tpop, env->line, env->col); + skip_to(env, '\n'); + return; + } + kindstr = "type"; } set_type_alignment_bytes(type, align); @@ -1043,7 +1102,7 @@ static void import_type(io_env_t *env) ARR_APP1(ir_type *, env->fixedtypes, type); set_id(env, typenr, type); - printf("Insert type %s %ld\n", name, typenr); + printf("Insert %s %s %ld\n", kindstr, name, typenr); } /** Reads an entity description and remembers it by its id. */ @@ -1115,13 +1174,24 @@ static int parse_typegraph(io_env_t *env) // parse all types first while(1) { + int isframetype = 0; + kind = read_str(env); if(kind[0] == '}' && !kind[1]) break; - if(!strcmp(kind, "type")) - import_type(env); - else - skip_to(env, '\n'); + keyword_t kwkind = (keyword_t) symbol(kind, tt_keyword); + switch(kwkind) + { + case kw_type: + case kw_frametype: + case kw_valuetype: + import_type(env, kwkind); + break; + + default: + skip_to(env, '\n'); + break; + } } // now parse rest @@ -1132,14 +1202,22 @@ static int parse_typegraph(io_env_t *env) kind = read_str(env); if(kind[0] == '}' && !kind[1]) break; - if(!strcmp(kind, "type")) - skip_to(env, '\n'); - else if(!strcmp(kind, "entity")) - import_entity(env); - else + switch(symbol(kind, tt_keyword)) { - printf("Type graph element not supported yet: \"%s\"\n", kind); - skip_to(env, '\n'); + case kw_type: + case kw_frametype: + case kw_valuetype: + skip_to(env, '\n'); + break; + + case kw_entity: + import_entity(env); + break; + + default: + printf("Type graph element not supported yet: \"%s\"\n", kind); + skip_to(env, '\n'); + break; } } return 1; @@ -1306,21 +1384,34 @@ void ir_import(const char *filename) { const char *str = read_str(env); if(!*str) break; - if(!strcmp(str, "typegraph")) - { - if(!parse_typegraph(env)) break; - } - else if(!strcmp(str, "irg")) + switch(symbol(str, tt_keyword)) { - ir_graph *irg = new_ir_graph(get_entity(env, read_long(env)), 0); - if(!parse_graph(env, irg)) break; - } - else if(!strcmp(str, "constirg")) - { - if(!parse_graph(env, get_const_code_irg())) break; + case kw_typegraph: + if(!parse_typegraph(env)) goto end; + break; + + case kw_irg: + { + ir_entity *irgent = get_entity(env, read_long(env)); + long valuetypeid; + ir_graph *irg = new_ir_graph(irgent, 0); + set_irg_frame_type(irg, get_type(env, read_long(env))); + valuetypeid = read_long(env); + if(valuetypeid != -1) + set_method_value_param_type(get_entity_type(irgent), + get_type(env, valuetypeid)); + + if(!parse_graph(env, irg)) goto end; + break; + } + + case kw_constirg: + if(!parse_graph(env, get_const_code_irg())) goto end; + break; } } +end: n = ARR_LEN(env->fixedtypes); for(i = 0; i < n; i++) set_type_state(env->fixedtypes[i], layout_fixed); diff --git a/ir/tr/type.c b/ir/tr/type.c index 0c3109fd6..5c12958d9 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -1326,6 +1326,14 @@ ir_entity *get_method_value_param_ent(ir_type *method, int pos) { return method->attr.ma.params[pos].ent; } +/* + * Sets the type that represents the copied value arguments. + */ +void set_method_value_param_type(ir_type *method, ir_type *tp) { + assert(method && (method->type_op == type_method)); + method->attr.ma.value_params = tp; +} + /* * Returns a type that represents the copied value arguments. */ @@ -2041,6 +2049,18 @@ int is_lowered_type(const ir_type *tp) { return tp->flags & tf_lowered_type; } +/* Makes a new value type. */ +ir_type *new_type_value(ident *name) { + ir_type *res = new_type_struct(name); + + res->flags |= tf_value_param_type; + + /* Remove type from type list. Must be treated differently than other types. */ + remove_irp_type(res); + + return res; +} + /* Makes a new frame type. */ ir_type *new_type_frame(ident *name) { ir_type *res = new_type_class(name); diff --git a/ir/tr/typewalk.c b/ir/tr/typewalk.c index 1b64e9bde..1c0b0d6cc 100644 --- a/ir/tr/typewalk.c +++ b/ir/tr/typewalk.c @@ -286,6 +286,10 @@ void type_walk_plus_frames(type_walk_func *pre, type_walk_func *post, void *env) ir_graph *irg = get_irp_irg(i); cont.typ = get_irg_frame_type(irg); do_type_walk(cont, pre, post, env); + + cont.typ = get_method_value_param_type(get_entity_type(get_irg_entity(irg))); + if(cont.typ) + do_type_walk(cont, pre, post, env); } } -- 2.20.1