+#ifdef INSN_SCHEDULING
+
+#ifdef ENABLE_CHECKING
+#define CHECK (true)
+#else
+#define CHECK (false)
+#endif
+
+/* Return the major type present in the DS. */
+enum reg_note
+ds_to_dk (ds_t ds)
+{
+ if (ds & DEP_TRUE)
+ return REG_DEP_TRUE;
+
+ if (ds & DEP_OUTPUT)
+ return REG_DEP_OUTPUT;
+
+ gcc_assert (ds & DEP_ANTI);
+
+ return REG_DEP_ANTI;
+}
+
+/* Return equivalent dep_status. */
+ds_t
+dk_to_ds (enum reg_note dk)
+{
+ switch (dk)
+ {
+ case REG_DEP_TRUE:
+ return DEP_TRUE;
+
+ case REG_DEP_OUTPUT:
+ return DEP_OUTPUT;
+
+ default:
+ gcc_assert (dk == REG_DEP_ANTI);
+ return DEP_ANTI;
+ }
+}
+
+/* Functions to operate with dependence information container - dep_t. */
+
+/* Init DEP with the arguments. */
+void
+init_dep_1 (dep_t dep, rtx pro, rtx con, enum reg_note type, ds_t ds)
+{
+ DEP_PRO (dep) = pro;
+ DEP_CON (dep) = con;
+ DEP_TYPE (dep) = type;
+ DEP_STATUS (dep) = ds;
+}
+
+/* Init DEP with the arguments.
+ While most of the scheduler (including targets) only need the major type
+ of the dependency, it is convenient to hide full dep_status from them. */
+void
+init_dep (dep_t dep, rtx pro, rtx con, enum reg_note kind)
+{
+ ds_t ds;
+
+ if ((current_sched_info->flags & USE_DEPS_LIST))
+ ds = dk_to_ds (kind);
+ else
+ ds = -1;
+
+ init_dep_1 (dep, pro, con, kind, ds);
+}
+
+/* Make a copy of FROM in TO. */
+static void
+copy_dep (dep_t to, dep_t from)
+{
+ memcpy (to, from, sizeof (*to));
+}
+
+static void dump_ds (FILE *, ds_t);
+
+/* Define flags for dump_dep (). */
+
+/* Dump producer of the dependence. */
+#define DUMP_DEP_PRO (2)
+
+/* Dump consumer of the dependence. */
+#define DUMP_DEP_CON (4)
+
+/* Dump type of the dependence. */
+#define DUMP_DEP_TYPE (8)
+
+/* Dump status of the dependence. */
+#define DUMP_DEP_STATUS (16)
+
+/* Dump all information about the dependence. */
+#define DUMP_DEP_ALL (DUMP_DEP_PRO | DUMP_DEP_CON | DUMP_DEP_TYPE \
+ |DUMP_DEP_STATUS)
+
+/* Dump DEP to DUMP.
+ FLAGS is a bit mask specifying what information about DEP needs
+ to be printed.
+ If FLAGS has the very first bit set, then dump all information about DEP
+ and propagate this bit into the callee dump functions. */
+static void
+dump_dep (FILE *dump, dep_t dep, int flags)
+{
+ if (flags & 1)
+ flags |= DUMP_DEP_ALL;
+
+ fprintf (dump, "<");
+
+ if (flags & DUMP_DEP_PRO)
+ fprintf (dump, "%d; ", INSN_UID (DEP_PRO (dep)));
+
+ if (flags & DUMP_DEP_CON)
+ fprintf (dump, "%d; ", INSN_UID (DEP_CON (dep)));
+
+ if (flags & DUMP_DEP_TYPE)
+ {
+ char t;
+ enum reg_note type = DEP_TYPE (dep);
+
+ switch (type)
+ {
+ case REG_DEP_TRUE:
+ t = 't';
+ break;
+
+ case REG_DEP_OUTPUT:
+ t = 'o';
+ break;
+
+ case REG_DEP_ANTI:
+ t = 'a';
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ fprintf (dump, "%c; ", t);
+ }
+
+ if (flags & DUMP_DEP_STATUS)
+ {
+ if (current_sched_info->flags & USE_DEPS_LIST)
+ dump_ds (dump, DEP_STATUS (dep));
+ }
+
+ fprintf (dump, ">");
+}
+
+/* Default flags for dump_dep (). */
+static int dump_dep_flags = (DUMP_DEP_PRO | DUMP_DEP_CON);
+
+/* Dump all fields of DEP to STDERR. */
+void
+sd_debug_dep (dep_t dep)
+{
+ dump_dep (stderr, dep, 1);
+ fprintf (stderr, "\n");
+}
+
+/* Functions to operate with a single link from the dependencies lists -
+ dep_link_t. */
+
+/* Attach L to appear after link X whose &DEP_LINK_NEXT (X) is given by
+ PREV_NEXT_P. */
+static void
+attach_dep_link (dep_link_t l, dep_link_t *prev_nextp)
+{
+ dep_link_t next = *prev_nextp;
+
+ gcc_assert (DEP_LINK_PREV_NEXTP (l) == NULL
+ && DEP_LINK_NEXT (l) == NULL);
+
+ /* Init node being inserted. */
+ DEP_LINK_PREV_NEXTP (l) = prev_nextp;
+ DEP_LINK_NEXT (l) = next;
+
+ /* Fix next node. */
+ if (next != NULL)
+ {
+ gcc_assert (DEP_LINK_PREV_NEXTP (next) == prev_nextp);
+
+ DEP_LINK_PREV_NEXTP (next) = &DEP_LINK_NEXT (l);
+ }
+
+ /* Fix prev node. */
+ *prev_nextp = l;
+}
+
+/* Add dep_link LINK to deps_list L. */
+static void
+add_to_deps_list (dep_link_t link, deps_list_t l)
+{
+ attach_dep_link (link, &DEPS_LIST_FIRST (l));
+
+ ++DEPS_LIST_N_LINKS (l);
+}
+
+/* Detach dep_link L from the list. */
+static void
+detach_dep_link (dep_link_t l)
+{
+ dep_link_t *prev_nextp = DEP_LINK_PREV_NEXTP (l);
+ dep_link_t next = DEP_LINK_NEXT (l);
+
+ *prev_nextp = next;
+
+ if (next != NULL)
+ DEP_LINK_PREV_NEXTP (next) = prev_nextp;
+
+ DEP_LINK_PREV_NEXTP (l) = NULL;
+ DEP_LINK_NEXT (l) = NULL;
+}
+
+/* Remove link LINK from list LIST. */
+static void
+remove_from_deps_list (dep_link_t link, deps_list_t list)
+{
+ detach_dep_link (link);
+
+ --DEPS_LIST_N_LINKS (list);
+}
+
+/* Move link LINK from list FROM to list TO. */
+static void
+move_dep_link (dep_link_t link, deps_list_t from, deps_list_t to)
+{
+ remove_from_deps_list (link, from);
+ add_to_deps_list (link, to);
+}
+
+/* Return true of LINK is not attached to any list. */
+static bool
+dep_link_is_detached_p (dep_link_t link)
+{
+ return DEP_LINK_PREV_NEXTP (link) == NULL;
+}
+
+/* Pool to hold all dependency nodes (dep_node_t). */
+static alloc_pool dn_pool;
+
+/* Number of dep_nodes out there. */
+static int dn_pool_diff = 0;
+
+/* Create a dep_node. */
+static dep_node_t
+create_dep_node (void)
+{
+ dep_node_t n = (dep_node_t) pool_alloc (dn_pool);
+ dep_link_t back = DEP_NODE_BACK (n);
+ dep_link_t forw = DEP_NODE_FORW (n);
+
+ DEP_LINK_NODE (back) = n;
+ DEP_LINK_NEXT (back) = NULL;
+ DEP_LINK_PREV_NEXTP (back) = NULL;
+
+ DEP_LINK_NODE (forw) = n;
+ DEP_LINK_NEXT (forw) = NULL;
+ DEP_LINK_PREV_NEXTP (forw) = NULL;
+
+ ++dn_pool_diff;
+
+ return n;
+}
+
+/* Delete dep_node N. N must not be connected to any deps_list. */
+static void
+delete_dep_node (dep_node_t n)
+{
+ gcc_assert (dep_link_is_detached_p (DEP_NODE_BACK (n))
+ && dep_link_is_detached_p (DEP_NODE_FORW (n)));
+
+ --dn_pool_diff;
+
+ pool_free (dn_pool, n);
+}
+
+/* Pool to hold dependencies lists (deps_list_t). */
+static alloc_pool dl_pool;
+
+/* Number of deps_lists out there. */
+static int dl_pool_diff = 0;
+
+/* Functions to operate with dependences lists - deps_list_t. */
+
+/* Return true if list L is empty. */
+static bool
+deps_list_empty_p (deps_list_t l)
+{
+ return DEPS_LIST_N_LINKS (l) == 0;
+}
+
+/* Create a new deps_list. */
+static deps_list_t
+create_deps_list (void)
+{
+ deps_list_t l = (deps_list_t) pool_alloc (dl_pool);
+
+ DEPS_LIST_FIRST (l) = NULL;
+ DEPS_LIST_N_LINKS (l) = 0;
+
+ ++dl_pool_diff;
+ return l;
+}
+
+/* Free deps_list L. */
+static void
+free_deps_list (deps_list_t l)
+{
+ gcc_assert (deps_list_empty_p (l));
+
+ --dl_pool_diff;
+
+ pool_free (dl_pool, l);
+}
+
+/* Return true if there is no dep_nodes and deps_lists out there.
+ After the region is scheduled all the dependency nodes and lists
+ should [generally] be returned to pool. */
+bool
+deps_pools_are_empty_p (void)
+{
+ return dn_pool_diff == 0 && dl_pool_diff == 0;
+}
+
+/* Remove all elements from L. */
+static void
+clear_deps_list (deps_list_t l)
+{
+ do
+ {
+ dep_link_t link = DEPS_LIST_FIRST (l);
+
+ if (link == NULL)
+ break;
+
+ remove_from_deps_list (link, l);
+ }
+ while (1);
+}