Added dead code elimination survival facility
[libfirm] / ir / common / survive_dce.c
1
2 #include "pmap.h"
3
4 #include "irnode_t.h"
5 #include "irhooks.h"
6 #include "irgwalk.h"
7
8 #include "survive_dce.h"
9
10 struct _survive_dce_t {
11         pmap *places;
12         pmap *new_places;
13         hook_entry_t dead_node_elim;
14         hook_entry_t dead_node_elim_subst;
15 };
16
17 static void dead_node_hook(void *context, ir_graph *irg, int start)
18 {
19         survive_dce_t *sd = context;
20
21         /* Create a new map before the dead node elimination is performed. */
22         if(start) {
23                 sd->new_places = pmap_create_ex(pmap_count(sd->places));
24         }
25
26         /* Patch back all nodes if dead node elimination is over and something is to be done. */
27         else {
28                 pmap_destroy(sd->places);
29                 sd->places     = sd->new_places;
30                 sd->new_places = NULL;
31         }
32 }
33
34 static void dead_node_subst_hook(void *context, ir_graph *irg, ir_node *old, ir_node *nw)
35 {
36         survive_dce_t *sd = context;
37         ir_node **place    = (ir_node **) pmap_get(sd->places, old);
38
39         /* If the node is to be patched back, do it. */
40         if(place) {
41                 *place = nw;
42                 pmap_insert(sd->new_places, nw, (void *) place);
43         }
44 }
45
46 survive_dce_t *new_survive_dce(void)
47 {
48         survive_dce_t *res = xmalloc(sizeof(res[0]));
49         res->places     = pmap_create();
50         res->new_places = NULL;
51
52         res->dead_node_elim.hook._hook_dead_node_elim = dead_node_hook;
53         res->dead_node_elim.context                   = res;
54         res->dead_node_elim.next                      = NULL;
55
56         res->dead_node_elim_subst.hook._hook_dead_node_elim_subst = dead_node_subst_hook;
57         res->dead_node_elim_subst.context = res;
58         res->dead_node_elim_subst.next    = NULL;
59
60         register_hook(hook_dead_node_elim, &res->dead_node_elim);
61         register_hook(hook_dead_node_elim_subst, &res->dead_node_elim_subst);
62         return res;
63 }
64
65 void free_survive_dce(survive_dce_t *sd)
66 {
67         pmap_destroy(sd->places);
68         unregister_hook(hook_dead_node_elim, &sd->dead_node_elim);
69         unregister_hook(hook_dead_node_elim_subst, &sd->dead_node_elim_subst);
70         free(sd);
71 }
72
73 void survive_dce_register_irn(survive_dce_t *sd, ir_node **place)
74 {
75         pmap_insert(sd->places, *place, (void *) place);
76 }