* @file
* @brief Optimization of function calls.
* @author Michael Beck
- * @version $Id$
*/
#include "config.h"
/* set the link to NULL for all non-const/pure calls */
set_irn_link(call, NULL);
ptr = get_Call_ptr(call);
- if (is_Global(ptr)) {
- ent = get_Global_entity(ptr);
+ if (is_SymConst_addr_ent(ptr)) {
+ ent = get_SymConst_entity(ptr);
prop = get_entity_additional_properties(ent);
if ((prop & (mtp_property_const|mtp_property_pure)) == 0)
or_prop = 0;
for (i = 0; i < n_callees; ++i) {
ent = get_Call_callee(call, i);
- if (ent == unknown_entity) {
+ if (is_unknown_entity(ent)) {
/* we don't know which entity is called here */
return;
}
}
case pn_Call_X_except:
exc_changed = 1;
- exchange(proj, get_irg_bad(irg));
+ exchange(proj, new_r_Bad(irg, mode_X));
break;
case pn_Call_X_regular: {
ir_node *block = get_nodes_block(call);
}
}
- /* changes were done ... */
- set_irg_outs_inconsistent(irg);
- set_irg_loopinfo_state(irg, loopinfo_cf_inconsistent);
-
if (exc_changed) {
/* ... including exception edges */
- set_irg_doms_inconsistent(irg);
+ clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE
+ | IR_GRAPH_STATE_CONSISTENT_LOOPINFO);
}
} /* fix_const_call_list */
/* set the link to NULL for all non-const/pure calls */
set_irn_link(call, NULL);
ptr = get_Call_ptr(call);
- if (is_Global(ptr)) {
- ent = get_Global_entity(ptr);
+ if (is_SymConst_addr_ent(ptr)) {
+ ent = get_SymConst_entity(ptr);
prop = get_entity_additional_properties(ent);
if ((prop & mtp_property_nothrow) == 0)
prop = mtp_property_nothrow;
for (i = 0; i < n_callees; ++i) {
ent = get_Call_callee(call, i);
- if (ent == unknown_entity) {
+ if (is_unknown_entity(ent)) {
/* we don't know which entity is called here */
return;
}
switch (get_Proj_proj(proj)) {
case pn_Call_X_except:
exc_changed = 1;
- exchange(proj, get_irg_bad(irg));
+ exchange(proj, new_r_Bad(irg, mode_X));
break;
case pn_Call_X_regular: {
ir_node *block = get_nodes_block(call);
}
/* changes were done ... */
- set_irg_outs_inconsistent(irg);
- set_irg_loopinfo_state(irg, loopinfo_cf_inconsistent);
-
if (exc_changed) {
/* ... including exception edges */
- set_irg_doms_inconsistent(irg);
+ clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE
+ | IR_GRAPH_STATE_CONSISTENT_LOOPINFO);
}
} /* fix_nothrow_call_list */
ir_entity *ent = get_SymConst_entity(ptr);
ir_graph *irg = get_entity_irg(ent);
- if (irg == get_irn_irg(node)) {
- /* A self-recursive call. The property did not depend on this call. */
- } else if (irg == NULL) {
+ if (irg == NULL) {
m = get_entity_additional_properties(ent) & (mtp_property_const|mtp_property_pure);
mode = max_property(mode, m);
- } else if (irg != NULL) {
+ } else {
/* we have a graph, analyze it. */
m = check_const_or_pure_function(irg, /*top=*/0);
mode = max_property(mode, m);
{
ir_node *end, *endbl;
int j;
+ ir_entity *entity = get_irg_entity(irg);
+ ir_type *type = get_entity_type(entity);
+ size_t n_params = get_method_n_params(type);
+ size_t i;
+ mtp_additional_properties may_be_const = mtp_property_const;
mtp_additional_properties prop = get_irg_additional_properties(irg);
+ /* libfirm handles aggregate parameters by passing around pointers to
+ * stuff in memory, so if we have compound parameters we are never const */
+ for (i = 0; i < n_params; ++i) {
+ ir_type *param = get_method_param_type(type, i);
+ if (is_compound_type(param)) {
+ prop &= ~mtp_property_const;
+ may_be_const = mtp_no_property;
+ }
+ }
+
if (prop & mtp_property_const) {
/* already marked as a const function */
return mtp_property_const;
return mtp_no_property;
}
if (IS_IRG_BUSY(irg)) {
- /* we are still evaluate this method. Be optimistic,
- return the best possible so far but mark the result as temporary. */
- return mtp_temporary | mtp_property_const;
+ /* We are still evaluate this method.
+ * The function (indirectly) calls itself and thus may not terminate.
+ */
+ return mtp_no_property;
}
SET_IRG_BUSY(irg);
end = get_irg_end(irg);
endbl = get_nodes_block(end);
- prop = mtp_property_const;
+ prop = may_be_const;
ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
inc_irg_visited(irg);
}
}
- if (prop != mtp_no_property) {
- if (top || (prop & mtp_temporary) == 0) {
- /* We use the temporary flag here to mark optimistic result.
- Set the property only if we are sure that it does NOT base on
- temporary results OR if we are at top-level. */
- add_irg_additional_properties(irg, prop & ~mtp_temporary);
- SET_IRG_READY(irg);
+ if (top) {
+ /* Set the property only if we are at top-level. */
+ if (prop != mtp_no_property) {
+ add_irg_additional_properties(irg, prop);
}
- }
- if (top)
SET_IRG_READY(irg);
+ }
CLEAR_IRG_BUSY(irg);
ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
return prop;
break;
case iro_Call:
ptr = get_Call_ptr(succ);
- if (is_Global(ptr)) {
- ir_entity *ent = get_Global_entity(ptr);
+ if (is_SymConst_addr_ent(ptr)) {
+ ir_entity *ent = get_SymConst_entity(ptr);
size_t i;
/* we know the called entity */
} else if (is_Call(res)) {
ir_node *ptr = get_Call_ptr(res);
- if (is_Global(ptr)) {
+ if (is_SymConst_addr_ent(ptr)) {
/* a direct call */
- ir_entity *ent = get_Global_entity(ptr);
+ ir_entity *ent = get_SymConst_entity(ptr);
ir_graph *callee = get_entity_irg(ent);
if (callee == irg) {
for (i = 0; i < n_callees; ++i) {
ir_entity *ent = get_Call_callee(res, i);
- if (ent == unknown_entity) {
+ if (is_unknown_entity(ent)) {
/* we don't know which entity is called here */
curr_prop &= ~mtp_property_malloc;
break;
if (is_Call(pred)) {
ir_node *ptr = get_Call_ptr(pred);
- if (is_Global(ptr)) {
+ if (is_SymConst_addr_ent(ptr)) {
/* a direct call */
- ir_entity *ent = get_Global_entity(ptr);
+ ir_entity *ent = get_SymConst_entity(ptr);
ir_graph *callee = get_entity_irg(ent);
if (callee == irg) {
for (i = 0; i < n_callees; ++i) {
ir_entity *ent = get_Call_callee(pred, i);
- if (ent == unknown_entity) {
+ if (is_unknown_entity(ent)) {
/* we don't know which entity is called here */
curr_prop &= ~mtp_property_nothrow;
break;
static void check_for_possible_endless_loops(ir_graph *irg)
{
ir_loop *root_loop;
- assure_cf_loop(irg);
+ assure_loopinfo(irg);
root_loop = get_irg_loop(irg);
if (root_loop->flags & loop_outer_loop)