[PATCH v1 01/18] graph: build the CFG reverse postorder traversal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 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

diff --git a/Makefile b/Makefile
index 5548f8483..329e792ff 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/flowgraph.c b/flowgraph.c
new file mode 100644
index 000000000..89897fa48
--- /dev/null
+++ b/flowgraph.c
@@ -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;
+}
diff --git a/flowgraph.h b/flowgraph.h
new file mode 100644
index 000000000..676c5b2d8
--- /dev/null
+++ b/flowgraph.h
@@ -0,0 +1,8 @@
+#ifndef FLOWGRAPH_H
+#define FLOWGRAPH_H
+
+struct entrypoint;
+
+int cfg_postorder(struct entrypoint *ep);
+
+#endif
diff --git a/linearize.h b/linearize.h
index 8790b7e58..50738a9d8 100644
--- a/linearize.h
+++ b/linearize.h
@@ -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 */
-- 
2.16.2

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux