static unsigned get_stmt_uid (tree stmt) { if (TREE_CODE (stmt) == PHI_NODE) return SSA_NAME_VERSION (PHI_RESULT (stmt)) + max_stmt_uid; return stmt_ann (stmt)->uid; }
enum move_pos movement_possibility (tree stmt) { tree lhs, rhs; if (flag_unswitch_loops && TREE_CODE (stmt) == COND_EXPR) { /* If we perform unswitching, force the operands of the invariant condition to be moved out of the loop. */ return MOVE_POSSIBLE; } if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT) return MOVE_IMPOSSIBLE; if (stmt_ends_bb_p (stmt)) return MOVE_IMPOSSIBLE; if (stmt_ann (stmt)->has_volatile_ops) return MOVE_IMPOSSIBLE; lhs = GIMPLE_STMT_OPERAND (stmt, 0); if (TREE_CODE (lhs) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) return MOVE_IMPOSSIBLE; rhs = GIMPLE_STMT_OPERAND (stmt, 1); if (TREE_SIDE_EFFECTS (rhs) || tree_could_throw_p (rhs)) return MOVE_IMPOSSIBLE; if (TREE_CODE (lhs) != SSA_NAME || tree_could_trap_p (rhs)) return MOVE_PRESERVE_EXECUTION; if (get_call_expr_in (stmt)) { /* While pure or const call is guaranteed to have no side effects, we cannot move it arbitrarily. Consider code like char *s = something (); while (1) { if (s) t = strlen (s); else t = 0; } Here the strlen call cannot be moved out of the loop, even though s is invariant. In addition to possibly creating a call with invalid arguments, moving out a function call that is not executed may cause performance regressions in case the call is costly and not executed at all. */ return MOVE_PRESERVE_EXECUTION; } return MOVE_POSSIBLE; }