]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib/table: remove nonsensical const, add pure
authorDavid Lamparter <equinox@diac24.net>
Tue, 21 May 2019 02:48:30 +0000 (04:48 +0200)
committerDavid Lamparter <equinox@diac24.net>
Tue, 21 May 2019 03:42:13 +0000 (05:42 +0200)
Passing the struct route_table *ptr as const doesn't really help; if
anything it semantically would imply that the returned route_node is
const too since constness should propagate (but it doesn't in C.)

The right thing to do here - which actually helps the compiler optimize
the code too - is to tag functions with __attribute__((pure)).  The
compiler does this automatically if it has the function body (and the
body of all called functions) available.  That should cover most "static
inline" functions in headers, as well as functions in the same file.

However, this doesn't work (at least without LTO) for extern functions.
Hence, add "ext_pure" for this case.  (Built-in "extern" to make lines
shorter.)

Signed-off-by: David Lamparter <equinox@diac24.net>
lib/compiler.h
lib/table.c
lib/table.h

index 474adc7c8bb08a1f1c7da14e7674442080b28ff4..c2e57db7f81af1e60780c4baeac45c166b644d44 100644 (file)
@@ -76,6 +76,15 @@ extern "C" {
 #define _DEPRECATED(x) deprecated
 #endif
 
+/* pure = function does not modify memory & return value is the same if
+ * memory hasn't changed (=> allows compiler to optimize)
+ *
+ * Mostly autodetected by the compiler if function body is available (i.e.
+ * static inline functions in headers).  Since that implies it should only be
+ * used in headers for non-inline functions, the "extern" is included here.
+ */
+#define ext_pure       extern __attribute__((pure))
+
 /* for helper functions defined inside macros */
 #define macro_inline   static inline __attribute__((unused))
 #define macro_pure     static inline __attribute__((unused, pure))
index 4bd52b3d80aadeea32edf22d7b67731a34f96cac..728615c7760180eb22ae9899f402b4f513f5a534 100644 (file)
@@ -191,7 +191,7 @@ static void set_link(struct route_node *node, struct route_node *new)
 }
 
 /* Find matched prefix. */
-struct route_node *route_node_match(const struct route_table *table,
+struct route_node *route_node_match(struct route_table *table,
                                    union prefixconstptr pu)
 {
        const struct prefix *p = pu.p;
@@ -221,7 +221,7 @@ struct route_node *route_node_match(const struct route_table *table,
        return NULL;
 }
 
-struct route_node *route_node_match_ipv4(const struct route_table *table,
+struct route_node *route_node_match_ipv4(struct route_table *table,
                                         const struct in_addr *addr)
 {
        struct prefix_ipv4 p;
@@ -234,7 +234,7 @@ struct route_node *route_node_match_ipv4(const struct route_table *table,
        return route_node_match(table, (struct prefix *)&p);
 }
 
-struct route_node *route_node_match_ipv6(const struct route_table *table,
+struct route_node *route_node_match_ipv6(struct route_table *table,
                                         const struct in6_addr *addr)
 {
        struct prefix_ipv6 p;
@@ -248,7 +248,7 @@ struct route_node *route_node_match_ipv6(const struct route_table *table,
 }
 
 /* Lookup same prefix node.  Return NULL when we can't find route. */
-struct route_node *route_node_lookup(const struct route_table *table,
+struct route_node *route_node_lookup(struct route_table *table,
                                     union prefixconstptr pu)
 {
        struct route_node rn, *node;
@@ -260,7 +260,7 @@ struct route_node *route_node_lookup(const struct route_table *table,
 }
 
 /* Lookup same prefix node.  Return NULL when we can't find route. */
-struct route_node *route_node_lookup_maynull(const struct route_table *table,
+struct route_node *route_node_lookup_maynull(struct route_table *table,
                                             union prefixconstptr pu)
 {
        struct route_node rn, *node;
@@ -272,7 +272,7 @@ struct route_node *route_node_lookup_maynull(const struct route_table *table,
 }
 
 /* Add node to routing table. */
-struct route_node *route_node_get(struct route_table *const table,
+struct route_node *route_node_get(struct route_table *table,
                                  union prefixconstptr pu)
 {
        struct route_node search;
@@ -471,7 +471,7 @@ struct route_node *route_next_until(struct route_node *node,
        return NULL;
 }
 
-unsigned long route_table_count(const struct route_table *table)
+unsigned long route_table_count(struct route_table *table)
 {
        return table->count;
 }
@@ -606,7 +606,7 @@ static struct route_node *route_get_subtree_next(struct route_node *node)
  * @see route_table_get_next
  */
 static struct route_node *
-route_table_get_next_internal(const struct route_table *table,
+route_table_get_next_internal(struct route_table *table,
                              const struct prefix *p)
 {
        struct route_node *node, *tmp_node;
@@ -707,7 +707,7 @@ route_table_get_next_internal(const struct route_table *table,
  * Find the node that occurs after the given prefix in order of
  * iteration.
  */
-struct route_node *route_table_get_next(const struct route_table *table,
+struct route_node *route_table_get_next(struct route_table *table,
                                        union prefixconstptr pu)
 {
        const struct prefix *p = pu.p;
index 3e3fb658aebe011df1ded9fde4bab856489b1b7c..14be7ab65668216e1dd899696a76ca835c909189 100644 (file)
@@ -198,26 +198,29 @@ static inline void route_table_set_info(struct route_table *table, void *d)
        table->info = d;
 }
 
+/* ext_pure => extern __attribute__((pure))
+ *   does not modify memory (but depends on mem), allows compiler to optimize
+ */
+
 extern void route_table_finish(struct route_table *table);
-extern struct route_node *route_top(struct route_table *table);
-extern struct route_node *route_next(struct route_node *node);
-extern struct route_node *route_next_until(struct route_node *node,
-                                          const struct route_node *limit);
-extern struct route_node *route_node_get(struct route_table *const table,
+ext_pure struct route_node *route_top(struct route_table *table);
+ext_pure struct route_node *route_next(struct route_node *node);
+ext_pure struct route_node *route_next_until(struct route_node *node,
+                                            const struct route_node *limit);
+extern struct route_node *route_node_get(struct route_table *table,
                                         union prefixconstptr pu);
-extern struct route_node *route_node_lookup(const struct route_table *table,
-                                           union prefixconstptr pu);
-extern struct route_node *
-route_node_lookup_maynull(const struct route_table *table,
-                         union prefixconstptr pu);
-extern struct route_node *route_node_match(const struct route_table *table,
-                                          union prefixconstptr pu);
-extern struct route_node *route_node_match_ipv4(const struct route_table *table,
-                                               const struct in_addr *addr);
-extern struct route_node *route_node_match_ipv6(const struct route_table *table,
-                                               const struct in6_addr *addr);
-
-extern unsigned long route_table_count(const struct route_table *table);
+ext_pure struct route_node *route_node_lookup(struct route_table *table,
+                                             union prefixconstptr pu);
+ext_pure struct route_node *route_node_lookup_maynull(struct route_table *table,
+                                                     union prefixconstptr pu);
+ext_pure struct route_node *route_node_match(struct route_table *table,
+                                            union prefixconstptr pu);
+ext_pure struct route_node *route_node_match_ipv4(struct route_table *table,
+                                                 const struct in_addr *addr);
+ext_pure struct route_node *route_node_match_ipv6(struct route_table *table,
+                                                 const struct in6_addr *addr);
+
+ext_pure unsigned long route_table_count(struct route_table *table);
 
 extern struct route_node *route_node_create(route_table_delegate_t *delegate,
                                            struct route_table *table);
@@ -226,10 +229,10 @@ extern void route_node_destroy(route_table_delegate_t *delegate,
                               struct route_table *table,
                               struct route_node *node);
 
-extern struct route_node *route_table_get_next(const struct route_table *table,
-                                              union prefixconstptr pu);
-extern int route_table_prefix_iter_cmp(const struct prefix *p1,
-                                      const struct prefix *p2);
+ext_pure struct route_node *route_table_get_next(struct route_table *table,
+                                                union prefixconstptr pu);
+ext_pure int route_table_prefix_iter_cmp(const struct prefix *p1,
+                                        const struct prefix *p2);
 
 /*
  * Iterator functions.