From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 122699 invoked by alias); 28 Nov 2018 21:09:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 122684 invoked by uid 89); 28 Nov 2018 21:09:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 spammy=function's, HX-Envelope-From:sk:michael, 747, formal X-HELO: aserp2120.oracle.com Received: from aserp2120.oracle.com (HELO aserp2120.oracle.com) (141.146.126.78) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 28 Nov 2018 21:09:26 +0000 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id wASL4Cwd053033; Wed, 28 Nov 2018 21:09:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : references : message-id : date : mime-version : in-reply-to : content-type; s=corp-2018-07-02; bh=M9PVDf5nxLnP/o1wtMcQwlL4ggwAYDQSDN2+lWIrEEc=; b=eB24l61uzzKxDbfFbpv5eGyYM9dURDNs7FidTZ9B+5oubo1bc0eLoFtxvZxfqg6dNxqp eIdPOtXdN2ynTh/6yum+Pvi6g1f+VZIi2FLMJC5bPLjA1GpIatMsMAiOHu/0xmQKdMlN eUWbXpkcI8m9VcKjIMCoDXfwh0kc6XW9LI+4IaxSIX+NNa5+EluQpBsq+zW53AKkEq31 6gGI0haifGirbZ0FNZLumhT7GQVnOsSNbby1m2XCrfzKnlsBxNQcNAWu9y69awdD4e0K ihXXCibCwBWGabOHt3Ak0PMvtK5D7hDcrTRP4US1nPhl68bMiE7FK2K8M121ZdVawZxa Dw== Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp2120.oracle.com with ESMTP id 2nxxkqmp2v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 28 Nov 2018 21:09:24 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id wASL9Ia6025377 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 28 Nov 2018 21:09:19 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id wASL9G0H021820; Wed, 28 Nov 2018 21:09:17 GMT Received: from [10.39.195.92] (/10.39.195.92) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 28 Nov 2018 13:09:16 -0800 Subject: [PATCH v3] Make function clone name numbering independent. From: Michael Ploujnikov To: Martin Jambor , Richard Biener Cc: GCC Patches , Jan Hubicka , segher@kernel.crashing.org References: <6A1E6E88-63F7-43E4-8A53-78C7694D34BE@gmail.com> <069cb2a6-2e37-58fb-2009-35e0300270f1@oracle.com> <618e046e-3f28-f008-237d-497bcff2531e@oracle.com> <121c01f4-c1a2-249e-2cac-c6d5ec250fcb@oracle.com> <702ab3f1-fe25-9013-7a1e-f5e1615c9396@oracle.com> <85bd8119-0bce-a06d-df3f-1a1a6ed88187@oracle.com> <3167e521-aa5b-e47c-6d9b-956a1af2a886@oracle.com> <078bf036-f02b-3bdb-545d-3f5ad67bc786@oracle.com> <3f9e8c2a-6112-b595-a932-137958e61f5e@oracle.com> Openpgp: preference=signencrypt Message-ID: Date: Wed, 28 Nov 2018 21:09:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <3f9e8c2a-6112-b595-a932-137958e61f5e@oracle.com> Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="BQWVSbjIK8xUscYBUJ9IkJcAT7a7ul4Pm" X-IsSubscribed: yes X-SW-Source: 2018-11/txt/msg02363.txt.bz2 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --BQWVSbjIK8xUscYBUJ9IkJcAT7a7ul4Pm Content-Type: multipart/mixed; boundary="fNkfdsemm3Uyyil40L7PoE6pGUJdmC8bO"; protected-headers="v1" From: Michael Ploujnikov To: Martin Jambor , Richard Biener Cc: GCC Patches , Jan Hubicka , segher@kernel.crashing.org Message-ID: Subject: [PATCH v3] Make function clone name numbering independent. References: <6A1E6E88-63F7-43E4-8A53-78C7694D34BE@gmail.com> <069cb2a6-2e37-58fb-2009-35e0300270f1@oracle.com> <618e046e-3f28-f008-237d-497bcff2531e@oracle.com> <121c01f4-c1a2-249e-2cac-c6d5ec250fcb@oracle.com> <702ab3f1-fe25-9013-7a1e-f5e1615c9396@oracle.com> <85bd8119-0bce-a06d-df3f-1a1a6ed88187@oracle.com> <3167e521-aa5b-e47c-6d9b-956a1af2a886@oracle.com> <078bf036-f02b-3bdb-545d-3f5ad67bc786@oracle.com> <3f9e8c2a-6112-b595-a932-137958e61f5e@oracle.com> In-Reply-To: <3f9e8c2a-6112-b595-a932-137958e61f5e@oracle.com> --fNkfdsemm3Uyyil40L7PoE6pGUJdmC8bO Content-Type: multipart/mixed; boundary="------------B5770DC0E6900C80244F7F3B" Content-Language: en-US This is a multi-part message in MIME format. --------------B5770DC0E6900C80244F7F3B Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Content-length: 1212 Continuing from https://gcc.gnu.org/ml/gcc-patches/2018-09/msg00228.html It took longer than expected, but I've finally rebased this on top of the new clone_function_name* API and included the requested optimizations. There are a few remaining spots where we could probably apply similar optimizations: - gcc/multiple_target.c:create_target_clone - gcc/multiple_target.c:create_dispatcher_calls - gcc/omp-expand.c:grid_expand_target_grid_body But I've yet to figure out how these work in detail and with the new API these shouldn't block the main change from being merged. I've also included a small change to rs6000 which I'm pretty sure is safe, but I have no way of testing. I'm not sure what's the consensus on what's more appropriate, but I thought that it would be a good idea to keep these changes as separate patches since only the first one really changes behaviour, while the rest are optimizations. It's conceivable that someone who is backporting this to an older release might want to just backport the core bits of the change. I can re-submit it as one patch if that's more appropriate. Everything in these patches was bootstrapped and regression tested on x86_64. Ok for trunk? - Michael --------------B5770DC0E6900C80244F7F3B Content-Type: text/x-patch; name="0001-Make-function-assembly-more-independent.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Make-function-assembly-more-independent.patch" Content-length: 3563 =46rom 40cb5c888522d69bc42791f0c884dcb9e29eff37 Mon Sep 17 00:00:00 2001 From: Michael Ploujnikov Date: Thu, 1 Nov 2018 12:57:30 -0400 Subject: [PATCH 1/4] Make function assembly more independent. This is achieved by having clone_function_name assign unique clone numbers for each function independently. gcc: 2018-11-28 Michael Ploujnikov * cgraphclones.c: Replaced clone_fn_id_num with clone_fn_ids; hash map. (clone_function_name_numbered): Use clone_fn_ids. gcc/testsuite: 2018-11-28 Michael Ploujnikov * gcc.dg/independent-cloneids-1.c: New test. --- gcc/cgraphclones.c | 10 ++++- gcc/testsuite/gcc.dg/independent-cloneids-1.c | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/independent-cloneids-1.c diff --git gcc/cgraphclones.c gcc/cgraphclones.c index e17959c0ca..fdd84b60d3 100644 --- gcc/cgraphclones.c +++ gcc/cgraphclones.c @@ -513,7 +513,7 @@ cgraph_node::create_clone (tree new_decl, profile_count= prof_count, return new_node; } =20 -static GTY(()) unsigned int clone_fn_id_num; +static GTY(()) hash_map *clone_fn_ids; =20 /* Return a new assembler name for a clone of decl named NAME. Apart from the string SUFFIX, the new name will end with a unique (for @@ -525,7 +525,13 @@ static GTY(()) unsigned int clone_fn_id_num; tree clone_function_name_numbered (const char *name, const char *suffix) { - return clone_function_name (name, suffix, clone_fn_id_num++); + /* Initialize the function->counter mapping the first time it's + needed. */ + if (!clone_fn_ids) + clone_fn_ids =3D hash_map::create_ggc (64); + unsigned int &suffix_counter =3D clone_fn_ids->get_or_insert ( + IDENTIFIER_POINTER (get_identifier (name))); + return clone_function_name (name, suffix, suffix_counter++); } =20 /* Return a new assembler name for a clone of DECL. Apart from string diff --git gcc/testsuite/gcc.dg/independent-cloneids-1.c gcc/testsuite/gcc.= dg/independent-cloneids-1.c new file mode 100644 index 0000000000..3203895492 --- /dev/null +++ gcc/testsuite/gcc.dg/independent-cloneids-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fipa-cp -fipa-cp-clone" } */ + +extern int printf (const char *, ...); + +static int __attribute__ ((noinline)) +foo (int arg) +{ + return 7 * arg; +} + +static int __attribute__ ((noinline)) +bar (int arg) +{ + return arg * arg; +} + +int +baz (int arg) +{ + printf("%d\n", bar (3)); + printf("%d\n", bar (4)); + printf("%d\n", foo (5)); + printf("%d\n", foo (6)); + /* adding or removing the following call should not affect foo + function's clone numbering */ + printf("%d\n", bar (7)); + return foo (8); +} + +/* { dg-final { scan-assembler-times {(?n)\m_*bar[.$_]constprop[.$_]0:} 1 = } } */ +/* { dg-final { scan-assembler-times {(?n)\m_*bar[.$_]constprop[.$_]1:} 1 = } } */ +/* { dg-final { scan-assembler-times {(?n)\m_*bar[.$_]constprop[.$_]2:} 1 = } } */ +/* { dg-final { scan-assembler-times {(?n)\m_*foo[.$_]constprop[.$_]0:} 1 = } } */ +/* { dg-final { scan-assembler-times {(?n)\m_*foo[.$_]constprop[.$_]1:} 1 = } } */ +/* { dg-final { scan-assembler-times {(?n)\m_*foo[.$_]constprop[.$_]2:} 1 = } } */ +/* { dg-final { scan-assembler-not {(?n)\m_*foo[.$_]constprop[.$_]3:} } } = */ +/* { dg-final { scan-assembler-not {(?n)\m_*foo[.$_]constprop[.$_]4:} } } = */ --=20 2.19.1 --------------B5770DC0E6900C80244F7F3B Content-Type: text/x-patch; name="0002-Minimize-clone-counter-memory-usage-in-create_virtua.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename*0="0002-Minimize-clone-counter-memory-usage-in-create_virtua.pa"; filename*1="tch" Content-length: 6513 =46rom 80b07ddf059415c896cecb9862517899db3993e9 Mon Sep 17 00:00:00 2001 From: Michael Ploujnikov Date: Mon, 17 Sep 2018 16:02:27 -0400 Subject: [PATCH 2/4] Minimize clone counter memory usage in create_virtual_clone. Based on Martin Jambour's suggestion: https://gcc.gnu.org/ml/gcc-patches/2018-09/msg00111.html gcc: 2018-11-28 Michael Ploujnikov * cgraph.h (cgraph_node::create_virtual_clone): Add a new argument: num_suffix. * cgraphclones.c (cgraph_node::create_virtual_clone): Pass num_suffix to clone_function_name. * ipa-cp.c (create_specialized_node): Keep track of clone counters in clone_num_suffixes hash map. (ipcp_driver): Free the counter hash map. * ipa-hsa.c (process_hsa_functions): Keep track of clone counters in hsa_clone_numbers hash map. --- gcc/cgraph.h | 8 +++++--- gcc/cgraphclones.c | 16 +++++++++++----- gcc/ipa-cp.c | 10 +++++++++- gcc/ipa-hsa.c | 9 +++++++-- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git gcc/cgraph.h gcc/cgraph.h index c13d79850f..4c0fb4da05 100644 --- gcc/cgraph.h +++ gcc/cgraph.h @@ -968,11 +968,13 @@ public: cgraph_node *new_inlined_to, bitmap args_to_skip, const char *suffix =3D NULL); =20 - /* Create callgraph node clone with new declaration. The actual body wi= ll - be copied later at compilation stage. */ + /* Create callgraph node clone with new declaration. The actual body wi= ll be + copied later at compilation stage. The name of the new clone will be + constructed from the name of the original node, SUFFIX and NUM_SUFFIX= . */ cgraph_node *create_virtual_clone (vec redirect_callers, vec *tree_map, - bitmap args_to_skip, const char * suffix); + bitmap args_to_skip, const char * suffix, + unsigned num_suffix); =20 /* cgraph node being removed from symbol table; see if its entry can be replaced by other inline clone. */ diff --git gcc/cgraphclones.c gcc/cgraphclones.c index fdd84b60d3..51bdd7680e 100644 --- gcc/cgraphclones.c +++ gcc/cgraphclones.c @@ -595,8 +595,9 @@ clone_function_name (tree decl, const char *suffix) } =20 =20 -/* Create callgraph node clone with new declaration. The actual body will - be copied later at compilation stage. +/* Create callgraph node clone with new declaration. The actual body will= be + copied later at compilation stage. The name of the new clone will be + constructed from the name of the original node, SUFFIX and NUM_SUFFIX. =20 TODO: after merging in ipa-sra use function call notes instead of args_= to_skip bitmap interface. @@ -604,7 +605,8 @@ clone_function_name (tree decl, const char *suffix) cgraph_node * cgraph_node::create_virtual_clone (vec redirect_callers, vec *tree_map, - bitmap args_to_skip, const char * suffix) + bitmap args_to_skip, const char * suffix, + unsigned num_suffix) { tree old_decl =3D decl; cgraph_node *new_node =3D NULL; @@ -639,8 +641,12 @@ cgraph_node::create_virtual_clone (vec = redirect_callers, strcpy (name + len + 1, suffix); name[len] =3D '.'; DECL_NAME (new_decl) =3D get_identifier (name); - SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name_numbered (old_dec= l, - suffix)); + SET_DECL_ASSEMBLER_NAME (new_decl, + clone_function_name ( + IDENTIFIER_POINTER ( + DECL_ASSEMBLER_NAME (old_decl)), + suffix, + num_suffix)); SET_DECL_RTL (new_decl, NULL); =20 new_node =3D create_clone (new_decl, count, false, diff --git gcc/ipa-cp.c gcc/ipa-cp.c index 4471bae11c..e0cd1bc45b 100644 --- gcc/ipa-cp.c +++ gcc/ipa-cp.c @@ -376,6 +376,9 @@ static profile_count max_count; =20 static long overall_size, max_new_size; =20 +/* Node to unique clone suffix number map. */ +static hash_map *clone_num_suffixes; + /* Return the param lattices structure corresponding to the Ith formal parameter of the function described by INFO. */ static inline struct ipcp_param_lattices * @@ -3828,8 +3831,11 @@ create_specialized_node (struct cgraph_node *node, } } =20 + unsigned &suffix_counter =3D clone_num_suffixes->get_or_insert (node); new_node =3D node->create_virtual_clone (callers, replace_trees, - args_to_skip, "constprop"); + args_to_skip, "constprop", + suffix_counter); + suffix_counter++; =20 bool have_self_recursive_calls =3D !self_recursive_calls.is_empty (); for (unsigned j =3D 0; j < self_recursive_calls.length (); j++) @@ -5043,6 +5049,7 @@ ipcp_driver (void) =20 ipa_check_create_node_params (); ipa_check_create_edge_args (); + clone_num_suffixes =3D new hash_map; =20 if (dump_file) { @@ -5064,6 +5071,7 @@ ipcp_driver (void) ipcp_store_vr_results (); =20 /* Free all IPCP structures. */ + delete clone_num_suffixes; free_toporder_info (&topo); delete edge_clone_summaries; edge_clone_summaries =3D NULL; diff --git gcc/ipa-hsa.c gcc/ipa-hsa.c index 7c6ceaab8f..b5dc3dfef2 100644 --- gcc/ipa-hsa.c +++ gcc/ipa-hsa.c @@ -74,6 +74,7 @@ process_hsa_functions (void) if (hsa_summaries =3D=3D NULL) hsa_summaries =3D new hsa_summary_t (symtab); =20 + hash_map hsa_clone_numbers; FOR_EACH_DEFINED_FUNCTION (node) { hsa_function_summary *s =3D hsa_summaries->get (node); @@ -86,9 +87,11 @@ process_hsa_functions (void) { if (!check_warn_node_versionable (node)) continue; + unsigned &clone_number =3D hsa_clone_numbers.get_or_insert (node); cgraph_node *clone =3D node->create_virtual_clone (vec (), - NULL, NULL, "hsa"); + NULL, NULL, "hsa", clone_number); + clone_number++; TREE_PUBLIC (clone->decl) =3D TREE_PUBLIC (node->decl); clone->externally_visible =3D node->externally_visible; =20 @@ -107,9 +110,11 @@ process_hsa_functions (void) { if (!check_warn_node_versionable (node)) continue; + unsigned &clone_number =3D hsa_clone_numbers.get_or_insert (node); cgraph_node *clone =3D node->create_virtual_clone (vec (), - NULL, NULL, "hsa"); + NULL, NULL, "hsa", clone_number); + clone_number++; TREE_PUBLIC (clone->decl) =3D TREE_PUBLIC (node->decl); clone->externally_visible =3D node->externally_visible; =20 --=20 2.19.1 --------------B5770DC0E6900C80244F7F3B Content-Type: text/x-patch; name="0003-Minimize-clone-counter-memory-usage-in-LTO.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0003-Minimize-clone-counter-memory-usage-in-LTO.patch" Content-length: 2560 =46rom 5bb67981114c08fbaf78e5cc0f3f8abaa0aee60b Mon Sep 17 00:00:00 2001 From: Michael Ploujnikov Date: Mon, 26 Nov 2018 14:22:39 -0500 Subject: [PATCH 3/4] Minimize clone counter memory usage in LTO. gcc/lto: 2018-11-28 Michael Ploujnikov * lto-partition.c (privatize_symbol_name_1): Keep track of non-unique symbol counters in the lto_clone_numbers hash map. (lto_promote_cross_file_statics): Allocate and free the lto_clone_numbers hash map. (lto_promote_statics_nonwpa): Free the lto_clone_numbers hash map. --- gcc/lto/lto-partition.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git gcc/lto/lto-partition.c gcc/lto/lto-partition.c index 24e7c23859..3afdcd6f5d 100644 --- gcc/lto/lto-partition.c +++ gcc/lto/lto-partition.c @@ -951,6 +951,9 @@ validize_symbol_for_target (symtab_node *node) } } =20 +/* Maps symbol names to unique lto clone counters. */ +static hash_map *lto_clone_numbers; + /* Helper for privatize_symbol_name. Mangle NODE symbol name represented by DECL. */ =20 @@ -962,10 +965,13 @@ privatize_symbol_name_1 (symtab_node *node, tree decl) if (must_not_rename (node, name)) return false; =20 + unsigned &clone_number =3D lto_clone_numbers->get_or_insert ( + IDENTIFIER_POINTER (DECL_NAME (decl))); name =3D maybe_rewrite_identifier (name); symtab->change_decl_assembler_name (decl, - clone_function_name_numbered ( - name, "lto_priv")); + clone_function_name ( + name, "lto_priv", clone_number)); + clone_number++; =20 if (node->lto_file_data) lto_record_renamed_decl (node->lto_file_data, name, @@ -1157,6 +1163,8 @@ lto_promote_cross_file_statics (void) part->encoder =3D compute_ltrans_boundary (part->encoder); } =20 + lto_clone_numbers =3D new hash_map; + /* Look at boundaries and promote symbols as needed. */ for (i =3D 0; i < n_sets; i++) { @@ -1187,6 +1195,7 @@ lto_promote_cross_file_statics (void) promote_symbol (node); } } + delete lto_clone_numbers; } =20 /* Rename statics in the whole unit in the case that=20 @@ -1196,9 +1205,12 @@ void lto_promote_statics_nonwpa (void) { symtab_node *node; + + lto_clone_numbers =3D new hash_map; FOR_EACH_SYMBOL (node) { rename_statics (NULL, node); validize_symbol_for_target (node); } + delete lto_clone_numbers; } --=20 2.19.1 --------------B5770DC0E6900C80244F7F3B Content-Type: text/x-patch; name="0004-There-can-be-at-most-one-.resolver-clone-per-functio.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename*0="0004-There-can-be-at-most-one-.resolver-clone-per-functio.pa"; filename*1="tch" Content-length: 1226 =46rom a822759e422f0cea11640ec3d6d6fba94bcd4ee9 Mon Sep 17 00:00:00 2001 From: Michael Ploujnikov Date: Wed, 28 Nov 2018 09:24:30 -0500 Subject: [PATCH 4/4] There can be at most one .resolver clone per function gcc: 2018-11-28 Michael Ploujnikov * config/rs6000/rs6000.c (make_resolver_func): Generate resolver symbol with clone_function_name instead of clone_function_name_numbered. --- gcc/config/rs6000/rs6000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git gcc/config/rs6000/rs6000.c gcc/config/rs6000/rs6000.c index 4f113cb025..a9d038829b 100644 --- gcc/config/rs6000/rs6000.c +++ gcc/config/rs6000/rs6000.c @@ -36997,7 +36997,7 @@ make_resolver_func (const tree default_decl, { /* Make the resolver function static. The resolver function returns void *. */ - tree decl_name =3D clone_function_name_numbered (default_decl, "resolver= "); + tree decl_name =3D clone_function_name (default_decl, "resolver"); const char *resolver_name =3D IDENTIFIER_POINTER (decl_name); tree type =3D build_function_type_list (ptr_type_node, NULL_TREE); tree decl =3D build_fn_decl (resolver_name, type); --=20 2.19.1 --------------B5770DC0E6900C80244F7F3B-- --fNkfdsemm3Uyyil40L7PoE6pGUJdmC8bO-- --BQWVSbjIK8xUscYBUJ9IkJcAT7a7ul4Pm Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" Content-length: 488 -----BEGIN PGP SIGNATURE----- iQEzBAEBCgAdFiEEIng1n4wZuilDJBeQGcevDr8Z+6QFAlv/A/oACgkQGcevDr8Z +6TuWwf9GsUAvNIQgx1K2YgpmienFcs6hRtwV9aJNsII3tHiYk7dmr7OD2u/712j spWHLiVojgCM+iWEGbDIkaB0LrBGaDevyVRsWpmReZPIV5TfiAK+mmbQtZ3nIDxe a2bWoUlLs1RZyaiq8eYOrjCFocVnNXzj308WLafjPwcmZgHUBUnYgbhk1GxnrAVu 5SJMl82Jeub8IrJupD3E6RR6LfggHXnRERKkNMHKVi0T/1PR/MZbvx2GZwjJ79/C dm68yfUq94Kc3HY7EjGemDEgTzz8K+2+BsTK2cWhBoUu48WCOdbbrMj521s+4jhX KePgjPxGWy5LbgML/fJ6kpdtrNpIXA== =rvRy -----END PGP SIGNATURE----- --BQWVSbjIK8xUscYBUJ9IkJcAT7a7ul4Pm--