becopyheur2: Cache the admissible registers eagerly.
[libfirm] / ir / ir / instrument.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief   Instrumentation of graphs.
9  * @date    14.4.2008
10  * @author  Michael Beck
11  */
12 #include "config.h"
13
14 #include "irgraph_t.h"
15 #include "iredges.h"
16 #include "error.h"
17 #include "ircons.h"
18 #include "instrument.h"
19
20 void instrument_initcall(ir_graph *irg, ir_entity *ent)
21 {
22         ir_node        *initial_exec;
23         ir_node        *first_block = NULL;
24         int             i, idx, need_new_block;
25         symconst_symbol sym;
26
27         assure_edges(irg);
28
29         /* find the first block */
30         initial_exec = get_irg_initial_exec(irg);
31
32         foreach_out_edge(initial_exec, edge) {
33                 ir_node *succ = get_edge_src_irn(edge);
34
35                 if (is_Block(succ)) {
36                         /* found the first block */
37                         first_block = succ;
38                         break;
39                 }
40         }
41         if (first_block == NULL) {
42                 panic("Cannot find first block of irg %+F", irg);
43         }
44
45         /* check if this block has only one predecessor */
46         idx = -1;
47         need_new_block = 0;
48         for (i = get_Block_n_cfgpreds(first_block) - 1; i >= 0; --i) {
49                 ir_node *p = get_Block_cfgpred(first_block, i);
50
51                 if (is_Bad(p))
52                         continue;
53                 if (p == initial_exec)
54                         idx = i;
55                 else
56                         need_new_block = 1;
57         }
58
59         if (need_new_block) {
60                 ir_node *blk = new_r_Block(irg, 1, &initial_exec);
61                 set_Block_cfgpred(first_block, idx, new_r_Jmp(blk));
62                 first_block = blk;
63         }
64
65         /* place the call */
66         sym.entity_p = ent;
67         ir_node *const adr         = new_r_SymConst(irg, mode_P_code, sym, symconst_addr_ent);
68         ir_node *const initial_mem = get_irg_initial_mem(irg);
69         ir_node *const call        = new_r_Call(first_block, initial_mem, adr, 0, NULL, get_entity_type(ent));
70         ir_node *const new_mem     = new_r_Proj(call, mode_M, pn_Call_M);
71
72         edges_reroute_except(initial_mem, new_mem, call);
73         /* beware: reroute routes anchor edges also, revert this */
74         set_irg_initial_mem(irg, initial_mem);
75 }