From fb648cf14f79e1baffd2b4c4b705f69383e9b613 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=B6tz=20Lindenmaier?= Date: Thu, 14 Feb 2002 16:52:03 +0000 Subject: [PATCH] minor changes to help with making the ajacs-jikes backend more general. [r313] --- ir/ana/irouts.c | 8 ----- ir/common/common.h | 11 ------ ir/ident/ident.c | 29 ++++++++++++++-- ir/ident/ident.h | 43 ++++++++++++++++++++++-- ir/ir/ircons.c | 67 +++++++++++++++++++++---------------- ir/ir/ircons.h | 7 ++++ ir/ir/irdump.c | 16 +++++---- ir/ir/irdump.h | 16 ++++----- ir/ir/irgopt.h | 2 +- ir/ir/irgraph.c | 18 ++++++++-- ir/ir/irgraph.h | 15 +++++---- ir/ir/irgraph_t.h | 2 ++ ir/ir/irgwalk.c | 22 +++++++++++- ir/ir/irgwalk.h | 7 ++++ ir/ir/irnode.c | 21 ++++++++++++ ir/ir/irnode.h | 28 ++++++++++++---- ir/ir/iropt.c | 1 + ir/tr/entity.c | 39 +++++++++++++++++++-- ir/tr/entity.h | 28 ++++++++++------ ir/tr/mangle.c | 17 +++++++++- ir/tr/mangle.h | 6 +++- ir/tr/type.c | 2 +- ir/tr/typewalk.c | 63 ++++++++++++++++++++++++++++++++-- ir/tr/typewalk.h | 14 ++++++-- ir/tv/tv.c | 2 +- testprograms/endless_loop.c | 3 +- 26 files changed, 381 insertions(+), 106 deletions(-) diff --git a/ir/ana/irouts.c b/ir/ana/irouts.c index ed00b68c3..b99169a72 100644 --- a/ir/ana/irouts.c +++ b/ir/ana/irouts.c @@ -10,14 +10,6 @@ /* $Id$ */ -#define DDMSG2(X) printf("%s(l.%i) %s%s: %ld\n", __FUNCTION__, __LINE__, \ - id_to_str(get_irn_opident(X)), id_to_str(get_irn_modeident(X)), \ - get_irn_node_nr(X)) -#define DDMSG5(X) printf("%s%s: %ld", \ - id_to_str(get_irn_opident(X)), id_to_str(get_irn_modeident(X)), \ - get_irn_node_nr(X)) - - #include "irouts.h" #include "irnode_t.h" #include "irgraph_t.h" /* To access irg->outs field (which is private to this module) diff --git a/ir/common/common.h b/ir/common/common.h index 21e7b171e..b77b3e6e6 100644 --- a/ir/common/common.h +++ b/ir/common/common.h @@ -57,17 +57,6 @@ typedef enum { k_ir_node } firm_kind; -#if 0 - k_type_class, - k_type_strct, - k_type_method, - k_type_union, - k_type_array, - k_type_enumeration, - k_type_pointer, - k_type_primitive, -#endif - /* returns the kind of the thing */ firm_kind get_kind(void *firm_thing); diff --git a/ir/ident/ident.c b/ir/ident/ident.c index 0ac80264b..1882c05d5 100644 --- a/ir/ident/ident.c +++ b/ir/ident/ident.c @@ -98,9 +98,12 @@ id_init (void) #if 1 -inline ident *id_from_str (char *str, int len) { +inline ident *id_from_str (const char *str, int len) { assert (len > 0); - return (const set_entry *)set_hinsert (id_set, (str), (len), ID_HASH ((str), (len))); + return (const set_entry *) set_hinsert (id_set, + (str), + (len), + ID_HASH ((str), (len))); } inline const char *id_to_str (ident *id) { @@ -110,5 +113,25 @@ inline const char *id_to_str (ident *id) { inline int id_to_strlen(ident *id) { return ((id)->size); } - #endif + +int id_is_prefix (ident *prefix, ident *id) { + int i; + if (id_to_strlen(prefix) > id_to_strlen(id)) return 0; + if (0 == memcmp(&(prefix->dptr[0]), &(id->dptr[0]), id_to_strlen(prefix))) + return 1; + return 0; +} + +int id_is_suffix (ident *suffix, ident *id) { + int suflen = id_to_strlen(suffix); + int idlen = id_to_strlen(id); + char *part; + if (suflen > idlen) return 0; + + part = (char *) &id->dptr[0]; + part = part + (idlen - suflen); + if (0 == memcmp(&(suffix->dptr[0]), part, suflen)) + return 1; + return 0; +} diff --git a/ir/ident/ident.h b/ir/ident/ident.h index 92c30c61c..60623777a 100644 --- a/ir/ident/ident.h +++ b/ir/ident/ident.h @@ -20,7 +20,7 @@ * ident -- identifiers in the firm library * NOTES * Identifiers are used in the firm library. This is the interface to it. - * + * @@@ we need comparison of the prefis of two idents! (strncmp); ****** */ @@ -51,7 +51,7 @@ typedef const struct set_entry ident; * id_to_str, id_to_strlen *** */ -inline ident *id_from_str (char *str, int len); +inline ident *id_from_str (const char *str, int len); /****f* ident/id_to_str * @@ -88,6 +88,43 @@ inline const char *id_to_str (ident *id); * id_from_str, id_to_str *** */ -inline int id_to_strlen(ident *id); +inline int id_to_strlen(ident *id); + +/****f* ident/id_is_suffix + * + * NAME + * + * SYNOPSIS + * int id_is_prefix (ident *prefix, ident *id); + * FUNCTION + * Returns true if prefix is prefix of id. + * INPUTS + * prefix - the prefix + * id - the ident + * SEE ALSO + * id_from_str, id_to_str, id_is_prefix + *** + */ +/* */ +int id_is_prefix (ident *prefix, ident *id); + +/****f* ident/id_is_suffix + * + * NAME + * + * SYNOPSIS + * int id_is_suffix (ident *suffix, ident *id); + * FUNCTION + * Returns true if suffix is suffix of id. + * INPUTS + * suffix - the suffix + * id - the ident + * SEE ALSO + * id_from_str, id_to_str, id_is_prefix + *** + */ +/* */ +int id_is_suffix (ident *suffix, ident *id); + # endif /* _IDENT_H_ */ diff --git a/ir/ir/ircons.c b/ir/ir/ircons.c index ec20feaf7..a7163e4ed 100644 --- a/ir/ir/ircons.c +++ b/ir/ir/ircons.c @@ -1134,20 +1134,22 @@ get_r_frag_value_internal (ir_node *block, ir_node *cfOp, int pos, ir_mode *mode if (!res) { if (block->attr.block.graph_arr[pos]) { /* There was a set_value after the cfOp and no get_value before that - set_value. We must build a Phi node now. */ + set_value. We must build a Phi node now. */ if (block->attr.block.matured) { - int ins = get_irn_arity(block); - ir_node **nin; - NEW_ARR_A (ir_node *, nin, ins); - res = phi_merge(block, pos, mode, nin, ins); + int ins = get_irn_arity(block); + ir_node **nin; + NEW_ARR_A (ir_node *, nin, ins); + res = phi_merge(block, pos, mode, nin, ins); } else { - res = new_r_Phi0 (current_ir_graph, block, mode); - res->attr.phi0_pos = pos; - res->link = block->link; - block->link = res; + res = new_r_Phi0 (current_ir_graph, block, mode); + res->attr.phi0_pos = pos; + res->link = block->link; + block->link = res; } - assert(res); - /* It's a Phi, we can write this into all graph_arrs with NULL */ + assert(res); + /* @@@ tested by Flo: set_frag_value(frag_arr, pos, res); + but this should be better: (remove comment if this works) */ + /* It's a Phi, we can write this into all graph_arrs with NULL */ set_frag_value(block->attr.block.graph_arr, pos, res); } else { res = get_r_value_internal(block, pos, mode); @@ -1169,7 +1171,6 @@ phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins) ir_node *prevBlock, *prevCfOp, *res, *phi0; int i; - /* If this block has no value at pos create a Phi0 and remember it in graph_arr to break recursions. Else we may not set graph_arr as there a later value is remembered. */ @@ -1193,11 +1194,13 @@ phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins) /* We don't need to care about exception ops in the start block. There are none by definition. */ return block->attr.block.graph_arr[pos]; - } else { + } else { phi0 = new_r_Phi0(current_ir_graph, block, mode); block->attr.block.graph_arr[pos] = phi0; #if PRECISE_EXC_CONTEXT - /* Set graph_arr for fragile ops. Also here we should break recursion. */ + /* Set graph_arr for fragile ops. Also here we should break recursion. + We could choose a cyclic path through an cfop. But the recursion would + break at some point. */ set_frag_value(block->attr.block.graph_arr, pos, phi0); #endif } @@ -1220,12 +1223,11 @@ phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins) if (!is_Bad(prevBlock)) { #if PRECISE_EXC_CONTEXT if (is_fragile_op(prevCfOp) && (get_irn_op (prevCfOp) != op_Bad)) { - assert(get_r_frag_value_internal (prevBlock, prevCfOp, pos, mode)); - - nin[i-1] = get_r_frag_value_internal (prevBlock, prevCfOp, pos, mode); - } else + assert(get_r_frag_value_internal (prevBlock, prevCfOp, pos, mode)); + nin[i-1] = get_r_frag_value_internal (prevBlock, prevCfOp, pos, mode); + } else #endif - nin[i-1] = get_r_value_internal (prevBlock, pos, mode); + nin[i-1] = get_r_value_internal (prevBlock, pos, mode); } else { nin[i-1] = new_Bad(); } @@ -1362,9 +1364,10 @@ mature_block (ir_node *block) if (!get_Block_matured(block)) { - /* an in-array for phi-merge with same size. */ + /* An array for building the Phi nodes. */ ins = ARR_LEN (block->in)-1; NEW_ARR_A (ir_node *, nin, ins); + /* shouldn't we delete this array at the end of the procedure? @@@ memory leak? */ /* Traverse a chain of Phi nodes attached to this block and mature these, too. **/ @@ -1477,7 +1480,8 @@ new_Quot (ir_node *memop, ir_node *op1, ir_node *op2) res = new_r_Quot (current_ir_graph, current_ir_graph->current_block, memop, op1, op2); #if PRECISE_EXC_CONTEXT - res->attr.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.frag_arr = new_frag_arr(res); #endif return res; @@ -1490,7 +1494,8 @@ new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2) res = new_r_DivMod (current_ir_graph, current_ir_graph->current_block, memop, op1, op2); #if PRECISE_EXC_CONTEXT - res->attr.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.frag_arr = new_frag_arr(res); #endif return res; @@ -1503,7 +1508,8 @@ new_Div (ir_node *memop, ir_node *op1, ir_node *op2) res = new_r_Div (current_ir_graph, current_ir_graph->current_block, memop, op1, op2); #if PRECISE_EXC_CONTEXT - res->attr.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.frag_arr = new_frag_arr(res); #endif return res; @@ -1516,7 +1522,8 @@ new_Mod (ir_node *memop, ir_node *op1, ir_node *op2) res = new_r_Mod (current_ir_graph, current_ir_graph->current_block, memop, op1, op2); #if PRECISE_EXC_CONTEXT - res->attr.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.frag_arr = new_frag_arr(res); #endif return res; @@ -1612,7 +1619,8 @@ new_Call (ir_node *store, ir_node *callee, int arity, ir_node **in, res = new_r_Call (current_ir_graph, current_ir_graph->current_block, store, callee, arity, in, type); #if PRECISE_EXC_CONTEXT - res->attr.call.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.call.frag_arr = new_frag_arr(res); #endif return res; @@ -1639,7 +1647,8 @@ new_Load (ir_node *store, ir_node *addr) res = new_r_Load (current_ir_graph, current_ir_graph->current_block, store, addr); #if PRECISE_EXC_CONTEXT - res->attr.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.frag_arr = new_frag_arr(res); #endif return res; @@ -1652,7 +1661,8 @@ new_Store (ir_node *store, ir_node *addr, ir_node *val) res = new_r_Store (current_ir_graph, current_ir_graph->current_block, store, addr, val); #if PRECISE_EXC_CONTEXT - res->attr.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.frag_arr = new_frag_arr(res); #endif return res; @@ -1666,7 +1676,8 @@ new_Alloc (ir_node *store, ir_node *size, type *alloc_type, res = new_r_Alloc (current_ir_graph, current_ir_graph->current_block, store, size, alloc_type, where); #if PRECISE_EXC_CONTEXT - res->attr.a.frag_arr = new_frag_arr(res); + if (current_ir_graph->phase_state == phase_building) + res->attr.a.frag_arr = new_frag_arr(res); #endif return res; diff --git a/ir/ir/ircons.h b/ir/ir/ircons.h index 6561c3859..99d8a1232 100644 --- a/ir/ir/ircons.h +++ b/ir/ir/ircons.h @@ -590,6 +590,13 @@ * size The symbolic constant represents the size of a class. * link_info Information for the linker, e.g. the name of a global * variable. + * To represent a pointer to an entity that is represented by an entity + * datastructure don't use + * new_SymConst((type_or_id*)get_entity_ld_ident(ent), linkage_ptr_info);. + * Use a real const instead: + * new_Const(mode_p, tarval_p_from_entity(ent)); + * This makes the Constant independent of name changes of the entity due to + * mangling. * * Parameters * kind The kind of the symbolic constant: type_tag, size or link_info. diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index 0ebc0b08d..4173b6e69 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -18,7 +18,7 @@ # include "irdump.h" # include "panic.h" # include -# include "entity.h" +# include "entity_t.h" # include # include "array.h" # include "irop_t.h" @@ -102,11 +102,11 @@ dump_node_opcode (ir_node *n) /* SymConst */ } else if (n->op->code == iro_SymConst) { if (get_SymConst_kind(n) == linkage_ptr_info) { - xfprintf (F, "%I", get_SymConst_ptrinfo(n)); + xfprintf (F, "SymC %I", get_SymConst_ptrinfo(n)); } else { assert(get_kind(get_SymConst_type(n)) == k_type); assert(get_type_ident(get_SymConst_type(n))); - xfprintf (F, "%s ", id_to_str(get_type_ident(get_SymConst_type(n)))); + xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n))); if (get_SymConst_kind == type_tag) xfprintf (F, "tag"); else @@ -644,8 +644,9 @@ dump_type_info (type_or_ent *tore, void *env) { } xfprintf(F, "\"}\n"); /* The Edges */ + /* skip this to reduce graph. Member edge of type is parallel to this edge. * xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" " - ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent)); + ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/ xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" " ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent)); for(i = 0; i < get_entity_n_overwrites(ent); i++) @@ -760,7 +761,8 @@ void vcg_open (ir_graph *irg, char *suffix) { /** open file for vcg graph */ ent = get_irg_ent(irg); - id = get_entity_ld_ident (ent); + id = ent->ld_name ? ent->ld_name : ent->name; + /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */ len = id_to_strlen (id); cp = id_to_str (id); fname = malloc (len + 5 + strlen(suffix)); @@ -1135,11 +1137,11 @@ void dump_all_ir_graphs (void dump_graph(ir_graph*)) { /* To turn off display of edge labels. Edge labels offen cause xvcg to abort with a segmentation fault. */ -void turn_of_edge_labels() { +void turn_off_edge_labels() { edge_label = 0; } -void dump_constant_entity_values() { +void turn_off_constant_entity_values() { const_entities = 0; } diff --git a/ir/ir/irdump.h b/ir/ir/irdump.h index 591a94849..ec6d921f3 100644 --- a/ir/ir/irdump.h +++ b/ir/ir/irdump.h @@ -220,9 +220,9 @@ void dump_all_ir_graphs (void dump_graph(ir_graph*)); /****m* irdump/turn_of_edge_labels * * NAME - * turn_of_edge_labels + * turn_off_edge_labels * SYNOPSIS - * void turn_of_edge_labels(); + * void turn_off_edge_labels(); * FUNCTION * Sets the vcg flag "display_edge_labels" to no. This is necessary * as xvcg and aisee both fail to display graphs with self-edges if these @@ -235,15 +235,15 @@ void dump_all_ir_graphs (void dump_graph(ir_graph*)); * *** */ -void turn_of_edge_labels(); +void turn_off_edge_labels(); -/****m* irdump/dump_constant_entity_values +/****m* irdump/turn_off_constant_entity_values * * NAME - * dump_constant_entity_values + * turn_off_constant_entity_values * SYNOPSIS - * void dump_constant_entity_values() + * void turn_off_constant_entity_values() * FUNCTION * Turns off dumping the values of constant entities. Makes type graphs * better readable. @@ -254,10 +254,10 @@ void turn_of_edge_labels(); * *** */ -void dump_constant_entity_values(); +void turn_off_constant_entity_values(); -/****m* irdump/dump_constant_entity_values +/****m* irdump/dump_keepalive_edges * * NAME * dump_keepalive_edges diff --git a/ir/ir/irgopt.h b/ir/ir/irgopt.h index 494f2b063..98bdfa625 100644 --- a/ir/ir/irgopt.h +++ b/ir/ir/irgopt.h @@ -21,7 +21,7 @@ void local_optimize_graph (ir_graph *irg); inputs to Phi nodes. The graph may not be in state phase_building. The outs datasturcture is freed, the outs state set to no_outs. (@@@ Change this? -> inconsistent.) - Removes old attributes of nodes. + Removes old attributes of nodes. Sets link field to NULL. Attention: the numbers assigned to nodes if the library is compiled for development/debugging are not conserved by copying. */ void dead_node_elimination(ir_graph *irg); diff --git a/ir/ir/irgraph.c b/ir/ir/irgraph.c index 74dc02c51..527a3537d 100644 --- a/ir/ir/irgraph.c +++ b/ir/ir/irgraph.c @@ -88,7 +88,8 @@ new_ir_graph (entity *ent, int n_loc) /** A type that represents the stack frame. A class type so that it can contain "inner" methods as in Pascal. **/ - res->frame_type = new_type_class(mangle(get_entity_ident(ent), id_from_str("frame_tp", 8))); + res->frame_type = new_type_class(mangle(get_entity_ident(ent), + id_from_str(FRAME_TP_SUFFIX, strlen(FRAME_TP_SUFFIX)))); /** Nodes needed in every graph **/ res->end_block = new_immBlock (); @@ -330,6 +331,15 @@ set_irg_frame_type (ir_graph *irg, type *ftp) irg->frame_type = ftp; } + +/* To test for a frame type */ +int +is_frame_type(type *ftp) { + return ((is_class_type(ftp) || is_struct_type(ftp)) && + id_is_suffix(id_from_str(FRAME_TP_SUFFIX, strlen(FRAME_TP_SUFFIX)), + get_type_ident(ftp))); +} + int get_irg_n_loc (ir_graph *irg) { @@ -343,7 +353,11 @@ get_irg_n_loc (ir_graph *irg) void set_irg_n_loc (ir_graph *irg, int n_loc) { - irg->n_loc = n_loc; +#if PRECISE_EXC_CONTEXT + irg->n_loc = n_loc + 1 + 1; +#else + irg->n_loc = n_loc + 1; +#endif } irg_phase_state get_irg_phase_state (ir_graph *irg) { diff --git a/ir/ir/irgraph.h b/ir/ir/irgraph.h index 8a690e263..28bc6e468 100644 --- a/ir/ir/irgraph.h +++ b/ir/ir/irgraph.h @@ -127,6 +127,8 @@ void set_irg_ent (ir_graph *irg, entity *ent); type *get_irg_frame_type (ir_graph *irg); void set_irg_frame_type (ir_graph *irg, type *ftp); +/* To test for a frame type */ +int is_frame_type(type *ftp); /* Use not encouraged, internal of Phi construction algorithm. */ int get_irg_n_loc (ir_graph *irg); @@ -141,12 +143,13 @@ void set_irg_n_loc (ir_graph *irg, int n_loc); information associated with the graph. Optimizations invalidate these states. */ -/* state: phase - values: phase_building, phase_high, phase_low - The irg is in phase_building during construction of the irgraph. - It is in phase_high after construction. All nodes are allowed. - To get the irgraph into phase_low all Sel nodes must be removed - and replaced by explicit address computations. @@@ More conditions? */ +/* state: phase values: phase_building, phase_high, phase_low. + The irg is in phase_building during construction of the irgraph. It is in + phase_high after construction. All nodes are allowed. To get the irgraph + into phase_low all Sel nodes must be removed and replaced by explicit + address computations. SymConst size and typetag nodes must be removed (@@@ + really?). Initialization of memory allocated by Alloc must be explicit. + @@@ More conditions? */ typedef enum { phase_building, phase_high, diff --git a/ir/ir/irgraph_t.h b/ir/ir/irgraph_t.h index ad99220cb..8f7848b4f 100644 --- a/ir/ir/irgraph_t.h +++ b/ir/ir/irgraph_t.h @@ -14,6 +14,8 @@ # include "pset.h" # include "irgraph.h" +#define FRAME_TP_SUFFIX "frame_tp" + /* ir_graph holds all information for a procedure */ struct ir_graph { /** Basics of the representation **/ diff --git a/ir/ir/irgwalk.c b/ir/ir/irgwalk.c index 5b15031fd..1c5c60bf1 100644 --- a/ir/ir/irgwalk.c +++ b/ir/ir/irgwalk.c @@ -16,7 +16,7 @@ # include "irnode.h" # include "irgraph.h" /* visited flag */ - +# include "irprog.h" void irg_walk_2(ir_node *node, void (pre)(ir_node*, void*), void (post)(ir_node*, void*), @@ -67,6 +67,26 @@ void irg_walk(ir_node *node, /***************************************************************************/ +/* Executes irg_walk(end, pre, post, env) for all irgraphs in irprog. + Sets current_ir_graph properly for each walk. Conserves current + current_ir_graph. */ +void all_irg_walk(void (pre)(ir_node*, void*), void (post)(ir_node*, void*), + void *env) { + int i; + ir_graph *irg, *rem; + + rem = current_ir_graph; + + for (i = 0; i < get_irp_n_irgs(); i++) { + irg = get_irp_irg(i); + current_ir_graph = irg; + irg_walk(get_irg_end(irg), pre, post, env); + } + current_ir_graph = rem; +} + +/***************************************************************************/ + /* Walks back from n until it finds a real cf op. */ ir_node *get_cf_op(ir_node *n) { ir_node *pred; diff --git a/ir/ir/irgwalk.h b/ir/ir/irgwalk.h index 5faca90b6..2275b8347 100644 --- a/ir/ir/irgwalk.h +++ b/ir/ir/irgwalk.h @@ -29,6 +29,13 @@ void irg_walk(ir_node *node, void (pre)(ir_node*, void*), void (post)(ir_node*, void*), void *env); +/* Executes irg_walk(end, pre, post, env) for all irgraphs in irprog. + Sets current_ir_graph properly for each walk. Conserves current + current_ir_graph. */ +void all_irg_walk(void (pre)(ir_node*, void*), void (post)(ir_node*, void*), + void *env); + + /* Walks only over Block nodes in the graph. Has it's own visited flag, so that it can be interleaved with the other walker. */ void irg_block_walk(ir_node *node, diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 7d07bb7c4..c192d9a4d 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -27,6 +27,7 @@ #define CALL_PARAM_OFFSET 2 #define SEL_INDEX_OFFSET 2 #define RETURN_RESULT_OFFSET 1 /* mem is not a result */ +#define END_KEEPALIVE_OFFSET 0 static char *pnc_name_arr [] = {"False", "Eq", "Lt", "Le", "Gt", "Ge", "Lg", "Leg", "Uo", @@ -300,6 +301,13 @@ set_irn_visited (ir_node *node, unsigned long visited) assert (node); node->visited = visited; } + +inline void +mark_irn_visited (ir_node *node) { + assert (node); + node->visited = current_ir_graph->visited; +} + inline void set_irn_link (ir_node *node, ir_node *link) { assert (node); @@ -471,6 +479,18 @@ set_Block_graph_arr (ir_node *node, int pos, ir_node *value) { node->attr.block.graph_arr[pos+1] = value; } +inline int +get_End_n_keepalives(ir_node *end) { + assert (end->op == op_End); + return (get_irn_arity(end) - END_KEEPALIVE_OFFSET); +} + +inline ir_node * +get_End_keepalive(ir_node *end, int pos) { + assert (end->op == op_End); + return get_irn_n(end, pos + END_KEEPALIVE_OFFSET); +} + inline void add_End_keepalive (ir_node *end, ir_node *ka) { assert (end->op == op_End); @@ -796,6 +816,7 @@ get_Call_n_params (ir_node *node) { inline int get_Call_arity (ir_node *node) { + assert (node->op == op_Call); return get_Call_n_params(node); } diff --git a/ir/ir/irnode.h b/ir/ir/irnode.h index b69ced1f4..b52024b3b 100644 --- a/ir/ir/irnode.h +++ b/ir/ir/irnode.h @@ -91,6 +91,8 @@ inline ident *get_irn_opident (ir_node *node); inline const char *get_irn_opname (ir_node *node); inline void set_irn_visited (ir_node *node, unsigned long visited); inline unsigned long get_irn_visited (ir_node *node); +/* Sets visited to get_irg_visited(current_ir_graph) */ +inline void mark_irn_visited (ir_node *node); inline void set_irn_link (ir_node *node, ir_node *link); inline ir_node *get_irn_link (ir_node *node); #ifdef DEBUG_libfirm @@ -149,9 +151,11 @@ inline ir_node *get_Block_graph_arr (ir_node *node, int pos); inline void set_Block_graph_arr (ir_node *node, int pos, ir_node *value); +inline int get_End_n_keepalives(ir_node *end); +inline ir_node *get_End_keepalive(ir_node *end, int pos); inline void add_End_keepalive (ir_node *end, ir_node *ka); /* Some parts of the End node are allocated seperately -- their memory - is not recovered by dead_node_elimination if a End not is dead. + is not recovered by dead_node_elimination if a End node is dead. free_End frees these data structures. */ inline void free_End (ir_node *end); @@ -480,7 +484,8 @@ inline int is_no_Block (ir_node *node); Start, End, Jmp, Cond, Return, Raise, Bad */ int is_cfop(ir_node *node); /* Returns true if the operation can change the control flow because - of an exception. */ + of an exception: Call, Quot, DivMod, Div, Mod, Load, Store, Alloc, + Bad. */ int is_fragile_op(ir_node *node); /* Returns the memory operand of fragile operations. */ ir_node *get_fragile_op_mem(ir_node *node); @@ -488,7 +493,7 @@ ir_node *get_fragile_op_mem(ir_node *node); /*****/ /* Makros for debugging the libfirm */ -#ifdef DEBUG_libfirm +/*#ifdef DEBUG_libfirm*/ #include "ident.h" #define DDMSG printf("%s(l.%i)\n", __FUNCTION__, __LINE__) @@ -499,12 +504,23 @@ ir_node *get_fragile_op_mem(ir_node *node); get_irn_node_nr(X)) #define DDMSG3(X) printf("%s(l.%i) %s: %p\n", __FUNCTION__, __LINE__, \ print_firm_kind(X), (X)) -#define DDMSG4(X) printf("%s(l.%i) %s %s: %p\n", __FUNCTION__, __LINE__, \ - get_type_tpop_name(X), get_type_name(X), (X)) +#define DDMSG4(X) xprintf("%s(l.%i) %I %I: %p\n", __FUNCTION__, __LINE__, \ + get_type_tpop_nameid(X), get_type_ident(X), (X)) #define DDMSG5(X) printf("%s%s: %ld", \ id_to_str(get_irn_opident(X)), id_to_str(get_irn_modeident(X)), \ get_irn_node_nr(X)) -#endif + +#define DDMN(X) xprintf("%s(l.%i) %I%I: %ld (%p)\n", __FUNCTION__, __LINE__, \ + get_irn_opident(X), get_irn_modeident(X), get_irn_node_nr(X), (X)) +#define DDMNB(X) xprintf("%I%I: %ld (in block %ld)\n", \ + get_irn_opident(X), get_irn_modeident(X), get_irn_node_nr(X), \ + get_irn_node_nr(get_nodes_Block(X))) +#define DDMT(X) xprintf("%s(l.%i) %I %I: %p\n", __FUNCTION__, __LINE__, \ + get_type_tpop_nameid(X), get_type_ident(X), (X)) +#define DDME(X) xprintf("%s(l.%i) %I: %p\n", __FUNCTION__, __LINE__, \ + get_entity_ident(X), (X)) + +/*#endif*/ # endif /* _IRNODE_H_ */ diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 74404057f..003b6b8ba 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -427,6 +427,7 @@ equivalent_node (ir_node *n) n_preds = get_Phi_n_preds(n); block = get_nodes_Block(n); + if (is_Bad(block)) return new_Bad(); assert(get_irn_op (block) == op_Block); /* there should be no Phi nodes in the Start region. */ diff --git a/ir/tr/entity.c b/ir/tr/entity.c index a87696c64..4af08366c 100644 --- a/ir/tr/entity.c +++ b/ir/tr/entity.c @@ -177,6 +177,11 @@ set_entity_ld_ident (entity *ent, ident *ld_ident) { ent->ld_name = ld_ident; } +inline const char * +get_entity_ld_name (entity *ent) { + return id_to_str(get_entity_ld_ident(ent)); +} + /* char *get_entity_ld_name (entity *); void set_entity_ld_name (entity *, char *ld_name); @@ -264,6 +269,30 @@ set_atomic_ent_value(entity *ent, ir_node *val) { ent->value = val; } +ir_node *copy_value(ir_node *n) { + ir_node *nn; + ir_mode *m; + + m = get_irn_mode(n); + switch(get_irn_opcode(n)) { + case iro_Const: + nn = new_Const(m, get_Const_tarval(n)); break; + case iro_SymConst: + nn = new_SymConst(get_SymConst_type_or_id(n), get_SymConst_kind(n)); break; + case iro_Add: + nn = new_Add(copy_value(get_Add_left(n)), copy_value(get_Add_right(n)), m); break; + default: + assert(0 && "opdope invalid or not implemented"); break; + } + return nn; +} + +/* Copies the value represented by the entity to current_block + in current_ir_graph. */ +ir_node *copy_atomic_ent_value(entity *ent) { + assert(ent && is_atomic_entity(ent) && (ent->variability != uninitialized)); + return copy_value(ent->value); +} /* A value of a compound entity is a pair of value and the corresponding member of the compound. */ @@ -286,6 +315,12 @@ get_compound_ent_value(entity *ent, int pos) { return ent->values[pos+1]; } +/* Copies the value i of the entity to current_block in current_ir_graph. */ +ir_node *copy_compound_ent_value(entity *ent, int pos) { + assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized)); + return copy_value(ent->values[pos+1]); +} + inline entity * get_compound_ent_value_member(entity *ent, int pos) { assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized)); @@ -362,13 +397,13 @@ set_entity_irg(entity *ent, ir_graph *irg) { } int is_atomic_entity(entity *ent) { - type* t = ent->type; + type* t = get_entity_type(ent); return (is_primitive_type(t) || is_pointer_type(t) || is_enumeration_type(t) || is_method_type(t)); } int is_compound_entity(entity *ent) { - type* t = ent->type; + type* t = get_entity_type(ent); return (is_class_type(t) || is_struct_type(t) || is_array_type(t) || is_union_type(t)); } diff --git a/ir/tr/entity.h b/ir/tr/entity.h index 1e4d527f7..c7bd82f5f 100644 --- a/ir/tr/entity.h +++ b/ir/tr/entity.h @@ -129,6 +129,7 @@ ident *get_entity_ident (entity *ent); with mangle_entity() and remembers this new name internally. */ ident *get_entity_ld_ident (entity *ent); void set_entity_ld_ident (entity *ent, ident *ld_ident); +const char *get_entity_ld_name (entity *end); /* char *get_entity_ld_name (entity *ent); @@ -193,17 +194,22 @@ typedef enum { ent_volatility get_entity_volatility (entity *ent); void set_entity_volatility (entity *ent, ent_volatility vol); -/* Set has no effect for entities of type method. */ -ir_node * get_atomic_ent_value(entity *ent); -void set_atomic_ent_value(entity *ent, ir_node *val); - -/* A value of a compound entity is a pair of value and the corresponding member of - the compound. */ -void add_compound_ent_value(entity *ent, ir_node *val, entity *member); -int get_compound_ent_n_values(entity *ent); -ir_node *get_compound_ent_value(entity *ent, int pos); -entity *get_compound_ent_value_member(entity *ent, int pos); -void set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos); +/* Set has no effect for entities of type method. */ +ir_node *get_atomic_ent_value(entity *ent); +void set_atomic_ent_value(entity *ent, ir_node *val); +/* Copies the value represented by the entity to current_block + in current_ir_graph. */ +ir_node *copy_atomic_ent_value(entity *ent); + +/* A value of a compound entity is a pair of value and the corresponding + member of the compound. */ +void add_compound_ent_value(entity *ent, ir_node *val, entity *member); +int get_compound_ent_n_values(entity *ent); +ir_node *get_compound_ent_value(entity *ent, int pos); +entity *get_compound_ent_value_member(entity *ent, int pos); +void set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos); +/* Copies the value pos of the entity to current_block in current_ir_graph. */ +ir_node *copy_compound_ent_value(entity *ent, int pos); /* Only set if layout = fixed. */ int get_entity_offset (entity *ent); diff --git a/ir/tr/mangle.c b/ir/tr/mangle.c index 2ac453213..bbdf74e11 100644 --- a/ir/tr/mangle.c +++ b/ir/tr/mangle.c @@ -59,12 +59,26 @@ mangle_type (type *type) return res; } -/* Returns a new ident that represents first_scnd. */ +/* Returns a new ident that represents firstscnd. */ ident *mangle (ident *first, ident* scnd) { char *cp; int len; ident *res; + xoprintf (&mangle_obst, "%I%I", first, scnd); + len = obstack_object_size (&mangle_obst); + cp = obstack_finish (&mangle_obst); + res = id_from_str (cp, len); + obstack_free (&mangle_obst, cp); + return res; +} + +/* Returns a new ident that represents first_scnd. */ +ident *mangle_u (ident *first, ident* scnd) { + char *cp; + int len; + ident *res; + xoprintf (&mangle_obst, "%I_%I", first, scnd); len = obstack_object_size (&mangle_obst); cp = obstack_finish (&mangle_obst); @@ -73,6 +87,7 @@ ident *mangle (ident *first, ident* scnd) { return res; } + void init_mangle (void) { diff --git a/ir/tr/mangle.h b/ir/tr/mangle.h index ca97e7464..72098a915 100644 --- a/ir/tr/mangle.h +++ b/ir/tr/mangle.h @@ -22,5 +22,9 @@ ident *mangle_entity (entity *ent); /* Sorry, I'm not sure what this does... seems to copy the string. */ ident *mangle_type (type *type); -/* Returns a new ident that represents first_scnd. */ +/* mangle underscore: Returns a new ident that represents first_scnd. */ +ident *mangle_u (ident *first, ident* scnd); + + +/* mangle: Returns a new ident that represents firstscnd. */ ident *mangle (ident *first, ident* scnd); diff --git a/ir/tr/type.c b/ir/tr/type.c index fc6a499c8..f17dece13 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -610,7 +610,7 @@ type *new_type_array (ident *name, int n_dimensions, res->attr.aa.order[i] = i; } res->attr.aa.element_type = element_type; - new_entity(res, mangle(name, id_from_str("elem_ent", 8)), element_type); + new_entity(res, mangle_u(name, id_from_str("elem_ent", 8)), element_type); return res; } inline void free_array_attrs (type *array) { diff --git a/ir/tr/typewalk.c b/ir/tr/typewalk.c index 0b95917a6..23043d0dd 100644 --- a/ir/tr/typewalk.c +++ b/ir/tr/typewalk.c @@ -18,7 +18,7 @@ #include #include #include "irgwalk.h" -#include "irgraph.h" +#include "irgraph_t.h" #include "irnode.h" #include "irprog.h" #include "type_or_entity.h" @@ -283,9 +283,68 @@ void type_walk_super2sub(void (pre)(type_or_ent*, void*), void (post)(type_or_ent*, void*), void *env) { int i; + type *tp; ++type_visited; type_walk_s2s_2((type_or_ent *)get_glob_type(), pre, post, env); for (i = 0; i < get_irp_n_types(); i++) { - type_walk_s2s_2((type_or_ent *)get_irp_type(i), pre, post, env); + tp = get_irp_type(i); + type_walk_s2s_2((type_or_ent *)tp, pre, post, env); + } +} + +/*****************************************************************************/ + + +void class_walk_s2s_2(type *tp, + void (pre)(type*, void*), + void (post)(type*, void*), + void *env) +{ + int i; + + /* marked? */ + if (tp->visit >= type_visited) return; + + assert(is_class_type(tp)); + /* Assure all supertypes are visited before */ + for (i=0; i < get_class_n_supertype(tp); i++) { + if (get_type_visited(get_class_supertype(tp, i)) < type_visited) + return; + } + + mark_type_visited(tp); + + /* execute pre method */ + if(pre) + pre(tp, env); + + tp = skip_tid((type*)tp); + for (i=0; ivisit < type_visited) && + (!is_frame_type(tp)) && + (tp != get_glob_type())) { + class_walk_s2s_2(tp, pre, post, env); + } } } diff --git a/ir/tr/typewalk.h b/ir/tr/typewalk.h index 9968375ed..23f5f73a8 100644 --- a/ir/tr/typewalk.h +++ b/ir/tr/typewalk.h @@ -35,15 +35,25 @@ void type_walk_irg(ir_graph *irg, void (post)(type_or_ent*, void*), void *env); -/** Walks over all classes information reachable from global roots. +/** Walks over all type information reachable from global roots. Touches every class in specified order: - first the super class - second the class itself - third the sub classes. If new classes are created during the traversal these will be visited, too. **/ -/** @@@ shoulc be named class-walk **/ +/** @@@ should be named class-walk **/ void type_walk_super2sub(void (pre)(type_or_ent*, void*), void (post)(type_or_ent*, void*), void *env); +/* Same as type_walk_super2sub, but visits only class types. + Executes pre for a class if all superclasses have been visited. + Then iterates to subclasses. Executes post after return from + subclass. + Does not visit global type, frame types. +*/ +/* @@@ ?? something is wrong with this. */ +void class_walk_super2sub(void (pre)(type*, void*), + void (post)(type*, void*), + void *env); #endif /* _TYPEWALK_H_ */ diff --git a/ir/tv/tv.c b/ir/tv/tv.c index 4e8f62d6d..80ea0dc9f 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -1672,7 +1672,7 @@ tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN) if (val->u.p.xname) { printed = XPR (val->u.p.xname); } else if (val->u.p.ent) { - printed = XPF1R ("(%I)", val->u.p.ent->name); + printed = XPF1R ("(%I)", get_entity_ld_ident(val->u.p.ent)); } else { assert (val == tarval_p_void); printed = XPSR ("(void)"); diff --git a/testprograms/endless_loop.c b/testprograms/endless_loop.c index 446b5b16f..eb7e380ff 100644 --- a/testprograms/endless_loop.c +++ b/testprograms/endless_loop.c @@ -136,7 +136,8 @@ main(void) /* output the vcg file */ printf("Done building the graph. Dumping it.\n"); - turn_of_edge_labels(); + //turn_of_edge_labels(); + dump_keepalive_edges(); dump_all_types(); dump_ir_block_graph (irg); printf("Use xvcg to view this graph:\n"); -- 2.20.1