+ir_node *(get_Block_phis)(const ir_node *block) {
+ return _get_Block_phis(block);
+}
+
+void (set_Block_phis)(ir_node *block, ir_node *phi) {
+ _set_Block_phis(block, phi);
+}
+
+void (add_Block_phi)(ir_node *block, ir_node *phi) {
+ _add_Block_phi(block, phi);
+}
+
+/* Get the Block mark (single bit). */
+unsigned (get_Block_mark)(const ir_node *block) {
+ return _get_Block_mark(block);
+}
+
+/* Set the Block mark (single bit). */
+void (set_Block_mark)(ir_node *block, unsigned mark) {
+ _set_Block_mark(block, mark);
+}
+
+int get_End_n_keepalives(const ir_node *end) {
+ assert(is_End(end));
+ return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
+}
+
+ir_node *get_End_keepalive(const ir_node *end, int pos) {
+ assert(is_End(end));
+ return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
+}
+
+void add_End_keepalive(ir_node *end, ir_node *ka) {
+ assert(is_End(end));
+ add_irn_n(end, ka);
+}
+
+void set_End_keepalive(ir_node *end, int pos, ir_node *ka) {
+ assert(is_End(end));
+ set_irn_n(end, pos + END_KEEPALIVE_OFFSET, ka);
+}
+
+/* Set new keep-alives */
+void set_End_keepalives(ir_node *end, int n, ir_node *in[]) {
+ int i;
+ ir_graph *irg = get_irn_irg(end);
+
+ /* notify that edges are deleted */
+ for (i = END_KEEPALIVE_OFFSET; i < ARR_LEN(end->in) - 1; ++i) {
+ edges_notify_edge(end, i, NULL, end->in[i + 1], irg);
+ }
+ ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
+
+ for (i = 0; i < n; ++i) {
+ end->in[1 + END_KEEPALIVE_OFFSET + i] = in[i];
+ edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, end->in[1 + END_KEEPALIVE_OFFSET + i], NULL, irg);
+ }
+}
+
+/* Set new keep-alives from old keep-alives, skipping irn */
+void remove_End_keepalive(ir_node *end, ir_node *irn) {
+ int n = get_End_n_keepalives(end);
+ int i, idx;
+ ir_graph *irg;
+
+ idx = -1;
+ for (i = n -1; i >= 0; --i) {
+ ir_node *old_ka = end->in[1 + END_KEEPALIVE_OFFSET + i];
+
+ /* find irn */
+ if (old_ka == irn) {
+ idx = i;
+ goto found;
+ }
+ }
+ return;
+found:
+ irg = get_irn_irg(end);
+
+ /* remove the edge */
+ edges_notify_edge(end, idx, NULL, irn, irg);
+
+ if (idx != n - 1) {
+ /* exchange with the last one */
+ ir_node *old = end->in[1 + END_KEEPALIVE_OFFSET + n - 1];
+ edges_notify_edge(end, n - 1, NULL, old, irg);
+ end->in[1 + END_KEEPALIVE_OFFSET + idx] = old;
+ edges_notify_edge(end, idx, old, NULL, irg);
+ }
+ /* now n - 1 keeps, 1 block input */
+ ARR_RESIZE(ir_node *, end->in, (n - 1) + 1 + END_KEEPALIVE_OFFSET);
+}
+
+/* remove Bads, NoMems and doublets from the keep-alive set */
+void remove_End_Bads_and_doublets(ir_node *end) {
+ pset_new_t keeps;
+ int idx, n = get_End_n_keepalives(end);
+ ir_graph *irg;
+
+ if (n <= 0)
+ return;
+
+ irg = get_irn_irg(end);
+ pset_new_init(&keeps);
+
+ for (idx = n - 1; idx >= 0; --idx) {
+ ir_node *ka = get_End_keepalive(end, idx);
+
+ if (is_Bad(ka) || is_NoMem(ka) || pset_new_contains(&keeps, ka)) {
+ /* remove the edge */
+ edges_notify_edge(end, idx, NULL, ka, irg);
+
+ if (idx != n - 1) {
+ /* exchange with the last one */
+ ir_node *old = end->in[1 + END_KEEPALIVE_OFFSET + n - 1];
+ edges_notify_edge(end, n - 1, NULL, old, irg);
+ end->in[1 + END_KEEPALIVE_OFFSET + idx] = old;
+ edges_notify_edge(end, idx, old, NULL, irg);
+ }
+ --n;
+ } else {
+ pset_new_insert(&keeps, ka);
+ }
+ }
+ /* n keeps, 1 block input */
+ ARR_RESIZE(ir_node *, end->in, n + 1 + END_KEEPALIVE_OFFSET);
+
+ pset_new_destroy(&keeps);
+}
+
+void free_End(ir_node *end) {
+ assert(is_End(end));
+ end->kind = k_BAD;
+ DEL_ARR_F(end->in);
+ end->in = NULL; /* @@@ make sure we get an error if we use the
+ in array afterwards ... */