1 /** vim: set sw=4 ts=4:
4 * @author Adam M. Szalkowski
6 * Code instrumentation and execution count profiling
8 * Copyright (C) 2006 Universitaet Karlsruhe
9 * Released under the GPL
30 #include "phiclass_t.h"
37 #include <lpp/lpp_net.h>
38 #include <lpp/lpp_cplex.h>
39 //#include <lc_pset.h>
40 //#include <libcore/lc_bitset.h>
44 #include "besched_t.h"
50 #include "bespillremat.h"
52 #include "bepressurestat.h"
54 #include "bechordal_t.h"
57 #include <libcore/lc_opts.h>
58 #include <libcore/lc_opts_enum.h>
59 #endif /* WITH_LIBCORE */
61 typedef struct _block_id_walker_data {
64 const ir_node *symconst;
65 } block_id_walker_data;
68 block_counter(ir_node * bb, void * data)
70 unsigned int *count = data;
75 count_blocks(const ir_graph * irg)
77 unsigned int count = 0;
79 irg_block_walk_graph(irg, block_counter, NULL, &count);
84 * Instrument a block with code needed for profiling
87 instrument_block(const ir_node * bb, const ir_node * address, unsigned int id)
89 ir_node *load, *store, *offset, *add, *projm, *proji;
91 offset = new_r_Add(get_irn_irg(bb), bb, address, new_Const_long(mode_Is, get_mode_size_bytes(mode_Iu)*id), mode_P);
92 load = new_r_Load(get_irn_irg(bb), bb, new_NoMem(), offset, mode_Iu);
93 projm = new_r_Proj(get_irn_irg(bb), bb, load, mode_M, 0);
94 proji = new_r_Proj(get_irn_irg(bb), bb, load, mode_Iu, 2);
95 add = new_r_Add(get_irn_irg(bb), bb, proji, new_Const_long(mode_Iu, 1), mode_Iu);
96 store = new_r_Store(get_irn_irg(bb), bb, projm, offset, add);
97 keep_alive(new_r_Proj(get_irn_irg(bb), bb, load, mode_M, 0));
101 * Generates a new irg which calls the initializer
104 gen_initializer_irg(entity * bblock_id, entitiy * bblock_counts, entity * bblock_count)
107 ir_node *ins[3] = {bblock_id, bblock_counts, bblock_count};
108 ident *name = new_id_from_str("__firmprof_initializer");
109 entity *ent = new_entity(get_glob_type(), name, new_type_method(name, 0, 0));
112 ident *init_name = new_id_from_str("__init_firmprof");
113 type *init_type = new_type_method(init_name, 3, 0);
115 set_method_param_type(init_type, 0, arrayptr);
116 set_method_param_type(init_type, 1, arrayptr);
117 set_method_param_type(init_type, 2, uint);
118 entify *init_ent = new_entity(get_glob_type(), init_name, init_type);
120 irg = new_ir_graph(ent, 0);
121 bb = get_cur_block();
123 call = new_r_Call( irg,
124 bb, //ir_node * block,
125 get_irn_initial_mem(irg), //ir_node * store,
128 ins, //ir_node ** in,
132 ret = new_r_Return ( irg,
133 bb, //ir_node * block,
134 new_r_Proj(irg, bb, call, mode_M, 0), //ir_node * store,
141 add_immBlock_pred(get_irg_end_block(irg), ret);
142 mature_immBlock(get_irg_end_block(irg));
148 block_id_walker(ir_node * bb, void * data)
150 block_id_walker_data *wd = data;
152 *wd->array[wd->id] = new_tarval_from_long(get_irn_node_nr(bb), mode_Iu);
153 instrument_block(bb, wd->symconst, wd->id);
158 be_profile_instrument(void)
161 unsigned int n_blocks = 0;
162 ir_entity *bblock_id, *bblock_counts, *bblock_count;
163 ir_type *array_type, *integer_type;
164 tarval **tarval_array;
166 block_id_walker_data wd;
169 integer_type = new_type_primitive(new_id_from_str("__uint"), mode_Iu);
170 array_type = new_type_array(new_id_from_str("__block_info_array"), 1, integer_type);
171 set_array_bounds_int(array_type, 0, 0, n_blocks);
172 bblock_id = new_entity(get_glob_type(), new_id_from_str("__BLOCK_IDS"), array_type);
173 bblock_counts = new_entity(get_glob_type(), new_id_from_str("__BLOCK_COUNTS"), array_type);
174 bblock_count = new_entity(get_glob_type(), new_id_from_str("__N_BLOCKS"), integer_type);
176 for (n = get_irp_n_irgs()-1; n>=0; --n) {
177 ir_graph *irg = get_irp_irg(n);
179 n_blocks += count_blocks(irg);
182 /* initialize count array */
183 tarval_array = alloca(sizeof(*null_array)*n_blocks);
184 for(i=0; i<n_blocks; ++i) {
185 null_array[i] = get_tarval_null(mode_Iu);
187 set_array_entitiy_values(bblock_counts, tarval_array, n_blocks);
189 /* initialize the block count entity */
190 set_atomic_ent_value(bblock_count, new_Const_long(mode_Iu, n_blocks));
192 /* generate a symbolic constant pointing to the count array */
193 sym.entity_p = bblock_count;
194 wd.symconst = new_SymConst(sym, symconst_addr_ent);
196 /* initialize block id array and instrument blocks */
197 wd.array = tarval_array;
199 for (n = get_irp_n_irgs()-1; n>=0; --n) {
200 ir_graph *irg = get_irp_irg(n);
202 irg_block_walk_graph(irg, block_id_walker, null, &wd);
204 set_array_entitiy_values(bblock_id, tarval_array, n_blocks);
206 gen_initializer_irg(bblock_id, bblock_counts, bblock_count);
211 be_profile_read(void)