3 * File name: ir/lower/lower_intrinsics.c
4 * Purpose: lowering of Calls of intrinsic functions
8 * Copyright: (c) 1998-2005 Universität Karlsruhe
9 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
28 #include "lower_intrinsics.h"
31 typedef struct _walker_env {
32 pmap *map; /**< the intrinsic map. */
33 unsigned nr_of_intrinsics; /**< statistics */
37 * walker: do the call mapping
39 static void call_mapper(ir_node *call, void *env) {
40 walker_env_t *wenv = env;
46 if (get_irn_op(call) != op_Call)
49 symconst = get_Call_ptr(call);
50 if (get_irn_op(symconst) != op_SymConst ||
51 get_SymConst_kind(symconst) != symconst_addr_ent)
54 ent = get_SymConst_entity(symconst);
55 p = pmap_find(wenv->map, ent);
59 wenv->nr_of_intrinsics += r->i_mapper(call, r->ctx) ? 1 : 0;
63 /* Go through all graphs and map calls to intrinsic functions. */
64 unsigned lower_intrinsic_calls(const i_record *list, int length) {
67 pmap *map = pmap_create_ex(length);
69 unsigned nr_of_intrinsics = 0;
71 /* fill a map for faster search */
72 for (i = length - 1; i >= 0; --i)
73 pmap_insert(map, list[i].i_ent, (void *)&list[i]);
77 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
80 wenv.nr_of_intrinsics = 0;
81 irg_walk_graph(irg, NULL, call_mapper, map);
83 if (wenv.nr_of_intrinsics) {
84 /* changes detected */
85 set_irg_outs_inconsistent(irg);
86 set_irg_callee_info_state(irg, irg_callee_info_inconsistent);
88 /* exception control flow might have changed */
89 set_irg_dom_inconsistent(irg);
90 set_irg_loopinfo_inconsistent(irg);
92 nr_of_intrinsics += wenv.nr_of_intrinsics;
97 return nr_of_intrinsics;
100 /* A mapper for the integer abs. */
101 int i_mapper_Abs(ir_node *call, void *ctx) {
102 ir_node *mem = get_Call_mem(call);
103 ir_node *block = get_nodes_block(call);
104 ir_node *op = get_Call_param(call, 0);
106 dbg_info *dbg = get_irn_dbg_info(call);
108 irn = new_rd_Abs(dbg, current_ir_graph, block, op, get_irn_mode(op));
109 irn = new_Tuple(1, &irn);
111 turn_into_tuple(call, pn_Call_max);
112 set_Tuple_pred(call, pn_Call_M_regular, mem);
113 set_Tuple_pred(call, pn_Call_X_except, new_Bad());
114 set_Tuple_pred(call, pn_Call_T_result, irn);
115 set_Tuple_pred(call, pn_Call_M_except, mem);
116 set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());
121 /* A mapper for the alloca() function. */
122 int i_mapper_Alloca(ir_node *call, void *ctx) {
123 ir_node *mem = get_Call_mem(call);
124 ir_node *block = get_nodes_block(call);
125 ir_node *op = get_Call_param(call, 0);
127 dbg_info *dbg = get_irn_dbg_info(call);
129 irn = new_rd_Alloc(dbg, current_ir_graph, block, mem, op, firm_unknown_type, stack_alloc);
130 mem = new_Proj(irn, mode_M, pn_Alloc_M);
131 exc = new_Proj(irn, mode_X, pn_Alloc_X_except);
132 irn = new_Proj(irn, get_modeP_data(), pn_Alloc_res);
133 irn = new_Tuple(1, &irn);
135 turn_into_tuple(call, pn_Call_max);
136 set_Tuple_pred(call, pn_Call_M_regular, mem);
137 set_Tuple_pred(call, pn_Call_X_except, exc);
138 set_Tuple_pred(call, pn_Call_T_result, irn);
139 set_Tuple_pred(call, pn_Call_M_except, mem);
140 set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());