+/********************************************************************/
+
+typedef struct walk_env {
+ irg_walk_func *pre;
+ irg_walk_func *post;
+ void *env;
+} walk_env;
+
+/* Walk to all constant expressions in this entity. */
+static void walk_entity(entity *ent, void *env)
+{
+ walk_env *my_env = (walk_env *)env;
+
+ if (get_entity_variability(ent) != variability_uninitialized) {
+ if (is_atomic_entity(ent)) {
+ irg_walk(get_atomic_ent_value(ent), my_env->pre, my_env->post, my_env->env);
+ }
+ else {
+ int i, n = get_compound_ent_n_values(ent);
+
+ for (i = 0; i < n; i++)
+ irg_walk(get_compound_ent_value(ent, i), my_env->pre, my_env->post, my_env->env);
+ }
+ }
+}
+
+/* Walks over all code in const_code_irg. */
+void walk_const_code(irg_walk_func *pre, irg_walk_func *post, void *env) {
+ int i, j;
+ walk_env my_env;
+
+ ir_graph *rem = current_ir_graph;
+ current_ir_graph = get_const_code_irg();
+ inc_irg_visited(current_ir_graph);
+
+ my_env.pre = pre;
+ my_env.post = post;
+ my_env.env = env;
+
+ /* Walk all types that can contain constant entities. */
+ walk_types_entities(get_glob_type(), &walk_entity, &my_env);
+ for (i = 0; i < get_irp_n_types(); i++)
+ walk_types_entities(get_irp_type(i), &walk_entity, &my_env);
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ walk_types_entities(get_irg_frame_type(get_irp_irg(i)), &walk_entity, &my_env);
+
+ /* Walk constant array bounds. */
+ for (i = 0; i < get_irp_n_types(); i++) {
+ type *tp = get_irp_type(i);
+ if (is_array_type(tp)) {
+ for (j = 0; j < get_array_n_dimensions(tp); j++) {
+ ir_node *n;
+ n = get_array_lower_bound(tp, j);
+ if (n) irg_walk(n, pre, post, env);
+ n = get_array_upper_bound(tp, j);
+ if (n) irg_walk(n, pre, post, env);
+ }
+ }
+ }
+
+ current_ir_graph = rem;
+}
+
+
+/********************************************************************/
+/** Walking support for interprocedural analysis **/
+/** **/
+/** @@@ Don't use, not operational yet, doesn't grok recursions!! **/
+/** @@@ Header for irgwalk.h, here until it works. **/
+/** **/
+/** Interprocedural walking should not walk all predecessors of **/
+/** all nodes. When leaving a procedure the walker should only **/
+/** follow the edge corresponding to the most recent entry of the **/
+/** procedure. The following functions use an internal stack to **/
+/** remember the current call site of a procedure. **/
+/** They also set current_ir_graph correctly. **/
+/** **/
+/** Usage example: **/
+/** **/
+/** void init_ip_walk (); **/
+/** work_on_graph(some_end_node); **/
+/** void finish_ip_walk(); **/
+/** **/
+/** work_on_graph(ir_node *n) { **/
+/** for (i = 0; i < get_irn_arity(n); i++) { **/
+/** if (...) continue; **/
+/** ir_node *m = get_irn_ip_pred(n, i); **/
+/** if !m continue; **/
+/** work_on_graph(m); **/
+/** return_recur(n, i); **/
+/** } **/
+/** } **/
+/********************************************************************/
+
+/* Call for i in {0|-1 ... get_irn_arity(n)}.
+ If n is a conventional node returns the same node as get_irn_n(n, i).
+ If the predecessors of n are in the callee of the procedure n belongs
+ to, returns get_irn_n(n, i) if this node is in the callee on the top
+ of the stack, else returns NULL.
+ If the predecessors of n are in a procedure called by the procedure n
+ belongs to pushes the caller on the caller stack in the callee.
+ Sets current_ir_graph to the graph the node returned is in. */
+ir_node *get_irn_ip_pred(ir_node *n, int pos);
+
+/* If get_irn_ip_pred() returned a node (not NULL) this must be
+ called to clear up the stacks.
+ Sets current_ir_graph to the graph n is in. */
+void return_recur(ir_node *n, int pos);