[PATCH 3/5] add ptr_list_multiple()

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

 



When doing IR simplification, it's often needed to check if the
result of a instructions is used by a single instruction in which
case it can be destructively modified together with its user.

Currently this is done using ptr_list_size() which needs to walk
the whole list which is relatively costly when the list is long
while knowing if the list contains more than 1 element can often
be answered cheaply by inspecting only the first block.

Add the helpers ptr_list_multiple() and multi_users().

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 linearize.h |  5 +++++
 ptrlist.c   | 21 +++++++++++++++++++++
 ptrlist.h   |  1 +
 simplify.c  |  2 +-
 4 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/linearize.h b/linearize.h
index de42e718d..b067b3e84 100644
--- a/linearize.h
+++ b/linearize.h
@@ -343,6 +343,11 @@ static inline int has_users(pseudo_t p)
 	return !pseudo_user_list_empty(p->users);
 }
 
+static inline bool multi_users(pseudo_t p)
+{
+	return ptr_list_multiple((struct ptr_list *)(p->users));
+}
+
 static inline struct pseudo_user *alloc_pseudo_user(struct instruction *insn, pseudo_t *pp)
 {
 	struct pseudo_user *user = __alloc_pseudo_user(0);
diff --git a/ptrlist.c b/ptrlist.c
index 40a671000..4cd3baca9 100644
--- a/ptrlist.c
+++ b/ptrlist.c
@@ -55,6 +55,27 @@ bool ptr_list_empty(const struct ptr_list *head)
 	return true;
 }
 
+///
+// test is a list contains more than one element
+// @head: the head of the list
+// @return: ``true`` if the list has more than 1 element, '``false`` otherwise.
+bool ptr_list_multiple(const struct ptr_list *head)
+{
+	const struct ptr_list *list = head;
+	int nr = 0;
+
+	if (!head)
+		return false;
+
+	do {
+		nr += list->nr - list->rm;
+		if (nr > 1)
+			return true;
+	} while ((list = list->next) != head);
+
+	return false;
+}
+
 ///
 // get the first element of a ptrlist
 // @head: the head of the list
diff --git a/ptrlist.h b/ptrlist.h
index f145bc5f1..176bb0712 100644
--- a/ptrlist.h
+++ b/ptrlist.h
@@ -39,6 +39,7 @@ extern void concat_ptr_list(struct ptr_list *a, struct ptr_list **b);
 extern void copy_ptr_list(struct ptr_list **h, struct ptr_list *t);
 extern int ptr_list_size(struct ptr_list *);
 extern bool ptr_list_empty(const struct ptr_list *head);
+extern bool ptr_list_multiple(const struct ptr_list *head);
 extern int linearize_ptr_list(struct ptr_list *, void **, int);
 extern void *first_ptr_list(struct ptr_list *);
 extern void *last_ptr_list(struct ptr_list *);
diff --git a/simplify.c b/simplify.c
index 4dc24a505..65f29de0a 100644
--- a/simplify.c
+++ b/simplify.c
@@ -824,7 +824,7 @@ static int simplify_associative_binop(struct instruction *insn)
 		return 0;
 	if (!simple_pseudo(def->src2))
 		return 0;
-	if (pseudo_user_list_size(def->target->users) != 1)
+	if (multi_users(def->target))
 		return 0;
 	switch_pseudo(def, &def->src1, insn, &insn->src2);
 	return REPEAT_CSE;
-- 
2.18.0

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