bugfixes
authorGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Tue, 9 Mar 2004 14:10:22 +0000 (14:10 +0000)
committerGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Tue, 9 Mar 2004 14:10:22 +0000 (14:10 +0000)
[r2515]

ir/ana/cgana.c
ir/ir/ircgcons.c
ir/ir/irgopt.c
ir/ir/irgopt.h
ir/ir/irgraph.c
ir/ir/irgraph.h
ir/ir/irgraph_t.h
ir/ir/irnode.h
ir/tr/entity.c
ir/tr/entity.h

index a750e02..619c304 100644 (file)
@@ -209,12 +209,22 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
     if (get_optimize() && get_opt_dyn_meth_dispatch() &&
        (get_irn_op(skip_Proj(get_Sel_ptr(node))) == op_Alloc)) {
       ir_node *new_node;
+      entity *called_ent;
       /* We know which method will be called, no dispatch necessary. */
+#if 0
       assert(get_entity_peculiarity(ent) != peculiarity_description);
       set_irg_current_block(current_ir_graph, get_nodes_Block(node));
       /* @@@ Is this correct?? Alloc could reference a subtype of the owner
         of Sel that overwrites the method referenced in Sel. */
+      /* @@@ Yes, this is wrong. GL, 10.3.04 */
       new_node = copy_const_value(get_atomic_ent_value(ent));              DBG_OPT_POLY_ALLOC;
+#else
+      called_ent = resolve_ent_polymorphy(get_Alloc_type(skip_Proj(get_Sel_ptr(node))), ent);
+      set_irg_current_block(current_ir_graph, get_nodes_Block(node));
+      /* called_ent may not be description: has no Address/Const to Call! */
+      assert(get_entity_peculiarity(called_ent) != peculiarity_description);
+      new_node = copy_const_value(get_atomic_ent_value(called_ent));       DBG_OPT_POLY_ALLOC;
+#endif
       exchange (node, new_node);
     } else {
       assert(get_entity_peculiarity(ent) != peculiarity_inherited);
@@ -508,6 +518,7 @@ static void callee_ana(void) {
   /* Alle Graphen analysieren. */
   for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
     irg_walk_graph(get_irp_irg(i), callee_walker, NULL, NULL);
+    set_irg_callee_info_state(get_irp_irg(i), irg_callee_info_consistent);
   }
 }
 
index 75f40cc..dd9af4a 100644 (file)
@@ -830,5 +830,6 @@ void cg_destruct(void) {
     irg_walk_graph(irg, destruct_walker, clear_link, NULL);
     set_irg_frame(irg, skip_nop(get_irg_frame(irg)));
     set_irg_globals(irg, skip_nop(get_irg_globals(irg)));
+    set_irg_callee_info_state(irg, irg_callee_info_none);
   }
 }
index 3ac0ec5..e170b8f 100644 (file)
@@ -412,6 +412,7 @@ dead_node_elimination(ir_graph *irg) {
 
   /* Handle graph state */
   assert(get_irg_phase_state(current_ir_graph) != phase_building);
+  assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none);
   free_outs(current_ir_graph);
 
   /* @@@ so far we loose loops when copying */
@@ -571,7 +572,6 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   ir_node **res_pred;
   ir_node **cf_pred;
   ir_node *ret, *phi;
-  ir_node *cf_op = NULL, *bl;
   int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
   int exc_handling; ir_node *proj;
   type *called_frame;
