remove opt_polymorphy
authorMatthias Braun <matze@braunis.de>
Fri, 18 Nov 2011 13:18:55 +0000 (14:18 +0100)
committerMatthias Braun <matze@braunis.de>
Fri, 18 Nov 2011 16:54:48 +0000 (17:54 +0100)
this is part of the initiative to move object-orientation support stuff
out of libfirm into liboo

include/libfirm/irflag.h
ir/ana/cgana.c
ir/ir/irflag_t.def
ir/ir/irflag_t.h
ir/ir/iropt.c
ir/opt/ldstopt.c
ir/opt/opt_polymorphy.c [deleted file]
ir/opt/opt_polymorphy.h [deleted file]

index 2356b25..e32d868 100644 (file)
@@ -96,15 +96,6 @@ FIRM_API int get_opt_cse(void);
  */
 FIRM_API void set_opt_global_cse(int value);
 
-/** Enable/Disable optimization of dynamic method dispatch.
- *
- * This flag enables/disables the optimization of dynamic method dispatch.
- * If the flag is turned on Sel nodes can be replaced by Const nodes representing
- * the address of a function.
- */
-FIRM_API void set_opt_dyn_meth_dispatch(int value);
-FIRM_API int get_opt_dyn_meth_dispatch(void);
-
 /** Restricts the behavior of cast optimization.
  *
  *  If set, downcast are not optimized if they might be
index e70ece6..edfd6ec 100644 (file)
@@ -185,6 +185,7 @@ static void sel_methods_walker(ir_node *node, void *env)
                         */
                        assert(get_entity_irg(ent) == NULL);
                }
+#if 0
                else if (get_opt_closed_world() && get_opt_dyn_meth_dispatch() &&
                        (ARR_LEN(arr) == 1 && arr[0] != NULL)) {
                        ir_node *new_node;
@@ -199,6 +200,7 @@ static void sel_methods_walker(ir_node *node, void *env)
                        DBG_OPT_POLY(node, new_node);
                        exchange(node, new_node);
                }
+#endif
        }
 }
 
index f86f957..b22823e 100644 (file)
@@ -51,9 +51,6 @@ I_FLAG(algebraic_simplification           , 4, ON)
 /** Use Global Null Pointer Test elimination. */
 I_FLAG(global_null_ptr_elimination        , 5, ON)
 
-/** Remove dynamic method dispatch. */
-E_FLAG(dyn_meth_dispatch                  , 6, ON)
-
 /** Optimize cast nodes. */
 E_FLAG(suppress_downcast_optimization     , 7, OFF)
 
index 72d864c..a963f9e 100644 (file)
@@ -103,7 +103,6 @@ static inline firm_verification_t get_node_verification_mode(void)
 
 #define get_optimize()                           get_optimize_()
 #define get_opt_cse()                            get_opt_cse_()
-#define get_opt_dyn_meth_dispatch()              get_opt_dyn_meth_dispatch_()
 #define get_opt_suppress_downcast_optimization() get_opt_suppress_downcast_optimization_()
 
 #endif
index ffafca6..2d4a5e9 100644 (file)
@@ -43,7 +43,6 @@
 #include "irhooks.h"
 #include "irarch.h"
 #include "hashptr.h"
-#include "opt_polymorphy.h"
 #include "irtools.h"
 #include "irhooks.h"
 #include "array_t.h"
@@ -6372,7 +6371,6 @@ void firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops)
        CASE(Phi);
        CASE(Proj);
        CASE(Rotl);
-       CASE(Sel);
        CASE(Shl);
        CASE(Shr);
        CASE(Shrs);
index f7d8278..9bb8de6 100644 (file)
@@ -43,7 +43,6 @@
 #include "irhooks.h"
 #include "iredges.h"
 #include "irpass.h"
-#include "opt_polymorphy.h"
 #include "irmemory.h"
 #include "irnodehashmap.h"
 #include "irgopt.h"
@@ -1142,61 +1141,56 @@ static unsigned optimize_load(ir_node *load)
                return res | DF_CHANGED;
        }
 
