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 /** Walker environment */
32 typedef struct _walker_env {
33 pmap *map; /**< the intrinsic map. */
34 unsigned nr_of_intrinsics; /**< statistics */
38 * walker: do the call mapping
40 static void call_mapper(ir_node *call, void *env) {
41 walker_env_t *wenv = env;
47 if (get_irn_op(call) != op_Call)
50 symconst = get_Call_ptr(call);
51 if (get_irn_op(symconst) != op_SymConst ||
52 get_SymConst_kind(symconst) != symconst_addr_ent)
55 ent = get_SymConst_entity(symconst);
56 p = pmap_find(wenv->map, ent);
60 wenv->nr_of_intrinsics += r->i_mapper(call, r->ctx) ? 1 : 0;
64 /* Go through all graphs and map calls to intrinsic functions. */
65 unsigned lower_intrinsic_calls(const i_record *list, int length) {
68 pmap *map = pmap_create_ex(length);
70 unsigned nr_of_intrinsics = 0;
72 /* fill a map for faster search */
73 for (i = length - 1; i >= 0; --i)
74 pmap_insert(map, list[i].i_ent, (void *)&list[i]);
78 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
81 wenv.nr_of_intrinsics = 0;
82 irg_walk_graph(irg, NULL, call_mapper, map);
84 if (wenv.nr_of_intrinsics) {
85 /* changes detected */
86 set_irg_outs_inconsistent(irg);
87 set_irg_callee_info_state(irg, irg_callee_info_inconsistent);
89 /* exception control flow might have changed */
90 set_irg_doms_inconsistent(irg);
91 set_irg_loopinfo_inconsistent(irg);
93 nr_of_intrinsics += wenv.nr_of_intrinsics;
98 return nr_of_intrinsics;
101 /* A mapper for the integer abs. */
102 int i_mapper_Abs(ir_node *call, void *ctx) {
103 ir_node *mem = get_Call_mem(call);
104 ir_node *block = get_nodes_block(call);
105 ir_node *op = get_Call_param(call, 0);
107 dbg_info *dbg = get_irn_dbg_info(call);
109 irn = new_rd_Abs(dbg, current_ir_graph, block, op, get_irn_mode(op));
110 irn = new_Tuple(1, &irn);
112 turn_into_tuple(call, pn_Call_max);
113 set_Tuple_pred(call, pn_Call_M_regular, mem);
114 set_Tuple_pred(call, pn_Call_X_except, new_Bad());
115 set_Tuple_pred(call, pn_Call_T_result, irn);
116 set_Tuple_pred(call, pn_Call_M_except, mem);
117 set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());
122 /* A mapper for the alloca() function. */
123 int i_mapper_Alloca(ir_node *call, void *ctx) {
124 ir_node *mem = get_Call_mem(call);
125 ir_node *block = get_nodes_block(call);
126 ir_node *op = get_Call_param(call, 0);
128 dbg_info *dbg = get_irn_dbg_info(call);
130 irn = new_rd_Alloc(dbg, current_ir_graph, block, mem, op, firm_unknown_type, stack_alloc);
131 mem = new_Proj(irn, mode_M, pn_Alloc_M);
132 exc = new_Proj(irn, mode_X, pn_Alloc_X_except);
133 irn = new_Proj(irn, get_modeP_data(), pn_Alloc_res);
134 irn = new_Tuple(1, &irn);
136 turn_into_tuple(call, pn_Call_max);
137 set_Tuple_pred(call, pn_Call_M_regular, mem);
138 set_Tuple_pred(call, pn_Call_X_except, exc);
139 set_Tuple_pred(call, pn_Call_T_result, irn);
140 set_Tuple_pred(call, pn_Call_M_except, mem);
141 set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());