From 382defb529c86fac61baacb80ce2d6ce3d5f88a9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=B6tz=20Lindenmaier?= Date: Thu, 19 Dec 2002 09:45:01 +0000 Subject: [PATCH] Added static to many static routines Fixed error in backedge: backedge array was not updated when in array was changed. [r564] --- ir/ana/ANALYSING_ALGORITHMS | 0 ir/ana/cgana.c | 10 +++++-- ir/ana/cgana.h | 12 +++++++-- ir/ana/irbackedge.c | 54 +++++++++++++++++++++++++++++++++++-- ir/ana/irbackedge_t.h | 18 +++---------- ir/ana/irdom.c | 8 +++--- ir/ana/irouts.c | 6 ++--- ir/ana/irscc.c | 11 ++++---- 8 files changed, 87 insertions(+), 32 deletions(-) create mode 100644 ir/ana/ANALYSING_ALGORITHMS diff --git a/ir/ana/ANALYSING_ALGORITHMS b/ir/ana/ANALYSING_ALGORITHMS new file mode 100644 index 000000000..e69de29bb diff --git a/ir/ana/cgana.c b/ir/ana/cgana.c index 6ce436709..a3a30d4b7 100644 --- a/ir/ana/cgana.c +++ b/ir/ana/cgana.c @@ -73,7 +73,12 @@ entity *get_inherited_methods_implementation(entity *inh_meth) { } -/* A recursive descend in the overwritten relation. +/* Collect the entity representing the implementation of this + entity (not the same if inherited) and all entities for overwriting + implementations in "set". + If the implementation of the method is not included in the + compilation unit "open" is set to true. + A recursive descend in the overwritten relation. Cycle-free, therefore must terminate. */ void collect_impls(entity *method, eset *set, int *size, bool *open) { int i; @@ -654,7 +659,8 @@ void cgana(int *length, entity ***free_methods) { DEL_ARR_F(free_meths); } -/* Alle SymConst-Operationen, die auf interne Methoden verweisen, +/* Optimize the address expressions passed to call nodes. + * Alle SymConst-Operationen, die auf interne Methoden verweisen, * werden durch Const-Operationen ersetzt. * Sel Knoten deren entitaeten nicht ueberschrieben werden, werden * durch Const ersetzt. diff --git a/ir/ana/cgana.h b/ir/ana/cgana.h index 78a4d4b70..141e0a15d 100644 --- a/ir/ana/cgana.h +++ b/ir/ana/cgana.h @@ -31,11 +31,17 @@ * Die Links an den "ir_node"s werden gelöscht. */ -/* Bestimmt für jede Call-Operation die Menge der aufrufbaren Methode + +/* Analyses a rough estimation of the possible call graph. + * Bestimmt für jede Call-Operation die Menge der aufrufbaren Methode * und speichert das Ergebnis in der Call-Operation. (siehe * "set_Call_callee"). Die Methode gibt die Menge der * "freien" Methoden zurück, die vom Aufrufer wieder freigegeben * werden muss (free). + * The algorithm implements roughly Static Class Hierarchy Analysis + * as described in "Optimization of Object-Oriented Programs Using + * Static Class Hierarchy Analysis" by Jeffrey Dean and David Grove + * and Craig Chambers. * * Performs some optimizations possible by the analysed information: * - Replace SymConst nodes by Const nodes if possible, @@ -45,7 +51,9 @@ /* @@@ I assume this can not be called via JNI :-( */ void cgana(int *len, entity ***free_methods); -/* Performs only the optimizations done by cgana. */ +/* Optimize the address expressions passed to call nodes. + * Performs only the optimizations done by cgana. */ /* @@@ move to irgopt ?! */ +/* @@@ not fully implemented as buggy !!! */ void opt_call_addrs(void); #endif /* _CGANA_H_ */ diff --git a/ir/ana/irbackedge.c b/ir/ana/irbackedge.c index 5d6a1c0cd..28cd09e2a 100644 --- a/ir/ana/irbackedge.c +++ b/ir/ana/irbackedge.c @@ -10,6 +10,8 @@ /* $Id$ */ #include "irnode_t.h" +#include "array.h" +#include "irbackedge_t.h" /**********************************************************************/ /** Backedge information. **/ @@ -17,8 +19,9 @@ /* Returns backarray if the node can have backedges. Else returns - NULL. */ -inline int *get_backarray(ir_node *n) { + NULL. Does not assert whether the backarray is correct -- use + very careful! */ +static INLINE int *mere_get_backarray(ir_node *n) { switch(get_irn_opcode(n)) { case iro_Block: if (interprocedural_view && n->attr.block.in_cg) { @@ -44,6 +47,53 @@ inline int *get_backarray(ir_node *n) { return NULL; } +/* Returns backarray if the node can have backedges. Else returns + NULL. */ +static INLINE int *get_backarray(ir_node *n) { + int *ba = mere_get_backarray(n); + + if (ba) { + int bal = ARR_LEN(ba); /* avoid makro expansion in assertion. */ + int inl = ARR_LEN(get_irn_in(n)) -1; /* Use get_irn_in -- sensitive to view! */ + assert(bal == inl && "backedge array with faulty length"); + } + + return ba; +} + +/* returns true if node has no backarray, or + if size of backarray == size of in array. */ +static INLINE bool legal_backarray (ir_node *n) { + int *ba = mere_get_backarray(n); + if (ba && (ARR_LEN(ba) != ARR_LEN(get_irn_in(n))-1)) /* Use get_irn_in -- sensitive to view! */ + return false; + return true; +} + + +INLINE void fix_backedges(struct obstack *obst, ir_node *n) { + opcode opc = get_irn_opcode(n); + int *arr = mere_get_backarray(n); + if (ARR_LEN(arr) == ARR_LEN(get_irn_in(n))-1) + return; + if (ARR_LEN(arr) != ARR_LEN(get_irn_in(n))-1) { + arr = new_backedge_arr(obst, ARR_LEN(get_irn_in(n))-1); + if (opc == iro_Phi) n->attr.phi_backedge = arr; + if ((opc == iro_Block) && !interprocedural_view) + n->attr.block.backedge = arr; + if ((opc == iro_Block) && interprocedural_view) + n->attr.block.cg_backedge = arr; + if (opc == iro_Filter) n->attr.filter.backedge = arr; + return; + } + assert(legal_backarray(n)); + // @@@ more efficient in memory consumption, not possible with + // array implementation. + //if (ARR_LEN(arr) < ARR_LEN(get_irn_in(n))-1) { + // ARR_SETLEN(int, arr, ARR_LEN(get_irn_in(n))-1); + //} +} + /* Returns true if the predesessor pos is a backedge. */ bool is_backedge (ir_node *n, int pos) { int *ba = get_backarray (n); diff --git a/ir/ana/irbackedge_t.h b/ir/ana/irbackedge_t.h index 4f3d9188f..2478d0206 100644 --- a/ir/ana/irbackedge_t.h +++ b/ir/ana/irbackedge_t.h @@ -9,19 +9,9 @@ static INLINE int * new_backedge_arr(struct obstack *obst, int size) { return res; } - -static INLINE void fix_backedges(struct obstack *obst, ir_node *n) { - opcode opc = get_irn_opcode(n); - int ** arr = NULL; - if (opc == iro_Phi) arr = &n->attr.phi_backedge; - if ((opc == iro_Block) && !interprocedural_view) - arr = &n->attr.block.backedge; - if ((opc == iro_Block) && interprocedural_view) - arr = &n->attr.block.cg_backedge; - if (opc == iro_Filter) arr = &n->attr.filter.backedge; - - if (ARR_LEN(arr) != ARR_LEN(get_irn_in(n))-1) - *arr = new_backedge_arr(obst, ARR_LEN(get_irn_in(n))-1); -} +/* Adapts backedges array to new size. + Must be called if in array of irnode is changed. Else + Segmentation faults might occur. */ +void fix_backedges(struct obstack *obst, ir_node *n); #endif /* _IRBACKEDGE_T_H_ */ diff --git a/ir/ana/irdom.c b/ir/ana/irdom.c index a66d209f9..de906b8d4 100644 --- a/ir/ana/irdom.c +++ b/ir/ana/irdom.c @@ -70,7 +70,7 @@ void set_Block_dom_depth(ir_node *bl, int depth) { /** **/ /**********************************************************************/ -void count_and_init_blocks(ir_node *bl, void *env) { +static void count_and_init_blocks(ir_node *bl, void *env) { int *n_blocks = (int *) env; (*n_blocks) ++; @@ -107,8 +107,8 @@ typedef struct { /* Walks Blocks along the out datastructure. If recursion started with Start block misses control dead blocks. */ -void init_tmp_dom_info(ir_node *bl, tmp_dom_info *parent, - tmp_dom_info *tdi_list, int* used) { +static void init_tmp_dom_info(ir_node *bl, tmp_dom_info *parent, + tmp_dom_info *tdi_list, int* used) { tmp_dom_info *tdi; int i; @@ -254,7 +254,7 @@ void compute_doms(ir_graph *irg) { } /* clean up */ - /* free(tdi_list); @@@ doew not work !!?? */ + /* free(tdi_list); @@@ does not work !!?? */ current_ir_graph = rem; } diff --git a/ir/ana/irouts.c b/ir/ana/irouts.c index 7fcaaec0c..bc5cbce04 100644 --- a/ir/ana/irouts.c +++ b/ir/ana/irouts.c @@ -164,7 +164,7 @@ void irg_out_block_walk(ir_node *node, /* Returns the amount of out edges for not yet visited successors. */ -int count_outs(ir_node *n) { +static int count_outs(ir_node *n) { int start, i, res; ir_node *succ; @@ -186,7 +186,7 @@ int count_outs(ir_node *n) { return res; } -ir_node **set_out_edges(ir_node *n, ir_node **free) { +static ir_node **set_out_edges(ir_node *n, ir_node **free) { int n_outs, start, i; ir_node *succ; @@ -214,7 +214,7 @@ ir_node **set_out_edges(ir_node *n, ir_node **free) { return free; } -INLINE void fix_start_proj(ir_graph *irg) { +static INLINE void fix_start_proj(ir_graph *irg) { ir_node *proj = NULL, *startbl; int i; if (get_Block_n_cfg_outs(get_irg_start_block(irg))) { diff --git a/ir/ana/irscc.c b/ir/ana/irscc.c index 3c8dcd6ef..0d462b821 100644 --- a/ir/ana/irscc.c +++ b/ir/ana/irscc.c @@ -109,7 +109,7 @@ get_irn_loop_tmp (ir_node *n) { return ((scc_info *)get_irn_link(n))->loop; } -ir_loop *find_nodes_loop (ir_node *n, ir_loop *l) { +static ir_loop *find_nodes_loop (ir_node *n, ir_loop *l) { int i; ir_loop *res = NULL; @@ -214,7 +214,7 @@ pop_scc_unmark_visit (ir_node *n) /* Allocates a new loop as son of current_loop. Sets current_loop to the new loop and returns the father. */ -ir_loop *new_loop (void) { +static ir_loop *new_loop (void) { ir_loop *father, *son; father = current_loop; @@ -239,7 +239,7 @@ ir_loop *new_loop (void) { /* Finishes the datastructures, copies the arrays to the obstack of current_ir_graph. */ -void mature_loop (ir_loop *loop) { +static void mature_loop (ir_loop *loop) { ir_loop **new_sons; ir_node **new_nods; @@ -357,6 +357,7 @@ init_ip_scc () { init_stack(); cg_walk (init_node, NULL, NULL); } + #if 0 Works, but is inefficient. static INLINE void @@ -375,7 +376,7 @@ init_ip_scc () { #endif /* Condition for breaking the recursion. */ -bool is_outermost_Start(ir_node *n) { +static bool is_outermost_Start(ir_node *n) { /* Test whether this is the outermost Start node. If so recursion must end. */ if ((get_irn_op(n) == op_Block) && @@ -603,7 +604,7 @@ find_tail (ir_node *n) { /* The core algorithm. *****************************************/ -void scc (ir_node *n) { +static void scc (ir_node *n) { int i; ir_graph *rem; -- 2.20.1