-       /* Load from a constant polymorphic field, where we can resolve
-          polymorphism. */
-       value = transform_polymorph_Load(load);
-       if (value == load) {
-               value = NULL;
-               /* check if we can determine the entity that will be loaded */
-               ent = find_constant_entity(ptr);
-               if (ent != NULL
-                               && get_entity_visibility(ent) != ir_visibility_external) {
-                       /* a static allocation that is not external: there should be NO
-                        * exception when loading even if we cannot replace the load itself.
-                        */
+       value = NULL;
+       /* check if we can determine the entity that will be loaded */
+       ent = find_constant_entity(ptr);
+       if (ent != NULL
+                       && get_entity_visibility(ent) != ir_visibility_external) {
+               /* a static allocation that is not external: there should be NO
+                * exception when loading even if we cannot replace the load itself.
+                */
 
-                       /* no exception, clear the info field as it might be checked later again */
-                       if (info->projs[pn_Load_X_except]) {
-                               ir_graph *irg = get_irn_irg(load);
-                               exchange(info->projs[pn_Load_X_except], new_r_Bad(irg, mode_X));
-                               info->projs[pn_Load_X_except] = NULL;
-                               res |= CF_CHANGED;
-                       }
-                       if (info->projs[pn_Load_X_regular]) {
-                               exchange(info->projs[pn_Load_X_regular], new_r_Jmp(get_nodes_block(load)));
-                               info->projs[pn_Load_X_regular] = NULL;
-                               res |= CF_CHANGED;
-                       }
+               /* no exception, clear the info field as it might be checked later again */
+               if (info->projs[pn_Load_X_except]) {
+                       ir_graph *irg = get_irn_irg(load);
+                       exchange(info->projs[pn_Load_X_except], new_r_Bad(irg, mode_X));
+                       info->projs[pn_Load_X_except] = NULL;
+                       res |= CF_CHANGED;
+               }
+               if (info->projs[pn_Load_X_regular]) {
+                       exchange(info->projs[pn_Load_X_regular], new_r_Jmp(get_nodes_block(load)));
+                       info->projs[pn_Load_X_regular] = NULL;
+                       res |= CF_CHANGED;
+               }
 
-                       if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) {
-                               if (has_entity_initializer(ent)) {
-                                       /* new style initializer */
-                                       value = find_compound_ent_value(ptr);
-                               } else if (entity_has_compound_ent_values(ent)) {
-                                       /* old style initializer */
-                                       compound_graph_path *path = get_accessed_path(ptr);
+               if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) {
+                       if (has_entity_initializer(ent)) {
+                               /* new style initializer */
+                               value = find_compound_ent_value(ptr);
+                       } else if (entity_has_compound_ent_values(ent)) {
+                               /* old style initializer */
+                               compound_graph_path *path = get_accessed_path(ptr);
 
-                                       if (path != NULL) {
-                                               assert(is_proper_compound_graph_path(path, get_compound_graph_path_length(path)-1));
+                               if (path != NULL) {
+                                       assert(is_proper_compound_graph_path(path, get_compound_graph_path_length(path)-1));
 
-                                               value = get_compound_ent_value_by_path(ent, path);
-                                               DB((dbg, LEVEL_1, "  Constant access at %F%F resulted in %+F\n", ent, path, value));
-                                               free_compound_graph_path(path);
-                                       }
+                                       value = get_compound_ent_value_by_path(ent, path);
+                                       DB((dbg, LEVEL_1, "  Constant access at %F%F resulted in %+F\n", ent, path, value));
+                                       free_compound_graph_path(path);
                                }
-                               if (value != NULL) {
-                                       ir_graph *irg = get_irn_irg(load);
-                                       value = can_replace_load_by_const(load, value);
-                                       if (value != NULL && is_Sel(ptr) &&
-                                                       !is_irg_state(irg, IR_GRAPH_STATE_IMPLICIT_BITFIELD_MASKING)) {
-                                               /* frontend has inserted masking operations after bitfield accesses,
-                                                * so we might have to shift the const. */
-                                               unsigned char bit_offset = get_entity_offset_bits_remainder(get_Sel_entity(ptr));
-                                               ir_tarval *tv_old = get_Const_tarval(value);
-                                               ir_tarval *tv_offset = new_tarval_from_long(bit_offset, mode_Bu);
-                                               ir_tarval *tv_new = tarval_shl(tv_old, tv_offset);
-                                               value = new_r_Const(irg, tv_new);
-                                       }
+                       }
+                       if (value != NULL) {
+                               ir_graph *irg = get_irn_irg(load);
+                               value = can_replace_load_by_const(load, value);
+                               if (value != NULL && is_Sel(ptr) &&
+                                               !is_irg_state(irg, IR_GRAPH_STATE_IMPLICIT_BITFIELD_MASKING)) {
+                                       /* frontend has inserted masking operations after bitfield accesses,
+                                        * so we might have to shift the const. */
+                                       unsigned char bit_offset = get_entity_offset_bits_remainder(get_Sel_entity(ptr));
+                                       ir_tarval *tv_old = get_Const_tarval(value);
+                                       ir_tarval *tv_offset = new_tarval_from_long(bit_offset, mode_Bu);
+                                       ir_tarval *tv_new = tarval_shl(tv_old, tv_offset);
+                                       value = new_r_Const(irg, tv_new);
                                }
                        }
                }
diff --git a/ir/opt/opt_polymorphy.c b/ir/opt/opt_polymorphy.c
deleted file mode 100644 (file)
index 42446d5..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief   Optimize polymorphic Sel and Load nodes.
- * @author  Goetz Lindenmaier, Michael Beck
- * @brief
- *  This file subsumes optimization code from cgana.
- */
-#include "config.h"
-
-#include "opt_polymorphy.h"
-#include "iroptimize.h"
-#include "irprog_t.h"
-#include "entity_t.h"
-#include "type_t.h"
-#include "irop.h"
-#include "irnode_t.h"
-#include "ircons.h"
-
-#include "iropt_dbg.h"
-#include "irflag_t.h"
-
-/**
- * Checks if a graph allocates new memory and returns the
- * type of the newly allocated entity.
- * Returns NULL if the graph did not represent an Allocation.
- *
- * The default implementation hecks for Alloc nodes only.
- */
-static ir_type *default_firm_get_Alloc(ir_node *n)
-{
-       n = skip_Proj(n);
-       if (is_Alloc(n)) {
-               return get_Alloc_type(n);
-       }
-       return NULL;
-}
-
-/** The get_Alloc function */
-static get_Alloc_func firm_get_Alloc = default_firm_get_Alloc;
-
-/** Set a new get_Alloc_func and returns the old one. */
-get_Alloc_func firm_set_Alloc_func(get_Alloc_func newf)
-{
-       get_Alloc_func old = firm_get_Alloc;
-       firm_get_Alloc = newf;
-       return old;
-}
-
-/** Return dynamic type of ptr.
- *
- * If we can deduct the dynamic type from the firm nodes
- * by a limited test we return the dynamic type.  Else
- * we return unknown_type.
- *
- * If we find a dynamic type this means that the pointer always points
- * to an object of this type during runtime.   We resolved polymorphy.
- */
-static ir_type *get_dynamic_type(ir_node *ptr)
-{
-       ir_type *tp;
-
-       /* skip Cast and Confirm nodes */
-       for (;;) {
-               unsigned code = get_irn_opcode(ptr);
-
-               switch (code) {
-               case iro_Cast:
-                       ptr = get_Cast_op(ptr);
-                       continue;
-               case iro_Confirm:
-                       ptr = get_Confirm_value(ptr);
-                       continue;
-               default:
-                       break;
-               }
-               break;
-       }
-       tp = (*firm_get_Alloc)(ptr);
-       return tp ? tp : firm_unknown_type;
-}
-
-/**
- * Check, if an entity is final, i.e. is not anymore overridden.
- */
-static int is_final_ent(ir_entity *ent)
-{
-       if (is_entity_final(ent)) {
-               /* not possible to override this entity. */
-               return 1;
-       }
-       if (get_opt_closed_world() && get_entity_n_overwrittenby(ent) == 0) {
-               /* we have a closed world, so simply check how often it was
-               overridden. */
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * Transform Sel[method] to SymC[method] if possible.
- */
-ir_node *transform_node_Sel(ir_node *node)
-{
-       ir_node   *new_node, *ptr;
-       ir_type   *dyn_tp;
-       ir_entity *ent = get_Sel_entity(node);
-
-       if (get_irp_phase_state() == phase_building) return node;
-
-       if (!get_opt_dyn_meth_dispatch())
-               return node;
-
-       if (!is_Method_type(get_entity_type(ent)))
-               return node;
-
-       /* If the entity is a leave in the inheritance tree,
-          we can replace the Sel by a constant. */
-       if (is_final_ent(ent)) {
-               /* In dead code, we might call a leave entity that is a description.
-                  Do not turn the Sel to a SymConst. */
-               if (get_entity_peculiarity(ent) == peculiarity_description) {
-                       /* We could remove the Call depending on this Sel. */
-                       new_node = node;
-               } else {
-                       new_node = copy_const_value(get_irn_dbg_info(node), get_atomic_ent_value(ent), get_nodes_block(node));
-                       DBG_OPT_POLY(node, new_node);
-               }
-               return new_node;
-       }
-
-       /* If we know the dynamic type, we can replace the Sel by a constant. */
-       ptr = get_Sel_ptr(node);      /* The address we select from. */
-       dyn_tp = get_dynamic_type(ptr);  /* The runtime type of ptr. */
-
-       if (dyn_tp != firm_unknown_type) {
-               ir_entity *called_ent;
-
-               /* We know which method will be called, no dispatch necessary. */
-               called_ent = resolve_ent_polymorphy(dyn_tp, ent);
-
-               new_node = copy_const_value(get_irn_dbg_info(node), get_atomic_ent_value(called_ent), get_nodes_block(node));
-               DBG_OPT_POLY(node, new_node);
-
-               return new_node;
-       }
-
-       return node;
-}
-
-/* Transform  Load(Sel(Alloc)[constant static entity])
- *  to Const[constant static entity value].
- *
- *  This function returns a node replacing the Proj(Load)[Value].
- *  If this is actually called in transform_node, we must build
- *  a tuple, or replace the Projs of the load.
- *  Therefore we call this optimization in ldstopt().
- */
-ir_node *transform_polymorph_Load(ir_node *load)
-{
-       ir_node *new_node = NULL;
-       ir_node *field_ptr, *ptr;
-       ir_entity *ent;
-       ir_type *dyn_tp;
-
-       if (!get_opt_dyn_meth_dispatch())
-               return load;
-
-       field_ptr = get_Load_ptr(load);
-
-       if (! is_Sel(field_ptr)) return load;
-
-       ent = get_Sel_entity(field_ptr);
-       if ( !(get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) )
-               return load;
-
-       /* If the entity is a leave in the inheritance tree,
-          we can replace the Sel by a constant. */
-       if ((get_irp_phase_state() != phase_building) && is_final_ent(ent)) {
-               new_node = get_atomic_ent_value(ent);
-       } else {
-               /* If we know the dynamic type, we can replace the Sel by a constant. */
-               ptr = get_Sel_ptr(field_ptr);    /* The address we select from. */
-               dyn_tp = get_dynamic_type(ptr);  /* The runtime type of ptr. */
-
-               if (dyn_tp != firm_unknown_type) {
-                       ir_entity *loaded_ent;
-
-                       /* We know which method will be called, no dispatch necessary. */
-                       loaded_ent = resolve_ent_polymorphy(dyn_tp, ent);
-                       new_node = get_atomic_ent_value(loaded_ent);
-               }
-       }
-       if (new_node != NULL) {
-               new_node = can_replace_load_by_const(load, new_node);
-               if (new_node != NULL) {
-                       DBG_OPT_POLY(field_ptr, new_node);
-
-                       return new_node;
-               }
-       }
-       return load;
-}
diff --git a/ir/opt/opt_polymorphy.h b/ir/opt/opt_polymorphy.h
deleted file mode 100644 (file)
index 16b1318..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief   Optimize polymorphic Sel and Load nodes.
- * @author  Goetz Lindenmaier, Michael Beck
- * @brief
- *  This file subsumes optimization code from cgana.
- */
-#ifndef FIRM_OPT_OPT_POLYMORPHY_H
-#define FIRM_OPT_OPT_POLYMORPHY_H
-
-#include "firm_types.h"
-
-/**
- * Transform  Sel(Alloc)[method]
- * to SymC[method] under the following conditions:
- *
- * - opt_dyn_meth_dispatch must be set
- * - the method is not overwritten OR
- * - the dynamic type is known
- */
-ir_node *transform_node_Sel(ir_node *node);
-
-/** Transform  Load(Sel(Alloc)[constant static entity])
- *  to Const[constant static entity value].
- *
- *  This function returns a node replacing the Proj(Load)[Value].
- *  If this is actually called in transform_node, we must build
- *  a tuple, or replace the Projs of the load.
- *  Therefore we call this optimization in ldstopt.
- */
-ir_node *transform_polymorph_Load(ir_node *n);
-
-#endif /* FIRM_OPT_OPT_POLYMORPHY_H */