3 * File name: ir/ana/field_temperature.c
4 * Purpose: Compute an estimate of field temperature, i.e., field access heuristic.
5 * Author: Goetz Lindenmaier
9 * Copyright: (c) 2004 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
13 #include "field_temperature.h"
16 #include "irgraph_t.h"
23 /* *************************************************************************** */
24 /* initialize, global variables. */
25 /* *************************************************************************** */
27 /* A list of Load and Store operations that have no analyseable address. */
28 static ir_node **unrecognized_access = NULL;
30 static void add_unrecognized_access(ir_node *n) {
31 ARR_APP1(ir_node *, unrecognized_access, n);
35 /* *************************************************************************** */
36 /* Access routines for irnodes */
37 /* *************************************************************************** */
39 /* The entities that can be accessed by this Sel node. */
40 int get_Sel_n_accessed_entities(ir_node *sel) {
44 entity *get_Sel_accessed_entity(ir_node *sel, int pos) {
45 return get_Sel_entity(sel);
48 /* An addr node is a SymConst or a Sel. */
49 int get_addr_n_entities(ir_node *addr) {
52 switch (get_irn_opcode(addr)) {
54 /* Treat jack array sels? */
55 n_ents = get_Sel_n_accessed_entities(addr);
58 if (get_SymConst_kind(addr) == symconst_addr_ent) {
63 //assert(0 && "unexpected address expression");
70 /* An addr node is a SymConst or a Sel. */
71 entity *get_addr_entity(ir_node *addr, int pos) {
74 switch (get_irn_opcode(addr)) {
76 /* Treat jack array sels? */
77 assert (0 <= pos && pos < get_Sel_n_accessed_entities(addr));
78 ent = get_Sel_accessed_entity(addr, pos);
81 if (get_SymConst_kind(addr) == symconst_addr_ent) {
83 ent = get_SymConst_entity(addr);
94 int get_irn_loop_call_depth(ir_node *n) {
95 ir_graph *irg = get_irn_irg(n);
96 return get_irg_loop_depth(irg);
99 int get_irn_loop_depth(ir_node *n) {
100 return get_loop_depth(get_irn_loop(get_nodes_block(n)));
103 int get_irn_recursion_depth(ir_node *n) {
104 ir_graph *irg = get_irn_irg(n);
105 return get_irg_recursion_depth(irg);
109 /* *************************************************************************** */
111 /* *************************************************************************** */
113 int get_weighted_loop_depth(ir_node *n) {
114 int loop_call_depth = get_irn_loop_call_depth(n);
115 int loop_depth = get_irn_loop_depth(n);
116 int recursion_depth = get_irn_recursion_depth(n);
118 return loop_call_depth + loop_depth + recursion_depth;
121 /* *************************************************************************** */
123 /* *************************************************************************** */
125 static void init_field_temperature(void) {
126 assert(!unrecognized_access);
127 unrecognized_access = NEW_ARR_F(ir_node *, 0);
131 static void chain_accesses(ir_node *n, void *env) {
135 if (get_irn_op(n) == op_Alloc) {
136 add_type_allocation(get_Alloc_type(n), n);
141 addr = get_memop_ptr(n);
142 } else if (get_irn_op(n) == op_Call) {
143 addr = get_Call_ptr(n);
144 if (get_irn_op(addr) != op_Sel) return; /* Sels before Calls mean a Load / polymorphic Call. */
149 n_ents = get_addr_n_entities(addr);
150 for (i = 0; i < n_ents; ++i) {
151 entity *ent = get_addr_entity(addr, i);
153 add_entity_access(ent, n);
155 add_unrecognized_access(n);
160 /* compute the field temperature. */
161 void compute_field_temperature(void) {
163 int i, n_irgs = get_irp_n_irgs();
165 init_field_temperature();
167 for (i=0; i < n_irgs; i++) {
168 current_ir_graph = get_irp_irg(i);
169 irg_walk_graph(current_ir_graph, NULL, chain_accesses, NULL);
173 /* free occupied memory, reset */
174 void free_field_temperature(void) {
175 DEL_ARR_F(unrecognized_access);
176 unrecognized_access = NULL;
181 /* *************************************************************************** */
183 /* *************************************************************************** */
186 int is_jack_rts_class(type *t) {
187 ident *name = get_type_ident(t);
189 if (id_is_prefix(new_id_from_str("java/"), name)) return 1;
190 if (id_is_prefix(new_id_from_str("["), name)) return 1;
191 if (id_is_prefix(new_id_from_str("gnu/"), name)) return 1;
192 if (id_is_prefix(new_id_from_str("java/"), name)) return 1;