diff mbox

[LEDE-DEV,1/2] libubox: Add pure attribute to several functions.

Message ID 1478055780-16694-1-git-send-email-rosenp@gmail.com
State Changes Requested
Headers show

Commit Message

Rosen Penev Nov. 2, 2016, 3:03 a.m. UTC
Manually adding pure allows the compiler to optimize several functions for better performance. All were found with gcc's -Wsuggest-attribute=pure. The switch is conservative meaning there are more such functions.

Signed-off by: Rosen Penev <rosenp@gmail.com>
---
 avl-cmp.h | 6 ++++--
 avl.c     | 2 ++
 blob.h    | 4 ++--
 blobmsg.h | 6 +++---
 jshn.c    | 1 +
 kvlist.h  | 4 ++--
 utils.h   | 4 ++++
 7 files changed, 18 insertions(+), 9 deletions(-)

Comments

Felix Fietkau Nov. 4, 2016, 12:14 p.m. UTC | #1
On 2016-11-02 04:03, Rosen Penev wrote:
> Manually adding pure allows the compiler to optimize several
> functions for better performance. All were found with gcc's
> -Wsuggest-attribute=pure. The switch is conservative meaning there are
> more such functions.
> 
> Signed-off by: Rosen Penev <rosenp@gmail.com>
Please linewrap your commit description.
You should also leave out __pure in .c files, it won't do anything
useful there, since it's relevant to callers only.
Also, you can leave out out of comparator functions for avl and kvlist.
Since they're stored as a function pointer in the tree struct and called
from there, there's no way that this can ever help the compiler make a
better decision.

- Felix
diff mbox

Patch

diff --git a/avl-cmp.h b/avl-cmp.h
index f97ae8d..ea415b3 100644
--- a/avl-cmp.h
+++ b/avl-cmp.h
@@ -16,7 +16,9 @@ 
 #ifndef __AVL_CMP_H
 #define __AVL_CMP_H
 
-int avl_strcmp(const void *k1, const void *k2, void *ptr);
-int avl_blobcmp(const void *k1, const void *k2, void *ptr);
+#include "utils.h"
+
+int avl_strcmp(const void *k1, const void *k2, void *ptr) __pure;
+int avl_blobcmp(const void *k1, const void *k2, void *ptr) __pure;
 
 #endif
diff --git a/avl.c b/avl.c
index 8d0bf65..424ce45 100644
--- a/avl.c
+++ b/avl.c
@@ -46,6 +46,7 @@ 
 
 #include "avl.h"
 #include "list.h"
+#include "utils.h"
 
 /**
  * internal type save inline function to calculate the maximum of
@@ -569,6 +570,7 @@  avl_post_delete(struct avl_tree *tree, struct avl_node *node)
   avl_post_delete(tree, parent->parent);
 }
 
+__pure
 static struct avl_node *
 avl_local_min(struct avl_node *node)
 {
diff --git a/blob.h b/blob.h
index ab077ea..d63b954 100644
--- a/blob.h
+++ b/blob.h
@@ -188,7 +188,7 @@  blob_next(const struct blob_attr *attr)
 
 extern void blob_fill_pad(struct blob_attr *attr);
 extern void blob_set_raw_len(struct blob_attr *attr, unsigned int len);
-extern bool blob_attr_equal(const struct blob_attr *a1, const struct blob_attr *a2);
+extern bool blob_attr_equal(const struct blob_attr *a1, const struct blob_attr *a2) __pure;
 extern int blob_buf_init(struct blob_buf *buf, int id);
 extern void blob_buf_free(struct blob_buf *buf);
 extern bool blob_buf_grow(struct blob_buf *buf, int required);
@@ -196,7 +196,7 @@  extern struct blob_attr *blob_new(struct blob_buf *buf, int id, int payload);
 extern void *blob_nest_start(struct blob_buf *buf, int id);
 extern void blob_nest_end(struct blob_buf *buf, void *cookie);
 extern struct blob_attr *blob_put(struct blob_buf *buf, int id, const void *ptr, unsigned int len);
-extern bool blob_check_type(const void *ptr, unsigned int len, int type);
+extern bool blob_check_type(const void *ptr, unsigned int len, int type) __pure;
 extern int blob_parse(struct blob_attr *attr, struct blob_attr **data, const struct blob_attr_info *info, int max);
 extern struct blob_attr *blob_memdup(struct blob_attr *attr);
 extern struct blob_attr *blob_put_raw(struct blob_buf *buf, const void *ptr, unsigned int len);
diff --git a/blobmsg.h b/blobmsg.h
index 84997a6..3114425 100644
--- a/blobmsg.h
+++ b/blobmsg.h
@@ -94,8 +94,8 @@  static inline int blobmsg_len(const struct blob_attr *attr)
 	return blobmsg_data_len(attr);
 }
 
-bool blobmsg_check_attr(const struct blob_attr *attr, bool name);
-bool blobmsg_check_attr_list(const struct blob_attr *attr, int type);
+bool blobmsg_check_attr(const struct blob_attr *attr, bool name) __pure;
+bool blobmsg_check_attr_list(const struct blob_attr *attr, int type) __pure;
 
 /*
  * blobmsg_check_array: validate array/table and return size
@@ -103,7 +103,7 @@  bool blobmsg_check_attr_list(const struct blob_attr *attr, int type);
  * Checks if all elements of an array or table are valid and have
  * the specified type. Returns the number of elements in the array
  */
-int blobmsg_check_array(const struct blob_attr *attr, int type);
+int blobmsg_check_array(const struct blob_attr *attr, int type) __pure;
 
 int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len,
                   struct blob_attr **tb, void *data, unsigned int len);
diff --git a/jshn.c b/jshn.c
index 4989099..9e3c3f4 100644
--- a/jshn.c
+++ b/jshn.c
@@ -304,6 +304,7 @@  static int usage(const char *progname)
 	return 2;
 }
 
+__pure
 static int avl_strcmp_var(const void *k1, const void *k2, void *ptr)
 {
 	const char *s1 = k1;
diff --git a/kvlist.h b/kvlist.h
index eaa691c..86abfb4 100644
--- a/kvlist.h
+++ b/kvlist.h
@@ -58,7 +58,7 @@  void *kvlist_get(struct kvlist *kv, const char *name);
 bool kvlist_set(struct kvlist *kv, const char *name, const void *data);
 bool kvlist_delete(struct kvlist *kv, const char *name);
 
-int kvlist_strlen(struct kvlist *kv, const void *data);
-int kvlist_blob_len(struct kvlist *kv, const void *data);
+int kvlist_strlen(struct kvlist *kv, const void *data) __pure;
+int kvlist_blob_len(struct kvlist *kv, const void *data) __pure;
 
 #endif
diff --git a/utils.h b/utils.h
index d00e76b..dc4a88a 100644
--- a/utils.h
+++ b/utils.h
@@ -156,6 +156,10 @@  static inline uint16_t __u_bswap16(uint16_t val)
 #define __packed __attribute__((packed))
 #endif
 
+#ifndef __pure
+#define __pure __attribute__((pure))
+#endif
+
 #ifndef __constructor
 #define __constructor __attribute__((constructor))
 #endif