@@ -972,6 +972,7 @@ void inline_small_irgs(ir_graph *irg, int size) {
   current_ir_graph = irg;
   /* Handle graph state */
   assert(get_irg_phase_state(current_ir_graph) != phase_building);
+  assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none);
 
   /* Find Call nodes to inline.
      (We can not inline during a walk of the graph, as inlineing the same
@@ -1081,6 +1082,7 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
   for (i = 0; i < n_irgs; ++i) {
     current_ir_graph = get_irp_irg(i);
     assert(get_irg_phase_state(current_ir_graph) != phase_building);
+    assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none);
 
     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
             get_irg_link(current_ir_graph));
index 0c249a2..e85fd4e 100644 (file)
@@ -38,6 +38,8 @@ void local_optimize_graph (ir_graph *irg);
 
    Backedge information is conserved.
    Removes old attributes of nodes.  Sets link field to NULL.
+   Callee information must be freed (irg_callee_info_none).
+
    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);
index 652f3b9..3356e91 100644 (file)
@@ -71,6 +71,7 @@ new_ir_graph (entity *ent, int n_loc)
   ir_node *projX;
 
   res = (ir_graph *) malloc (sizeof (ir_graph));
+  memset(res, 0, sizeof (ir_graph));
   res->kind=k_ir_graph;
 
   current_ir_graph = res;
@@ -533,6 +534,15 @@ set_irg_pinned (ir_graph *irg, op_pinned p) {
   irg->pinned = p;
 }
 
+
+irg_callee_info_state get_irg_callee_info_state(ir_graph *irg) {
+  return irg->callee_info_state;
+}
+
+void set_irg_callee_info_state(ir_graph *irg, irg_callee_info_state s) {
+  irg->callee_info_state = s;
+}
+
 INLINE void
 set_irg_link (ir_graph *irg, void *thing) {
   irg->link = thing;
index c4a18f2..fae83fa 100644 (file)
@@ -254,6 +254,17 @@ irg_loopinfo_state get_irg_loopinfo_state(ir_graph *irg);
 void set_irg_loopinfo_inconsistent(ir_graph *irg);
 
 
+/** state: callee_information_state
+ *  Call nodes contain a list of possible callees.  This list must be
+ *  computed by an anlyses.  */
+typedef enum {
+  irg_callee_info_none,
+  irg_callee_info_consistent,
+  irg_callee_info_inconsistent
+} irg_callee_info_state;
+irg_callee_info_state get_irg_callee_info_state(ir_graph *irg);
+void set_irg_callee_info_state(ir_graph *irg, irg_callee_info_state s);
+
 /* A void * field to link arbritary information to the node. */
 void  set_irg_link (ir_graph *irg, void *thing);
 void *get_irg_link (ir_graph *irg);
index 0d0740c..4b8a0b5 100644 (file)
@@ -60,7 +60,8 @@ struct ir_graph {
   op_pinned pinned;                  /**< Flag for status of nodes */
   irg_outs_state outs_state;         /**< Out edges. */
   irg_dom_state dom_state;           /**< Dominator information */
-  irg_typeinfo_state typeinfo_state; /**< Validity of type inforamtion */
+  irg_typeinfo_state typeinfo_state; /**< Validity of type information */
+  irg_callee_info_state callee_info_state; /**< Validity of callee information */
 
   /* -- Fields for construction -- */
 #if USE_EXPLICIT_PHI_IN_STACK
index ed1b167..1e655b0 100644 (file)
@@ -448,6 +448,7 @@ INLINE int      get_Call_arity (ir_node *node);
 int     Call_has_callees      (ir_node *node);
 int     get_Call_n_callees    (ir_node * node);
 entity *get_Call_callee       (ir_node * node, int pos);
+/* assumes current_ir_graph set properly! */
 void    set_Call_callee_arr   (ir_node * node, int n, entity ** arr);
 void    remove_Call_callee_arr(ir_node * node);
 
index 0cd48b9..2bee183 100644 (file)
@@ -894,3 +894,28 @@ INLINE bool entity_visited(entity *ent) {
 INLINE bool entity_not_visited(entity *ent) {
   return get_entity_visited(ent) < type_visited;
 }
+
+/* Need two routines because I want to assert the result. */
+static INLINE entity *resolve_ent_polymorphy2 (type *dynamic_class, entity* static_ent) {
+  int i, n_overwrittenby;
+  entity *res = NULL;
+
+  if (get_entity_owner(static_ent) == dynamic_class) return static_ent;
+
+  n_overwrittenby = get_entity_n_overwrittenby(static_ent);
+  for (i = 0; i < n_overwrittenby; ++i) {
+    res = resolve_ent_polymorphy2(dynamic_class, get_entity_overwrittenby(static_ent, i));
+    if (res) break;
+  }
+
+  return res;
+}
+
+/* Returns the dynamically referenced entity if the static entity and the
+ *  dynamic type are given.
+ *  Search downwards in overwritten tree. */
+entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent) {
+  entity *res = resolve_ent_polymorphy2(dynamic_class, static_ent);
+  assert(res);
+  return res;
+}
index 72ac0bf..6938e11 100644 (file)
@@ -451,4 +451,8 @@ bool        entity_visited(entity *ent);
 /** Returns true if this entity was not visited. */
 bool        entity_not_visited(entity *ent);
 
+/** Returns the dynamically referenced entity if the static entity and the
+ *  dynamic type are given. */
+entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent);
+
 # endif /* _ENTITY_H_ */