+static INLINE int get_irn_not_sched_user(block_sched_env_t *env, ir_node *n) {
+ int idx = get_irn_idx(n);
+
+ assert(idx < ARR_LEN(env->sched_info));
+ return env->sched_info[idx].num_not_sched_user;
+}
+
+/**
+ * Sets the number of not yet schedules users.
+ */
+static INLINE void set_irn_not_sched_user(block_sched_env_t *env, ir_node *n, int num) {
+ int idx = get_irn_idx(n);
+
+ assert(idx < ARR_LEN(env->sched_info));
+ env->sched_info[idx].num_not_sched_user = num;
+}
+
+/**
+ * Add @p num to the number of not yet schedules users and returns the result.
+ */
+static INLINE int add_irn_not_sched_user(block_sched_env_t *env, ir_node *n, int num) {
+ int idx = get_irn_idx(n);
+
+ assert(idx < ARR_LEN(env->sched_info));
+ env->sched_info[idx].num_not_sched_user += num;
+ return env->sched_info[idx].num_not_sched_user;
+}
+
+/**
+ * Returns the number of users of a node having mode datab.
+ */
+static int get_num_successors(ir_node *irn) {
+ int sum = 0;
+ const ir_edge_t *edge;
+
+ if (get_irn_mode(irn) == mode_T) {
+ /* for mode_T nodes: count the users of all Projs */
+ foreach_out_edge(irn, edge) {
+ ir_node *proj = get_edge_src_irn(edge);
+ ir_mode *mode = get_irn_mode(proj);
+
+ if (mode == mode_T)
+ sum += get_num_successors(proj);
+ else if (mode_is_datab(mode))
+ sum += get_irn_n_edges(proj);
+ }
+ }
+ else {
+ /* do not count keep-alive edges */
+ foreach_out_edge(irn, edge) {
+ if (get_irn_opcode(get_edge_src_irn(edge)) != iro_End)
+ sum++;
+ }
+ }
+
+ return sum;
+}
+
+/**
+ * Adds irn to @p live, updates all inputs that this user is scheduled
+ * and counts all of it's non scheduled users.
+ */
+static void update_sched_liveness(block_sched_env_t *env, ir_node *irn) {
+ int i;
+
+ /* ignore Projs */
+ if (is_Proj(irn))
+ return;
+
+ for (i = get_irn_ins_or_deps(irn) - 1; i >= 0; --i) {
+ ir_node *in = get_irn_in_or_dep(irn, i);
+
+ /* if in is a proj: update predecessor */
+ while (is_Proj(in))
+ in = get_Proj_pred(in);
+
+ /* if in is still in the live set: reduce number of users by one */
+ if (nodeset_find(env->live, in)) {
+ if (add_irn_not_sched_user(env, in, -1) <= 0)
+ nodeset_remove(env->live, in);
+ }
+ }
+
+ /*
+ get_num_successors returns the number of all users. This includes
+ users in different blocks as well. As the each block is scheduled separately
+ the liveness info of those users will not be updated and so these
+ users will keep up the register pressure as it is desired.
+ */
+ i = get_num_successors(irn);
+ if (i > 0) {
+ set_irn_not_sched_user(env, irn, i);
+ nodeset_insert(env->live, irn);
+ }
+}
+
+static INLINE int must_appear_in_schedule(const list_sched_selector_t *sel, void *block_env, const ir_node *irn)