From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6E82CA2EFC for ; Wed, 18 Sep 2019 15:32:32 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0310C1D127; Wed, 18 Sep 2019 15:32:32 +0200 (CEST) Received: from relay0236.mxlogin.com (relay0236.mxlogin.com [199.181.239.236]) by dpdk.org (Postfix) with ESMTP id 13CDD1C43A for ; Wed, 18 Sep 2019 15:32:31 +0200 (CEST) Received: from filter002.mxroute.com (unknown [116.203.155.46]) by relay0236.mxlogin.com (Postfix) with ESMTP id DA76DCD30324; Wed, 18 Sep 2019 08:32:29 -0500 (CDT) Received: from galaxy.mxroute.com (unknown [23.92.70.113]) by filter002.mxroute.com (Postfix) with ESMTPS id DA09B3F0CF; Wed, 18 Sep 2019 13:32:23 +0000 (UTC) Received: from irdmzpr01-ext.ir.intel.com ([192.198.151.36]) by galaxy.mxroute.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.91) (envelope-from ) id 1iAZvz-0007Ms-Oo; Wed, 18 Sep 2019 09:23:52 -0400 To: Andrzej Ostruszka , dev@dpdk.org, Aaron Conole , Michael Santana , Thomas Monjalon , John McNamara , Marko Kovacevic , David Hunt , Bruce Richardson , Vladimir Medvedkin , Robert Sanford , Erik Gabriel Carrillo Cc: mattias.ronnblom@ericsson.com, stephen@networkplumber.org, Andrzej Ostruszka References: <20190917075754.8310-1-amo@semihalf.com> <20190917075754.8310-2-amo@semihalf.com> From: Ray Kinsella Openpgp: preference=signencrypt Autocrypt: addr=mdr@ashroe.eu; keydata= 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 Message-ID: <8ba7ce2f-e687-3e1c-c7ab-7749764e80d8@ashroe.eu> Date: Wed, 18 Sep 2019 14:32:18 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: <20190917075754.8310-2-amo@semihalf.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-AuthUser: mdr@ashroe.eu Subject: Re: [dpdk-dev] [PATCH v2 01/10] build: add an option to enable LTO build X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" this is cool, good work. comments below. On 17/09/2019 08:57, Andrzej Ostruszka wrote: > This patch adds an option to enable link time optimization. In addition > to LTO option itself (-flto) fat-lto-objects are being used. This is > because during the build pmdinfogen scans the generated ELF objects to > find this_pmd_name* symbol in symbol table. Without fat-lto-objects gcc > produces ELF only with extra symbols for internal use during linking and > clang does not produce ELF at all (only LLVM IR bitcode). > > Signed-off-by: Andrzej Ostruszka > --- > .travis.yml | 7 ++++ > config/common_base | 5 +++ > config/meson.build | 15 ++++++++ > doc/guides/prog_guide/lto.rst | 37 ++++++++++++++++++++ > doc/guides/rel_notes/release_19_11.rst | 8 +++++ > lib/librte_distributor/rte_distributor.c | 18 +++++----- > lib/librte_distributor/rte_distributor_v20.c | 18 +++++----- > lib/librte_lpm/rte_lpm.c | 28 +++++++-------- > lib/librte_lpm/rte_lpm6.c | 16 ++++----- > lib/librte_timer/rte_timer.c | 20 +++++------ > mk/toolchain/clang/rte.toolchain-compat.mk | 4 +++ > mk/toolchain/clang/rte.vars.mk | 8 +++++ > mk/toolchain/gcc/rte.toolchain-compat.mk | 4 +++ > mk/toolchain/gcc/rte.vars.mk | 12 +++++++ > mk/toolchain/icc/rte.vars.mk | 8 +++++ > 15 files changed, 158 insertions(+), 50 deletions(-) > create mode 100644 doc/guides/prog_guide/lto.rst > > diff --git a/.travis.yml b/.travis.yml > index 781f9f666..70d221852 100644 > --- a/.travis.yml > +++ b/.travis.yml > @@ -31,6 +31,7 @@ env: > - DEF_LIB="static" OPTS="-Denable_kmods=false" > - DEF_LIB="shared" OPTS="-Denable_kmods=false" > - DEF_LIB="shared" RUN_TESTS=1 BUILD_DOCS=1 > + - DEF_LIB="shared" OPTS="-Db_lto=true" > > matrix: > include: > @@ -100,6 +101,12 @@ matrix: > apt: > packages: > - *extra_packages > + - env: DEF_LIB="shared" OPTS="-Db_lto=true" EXTRA_PACKAGES=1 > + compiler: gcc > + addons: > + apt: > + packages: > + - *extra_packages > > > script: ./.ci/${TRAVIS_OS_NAME}-build.sh > diff --git a/config/common_base b/config/common_base > index 8ef75c203..73a55fdec 100644 > --- a/config/common_base > +++ b/config/common_base > @@ -49,6 +49,11 @@ CONFIG_RTE_FORCE_INTRINSICS=n > # > CONFIG_RTE_ARCH_STRICT_ALIGN=n > > +# > +# Enable link time optimization > +# > +CONFIG_RTE_ENABLE_LTO=n > + > # > # Compile to share library > # Why would we make this optional in this way and expand the matrix of different ways to build DPDK. To ask another way, why wouldn't a user turn on GSO. > diff --git a/config/meson.build b/config/meson.build > index 2bafea530..97bbc323b 100644 > --- a/config/meson.build > +++ b/config/meson.build > @@ -196,3 +196,18 @@ add_project_arguments('-D_GNU_SOURCE', language: 'c') > if is_freebsd > add_project_arguments('-D__BSD_VISIBLE', language: 'c') > endif > + > +if get_option('b_lto') > + if cc.has_argument('-ffat-lto-objects') > + add_project_arguments('-ffat-lto-objects', language: 'c') > + else > + error('compiler does not support fat LTO objects - please turn LTO off') > + endif > + if cc.get_id() == 'gcc' > + # workaround for bug 81440 > + if cc.version().version_compare('<8.0') > + add_project_arguments('-Wno-lto-type-mismatch', language: 'c') > + add_project_link_arguments('-Wno-lto-type-mismatch', language: 'c') > + endif > + endif > +endif > diff --git a/doc/guides/prog_guide/lto.rst b/doc/guides/prog_guide/lto.rst > new file mode 100644 > index 000000000..b2b36e51c > --- /dev/null > +++ b/doc/guides/prog_guide/lto.rst > @@ -0,0 +1,37 @@ > +Link Time Optimization > +====================== > + > +The DPDK framework supports compilation with link time optimization > +turned on. This depends obviously on the capabilities of the compiler > +to do "whole program" optimization at link time and is available only > +for compilers that support that feature (gcc, clang and icc). To be > +more specific compiler have to support creation of ELF objects > +containing both normal code and internal representation > +(fat-lto-objects). This is required since during build some code is > +generated by parsing produced ELF objects (pmdinfogen). > + > +The amount of performance gain that one can get from LTO depends on the > +compiler and the code that is being compiled. However LTO is also > +useful for additional code analysis done by the compiler. In particular > +due to interprocedural analysis compiler can produce additional warnings > +about variables that might be used uninitialized. Some of these > +warnings might be "false positives" though and you might need to > +explicitly initialize variable in order to silence the compiler. > + > +Link time optimization can be enabled for whole DPDK framework by > +setting: > + > +.. code-block:: console > + CONFIG_ENABLE_LTO=y > + > +in config file for the case of make based build and by: > + > +.. code-block:: console > + meson build -Db_lto=true -Ddefault_library=shared > + ninja -C build > + > +for the case of meson based build (only shared libraries are supported > +when building with meson and LTO enabled). > + > +Please note that turning LTO on causes considerable extension of > +compilation time. > diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst > index 8490d897c..97b4f4083 100644 > --- a/doc/guides/rel_notes/release_19_11.rst > +++ b/doc/guides/rel_notes/release_19_11.rst > @@ -56,6 +56,14 @@ New Features > Also, make sure to start the actual text at the margin. > ========================================================= > > +**Added build support for Link Time Optimization.** > + > + LTO is an optimization technique used by the compiler to perform whole > + program analysis and optimization at link time. In order to do that > + compilers store their internal representation of the source code that > + the linker uses at the final stage of compilation process. > + > + See :doc:`../prog_guide/lto` for more information: > > Removed Items > ------------- > diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c > index 21eb1fb0a..848250f4a 100644 > --- a/lib/librte_distributor/rte_distributor.c > +++ b/lib/librte_distributor/rte_distributor.c > @@ -32,7 +32,7 @@ EAL_REGISTER_TAILQ(rte_dist_burst_tailq) > > /**** Burst Packet APIs called by workers ****/ > > -void > +void __vsym all these additional __vsym annotations looks like they belong in a seperate patch, as they are fixing a bug and are not directly related to adding LTO the build system. > rte_distributor_request_pkt_v1705(struct rte_distributor *d, > unsigned int worker_id, struct rte_mbuf **oldpkt, > unsigned int count) > @@ -84,7 +84,7 @@ MAP_STATIC_SYMBOL(void rte_distributor_request_pkt(struct rte_distributor *d, > unsigned int count), > rte_distributor_request_pkt_v1705); > > -int > +int __vsym > rte_distributor_poll_pkt_v1705(struct rte_distributor *d, > unsigned int worker_id, struct rte_mbuf **pkts) > { > @@ -124,7 +124,7 @@ MAP_STATIC_SYMBOL(int rte_distributor_poll_pkt(struct rte_distributor *d, > unsigned int worker_id, struct rte_mbuf **pkts), > rte_distributor_poll_pkt_v1705); > > -int > +int __vsym > rte_distributor_get_pkt_v1705(struct rte_distributor *d, > unsigned int worker_id, struct rte_mbuf **pkts, > struct rte_mbuf **oldpkt, unsigned int return_count) > @@ -159,7 +159,7 @@ MAP_STATIC_SYMBOL(int rte_distributor_get_pkt(struct rte_distributor *d, > struct rte_mbuf **oldpkt, unsigned int return_count), > rte_distributor_get_pkt_v1705); > > -int > +int __vsym > rte_distributor_return_pkt_v1705(struct rte_distributor *d, > unsigned int worker_id, struct rte_mbuf **oldpkt, int num) > { > @@ -335,7 +335,7 @@ release(struct rte_distributor *d, unsigned int wkr) > > > /* process a set of packets to distribute them to workers */ > -int > +int __vsym > rte_distributor_process_v1705(struct rte_distributor *d, > struct rte_mbuf **mbufs, unsigned int num_mbufs) > { > @@ -476,7 +476,7 @@ MAP_STATIC_SYMBOL(int rte_distributor_process(struct rte_distributor *d, > rte_distributor_process_v1705); > > /* return to the caller, packets returned from workers */ > -int > +int __vsym > rte_distributor_returned_pkts_v1705(struct rte_distributor *d, > struct rte_mbuf **mbufs, unsigned int max_mbufs) > { > @@ -526,7 +526,7 @@ total_outstanding(const struct rte_distributor *d) > * Flush the distributor, so that there are no outstanding packets in flight or > * queued up. > */ > -int > +int __vsym > rte_distributor_flush_v1705(struct rte_distributor *d) > { > unsigned int flushed; > @@ -561,7 +561,7 @@ MAP_STATIC_SYMBOL(int rte_distributor_flush(struct rte_distributor *d), > rte_distributor_flush_v1705); > > /* clears the internal returns array in the distributor */ > -void > +void __vsym > rte_distributor_clear_returns_v1705(struct rte_distributor *d) > { > unsigned int wkr; > @@ -581,7 +581,7 @@ MAP_STATIC_SYMBOL(void rte_distributor_clear_returns(struct rte_distributor *d), > rte_distributor_clear_returns_v1705); > > /* creates a distributor instance */ > -struct rte_distributor * > +struct rte_distributor * __vsym > rte_distributor_create_v1705(const char *name, > unsigned int socket_id, > unsigned int num_workers, > diff --git a/lib/librte_distributor/rte_distributor_v20.c b/lib/librte_distributor/rte_distributor_v20.c > index cdc0969a8..31c766421 100644 > --- a/lib/librte_distributor/rte_distributor_v20.c > +++ b/lib/librte_distributor/rte_distributor_v20.c > @@ -27,7 +27,7 @@ EAL_REGISTER_TAILQ(rte_distributor_tailq) > > /**** APIs called by workers ****/ > > -void > +void __vsym > rte_distributor_request_pkt_v20(struct rte_distributor_v20 *d, > unsigned worker_id, struct rte_mbuf *oldpkt) > { > @@ -40,7 +40,7 @@ rte_distributor_request_pkt_v20(struct rte_distributor_v20 *d, > } > VERSION_SYMBOL(rte_distributor_request_pkt, _v20, 2.0); > > -struct rte_mbuf * > +struct rte_mbuf * __vsym > rte_distributor_poll_pkt_v20(struct rte_distributor_v20 *d, > unsigned worker_id) > { > @@ -54,7 +54,7 @@ rte_distributor_poll_pkt_v20(struct rte_distributor_v20 *d, > } > VERSION_SYMBOL(rte_distributor_poll_pkt, _v20, 2.0); > > -struct rte_mbuf * > +struct rte_mbuf * __vsym > rte_distributor_get_pkt_v20(struct rte_distributor_v20 *d, > unsigned worker_id, struct rte_mbuf *oldpkt) > { > @@ -66,7 +66,7 @@ rte_distributor_get_pkt_v20(struct rte_distributor_v20 *d, > } > VERSION_SYMBOL(rte_distributor_get_pkt, _v20, 2.0); > > -int > +int __vsym > rte_distributor_return_pkt_v20(struct rte_distributor_v20 *d, > unsigned worker_id, struct rte_mbuf *oldpkt) > { > @@ -191,7 +191,7 @@ process_returns(struct rte_distributor_v20 *d) > } > > /* process a set of packets to distribute them to workers */ > -int > +int __vsym > rte_distributor_process_v20(struct rte_distributor_v20 *d, > struct rte_mbuf **mbufs, unsigned num_mbufs) > { > @@ -296,7 +296,7 @@ rte_distributor_process_v20(struct rte_distributor_v20 *d, > VERSION_SYMBOL(rte_distributor_process, _v20, 2.0); > > /* return to the caller, packets returned from workers */ > -int > +int __vsym > rte_distributor_returned_pkts_v20(struct rte_distributor_v20 *d, > struct rte_mbuf **mbufs, unsigned max_mbufs) > { > @@ -334,7 +334,7 @@ total_outstanding(const struct rte_distributor_v20 *d) > > /* flush the distributor, so that there are no outstanding packets in flight or > * queued up. */ > -int > +int __vsym > rte_distributor_flush_v20(struct rte_distributor_v20 *d) > { > const unsigned flushed = total_outstanding(d); > @@ -347,7 +347,7 @@ rte_distributor_flush_v20(struct rte_distributor_v20 *d) > VERSION_SYMBOL(rte_distributor_flush, _v20, 2.0); > > /* clears the internal returns array in the distributor */ > -void > +void __vsym > rte_distributor_clear_returns_v20(struct rte_distributor_v20 *d) > { > d->returns.start = d->returns.count = 0; > @@ -358,7 +358,7 @@ rte_distributor_clear_returns_v20(struct rte_distributor_v20 *d) > VERSION_SYMBOL(rte_distributor_clear_returns, _v20, 2.0); > > /* creates a distributor instance */ > -struct rte_distributor_v20 * > +struct rte_distributor_v20 * __vsym > rte_distributor_create_v20(const char *name, > unsigned socket_id, > unsigned num_workers) > diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c > index 3a929a1b1..a2fba8d61 100644 > --- a/lib/librte_lpm/rte_lpm.c > +++ b/lib/librte_lpm/rte_lpm.c > @@ -89,7 +89,7 @@ depth_to_range(uint8_t depth) > /* > * Find an existing lpm table and return a pointer to it. > */ > -struct rte_lpm_v20 * > +struct rte_lpm_v20 * __vsym > rte_lpm_find_existing_v20(const char *name) > { > struct rte_lpm_v20 *l = NULL; > @@ -115,7 +115,7 @@ rte_lpm_find_existing_v20(const char *name) > } > VERSION_SYMBOL(rte_lpm_find_existing, _v20, 2.0); > > -struct rte_lpm * > +struct rte_lpm * __vsym > rte_lpm_find_existing_v1604(const char *name) > { > struct rte_lpm *l = NULL; > @@ -146,7 +146,7 @@ MAP_STATIC_SYMBOL(struct rte_lpm *rte_lpm_find_existing(const char *name), > /* > * Allocates memory for LPM object > */ > -struct rte_lpm_v20 * > +struct rte_lpm_v20 * __vsym > rte_lpm_create_v20(const char *name, int socket_id, int max_rules, > __rte_unused int flags) > { > @@ -219,7 +219,7 @@ rte_lpm_create_v20(const char *name, int socket_id, int max_rules, > } > VERSION_SYMBOL(rte_lpm_create, _v20, 2.0); > > -struct rte_lpm * > +struct rte_lpm * __vsym > rte_lpm_create_v1604(const char *name, int socket_id, > const struct rte_lpm_config *config) > { > @@ -328,7 +328,7 @@ MAP_STATIC_SYMBOL( > /* > * Deallocates memory for given LPM table. > */ > -void > +void __vsym > rte_lpm_free_v20(struct rte_lpm_v20 *lpm) > { > struct rte_lpm_list *lpm_list; > @@ -357,7 +357,7 @@ rte_lpm_free_v20(struct rte_lpm_v20 *lpm) > } > VERSION_SYMBOL(rte_lpm_free, _v20, 2.0); > > -void > +void __vsym > rte_lpm_free_v1604(struct rte_lpm *lpm) > { > struct rte_lpm_list *lpm_list; > @@ -1176,7 +1176,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth, > /* > * Add a route > */ > -int > +int __vsym > rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth, > uint8_t next_hop) > { > @@ -1217,7 +1217,7 @@ rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth, > } > VERSION_SYMBOL(rte_lpm_add, _v20, 2.0); > > -int > +int __vsym > rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, > uint32_t next_hop) > { > @@ -1263,7 +1263,7 @@ MAP_STATIC_SYMBOL(int rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, > /* > * Look for a rule in the high-level rules table > */ > -int > +int __vsym > rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth, > uint8_t *next_hop) > { > @@ -1290,7 +1290,7 @@ uint8_t *next_hop) > } > VERSION_SYMBOL(rte_lpm_is_rule_present, _v20, 2.0); > > -int > +int __vsym > rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, > uint32_t *next_hop) > { > @@ -1843,7 +1843,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, > /* > * Deletes a rule > */ > -int > +int __vsym > rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth) > { > int32_t rule_to_delete_index, sub_rule_index; > @@ -1897,7 +1897,7 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth) > } > VERSION_SYMBOL(rte_lpm_delete, _v20, 2.0); > > -int > +int __vsym > rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth) > { > int32_t rule_to_delete_index, sub_rule_index; > @@ -1956,7 +1956,7 @@ MAP_STATIC_SYMBOL(int rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, > /* > * Delete all rules from the LPM table. > */ > -void > +void __vsym > rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm) > { > /* Zero rule information. */ > @@ -1973,7 +1973,7 @@ rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm) > } > VERSION_SYMBOL(rte_lpm_delete_all, _v20, 2.0); > > -void > +void __vsym > rte_lpm_delete_all_v1604(struct rte_lpm *lpm) > { > /* Zero rule information. */ > diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c > index 9b8aeb972..49a7fea1d 100644 > --- a/lib/librte_lpm/rte_lpm6.c > +++ b/lib/librte_lpm/rte_lpm6.c > @@ -811,7 +811,7 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl, > /* > * Add a route > */ > -int > +int __vsym > rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, > uint8_t next_hop) > { > @@ -861,7 +861,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth) > return 0; > } > > -int > +int __vsym > rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, > uint32_t next_hop) > { > @@ -954,7 +954,7 @@ lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl, > /* > * Looks up an IP > */ > -int > +int __vsym > rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop) > { > uint32_t next_hop32 = 0; > @@ -972,7 +972,7 @@ rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop) > } > VERSION_SYMBOL(rte_lpm6_lookup, _v20, 2.0); > > -int > +int __vsym > rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip, > uint32_t *next_hop) > { > @@ -1007,7 +1007,7 @@ MAP_STATIC_SYMBOL(int rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, > /* > * Looks up a group of IP addresses > */ > -int > +int __vsym > rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm, > uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], > int16_t * next_hops, unsigned n) > @@ -1048,7 +1048,7 @@ rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm, > } > VERSION_SYMBOL(rte_lpm6_lookup_bulk_func, _v20, 2.0); > > -int > +int __vsym > rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm, > uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], > int32_t *next_hops, unsigned int n) > @@ -1098,7 +1098,7 @@ MAP_STATIC_SYMBOL(int rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm, > /* > * Look for a rule in the high-level rules table > */ > -int > +int __vsym > rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, > uint8_t *next_hop) > { > @@ -1118,7 +1118,7 @@ rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, > } > VERSION_SYMBOL(rte_lpm6_is_rule_present, _v20, 2.0); > > -int > +int __vsym > rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, > uint32_t *next_hop) > { > diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c > index bdcf05d06..e560ace06 100644 > --- a/lib/librte_timer/rte_timer.c > +++ b/lib/librte_timer/rte_timer.c > @@ -131,7 +131,7 @@ rte_timer_data_dealloc(uint32_t id) > return 0; > } > > -void > +void __vsym > rte_timer_subsystem_init_v20(void) > { > unsigned lcore_id; > @@ -153,7 +153,7 @@ VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0); > * secondary processes should be empty, the zeroth entry can be shared by > * multiple processes. > */ > -int > +int __vsym > rte_timer_subsystem_init_v1905(void) > { > const struct rte_memzone *mz; > @@ -551,7 +551,7 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t expire, > } > > /* Reset and start the timer associated with the timer handle tim */ > -int > +int __vsym > rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks, > enum rte_timer_type type, unsigned int tim_lcore, > rte_timer_cb_t fct, void *arg) > @@ -574,7 +574,7 @@ rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks, > } > VERSION_SYMBOL(rte_timer_reset, _v20, 2.0); > > -int > +int __vsym > rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks, > enum rte_timer_type type, unsigned int tim_lcore, > rte_timer_cb_t fct, void *arg) > @@ -657,14 +657,14 @@ __rte_timer_stop(struct rte_timer *tim, int local_is_locked, > } > > /* Stop the timer associated with the timer handle tim */ > -int > +int __vsym > rte_timer_stop_v20(struct rte_timer *tim) > { > return __rte_timer_stop(tim, 0, &default_timer_data); > } > VERSION_SYMBOL(rte_timer_stop, _v20, 2.0); > > -int > +int __vsym > rte_timer_stop_v1905(struct rte_timer *tim) > { > return rte_timer_alt_stop(default_data_id, tim); > @@ -817,14 +817,14 @@ __rte_timer_manage(struct rte_timer_data *timer_data) > priv_timer[lcore_id].running_tim = NULL; > } > > -void > +void __vsym > rte_timer_manage_v20(void) > { > __rte_timer_manage(&default_timer_data); > } > VERSION_SYMBOL(rte_timer_manage, _v20, 2.0); > > -int > +int __vsym > rte_timer_manage_v1905(void) > { > struct rte_timer_data *timer_data; > @@ -1074,14 +1074,14 @@ __rte_timer_dump_stats(struct rte_timer_data *timer_data __rte_unused, FILE *f) > #endif > } > > -void > +void __vsym > rte_timer_dump_stats_v20(FILE *f) > { > __rte_timer_dump_stats(&default_timer_data, f); > } > VERSION_SYMBOL(rte_timer_dump_stats, _v20, 2.0); > > -int > +int __vsym > rte_timer_dump_stats_v1905(FILE *f) > { > return rte_timer_alt_dump_stats(default_data_id, f); > diff --git a/mk/toolchain/clang/rte.toolchain-compat.mk b/mk/toolchain/clang/rte.toolchain-compat.mk > index e6189b498..78f96c648 100644 > --- a/mk/toolchain/clang/rte.toolchain-compat.mk > +++ b/mk/toolchain/clang/rte.toolchain-compat.mk > @@ -20,3 +20,7 @@ CLANG_MINOR_VERSION := $(shell echo $(CLANG_VERSION) | cut -f2 -d.) > ifeq ($(shell test $(CLANG_MAJOR_VERSION)$(CLANG_MINOR_VERSION) -lt 35 && echo 1), 1) > CC_SUPPORTS_Z := false > endif > + > +ifeq ($(shell test $(CLANG_MAJOR_VERSION)$(CLANG_MINOR_VERSION) -lt 60 && echo 1), 1) > + CONFIG_RTE_ENABLE_LTO=n > +endif > diff --git a/mk/toolchain/clang/rte.vars.mk b/mk/toolchain/clang/rte.vars.mk > index 3c49dc568..3b1fa05f9 100644 > --- a/mk/toolchain/clang/rte.vars.mk > +++ b/mk/toolchain/clang/rte.vars.mk > @@ -48,6 +48,14 @@ endif > # process cpu flags > include $(RTE_SDK)/mk/toolchain/$(RTE_TOOLCHAIN)/rte.toolchain-compat.mk > > +ifeq ($(CONFIG_RTE_ENABLE_LTO),y) > +# 'fat-lto' is used since pmdinfogen needs to have 'this_pmd_nameX' > +# exported in symbol table and without this option only internal > +# representation is present. > +TOOLCHAIN_CFLAGS += -flto -ffat-lto-objects > +TOOLCHAIN_LDFLAGS += -flto > +endif > + > # workaround clang bug with warning "missing field initializer" for "= {0}" > WERROR_FLAGS += -Wno-missing-field-initializers > > diff --git a/mk/toolchain/gcc/rte.toolchain-compat.mk b/mk/toolchain/gcc/rte.toolchain-compat.mk > index ea40a11c0..ad4fad83c 100644 > --- a/mk/toolchain/gcc/rte.toolchain-compat.mk > +++ b/mk/toolchain/gcc/rte.toolchain-compat.mk > @@ -88,6 +88,10 @@ else > MACHINE_CFLAGS := $(filter-out -march% -mtune% -msse%,$(MACHINE_CFLAGS)) > endif > > + ifeq ($(shell test $(GCC_VERSION) -lt 45 && echo 1), 1) > + CONFIG_RTE_ENABLE_LTO=n > + endif > + > # Disable thunderx PMD for gcc < 4.7 > ifeq ($(shell test $(GCC_VERSION) -lt 47 && echo 1), 1) > CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD=d > diff --git a/mk/toolchain/gcc/rte.vars.mk b/mk/toolchain/gcc/rte.vars.mk > index b852fcfd7..9fc704193 100644 > --- a/mk/toolchain/gcc/rte.vars.mk > +++ b/mk/toolchain/gcc/rte.vars.mk > @@ -62,6 +62,18 @@ endif > # process cpu flags > include $(RTE_SDK)/mk/toolchain/$(RTE_TOOLCHAIN)/rte.toolchain-compat.mk > > +ifeq ($(CONFIG_RTE_ENABLE_LTO),y) > +# 'fat-lto' is used since pmdinfogen needs to have 'this_pmd_nameX' > +# exported in symbol table and without this option only internal > +# representation is present. > +TOOLCHAIN_CFLAGS += -flto -ffat-lto-objects > +TOOLCHAIN_LDFLAGS += -flto > +# workaround for GCC bug 81440 > +ifeq ($(shell test $(GCC_VERSION) -lt 80 && echo 1), 1) > +WERROR_FLAGS += -Wno-lto-type-mismatch > +endif > +endif > + > # workaround GCC bug with warning "missing initializer" for "= {0}" > ifeq ($(shell test $(GCC_VERSION) -lt 47 && echo 1), 1) > WERROR_FLAGS += -Wno-missing-field-initializers > diff --git a/mk/toolchain/icc/rte.vars.mk b/mk/toolchain/icc/rte.vars.mk > index aa1422bf1..8aa87aa1e 100644 > --- a/mk/toolchain/icc/rte.vars.mk > +++ b/mk/toolchain/icc/rte.vars.mk > @@ -54,5 +54,13 @@ endif > # process cpu flags > include $(RTE_SDK)/mk/toolchain/$(RTE_TOOLCHAIN)/rte.toolchain-compat.mk > > +ifeq ($(CONFIG_RTE_ENABLE_LTO),y) > +# 'fat-lto' is used since pmdinfogen needs to have 'this_pmd_nameX' > +# exported in symbol table and without this option only internal > +# representation is present. > +TOOLCHAIN_CFLAGS += -flto -ffat-lto-objects > +TOOLCHAIN_LDFLAGS += -flto > +endif > + > export CC AS AR LD OBJCOPY OBJDUMP STRIP READELF > export TOOLCHAIN_CFLAGS TOOLCHAIN_LDFLAGS TOOLCHAIN_ASFLAGS >