static void constraints(ir_node *const bl, void *const data)
{
be_chordal_env_t *const env = (be_chordal_env_t*)data;
- for (ir_node *irn = sched_first(bl); !sched_is_end(irn);) {
- ir_node *const next = sched_next(irn);
+ sched_foreach_safe(bl, irn) {
handle_constraints(env, irn);
- irn = next;
}
}
static void remove_dead_nodes_walker(ir_node *block, void *data)
{
remove_dead_nodes_env_t *env = (remove_dead_nodes_env_t*) data;
- ir_node *node, *next;
-
- for (node = sched_first(block); ! sched_is_end(node); node = next) {
- /* get next node now, as after calling sched_remove it will be invalid */
- next = sched_next(node);
+ sched_foreach_safe(block, node) {
if (bitset_is_set(env->reachable, get_irn_idx(node)))
continue;
static void insert_perms(ir_node *block, void *data)
{
be_chordal_env_t *env = (be_chordal_env_t*)data;
- ir_node *irn;
- for (irn = sched_first(block); !sched_is_end(irn);) {
- ir_node *const next = sched_next(irn);
- be_insn_t * insn = be_scan_insn(env, irn);
+ sched_foreach_safe(block, irn) {
+ be_insn_t *insn = be_scan_insn(env, irn);
if (insn)
pre_process_constraints(env, &insn);
-
- irn = next;
}
}
#define sched_foreach_reverse(block,irn) \
sched_foreach_reverse_before((assert(is_Block(block)), block), irn)
+/**
+ * A shorthand macro for iterating over a schedule while the current node may be
+ * removed or replaced.
+ *
+ * @param block The block.
+ * @param irn A ir node pointer used as an iterator.
+ */
+#define sched_foreach_safe(block, irn) \
+ for (ir_node *irn, *irn##__next = sched_first(block); !sched_is_end(irn = irn##__next) ? irn##__next = sched_next(irn), 1 : 0;)
+
/**
* Type for a function scheduling a graph
*/
*/
static void ia32_finish_irg_walker(ir_node *block, void *env)
{
- ir_node *irn, *next;
(void) env;
/* first: turn back AM source if necessary */
- for (irn = sched_first(block); ! sched_is_end(irn); irn = next) {
- next = sched_next(irn);
+ sched_foreach_safe(block, irn) {
fix_am_source(irn);
}
- for (irn = sched_first(block); ! sched_is_end(irn); irn = next) {
- next = sched_next(irn);
-
+ sched_foreach_safe(block, irn) {
/* check if there is a sub which need to be transformed */
if (is_ia32_Sub(irn) || is_ia32_Sbb(irn) || is_ia32_xSub(irn)) {
ia32_transform_sub_to_neg_add(irn);
}
/* second: insert copies and finish irg */
- for (irn = sched_first(block); ! sched_is_end(irn); irn = next) {
- next = sched_next(irn);
+ sched_foreach_safe(block, irn) {
if (is_ia32_irn(irn)) {
/* some nodes are just a bit less efficient, but need no fixing if the
* should be same requirement is not fulfilled */