void add_End_keepalive(ir_node *end, ir_node *ka);
/** Set the Keep alive node at position pos. */
void set_End_keepalive(ir_node *end, int pos, ir_node *ka);
-/** Set new keep-alives. */
+
+/**
+ * Set new keep-alives.
+ * Beware: This might be an expensive operation if dynamic edges are enabled,
+ * so avoid it in the backend.
+ */
void set_End_keepalives(ir_node *end, int n, ir_node *in[]);
-/** Set new keep-alives from old keep-alives, skipping irn. */
+
+/** Remove irn from the keep-alive set. */
void remove_End_keepalive(ir_node *end, ir_node *irn);
/** Some parts of the End node are allocated separately -- their memory
/* 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);
- ir_node **in;
- int i, idx;
-
- NEW_ARR_A(ir_node *, in, n);
-
- for (idx = i = 0; i < n; ++i) {
- ir_node *old_ka = get_End_keepalive(end, i);
-
- /* skip irn */
- if (old_ka != irn)
- in[idx++] = old_ka;
+ 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;
+ }
}
-
- /* set new keep-alives */
- set_End_keepalives(end, idx, in);
+ 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);
+ }
+ ARR_RESIZE(ir_node *, end->in, (n - 1) + 1 + END_KEEPALIVE_OFFSET);
}
void