X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firprog.c;h=8941410f2d28ef5928df76570caa997eb9bdd634;hb=5c1ded548038459acf350812d820d8bbd7901ab0;hp=3ff354267b1911889a535fd6c614b909ac14fda3;hpb=bd84c0c27fb6a39f8d2fe340c50dab076bacbb63;p=libfirm diff --git a/ir/ir/irprog.c b/ir/ir/irprog.c index 3ff354267..8941410f2 100644 --- a/ir/ir/irprog.c +++ b/ir/ir/irprog.c @@ -24,28 +24,19 @@ * @date 2000 * @version $Id$ */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" -#ifdef HAVE_STRING_H -# include -#endif +#include #include "irprog_t.h" #include "irgraph_t.h" #include "pseudo_irg.h" #include "array.h" +#include "error.h" #include "obst.h" #include "irop_t.h" #include "irmemory.h" -/** The name of the Global type. */ -#define GLOBAL_TYPE_NAME "GlobalType" -/** The name of the Thread Local Storage type. */ -#define TLS_TYPE_NAME "TLS" -/** The name of the constructors type. */ -#define CONSTRUCTORS_TYPE_NAME "Constructors" /** The initial name of the irp program. */ #define INITAL_PROG_NAME "no_name_set" @@ -56,11 +47,9 @@ ir_prog *get_irp(void) { return irp; } /** * Create a new incomplete ir_prog. */ -static ir_prog *new_incomplete_ir_prog(void) { - ir_prog *res; - - res = xmalloc(sizeof(*res)); - memset(res, 0, sizeof(*res)); +static ir_prog *new_incomplete_ir_prog(void) +{ + ir_prog *res = XMALLOCZ(ir_prog); res->kind = k_ir_prog; res->graphs = NEW_ARR_F(ir_graph *, 0); @@ -68,47 +57,60 @@ static ir_prog *new_incomplete_ir_prog(void) { res->types = NEW_ARR_F(ir_type *, 0); res->modes = NEW_ARR_F(ir_mode *, 0); res->opcodes = NEW_ARR_F(ir_op *, 0); + res->global_asms = NEW_ARR_F(ident *, 0); res->last_region_nr = 0; res->last_label_nr = 1; /* 0 is reserved as non-label */ res->max_irg_idx = 0; - -#ifdef DEBUG_libfirm - res->max_node_nr = 0; + res->max_node_nr = 0; +#ifndef NDEBUG + res->reserved_resources = 0; #endif return res; } -/** Completes an incomplete irprog. */ -static ir_prog *complete_ir_prog(ir_prog *irp) { -#define IDENT(s) new_id_from_chars(s, sizeof(s)-1) +/** + * Completes an incomplete irprog. + * + * @param irp the (yet incomplete) irp + * @param module_name the (module) name for this irp + */ +static ir_prog *complete_ir_prog(ir_prog *irp, const char *module_name) { + int i; + +#define IDENT(x) new_id_from_chars(x, sizeof(x) - 1) - irp->name = IDENT(INITAL_PROG_NAME); - irp->glob_type = new_type_class(IDENT(GLOBAL_TYPE_NAME)); - irp->tls_type = new_type_struct(IDENT(TLS_TYPE_NAME)); - irp->constructors_type = new_type_struct(IDENT(CONSTRUCTORS_TYPE_NAME)); + irp->name = new_id_from_str(module_name); + irp->segment_types[IR_SEGMENT_GLOBAL] = new_type_class(IDENT("GlobalType")); + irp->segment_types[IR_SEGMENT_THREAD_LOCAL] + = new_type_struct(IDENT("ThreadLocal")); + irp->segment_types[IR_SEGMENT_CONSTRUCTORS] + = new_type_struct(IDENT("Constructors")); + irp->segment_types[IR_SEGMENT_DESTRUCTORS] + = new_type_struct(IDENT("Destructors")); /* Remove these types from type list. Must be treated differently than other types. */ - remove_irp_type(irp->glob_type); - remove_irp_type(irp->tls_type); - remove_irp_type(irp->constructors_type); + for (i = 0; i < IR_SEGMENT_COUNT; ++i) { + remove_irp_type(irp->segment_types[i]); + } /* Set these flags for debugging. */ - irp->glob_type->flags |= tf_global_type; - irp->tls_type->flags |= tf_tls_type; + irp->segment_types[IR_SEGMENT_GLOBAL]->flags |= tf_global_type; + irp->segment_types[IR_SEGMENT_THREAD_LOCAL]->flags |= tf_tls_type; + irp->segment_types[IR_SEGMENT_CONSTRUCTORS]->flags |= tf_constructors; + irp->segment_types[IR_SEGMENT_DESTRUCTORS]->flags |= tf_destructors; /* The global type is a class, but we cannot derive from it, so set the final property to assist optimizations that checks for it. */ - set_class_final(irp->glob_type, 1); - - irp->const_code_irg = new_const_code_irg(); + set_class_final(irp->segment_types[IR_SEGMENT_GLOBAL], 1); - irp->phase_state = phase_building; - irp->outs_state = outs_none; - irp->ip_outedges = NULL; - irp->trouts_state = outs_none; - irp->class_cast_state = ir_class_casts_transitive; - irp->globals_adr_taken_state = ir_address_taken_not_computed; + irp->const_code_irg = new_const_code_irg(); + irp->phase_state = phase_building; + irp->outs_state = outs_none; + irp->ip_outedges = NULL; + irp->trouts_state = outs_none; + irp->class_cast_state = ir_class_casts_transitive; + irp->globals_entity_usage_state = ir_entity_usage_not_computed; return irp; #undef IDENT @@ -121,28 +123,32 @@ void init_irprog_1(void) { /* Completes ir_prog. */ void init_irprog_2(void) { - complete_ir_prog(irp); + (void)complete_ir_prog(irp, INITAL_PROG_NAME); } /* Create a new ir prog. Automatically called by init_firm through init_irprog. */ -ir_prog *new_ir_prog (void) { - return complete_ir_prog(new_incomplete_ir_prog()); +ir_prog *new_ir_prog(const char *name) { + return complete_ir_prog(new_incomplete_ir_prog(), name); } /* frees all memory used by irp. Types in type list, irgs in irg list and entities in global type must be freed by hand before. */ void free_ir_prog(void) { - free_type(irp->glob_type); - free_type(irp->tls_type); - free_type(irp->constructors_type); + int i; + for (i = 0; i < IR_SEGMENT_COUNT; ++i) { + free_type(irp->segment_types[i]); + } - /* @@@ * free_ir_graph(irp->const_code_irg); * ?? End has no in?? */ + free_ir_graph(irp->const_code_irg); DEL_ARR_F(irp->graphs); DEL_ARR_F(irp->pseudo_graphs); DEL_ARR_F(irp->types); DEL_ARR_F(irp->modes); + + finish_op(); DEL_ARR_F(irp->opcodes); + DEL_ARR_F(irp->global_asms); irp->name = NULL; irp->const_code_irg = NULL; @@ -159,10 +165,14 @@ ir_graph *get_irp_main_irg(void) { } void set_irp_main_irg(ir_graph *main_irg) { - assert (irp); + assert(irp); irp->main_irg = main_irg; } +ir_type *(get_segment_type)(ir_segment_t segment) { + return _get_segment_type(segment); +} + ir_type *(get_glob_type)(void) { return _get_glob_type(); } @@ -171,10 +181,6 @@ ir_type *(get_tls_type)(void) { return _get_tls_type(); } -ir_type *(get_constructors_type)(void) { - return _get_constructors_type(); -} - /* Adds irg to the list of ir graphs in irp. */ void add_irp_irg(ir_graph *irg) { assert(irg != NULL); @@ -184,26 +190,28 @@ void add_irp_irg(ir_graph *irg) { /* Removes irg from the list or irgs, shrinks the list by one. */ void remove_irp_irg_from_list(ir_graph *irg){ - int i, found = 0; + int i, l, found = 0; assert(irg); - for (i = 0; i < (ARR_LEN (irp->graphs)); i++) { + l = ARR_LEN(irp->graphs); + for (i = 0; i < l; i++) { if (irp->graphs[i] == irg) { found = 1; - for(; i < (ARR_LEN (irp->graphs)) - 1; i++) { + for(; i < l - 1; i++) { irp->graphs[i] = irp->graphs[i+1]; } - ARR_SETLEN(ir_graph*, irp->graphs, (ARR_LEN(irp->graphs)) - 1); + ARR_SETLEN(ir_graph*, irp->graphs, l - 1); break; } } if (!found) { - for (i = 0; i < (ARR_LEN (irp->pseudo_graphs)); i++) { + l = ARR_LEN(irp->pseudo_graphs); + for (i = 0; i < l; i++) { if (irp->pseudo_graphs[i] == irg) { - for(; i < (ARR_LEN (irp->pseudo_graphs)) - 1; i++) { + for(; i < l - 1; i++) { irp->pseudo_graphs[i] = irp->pseudo_graphs[i+1]; } - ARR_SETLEN(ir_graph*, irp->pseudo_graphs, (ARR_LEN(irp->pseudo_graphs)) - 1); + ARR_SETLEN(ir_graph*, irp->pseudo_graphs, l - 1); break; } } @@ -212,7 +220,6 @@ void remove_irp_irg_from_list(ir_graph *irg){ /* Removes irg from the list or irgs, shrinks the list by one. */ void remove_irp_irg(ir_graph *irg){ - assert(irg); free_ir_graph(irg); remove_irp_irg_from_list(irg); } @@ -257,15 +264,15 @@ ir_graph *get_irp_allirg(int pos) { void add_irp_type(ir_type *typ) { assert(typ != NULL); assert(irp); - ARR_APP1 (ir_type *, irp->types, typ); + ARR_APP1(ir_type *, irp->types, typ); } -/* Remove type form the list of types in irp. */ +/* Remove type from the list of types in irp. */ void remove_irp_type(ir_type *typ) { int i; assert(typ); - for (i = ARR_LEN(irp->types) -1; i >= 0; i--) { + for (i = ARR_LEN(irp->types) - 1; i >= 0; i--) { if (irp->types[i] == typ) { for(; i < (ARR_LEN(irp->types)) - 1; i++) { irp->types[i] = irp->types[i+1]; @@ -309,26 +316,25 @@ void add_irp_mode(ir_mode *mode) { /* Adds opcode to the list of opcodes in irp. */ void add_irp_opcode(ir_op *opcode) { + int len; + size_t code; assert(opcode != NULL); assert(irp); - assert(opcode->code == (unsigned) ARR_LEN(irp->opcodes) && "new_ir_op() called in wrong order"); - ARR_APP1(ir_op *, irp->opcodes, opcode); + len = ARR_LEN(irp->opcodes); + code = opcode->code; + if ((int) code >= len) { + ARR_RESIZE(ir_op*, irp->opcodes, code+1); + memset(&irp->opcodes[len], 0, (code-len+1) * sizeof(irp->opcodes[0])); + } + + assert(irp->opcodes[code] == NULL && "opcode registered twice"); + irp->opcodes[code] = opcode; } /* Removes opcode from the list of opcodes and shrinks the list by one. */ void remove_irp_opcode(ir_op *opcode) { - int i; - - assert(opcode); - for (i = ARR_LEN(irp->opcodes) -1; i >= 0; i--) { - if (irp->opcodes[i] == opcode) { - for (; i < (ARR_LEN(irp->opcodes)) - 1; i++) { - irp->opcodes[i] = irp->opcodes[i+1]; - } - ARR_SETLEN(ir_op *, irp->opcodes, (ARR_LEN(irp->opcodes)) - 1); - break; - } - } + assert(opcode->code < ARR_LEN(irp->opcodes)); + irp->opcodes[opcode->code] = NULL; } /* Returns the number of all opcodes in the irp. */ @@ -358,10 +364,10 @@ void set_irp_prog_name(ident *name) { int irp_prog_name_is_set(void) { return irp->name != new_id_from_str(INITAL_PROG_NAME); } -ident *get_irp_prog_ident(void) { +ident *get_irp_ident(void) { return irp->name; } -const char *get_irp_prog_name(void) { +const char *get_irp_name(void) { return get_id_str(irp->name); } @@ -394,7 +400,6 @@ ir_node** get_irp_ip_outedges(void) { return irp->ip_outedges; } - irg_callee_info_state get_irp_callee_info_state(void) { return irp->callee_info_state; } @@ -412,3 +417,36 @@ ir_exc_region_t (get_irp_next_region_nr)(void) { ir_label_t (get_irp_next_label_nr)(void) { return _get_irp_next_label_nr(); } + +/* Add a new global asm include */ +void add_irp_asm(ident *asm_string) { + ARR_APP1(ident *, irp->global_asms, asm_string); +} + +/* Return the number of global asm includes. */ +int get_irp_n_asms(void) { + return ARR_LEN(irp->global_asms); +} + +/* Return the global asm include at position pos. */ +ident *get_irp_asm(int pos) { + assert(0 <= pos && pos < get_irp_n_asms()); + return irp->global_asms[pos]; +} + +#ifndef NDEBUG +void irp_reserve_resources(ir_prog *irp, ir_resources_t resources) { + assert((resources & ~IR_RESOURCE_GLOBAL_MASK) == 0); + assert((irp->reserved_resources & resources) == 0); + irp->reserved_resources |= resources; +} + +void irp_free_resources(ir_prog *irp, ir_resources_t resources) { + assert((irp->reserved_resources & resources) == resources); + irp->reserved_resources &= ~resources; +} + +ir_resources_t irp_resources_reserved(const ir_prog *irp) { + return irp->reserved_resources; +} +#endif