diff mbox

[4/4] ir-validate: add validation of (nbr of) phi operands

Message ID 20180615164931.51695-5-luc.vanoostenryck@gmail.com (mailing list archive)
State Mainlined, archived
Headers show

Commit Message

Luc Van Oostenryck June 15, 2018, 4:49 p.m. UTC
This patch verify that every phi-nodes have the same number of
operands as the current BB has parents.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 ir.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
diff mbox

Patch

diff --git a/ir.c b/ir.c
index da677afc1..5a283d817 100644
--- a/ir.c
+++ b/ir.c
@@ -1,8 +1,59 @@ 
 #include "ir.h"
 #include "linearize.h"
 #include <stdlib.h>
+#include <assert.h>
 
 
+static int nbr_phi_operands(struct instruction *insn)
+{
+	pseudo_t p;
+	int nbr = 0;
+
+	if (!insn->phi_list)
+		return 0;
+
+	FOR_EACH_PTR(insn->phi_list, p) {
+		if (p == VOID)
+			continue;
+		nbr++;
+	} END_FOR_EACH_PTR(p);
+
+	return nbr;
+}
+
+static int check_phi_node(struct instruction *insn)
+{
+	struct basic_block *par;
+	pseudo_t phi;
+	int err = 0;
+
+	if (bb_list_size(insn->bb->parents) != nbr_phi_operands(insn)) {
+		sparse_error(insn->pos, "bad number of phi operands in:\n\t%s",
+			show_instruction(insn));
+		info(insn->pos, "parents: %d", bb_list_size(insn->bb->parents));
+		info(insn->pos, "phisrcs: %d", nbr_phi_operands(insn));
+		return 1;
+	}
+
+	PREPARE_PTR_LIST(insn->bb->parents, par);
+	FOR_EACH_PTR(insn->phi_list, phi) {
+		struct instruction *src;
+		if (phi == VOID)
+			continue;
+		assert(phi->type == PSEUDO_PHI);
+		src = phi->def;
+		if (src->bb != par) {
+			sparse_error(src->pos, "wrong BB for %s:", show_instruction(src));
+			info(src->pos, "expected: %s", show_label(par));
+			info(src->pos, "     got: %s", show_label(src->bb));
+			err++;
+		}
+		NEXT_PTR_LIST(par);
+	} END_FOR_EACH_PTR(phi);
+	FINISH_PTR_LIST(par);
+	return err;
+}
+
 static int check_user(struct instruction *insn, pseudo_t pseudo)
 {
 	struct instruction *def;
@@ -60,6 +111,7 @@  static int validate_insn(struct instruction *insn)
 		break;
 
 	case OP_PHI:
+		err += check_phi_node(insn);
 		break;
 
 	case OP_CALL: