@@ -41,6 +41,7 @@ LIB_OBJS += evaluate.o
LIB_OBJS += expand.o
LIB_OBJS += expression.o
LIB_OBJS += flow.o
+LIB_OBJS += flowgraph.o
LIB_OBJS += inline.o
LIB_OBJS += lib.o
LIB_OBJS += linearize.o
new file mode 100644
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: MIT
+//
+// Various utilities for flowgraphs.
+//
+// Copyright (c) 2017 Luc Van Oostenryck.
+//
+
+#include "flowgraph.h"
+#include "linearize.h"
+#include "flow.h" // for bb_generation
+
+
+struct cfg_info {
+ struct basic_block_list *list;
+ unsigned long gen;
+ unsigned int nr;
+};
+
+
+static void label_postorder(struct basic_block *bb, struct cfg_info *info)
+{
+ struct basic_block *child;
+
+ if (bb->generation == info->gen)
+ return;
+
+ bb->generation = info->gen;
+ FOR_EACH_PTR_REVERSE(bb->children, child) {
+ label_postorder(child, info);
+ } END_FOR_EACH_PTR_REVERSE(child);
+
+ bb->postorder_nr = info->nr++;
+ add_bb(&info->list, bb);
+}
+
+static void reverse_bbs(struct basic_block_list **dst, struct basic_block_list *src)
+{
+ struct basic_block *bb;
+ FOR_EACH_PTR_REVERSE(src, bb) {
+ add_bb(dst, bb);
+ } END_FOR_EACH_PTR_REVERSE(bb);
+}
+
+//
+// cfg_postorder - Set the BB's reverse postorder links
+//
+// Do a postorder DFS walk and set the links
+// (which will do the reverse part).
+//
+int cfg_postorder(struct entrypoint *ep)
+{
+ struct cfg_info info = {
+ .gen = ++bb_generation,
+ };
+
+ label_postorder(ep->entry->bb, &info);
+
+ // OK, now info.list contains the node in postorder
+ // Reuse ep->bbs for the reverse postorder.
+ free_ptr_list(&ep->bbs);
+ ep->bbs = NULL;
+ reverse_bbs(&ep->bbs, info.list);
+ free_ptr_list(&info.list);
+ return info.nr;
+}
new file mode 100644
@@ -0,0 +1,8 @@
+#ifndef FLOWGRAPH_H
+#define FLOWGRAPH_H
+
+struct entrypoint;
+
+int cfg_postorder(struct entrypoint *ep);
+
+#endif
@@ -257,7 +257,10 @@ struct instruction_list;
struct basic_block {
struct position pos;
unsigned long generation;
- int context;
+ union {
+ int context;
+ int postorder_nr; /* postorder number */
+ };
struct entrypoint *ep;
struct basic_block_list *parents; /* sources */
struct basic_block_list *children; /* destinations */
Do a DFS on the CFG and record the (reverse) postorder. Use this order for the normal BB traversal (ep->bbs). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- Makefile | 1 + flowgraph.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ flowgraph.h | 8 ++++++++ linearize.h | 5 ++++- 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 flowgraph.c create mode 100644 flowgraph.h