beifg: Simplify the implementation of be_ifg_foreach_node().
[libfirm] / ir / opt / opt_frame.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief   Optimize the frame type.
9  * @date    15.03.2006
10  * @author  Michael Beck
11  * @brief
12  *   Optimize the frame type by removing unused type members.
13  */
14 #include "config.h"
15
16 #include "iroptimize.h"
17 #include "irgraph_t.h"
18 #include "type_t.h"
19 #include "irouts.h"
20 #include "iredges.h"
21 #include "irpass.h"
22
23 /*
24  * Optimize the frame type of an irg by removing
25  * never touched entities.
26  */
27 void opt_frame_irg(ir_graph *irg)
28 {
29         ir_type   *frame_tp = get_irg_frame_type(irg);
30         ir_entity *ent, *list;
31         ir_node   *frame, *sel;
32         size_t    i, n = get_class_n_members(frame_tp);
33         int       o;
34
35         if (n <= 0)
36                 return;
37
38         assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);
39
40         irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK);
41
42         /* clear all entity links */
43         for (i = n; i > 0;) {
44                 ent = get_class_member(frame_tp, --i);
45                 set_entity_link(ent, NULL);
46         }
47
48         /* look for uses */
49         frame = get_irg_frame(irg);
50
51         /* mark all used entities */
52         for (o = get_irn_n_outs(frame) - 1; o >= 0; --o) {
53                 sel = get_irn_out(frame, o);
54                 if (is_Sel(sel)) {
55                         ent = get_Sel_entity(sel);
56                         /* only entities on the frame */
57                         if (get_entity_owner(ent) == frame_tp)
58                                 set_entity_link(ent, ent);
59                 }
60         }
61
62         /* link unused ones */
63         list = NULL;
64         for (i = n; i > 0;) {
65                 ent = get_class_member(frame_tp, --i);
66                 /* beware of inner functions: those are NOT unused */
67                 if (get_entity_link(ent) == NULL && !is_method_entity(ent)) {
68                         set_entity_link(ent, list);
69                         list = ent;
70                 }
71         }
72
73         if (list != NULL) {
74                 /* delete list members */
75                 for (ent = list; ent; ent = list) {
76                         list = (ir_entity*)get_entity_link(ent);
77                         free_entity(ent);
78                 }
79                 /* we changed the frame type, its layout should be redefined */
80                 set_type_state(frame_tp, layout_undefined);
81         }
82         irp_free_resources(irp, IRP_RESOURCE_ENTITY_LINK);
83
84         /* we changed the type, this affects none of the currently known graph
85          * properties, but I don't use ALL because I don't know if someone adds
86          * type-based properties at some point */
87         confirm_irg_properties(irg,
88                 IR_GRAPH_PROPERTIES_CONTROL_FLOW
89                 | IR_GRAPH_PROPERTY_NO_BADS
90                 | IR_GRAPH_PROPERTY_NO_TUPLES
91                 | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES
92                 | IR_GRAPH_PROPERTY_CONSISTENT_OUTS
93                 | IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE
94                 | IR_GRAPH_PROPERTY_MANY_RETURNS);
95 }
96
97 ir_graph_pass_t *opt_frame_irg_pass(const char *name)
98 {
99         return def_graph_pass(name ? name : "opt_frame_irg", opt_frame_irg);
100 }