- assert(get_irn_mode(node) == mode_T);
- if (get_irn_link(node) == MARK) {
- /* already visited */
- return;
- }
- set_irn_link(node, MARK);
- switch (get_irn_opcode(node)) {
- case iro_Proj: {
- /* proj_proj: in einem "sinnvollen" Graphen kommt jetzt ein
- * op_Tuple oder ein Knoten, der in "free_ana_walker" behandelt
- * wird. */
- ir_node * pred = get_Proj_pred(node);
- if (get_irn_link(pred) != MARK && get_irn_op(pred) == op_Tuple) {
- free_mark_proj(get_Tuple_pred(pred, get_Proj_proj(node)), n, set);
- } else {
- /* nothing: da in "free_ana_walker" behandelt. */
- }
- break;
- }
-
- case iro_Tuple:
- free_mark(get_Tuple_pred(node, n), set);
- break;
-
- case iro_Id:
- free_mark_proj(get_Id_pred(node), n, set);
- break;
-
- case iro_Start:
- case iro_Alloc:
- case iro_Load:
- /* nothing: Die Operationen werden in "free_ana_walker" selbst
- * behandelt. */
- break;
-
- default:
- assert(0 && "unexpected opcode or opcode not implemented");
- break;
- }
- set_irn_link(node, NULL);
+ assert(get_irn_mode(node) == mode_T);
+ if (get_irn_link(node) == MARK) {
+ /* already visited */
+ return;
+ }
+ set_irn_link(node, MARK);
+ switch (get_irn_opcode(node)) {
+ case iro_Proj: {
+ /* proj_proj: in einem "sinnvollen" Graphen kommt jetzt ein
+ * op_Tuple oder ein Knoten, der in "free_ana_walker" behandelt
+ * wird. */
+ ir_node * pred = get_Proj_pred(node);
+ if (get_irn_link(pred) != MARK && get_irn_op(pred) == op_Tuple) {
+ free_mark_proj(get_Tuple_pred(pred, get_Proj_proj(node)), n, set);
+ } else {
+ /* nothing: da in "free_ana_walker" behandelt. */
+ }
+ break;
+ }
+
+ case iro_Tuple:
+ free_mark(get_Tuple_pred(node, n), set);
+ break;
+
+ case iro_Id:
+ free_mark_proj(get_Id_pred(node), n, set);
+ break;
+
+ case iro_Start:
+ case iro_Alloc:
+ case iro_Load:
+ /* nothing: Die Operationen werden in free_ana_walker() selbst
+ * behandelt. */
+ break;
+
+ default:
+ assert(0 && "unexpected opcode or opcode not implemented");
+ break;
+ }
+ // set_irn_link(node, NULL);
+}
+
+/**
+ * Called for predecessors nodes of "interesting" ones.
+ * Interesting ones include all nodes that can somehow make
+ * a method visible.
+ *
+ * If a method (or a set of methods in case of polymorph calls) gets visible,
+ * add it to the set of 'free' methods
+ *
+ * @param node the current visited node
+ * @param set the set of all free methods
+ */
+static void free_mark(ir_node *node, eset * set) {
+ int i;
+
+ if (get_irn_link(node) == MARK)
+ return; /* already visited */
+
+ set_irn_link(node, MARK);
+
+ switch (get_irn_opcode(node)) {
+ case iro_Sel: {
+ ir_entity *ent = get_Sel_entity(node);
+ if (is_method_entity(ent)) {
+ for (i = get_Sel_n_methods(node) - 1; i >= 0; --i) {
+ eset_insert(set, get_Sel_method(node, i));
+ }
+ }
+ break;
+ }
+ case iro_SymConst:
+ if (get_SymConst_kind(node) == symconst_addr_ent) {
+ ir_entity *ent = get_SymConst_entity(node);
+ if (is_method_entity(ent)) {
+ eset_insert(set, ent);
+ }
+ } else {
+ assert(get_SymConst_kind(node) == symconst_addr_name);
+ /* nothing: SymConst points to extern method */
+ }
+ break;
+
+ case iro_Phi:
+ for (i = get_Phi_n_preds(node) - 1; i >= 0; --i) {
+ free_mark(get_Phi_pred(node, i), set);
+ }
+ break;
+ case iro_Proj:
+ free_mark_proj(get_Proj_pred(node), get_Proj_proj(node), set);
+ break;
+ default:
+ /* nothing: */
+ break;
+ }