+ set_interprocedural_view(rem);
+}
+
+
+
+
+
+/* Debug stuff *************************************************/
+
+static int test_loop_node(ir_loop *l) {
+ int i, has_node = 0, found_problem = 0;
+ loop_element le;
+
+ assert(l && l->kind == k_ir_loop);
+
+ if (get_loop_n_elements(l) == 0) {
+ printf(" Loop completely empty! "); DDML(l);
+ found_problem = 1;
+ dump_loop(l, "-ha");
+ }
+
+ le = get_loop_element(l, 0);
+ if (*(le.kind) != k_ir_node) {
+ assert(le.kind && *(le.kind) == k_ir_loop);
+ printf(" First loop element is not a node! "); DDML(l);
+ printf(" "); DDML(le.son);
+
+ found_problem = 1;
+ dump_loop(l, "-ha");
+ }
+
+ if ((*(le.kind) == k_ir_node) && !is_possible_loop_head(le.node)) {
+ printf(" Wrong node as head! "); DDML(l);
+ printf(" "); DDMN(le.node);
+ found_problem = 1;
+ dump_loop(l, "-ha");
+ }
+
+ if ((get_loop_depth(l) != 0) &&
+ (*(le.kind) == k_ir_node) && !has_backedges(le.node)) {
+ printf(" Loop head has no backedges! "); DDML(l);
+ printf(" "); DDMN(le.node);
+ found_problem = 1;
+ dump_loop(l, "-ha");
+ }
+
+ /* Recur */
+ has_node = 0;
+ for (i = 0; i < get_loop_n_elements(l); ++i) {
+ le = get_loop_element(l, i);
+ if (*(le.kind) == k_ir_node)
+ has_node++;
+ else
+ if (test_loop_node(le.son)) found_problem = 1;
+ }
+
+ if (has_node == 0) {
+ printf(" Loop has no firm node! "); DDML(l);
+ found_problem = 1;
+ dump_loop(l, "-ha");
+ }
+
+ return found_problem;
+}
+
+/** Prints all loop nodes that
+ * - do not have any firm nodes, only loop sons
+ * - the header is not a Phi, Block or Filter.
+ */
+void find_strange_loop_nodes(ir_loop *l) {
+ int found_problem = 0;
+ printf("\nTesting loop "); DDML(l);
+ found_problem = test_loop_node(l);
+ printf("Finished Test\n\n");
+ if (found_problem) exit(0);
+
+}
+
+/* ------------------------------------------------------------------- */
+/* Simple analyses based on the loop information */
+/* ------------------------------------------------------------------- */
+
+int is_loop_variant(ir_loop *l, ir_loop *b) {
+ int i, n_elems;
+
+ if (l == b) return 1;
+
+ n_elems = get_loop_n_elements(l);
+ for (i = 0; i < n_elems; ++i) {
+ loop_element e = get_loop_element(l, i);
+ if (is_ir_loop(e.kind))
+ if (is_loop_variant(e.son, b))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Test whether a value is loop invariant.
+ *
+ * @param n The node to be tested.
+ * @param block A block node. We pass the block, not the loop as we must
+ * start off with a block loop to find all proper uses.
+ *
+ * Returns non-zero, if the node n is not changed in the loop block
+ * belongs to or in inner loops of this blocks loop. */
+int is_loop_invariant(ir_node *n, ir_node *block) {
+ ir_loop *l = get_irn_loop(block);
+ ir_node *b = (is_Block(n)) ? n : get_nodes_block(n);
+ return !is_loop_variant(l, get_irn_loop(b));