From bdadb741281a7605235767c99d1440ab1edb3848 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Fri, 25 Jun 2004 12:24:33 +0000 Subject: [PATCH] irgraph: can be interrogated for initial mem Optimizations: Division by a non-NULL constant did not create a exception [r3213] --- ir/ir/ircgcons.c | 6 +- ir/ir/irgopt.c | 23 ++++-- ir/ir/irgraph.c | 205 +++++++++++++++++++++------------------------- ir/ir/irgraph.h | 45 ++++++---- ir/ir/irgraph_t.h | 171 ++++++++++++++++++++++++++++++-------- ir/ir/iropt.c | 107 ++++++++++++++++-------- 6 files changed, 357 insertions(+), 200 deletions(-) diff --git a/ir/ir/ircgcons.c b/ir/ir/ircgcons.c index 97e644eb7..c6011ea48 100644 --- a/ir/ir/ircgcons.c +++ b/ir/ir/ircgcons.c @@ -249,8 +249,9 @@ static void prepare_irg(ir_graph * irg, irg_data_t * data) { } } /* Globle Einträge für ersetzte Operationen korrigieren. */ - set_irg_frame(irg, skip_nop(get_irg_frame(irg))); - set_irg_globals(irg, skip_nop(get_irg_globals(irg))); + set_irg_frame (irg, skip_nop(get_irg_frame(irg))); + set_irg_globals (irg, skip_nop(get_irg_globals(irg))); + set_irg_initial_mem(irg, skip_nop(get_irg_initial_mem(irg))); /* Unbekannten Aufrufer sofort eintragen. */ if (data->open) { @@ -863,6 +864,7 @@ 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_initial_mem(irg, skip_nop(get_irg_initial_mem(irg))); set_irg_callee_info_state(irg, irg_callee_info_none); set_irg_end_reg(irg, get_irg_end(irg)); set_irg_end_except(irg, get_irg_end(irg)); diff --git a/ir/ir/irgopt.c b/ir/ir/irgopt.c index 06706f58d..6c9dcc740 100644 --- a/ir/ir/irgopt.c +++ b/ir/ir/irgopt.c @@ -387,9 +387,10 @@ copy_graph_env (void) { /* Not all nodes remembered in current_ir_graph might be reachable from the end node. Assure their link is set to NULL, so that we can test whether new nodes have been computed. */ - set_irn_link(get_irg_frame (current_ir_graph), NULL); - set_irn_link(get_irg_globals(current_ir_graph), NULL); - set_irn_link(get_irg_args (current_ir_graph), NULL); + set_irn_link(get_irg_frame (current_ir_graph), NULL); + set_irn_link(get_irg_globals (current_ir_graph), NULL); + set_irn_link(get_irg_args (current_ir_graph), NULL); + set_irn_link(get_irg_initial_mem(current_ir_graph), NULL); /* we use the block walk flag for removing Bads from Blocks ins. */ inc_irg_block_visited(current_ir_graph); @@ -412,17 +413,23 @@ copy_graph_env (void) { copy_node (get_irg_globals(current_ir_graph), NULL); copy_preds(get_irg_globals(current_ir_graph), NULL); } + if (get_irn_link(get_irg_initial_mem(current_ir_graph)) == NULL) { + copy_node (get_irg_initial_mem(current_ir_graph), NULL); + copy_preds(get_irg_initial_mem(current_ir_graph), NULL); + } if (get_irn_link(get_irg_args(current_ir_graph)) == NULL) { copy_node (get_irg_args(current_ir_graph), NULL); copy_preds(get_irg_args(current_ir_graph), NULL); } - set_irg_start (current_ir_graph, get_new_node(get_irg_start(current_ir_graph))); + set_irg_start (current_ir_graph, get_new_node(get_irg_start(current_ir_graph))); set_irg_start_block(current_ir_graph, get_new_node(get_irg_start_block(current_ir_graph))); - set_irg_frame (current_ir_graph, get_new_node(get_irg_frame(current_ir_graph))); - set_irg_globals(current_ir_graph, get_new_node(get_irg_globals(current_ir_graph))); - set_irg_args (current_ir_graph, get_new_node(get_irg_args(current_ir_graph))); + set_irg_frame (current_ir_graph, get_new_node(get_irg_frame(current_ir_graph))); + set_irg_globals (current_ir_graph, get_new_node(get_irg_globals(current_ir_graph))); + set_irg_initial_mem(current_ir_graph, get_new_node(get_irg_initial_mem(current_ir_graph))); + set_irg_args (current_ir_graph, get_new_node(get_irg_args(current_ir_graph))); + if (get_irn_link(get_irg_bad(current_ir_graph)) == NULL) { copy_node(get_irg_bad(current_ir_graph), NULL); copy_preds(get_irg_bad(current_ir_graph), NULL); @@ -445,6 +452,7 @@ dead_node_elimination(ir_graph *irg) { struct obstack *graveyard_obst = NULL; struct obstack *rebirth_obst = NULL; + /* inform statistics that we started a dead-node elimination run */ stat_dead_node_elim_start(irg); /* Remember external state of current_ir_graph. */ @@ -482,6 +490,7 @@ dead_node_elimination(ir_graph *irg) { xfree (graveyard_obst); /* ... then free it. */ } + /* inform statistics that the run is over */ stat_dead_node_elim_stop(irg); current_ir_graph = rem; diff --git a/ir/ir/irgraph.c b/ir/ir/irgraph.c index ac197ac55..aa2bf5777 100644 --- a/ir/ir/irgraph.c +++ b/ir/ir/irgraph.c @@ -112,10 +112,10 @@ new_ir_graph (entity *ent, int n_loc) iropt.c */ res->outs = NULL; - res->phase_state = phase_building; - res->pinned = pinned; - res->outs_state = no_outs; - res->dom_state = no_dom; + res->phase_state = phase_building; + res->pinned = pinned; + res->outs_state = no_outs; + res->dom_state = no_dom; res->typeinfo_state = irg_typeinfo_none; res->loopinfo_state = loopinfo_none; @@ -125,30 +125,32 @@ new_ir_graph (entity *ent, int n_loc) /*-- contain "inner" methods as in Pascal. --*/ res->frame_type = new_type_class(mangle(get_entity_ident(ent), frame_type_suffix)); + /* Remove type from type list. Must be treated differently than other types. */ remove_irp_type_from_list(res->frame_type); /*-- Nodes needed in every graph --*/ - res->end_block = new_immBlock (); - res->end = new_End (); + res->end_block = new_immBlock(); + res->end = new_End(); res->end_reg = res->end; res->end_except = res->end; - res->start_block = new_immBlock (); - res->start = new_Start (); - res->bad = new_ir_node (NULL, res, res->start_block, op_Bad, mode_T, 0, NULL); + res->start_block = new_immBlock(); + res->start = new_Start(); + res->bad = new_ir_node(NULL, res, res->start_block, op_Bad, mode_T, 0, NULL); /* res->unknown = new_ir_node (NULL, res, res->start_block, op_Unknown, mode_T, 0, NULL); */ /* Proj results of start node */ - projX = new_Proj (res->start, mode_X, pns_initial_exec); - set_store (new_Proj (res->start, mode_M, pns_global_store)); - res->frame = new_Proj (res->start, mode_P_mach, pns_frame_base); - res->globals = new_Proj (res->start, mode_P_mach, pns_globals); - res->args = new_Proj (res->start, mode_T, pns_args); + projX = new_Proj (res->start, mode_X, pns_initial_exec); + res->frame = new_Proj (res->start, mode_P_mach, pns_frame_base); + res->globals = new_Proj (res->start, mode_P_mach, pns_globals); + res->initial_mem = new_Proj (res->start, mode_M, pns_global_store); + res->args = new_Proj (res->start, mode_T, pns_args); #ifdef DEBUG_libfirm - res->graph_nr = get_irp_new_node_nr(); + res->graph_nr = get_irp_new_node_nr(); #endif + set_store(res->initial_mem); add_in_edge(res->start_block, projX); /* @@ -159,10 +161,9 @@ new_ir_graph (entity *ent, int n_loc) mature_block (res->current_block); /*-- Make a block to start with --*/ - first_block = new_immBlock (); + first_block = new_immBlock(); add_in_edge (first_block, projX); - return res; } @@ -208,7 +209,6 @@ ir_graph *new_const_code_irg(void) { /* Proj results of start node */ projX = new_Proj (res->start, mode_X, pns_initial_exec); - set_store (new_Proj (res->start, mode_M, pns_global_store)); add_in_edge(res->start_block, projX); mature_block (res->current_block); add_in_edge (new_immBlock (), projX); @@ -254,12 +254,8 @@ void free_ir_graph (ir_graph *irg) { void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */ int -is_ir_graph(void *thing) { - assert(thing); - if (get_kind(thing) == k_ir_graph) - return 1; - else - return 0; +(is_ir_graph)(void *thing) { + return __is_ir_graph(thing); } /* Outputs a unique number for this node */ @@ -270,55 +266,47 @@ get_irg_graph_nr(ir_graph *irg) { #ifdef DEBUG_libfirm return irg->graph_nr; #else - return 0; + return (long)irg; #endif } ir_node * -(get_irg_start_block)(ir_graph *irg) -{ +(get_irg_start_block)(ir_graph *irg) { return __get_irg_start_block(irg); } void -(set_irg_start_block)(ir_graph *irg, ir_node *node) -{ +(set_irg_start_block)(ir_graph *irg, ir_node *node) { __set_irg_start_block(irg, node); } ir_node * -(get_irg_start)(ir_graph *irg) -{ +(get_irg_start)(ir_graph *irg) { return __get_irg_start(irg); } void -(set_irg_start)(ir_graph *irg, ir_node *node) -{ +(set_irg_start)(ir_graph *irg, ir_node *node) { __set_irg_start(irg, node); } ir_node * -(get_irg_end_block)(ir_graph *irg) -{ +(get_irg_end_block)(ir_graph *irg) { return __get_irg_end_block(irg); } void -(set_irg_end_block)(ir_graph *irg, ir_node *node) -{ +(set_irg_end_block)(ir_graph *irg, ir_node *node) { __set_irg_end_block(irg, node); } ir_node * -(get_irg_end)(ir_graph *irg) -{ +(get_irg_end)(ir_graph *irg) { return __get_irg_end(irg); } void -(set_irg_end)(ir_graph *irg, ir_node *node) -{ +(set_irg_end)(ir_graph *irg, ir_node *node) { __set_irg_end(irg, node); } @@ -343,62 +331,63 @@ void set_irg_end_except (ir_graph *irg, ir_node *node) { } ir_node * -(get_irg_cstore)(ir_graph *irg) -{ +(get_irg_cstore)(ir_graph *irg) { return __get_irg_cstore(irg); } void -(set_irg_cstore)(ir_graph *irg, ir_node *node) -{ +(set_irg_cstore)(ir_graph *irg, ir_node *node) { __set_irg_cstore(irg, node); } ir_node * -(get_irg_frame)(ir_graph *irg) -{ +(get_irg_frame)(ir_graph *irg) { return __get_irg_frame(irg); } void -(set_irg_frame)(ir_graph *irg, ir_node *node) -{ +(set_irg_frame)(ir_graph *irg, ir_node *node) { __set_irg_frame(irg, node); } ir_node * -(get_irg_globals)(ir_graph *irg) -{ +(get_irg_globals)(ir_graph *irg) { return __get_irg_globals(irg); } void -(set_irg_globals)(ir_graph *irg, ir_node *node) -{ +(set_irg_globals)(ir_graph *irg, ir_node *node) { __set_irg_globals(irg, node); } ir_node * -(get_irg_args)(ir_graph *irg) +(get_irg_initial_mem)(ir_graph *irg) { + return __get_irg_initial_mem(irg); +} + +void +(set_irg_initial_mem)(ir_graph *irg, ir_node *node) { + __set_irg_initial_mem(irg, node); +} + +ir_node * +(get_irg_args)(ir_graph *irg) { return __get_irg_args(irg); } void -(set_irg_args)(ir_graph *irg, ir_node *node) -{ +(set_irg_args)(ir_graph *irg, ir_node *node) { __set_irg_args(irg, node); } ir_node * -(get_irg_bad)(ir_graph *irg) -{ +(get_irg_bad)(ir_graph *irg) { return __get_irg_bad(irg); } void -(set_irg_bad)(ir_graph *irg, ir_node *node) -{ +(set_irg_bad)(ir_graph *irg, ir_node *node) { __set_irg_bad(irg, node); } @@ -417,38 +406,32 @@ set_irg_unknown (ir_graph *irg, ir_node *node) */ ir_node * -(get_irg_current_block)(ir_graph *irg) -{ +(get_irg_current_block)(ir_graph *irg) { return __get_irg_current_block(irg); } void -(set_irg_current_block)(ir_graph *irg, ir_node *node) -{ +(set_irg_current_block)(ir_graph *irg, ir_node *node) { __set_irg_current_block(irg, node); } entity * -(get_irg_ent)(ir_graph *irg) -{ +(get_irg_ent)(ir_graph *irg) { return __get_irg_ent(irg); } void -(set_irg_ent)(ir_graph *irg, entity *ent) -{ +(set_irg_ent)(ir_graph *irg, entity *ent) { __set_irg_ent(irg, ent); } type * -(get_irg_frame_type)(ir_graph *irg) -{ +(get_irg_frame_type)(ir_graph *irg) { return __get_irg_frame_type(irg); } void -(set_irg_frame_type)(ir_graph *irg, type *ftp) -{ +(set_irg_frame_type)(ir_graph *irg, type *ftp) { __set_irg_frame_type(irg, ftp); } @@ -514,47 +497,48 @@ int node_is_in_irgs_storage(ir_graph *irg, ir_node *n) } irg_phase_state -get_irg_phase_state (ir_graph *irg) { - return irg->phase_state; +(get_irg_phase_state)(ir_graph *irg) { + return __get_irg_phase_state(irg); } void -set_irg_phase_low(ir_graph *irg) { - irg->phase_state = phase_low; +(set_irg_phase_low)(ir_graph *irg) { + __set_irg_phase_low(irg); } op_pinned -get_irg_pinned (ir_graph *irg) { - return irg->pinned; +(get_irg_pinned)(ir_graph *irg) { + return __get_irg_pinned(irg); } irg_outs_state -get_irg_outs_state(ir_graph *irg) { - return irg->outs_state; +(get_irg_outs_state)(ir_graph *irg) { + return __get_irg_outs_state(irg); } void -set_irg_outs_inconsistent(ir_graph *irg) { - irg->outs_state = outs_inconsistent; +(set_irg_outs_inconsistent)(ir_graph *irg) { + __set_irg_outs_inconsistent(irg); } irg_dom_state -get_irg_dom_state(ir_graph *irg) { - return irg->dom_state; +(get_irg_dom_state)(ir_graph *irg) { + return __get_irg_dom_state(irg); } void -set_irg_dom_inconsistent(ir_graph *irg) { - irg->dom_state = dom_inconsistent; +(set_irg_dom_inconsistent)(ir_graph *irg) { + __set_irg_dom_inconsistent(irg); } irg_loopinfo_state -get_irg_loopinfo_state(ir_graph *irg) { - return irg->loopinfo_state; +(get_irg_loopinfo_state)(ir_graph *irg) { + return __get_irg_loopinfo_state(irg); } -void set_irg_loopinfo_state(ir_graph *irg, irg_loopinfo_state s) { - irg->loopinfo_state = s; +void +(set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s) { + __set_irg_loopinfo_state(irg, s); } void @@ -572,27 +556,30 @@ set_irg_loopinfo_inconsistent(ir_graph *irg) { irg->loopinfo_state = loopinfo_cf_inconsistent; } -INLINE void -set_irg_pinned (ir_graph *irg, op_pinned p) { - irg->pinned = p; +void +(set_irg_pinned)(ir_graph *irg, op_pinned p) { + __set_irg_pinned(irg, p); } - -irg_callee_info_state get_irg_callee_info_state(ir_graph *irg) { - return irg->callee_info_state; +irg_callee_info_state +(get_irg_callee_info_state)(ir_graph *irg) { + return __get_irg_callee_info_state(irg); } -void set_irg_callee_info_state(ir_graph *irg, irg_callee_info_state s) { - irg->callee_info_state = s; +void +(set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s) { + __set_irg_callee_info_state(irg, s); } -irg_inline_property get_irg_inline_property(ir_graph *irg) { - return irg->inline_property; -} -void set_irg_inline_property(ir_graph *irg, irg_inline_property s) { - irg->inline_property = s; +irg_inline_property +(get_irg_inline_property)(ir_graph *irg) { + return __get_irg_inline_property(irg); } +void +(set_irg_inline_property)(ir_graph *irg, irg_inline_property s) { + __set_irg_inline_property(irg, s); +} void (set_irg_link)(ir_graph *irg, void *thing) { @@ -608,8 +595,7 @@ void * static int max_irg_visited = 0; unsigned long -(get_irg_visited)(ir_graph *irg) -{ +(get_irg_visited)(ir_graph *irg) { return __get_irg_visited(irg); } @@ -658,19 +644,16 @@ inc_max_irg_visited(void) } unsigned long -(get_irg_block_visited)(ir_graph *irg) -{ +(get_irg_block_visited)(ir_graph *irg) { return __get_irg_block_visited(irg); } void -(set_irg_block_visited)(ir_graph *irg, unsigned long visited) -{ +(set_irg_block_visited)(ir_graph *irg, unsigned long visited) { __set_irg_block_visited(irg, visited); } void -(inc_irg_block_visited)(ir_graph *irg) -{ +(inc_irg_block_visited)(ir_graph *irg) { __inc_irg_block_visited(irg); } diff --git a/ir/ir/irgraph.h b/ir/ir/irgraph.h index 4282b3bfe..d095983cf 100644 --- a/ir/ir/irgraph.h +++ b/ir/ir/irgraph.h @@ -75,10 +75,12 @@ typedef struct ir_graph ir_graph; * did actually change something). Code placement is necessary. */ -/* Global variable holding the current_ir_graph. This global variable - is used by the ir construction interface in ircons and by the - optimizations. */ +/** Global variable holding the current IR-graph. + * This global variable is used by the ir construction + * interface in ircons and by the optimizations. + */ extern ir_graph *current_ir_graph; + ir_graph *get_current_ir_graph(void); void set_current_ir_graph(ir_graph *graph); @@ -100,12 +102,13 @@ void set_interprocedural_view(bool state); ir_graph *new_ir_graph (entity *ent, int n_loc); /** Frees the passed irgraph. - Deallocates all nodes in this graph and the ir_graph structure. - Sets the field irgraph in the corresponding entity to NULL. - Does not remove the irgraph from the list in irprog (requires - inefficient search, call remove_irp_irg by hand). - Does not free types, entities or modes that are used only by this - graph, nor the entity standing for this graph. */ + * Deallocates all nodes in this graph and the ir_graph structure. + * Sets the field irgraph in the corresponding entity to NULL. + * Does not remove the irgraph from the list in irprog (requires + * inefficient search, call remove_irp_irg by hand). + * Does not free types, entities or modes that are used only by this + * graph, nor the entity standing for this graph. + */ void free_ir_graph (ir_graph *irg); /* --- access routines for all ir_graph attributes --- */ @@ -118,8 +121,7 @@ void free_ir_graph (ir_graph *irg); * @return * true if the thing is a ir graph, else false */ -int -is_ir_graph(void *thing); +int is_ir_graph(void *thing); #define get_irg_entity get_irg_ent #define set_irg_entity set_irg_ent @@ -158,18 +160,29 @@ ir_node *get_irg_cstore (ir_graph *irg); void set_irg_cstore (ir_graph *irg, ir_node *node); /* end oblivious */ -/* node that represents frame pointer */ +/** Returns the node that represents the frame pointer. */ ir_node *get_irg_frame (ir_graph *irg); +/** Sets the node that represents the frame pointer. */ void set_irg_frame (ir_graph *irg, ir_node *node); -/* node that represents global pointer */ +/** Returns the node that represents the global pointer. */ ir_node *get_irg_globals (ir_graph *irg); +/** Sets the node that represents the global pointer. */ void set_irg_globals (ir_graph *irg, ir_node *node); +/** Returns the node that represents the initial memory. */ +ir_node *get_irg_initial_mem (ir_graph *irg); +/** Sets the node that represents the initial memory. */ +void set_irg_initial_mem (ir_graph *irg, ir_node *node); + +/** Returns the node that represents the argument pointer. */ ir_node *get_irg_args (ir_graph *irg); +/** Sets the node that represents the argument pointer. */ void set_irg_args (ir_graph *irg, ir_node *node); +/** Returns the current block of a graph. */ ir_node *get_irg_current_block (ir_graph *irg); +/** Sets the current block of a graph. */ void set_irg_current_block (ir_graph *irg, ir_node *node); /* Use new_Bad() instead!! */ @@ -182,8 +195,10 @@ ir_node *get_irg_unknown (ir_graph *irg); void set_irg_unknown (ir_graph *irg, ir_node *node); */ +/** Returns teh number of value numbers of a graph. */ int get_irg_n_locs (ir_graph *irg); +/** Returns the graph number. */ long get_irg_graph_nr(ir_graph *irg); /********************************************************************************/ @@ -210,7 +225,7 @@ typedef enum { irg_phase_state get_irg_phase_state (ir_graph *irg); void set_irg_phase_low(ir_graph *irg); -/* state: pinned +/** state: pinned The graph is "pinned" if all nodes are associated with a basic block. It is in state "floats" if nodes are in arbitrary blocks. In state "floats" the block predecessor is set in all nodes, but this can be an @@ -295,7 +310,7 @@ typedef enum { irg_inline_property get_irg_inline_property(ir_graph *irg); void set_irg_inline_property(ir_graph *irg, irg_inline_property s); -/* A void * field to link arbritary information to the node. */ +/** 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); diff --git a/ir/ir/irgraph_t.h b/ir/ir/irgraph_t.h index 5338a620d..8040fdf84 100644 --- a/ir/ir/irgraph_t.h +++ b/ir/ir/irgraph_t.h @@ -48,6 +48,7 @@ struct ir_graph { struct ir_node *frame; /**< method's frame */ struct ir_node *globals; /**< pointer to the data segment containing all globals as well as global procedures. */ + struct ir_node *initial_mem; /**< initial memory of this graph */ struct ir_node *args; /**< methods arguments */ struct ir_node *bad; /**< bad node of this ir_graph, the one and only in this graph */ @@ -128,6 +129,11 @@ int node_is_in_irgs_storage(ir_graph *irg, ir_node *n); /* inline functions for graphs */ /*-------------------------------------------------------------------*/ +static INLINE int +__is_ir_graph(void *thing) { + return (get_kind(thing) == k_ir_graph); +} + /** Returns the start block of a graph. */ static INLINE ir_node * __get_irg_start_block(ir_graph *irg) @@ -223,6 +229,18 @@ __set_irg_globals(ir_graph *irg, ir_node *node) irg->globals = node; } +static INLINE ir_node * +__get_irg_initial_mem(ir_graph *irg) +{ + return irg->initial_mem; +} + +static INLINE void +__set_irg_initial_mem(ir_graph *irg, ir_node *node) +{ + irg->initial_mem = node; +} + static INLINE ir_node * __get_irg_args(ir_graph *irg) { @@ -292,6 +310,76 @@ __get_irg_obstack(ir_graph *irg) { } +static INLINE irg_phase_state +__get_irg_phase_state(ir_graph *irg) { + return irg->phase_state; +} + +static INLINE void +__set_irg_phase_low(ir_graph *irg) { + irg->phase_state = phase_low; +} + +static INLINE op_pinned +__get_irg_pinned(ir_graph *irg) { + return irg->pinned; +} + +static INLINE irg_outs_state +__get_irg_outs_state(ir_graph *irg) { + return irg->outs_state; +} + +static INLINE void +__set_irg_outs_inconsistent(ir_graph *irg) { + irg->outs_state = outs_inconsistent; +} + +static INLINE irg_dom_state +__get_irg_dom_state(ir_graph *irg) { + return irg->dom_state; +} + +static INLINE void +__set_irg_dom_inconsistent(ir_graph *irg) { + irg->dom_state = dom_inconsistent; +} + +static INLINE irg_loopinfo_state +__get_irg_loopinfo_state(ir_graph *irg) { + return irg->loopinfo_state; +} + +static INLINE void +__set_irg_loopinfo_state(ir_graph *irg, irg_loopinfo_state s) { + irg->loopinfo_state = s; +} + +static INLINE void +__set_irg_pinned(ir_graph *irg, op_pinned p) { + irg->pinned = p; +} + +static INLINE irg_callee_info_state +__get_irg_callee_info_state(ir_graph *irg) { + return irg->callee_info_state; +} + +static INLINE void +__set_irg_callee_info_state(ir_graph *irg, irg_callee_info_state s) { + irg->callee_info_state = s; +} + +static INLINE irg_inline_property +__get_irg_inline_property(ir_graph *irg) { + return irg->inline_property; +} + +static INLINE void +__set_irg_inline_property(ir_graph *irg, irg_inline_property s) { + irg->inline_property = s; +} + static INLINE void __set_irg_link(ir_graph *irg, void *thing) { irg->link = thing; @@ -326,38 +414,55 @@ __inc_irg_block_visited(ir_graph *irg) ++irg->block_visited; } -#define get_irg_start_block(irg) __get_irg_start_block(irg) -#define set_irg_start_block(irg, node) __set_irg_start_block(irg, node) -#define get_irg_start(irg) __get_irg_start(irg) -#define set_irg_start(irg, node) __set_irg_start(irg, node) -#define get_irg_end_block(irg) __get_irg_end_block(irg) -#define set_irg_end_block(irg, node) __set_irg_end_block(irg, node) -#define get_irg_end(irg) __get_irg_end(irg) -#define set_irg_end(irg, node) __set_irg_end(irg, node) -#define get_irg_end_reg(irg) __get_irg_end_reg(irg) -#define get_irg_end_except(irg) __get_irg_end_except(irg) -#define get_irg_cstore(irg) __get_irg_cstore(irg) -#define set_irg_cstore(irg, node) __set_irg_cstore(irg, node) -#define get_irg_frame(irg) __get_irg_frame(irg) -#define set_irg_frame(irg, node) __set_irg_frame(irg, node) -#define get_irg_globals(irg) __get_irg_globals(irg) -#define set_irg_globals(irg, node) __set_irg_globals(irg, node) -#define get_irg_args(irg) __get_irg_args(irg) -#define set_irg_args(irg, node) __set_irg_args(irg, node) -#define get_irg_bad(irg) __get_irg_bad(irg) -#define set_irg_bad(irg, node) __set_irg_bad(irg, node) -#define get_irg_current_block(irg) __get_irg_current_block(irg) -#define set_irg_current_block(irg, node) __set_irg_current_block(irg, node) -#define get_irg_ent(irg) __get_irg_ent(irg) -#define set_irg_ent(irg, ent) __set_irg_ent(irg, ent) -#define get_irg_frame_type(irg) __get_irg_frame_type(irg) -#define set_irg_frame_type(irg, ftp) __set_irg_frame_type(irg, ftp) -#define get_irg_obstack(irg) __get_irg_obstack(irg) -#define set_irg_link(irg, thing) __set_irg_link(irg, thing) -#define get_irg_link(irg) __get_irg_link(irg) -#define get_irg_visited(irg) __get_irg_visited(irg) -#define get_irg_block_visited(irg) __get_irg_block_visited(irg) -#define set_irg_block_visited(irg, v) __set_irg_block_visited(irg, v) -#define inc_irg_block_visited(irg) __inc_irg_block_visited(irg) +#define is_ir_graph(thing) __is_ir_graph(thing) +#define get_irg_start_block(irg) __get_irg_start_block(irg) +#define set_irg_start_block(irg, node) __set_irg_start_block(irg, node) +#define get_irg_start(irg) __get_irg_start(irg) +#define set_irg_start(irg, node) __set_irg_start(irg, node) +#define get_irg_end_block(irg) __get_irg_end_block(irg) +#define set_irg_end_block(irg, node) __set_irg_end_block(irg, node) +#define get_irg_end(irg) __get_irg_end(irg) +#define set_irg_end(irg, node) __set_irg_end(irg, node) +#define get_irg_end_reg(irg) __get_irg_end_reg(irg) +#define get_irg_end_except(irg) __get_irg_end_except(irg) +#define get_irg_cstore(irg) __get_irg_cstore(irg) +#define set_irg_cstore(irg, node) __set_irg_cstore(irg, node) +#define get_irg_frame(irg) __get_irg_frame(irg) +#define set_irg_frame(irg, node) __set_irg_frame(irg, node) +#define get_irg_globals(irg) __get_irg_globals(irg) +#define set_irg_globals(irg, node) __set_irg_globals(irg, node) +#define get_irg_initial_mem(irg) __get_irg_initial_mem(irg) +#define set_irg_initial_mem(irg, node) __set_irg_initial_mem(irg, node) +#define get_irg_args(irg) __get_irg_args(irg) +#define set_irg_args(irg, node) __set_irg_args(irg, node) +#define get_irg_bad(irg) __get_irg_bad(irg) +#define set_irg_bad(irg, node) __set_irg_bad(irg, node) +#define get_irg_current_block(irg) __get_irg_current_block(irg) +#define set_irg_current_block(irg, node) __set_irg_current_block(irg, node) +#define get_irg_ent(irg) __get_irg_ent(irg) +#define set_irg_ent(irg, ent) __set_irg_ent(irg, ent) +#define get_irg_frame_type(irg) __get_irg_frame_type(irg) +#define set_irg_frame_type(irg, ftp) __set_irg_frame_type(irg, ftp) +#define get_irg_obstack(irg) __get_irg_obstack(irg) +#define get_irg_phase_state(irg) __get_irg_phase_state(irg) +#define set_irg_phase_low(irg) __set_irg_phase_low(irg) +#define get_irg_pinned(irg) __get_irg_pinned(irg) +#define get_irg_outs_state(irg) __get_irg_outs_state(irg) +#define set_irg_outs_inconsistent(irg) __set_irg_outs_inconsistent(irg) +#define get_irg_dom_state(irg) __get_irg_dom_state(irg) +#define set_irg_dom_inconsistent(irg) __set_irg_dom_inconsistent(irg) +#define get_irg_loopinfo_state(irg) __get_irg_loopinfo_state(irg) +#define set_irg_loopinfo_state(irg, s) __set_irg_loopinfo_state(irg, s) +#define set_irg_pinned(irg, p) __set_irg_pinned(irg, p) +#define get_irg_callee_info_state(irg) __get_irg_callee_info_state(irg) +#define set_irg_callee_info_state(irg, s) __set_irg_callee_info_state(irg, s) +#define get_irg_inline_property(irg) __get_irg_inline_property(irg) +#define set_irg_inline_property(irg, s) __set_irg_inline_property(irg, s) +#define set_irg_link(irg, thing) __set_irg_link(irg, thing) +#define get_irg_link(irg) __get_irg_link(irg) +#define get_irg_visited(irg) __get_irg_visited(irg) +#define get_irg_block_visited(irg) __get_irg_block_visited(irg) +#define set_irg_block_visited(irg, v) __set_irg_block_visited(irg, v) +#define inc_irg_block_visited(irg) __inc_irg_block_visited(irg) # endif /* _IRGRAPH_T_H_ */ diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index a60667777..12c35462f 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -707,7 +707,7 @@ static ir_node *equivalent_node_Div(ir_node *n) ir_node *b = get_Div_right(n); /* Div is not commutative. */ - if (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */ + if (tarval_classify(computed_value(b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */ /* Turn Div into a tuple (mem, bad, a) */ ir_node *mem = get_Div_mem(n); turn_into_tuple(n, 3); @@ -1034,31 +1034,79 @@ optimize_preds(ir_node *n) { static ir_node *transform_node_Div(ir_node *n) { - tarval *ta = computed_value(n); + tarval *tv = computed_value(n); + ir_node *b = get_Div_right(n); + tarval *tb = computed_value(b); + + /* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */ - if (ta != tarval_bad) { + if (tv != tarval_bad) { /* Turn Div into a tuple (mem, bad, value) */ ir_node *mem = get_Div_mem(n); turn_into_tuple(n, 3); set_Tuple_pred(n, pn_Div_M, mem); set_Tuple_pred(n, pn_Div_X_except, new_Bad()); - set_Tuple_pred(n, pn_Div_res, new_Const(get_tarval_mode(ta), ta)); + set_Tuple_pred(n, pn_Div_res, new_Const(get_tarval_mode(tv), tv)); + } + else if (tb != tarval_bad && tarval_classify(tb) != TV_CLASSIFY_NULL) { /* div(x, c) && c != 0 */ + ir_node *div, *proj; + ir_node *a = get_Div_left(n); + ir_node *mem = get_Div_mem(n); + int rem = get_optimize(); + + set_optimize(0); + { + div = new_rd_Div(get_irn_dbg_info(n), current_ir_graph, + get_nodes_Block(n), get_irg_initial_mem(current_ir_graph), a, b); + } + set_optimize(rem); + proj = new_r_Proj(current_ir_graph, get_nodes_Block(n), div, get_irn_mode(a), pn_Div_res); + + turn_into_tuple(n, 3); + set_Tuple_pred(n, pn_Div_M, mem); + set_Tuple_pred(n, pn_Div_X_except, new_Bad()); + set_Tuple_pred(n, pn_Div_res, proj); + } return n; } static ir_node *transform_node_Mod(ir_node *n) { - tarval *ta = computed_value(n); + tarval *tv = computed_value(n); + ir_node *b = get_Mod_right(n); + tarval *tb = computed_value(b); - if (ta != tarval_bad) { + /* BEWARE: it is NOT possible to optimize a%a to 0, as this may cause a exception */ + + if (tv != tarval_bad) { /* Turn Mod into a tuple (mem, bad, value) */ ir_node *mem = get_Mod_mem(n); turn_into_tuple(n, 3); set_Tuple_pred(n, pn_Mod_M, mem); set_Tuple_pred(n, pn_Mod_X_except, new_Bad()); - set_Tuple_pred(n, pn_Mod_res, new_Const(get_tarval_mode(ta), ta)); + set_Tuple_pred(n, pn_Mod_res, new_Const(get_tarval_mode(tv), tv)); + } + else if (tb != tarval_bad && tarval_classify(tb) != TV_CLASSIFY_NULL) { /* div(x, c) && c != 0 */ + ir_node *mod, *proj; + ir_node *a = get_Mod_left(n); + ir_node *mem = get_Mod_mem(n); + int rem = get_optimize(); + + set_optimize(0); + { + mod = new_rd_Mod(get_irn_dbg_info(n), current_ir_graph, + get_nodes_Block(n), get_irg_initial_mem(current_ir_graph), a, b); + } + set_optimize(rem); + proj = new_r_Proj(current_ir_graph, get_nodes_Block(n), mod, get_irn_mode(a), pn_Mod_res); + + turn_into_tuple(n, 3); + set_Tuple_pred(n, pn_Mod_M, mem); + set_Tuple_pred(n, pn_Mod_X_except, new_Bad()); + set_Tuple_pred(n, pn_Mod_res, proj); + } return n; } @@ -1070,37 +1118,32 @@ static ir_node *transform_node_DivMod(ir_node *n) ir_node *a = get_DivMod_left(n); ir_node *b = get_DivMod_right(n); ir_mode *mode = get_irn_mode(a); + tarval *ta = value_of(a); + tarval *tb = value_of(b); if (!(mode_is_int(mode) && mode_is_int(get_irn_mode(b)))) return n; - if (a == b) { - a = new_Const(mode, get_mode_one(mode)); - b = new_Const(mode, get_mode_null(mode)); - evaluated = 1; - } else { - tarval *ta = value_of(a); - tarval *tb = value_of(b); - - if (tb != tarval_bad) { - if (tb == get_mode_one(get_tarval_mode(tb))) { - b = new_Const (mode, get_mode_null(mode)); - evaluated = 1; - } else if (ta != tarval_bad) { - tarval *resa, *resb; - resa = tarval_div (ta, tb); - if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through - Jmp for X result!? */ - resb = tarval_mod (ta, tb); - if (resb == tarval_bad) return n; /* Causes exception! */ - a = new_Const (mode, resa); - b = new_Const (mode, resb); - evaluated = 1; - } - } else if (ta == get_mode_null(mode)) { - b = a; + /* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */ + + if (tb != tarval_bad) { + if (tb == get_mode_one(get_tarval_mode(tb))) { + b = new_Const (mode, get_mode_null(mode)); + evaluated = 1; + } else if (ta != tarval_bad) { + tarval *resa, *resb; + resa = tarval_div (ta, tb); + if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through + Jmp for X result!? */ + resb = tarval_mod (ta, tb); + if (resb == tarval_bad) return n; /* Causes exception! */ + a = new_Const (mode, resa); + b = new_Const (mode, resb); evaluated = 1; } + } else if (ta == get_mode_null(mode)) { + b = a; + evaluated = 1; } if (evaluated) { /* replace by tuple */ ir_node *mem = get_DivMod_mem(n); -- 2.20.1