#include "config.h"
#endif
+#ifdef HAVE_STRING_H
#include <string.h>
+#endif
+
+#include <stdlib.h>
#include "irloop_t.h"
#endif
}
+int is_ir_loop(const void *thing) {
+ return (get_kind(thing) == k_ir_loop);
+}
+
/* The outermost loop is remarked in the surrounding graph. */
void set_irg_loop(ir_graph *irg, ir_loop *loop) {
assert(irg);
init_node (ir_node *n, void *env) {
set_irn_link (n, new_scc_info());
clear_backedges(n);
-#if 0
- /* Also init nodes not visible in intraproc_view. */
- /* @@@ init_node is called for too many nodes -- this wastes memory!.
- The mem is not lost as its on the obstack. */
- if (get_irn_op(n) == op_Filter) {
- for (i = 0; i < get_Filter_n_cg_preds(n); i++)
- init_node(get_Filter_cg_pred(n, i), NULL);
- }
- if (get_irn_op(n) == op_Block) {
- for (i = 0; i < get_Block_cg_n_cfgpreds(n); i++) {
- init_node(get_Block_cg_cfgpred(n, i), NULL);
- }
- }
- /* The following pattern matches only after a call from above pattern. */
- if ((get_irn_op(n) == op_Proj) /*&& (get_Proj_proj(n) == 0)*/) {
- /* @@@ init_node is called for every proj -- this wastes memory!.
- The mem is not lost as its on the obstack. */
- ir_node *cb = get_Proj_pred(n);
- if ((get_irn_op(cb) == op_CallBegin) ||
- (get_irn_op(cb) == op_EndReg) ||
- (get_irn_op(cb) == op_EndExcept)) {
- init_node(cb, NULL);
- init_node(get_nodes_block(cb), NULL);
- }
- }
-#endif
}
static INLINE void
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 true;
+
+ 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 true;
+ }
+
+ return false;
+}
+
+/* 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 true, if the node n is not changed in the loop block
+ * belongs to or in inner loops of this block. */
+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));
+}