3 * File name: ir/opt/ldstopt.c
4 * Purpose: optimization of function calls
8 * Copyright: (c) 1998-2004 Universität Karlsruhe
9 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
12 #include "irgraph_t.h"
16 #include "dbginfo_t.h"
24 * The walker environment for rem_mem_from_real_fkt_calls
26 typedef struct _env_t {
27 eset *pure_fkt; /**< set containing all real functions */
28 int changed; /**< flag, is set if a graph was changed */
32 * remove memory from real function calls by rerouting
33 * it's ProjM and connection the call with a NoMem node.
35 * Note: By "real function" we understand a function that did neither
36 * read nor write memory.
38 static void rem_mem_from_real_fkt_calls(ir_node *node, void *env)
41 ir_node *call, *ptr, *mem;
44 if (get_irn_op(node) != op_Proj || get_irn_mode(node) != mode_M)
47 /* look at Memory Proj's */
48 call = get_Proj_pred(node);
49 if (get_irn_op(call) != op_Call)
52 ptr = get_Call_ptr(call);
53 if (get_irn_op(ptr) != op_SymConst || get_SymConst_kind(ptr) != symconst_addr_ent)
56 ent = get_SymConst_entity(ptr);
58 if (! eset_contains(ctx->pure_fkt, ent))
61 /* ok, if we get here we found a call to a pure function,
62 * route the NoMem node to the call */
63 mem = get_Call_mem(call);
66 set_Call_mem(call, new_r_NoMem(current_ir_graph));
68 /* finally, this call can floats */
69 set_irn_pinned(call, op_pin_state_floats);
71 hook_func_call(current_ir_graph, call);
77 * optimize function calls by handling real functions
79 void optimize_funccalls(void)
83 unsigned num_pure = 0;
84 eset *pure_fkt = eset_create();
86 if (! get_opt_real_func_call())
89 /* first step: detect, which functions are pure, ie do NOT change any memory */
90 for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
91 ir_graph *irg = get_irp_irg(i);
92 ir_node *end = get_irg_end(irg);
93 ir_node *endbl = get_nodes_block(end);
97 /* visit every Return */
98 for (j = 0, k = get_Block_n_cfgpreds(endbl); j < k; ++j) {
99 ir_node *ret = get_Block_cfgpred(endbl, j);
102 /* Bad nodes usually do NOT produce anything, so it's ok */
106 mem = get_Return_mem(ret);
108 /* Bad nodes usually do NOT produce anything, so it's ok */
112 change = mem != get_irg_initial_mem(irg);
118 /* check, if a keep-alive exists */
119 for (j = 0, k = get_End_n_keepalives(end); j < k; ++j) {
120 ir_node *mem = get_End_keepalive(end, j);
122 if (mode_M != get_irn_mode(mem))
125 change = mem != get_irg_initial_mem(irg);
132 eset_insert(pure_fkt, get_irg_entity(irg));
140 ctx.pure_fkt = pure_fkt;
142 /* all calls of pure functions can be transformed into FuncCalls */
143 for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
144 ir_graph *irg = get_irp_irg(i);
147 irg_walk_graph(irg, NULL, rem_mem_from_real_fkt_calls, &ctx);
150 /* changes were done */
151 set_irg_outs_inconsistent(irg);
152 set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_inconsistent);
157 eset_destroy(pure_fkt);