* [PATCH, CHKP] Fix static const bounds creation in LTO
@ 2015-04-02 15:22 Ilya Enkovich
2015-04-02 20:45 ` Jan Hubicka
0 siblings, 1 reply; 7+ messages in thread
From: Ilya Enkovich @ 2015-04-02 15:22 UTC (permalink / raw)
To: gcc-patches
Hi,
Current in LTO static const bounds are created as external symbol. It doesn't work in case original symbols were removed and privatized. This patch introduces a separate comdat symbol to be used in LTO. Bootstrapped and tested on x86_64-unknown-linux-gnu. Does this approach look OK?
Thanks,
Ilya
--
gcc/
2015-04-02 Ilya Enkovich <ilya.enkovich@intel.com>
* tree-chkp.c (CHKP_LTO_SYMBOL_SUFFIX): New.
(chkp_make_static_const_bounds): Use another
symbol in LTO.
gcc/testsuite/
2015-04-02 Ilya Enkovich <ilya.enkovich@intel.com>
* gcc.dg/lto/chkp-static-bounds_0.c: New.
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
new file mode 100644
index 0000000..e896eb1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
@@ -0,0 +1,26 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -flto -flto-partition=max -fcheck-pointer-bounds -mmpx } } } */
+
+char *cc;
+
+int test1 (const char *c)
+{
+ c = __builtin___bnd_init_ptr_bounds (c);
+ cc = c;
+ return c[0] * 2;
+}
+
+struct S
+{
+ int (*fnptr) (const char *);
+} S;
+
+struct S s1 = {test1};
+struct S s2 = {test1};
+struct S s3 = {test1};
+
+int main (int argc, const char **argv)
+{
+ return s1.fnptr (argv[0]) + s2.fnptr (argv[1]);
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index d2df4ba..0578936 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -421,6 +421,7 @@ static bool in_chkp_pass;
#define CHKP_VAR_BOUNDS_PREFIX "__chkp_var_bounds_"
#define CHKP_ZERO_BOUNDS_VAR_NAME "__chkp_zero_bounds"
#define CHKP_NONE_BOUNDS_VAR_NAME "__chkp_none_bounds"
+#define CHKP_LTO_SYMBOL_SUFFIX ".lto"
/* Static checker constructors may become very large and their
compilation with optimization may take too much time.
@@ -1906,7 +1907,8 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
HOST_WIDE_INT ub,
const char *name)
{
- tree var;
+ tree var, id;
+ varpool_node *node;
/* With LTO we may have constant bounds already in varpool.
Try to find it. */
@@ -1915,8 +1917,22 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
if (var)
return var;
- var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier (name), pointer_bounds_type_node);
+ /* In LTO we may have symbol with changed visibility, comdat
+ group etc. Therefore we shouldn't recreate the same symbol.
+ Use LTO version instead. */
+ if (in_lto_p)
+ {
+ int len = strlen (name) + strlen (CHKP_LTO_SYMBOL_SUFFIX) + 1;
+ char *new_name = XALLOCAVEC (char, len);
+ strcpy (new_name, name);
+ strcat (new_name, CHKP_LTO_SYMBOL_SUFFIX);
+ id = get_identifier (new_name);
+ }
+ else
+ id = get_identifier (name);
+
+ var = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+ pointer_bounds_type_node);
TREE_PUBLIC (var) = 1;
TREE_USED (var) = 1;
@@ -1925,18 +1941,17 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
TREE_ADDRESSABLE (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_READ_P (var) = 1;
+ DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
+ DECL_COMDAT (var) = 1;
+ DECL_WEAK (var) = 1;
/* We may use this symbol during ctors generation in chkp_finish_file
when all symbols are emitted. Force output to avoid undefined
symbols in ctors. */
- if (!in_lto_p)
- {
- DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
- DECL_COMDAT (var) = 1;
- varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
- varpool_node::get_create (var)->force_output = 1;
- }
- else
- DECL_EXTERNAL (var) = 1;
+ node = varpool_node::get_create (var);
+ node->set_comdat_group (DECL_ASSEMBLER_NAME (var));
+ node->force_output = 1;
+ node->externally_visible = 1;
+
varpool_node::finalize_decl (var);
return var;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH, CHKP] Fix static const bounds creation in LTO
2015-04-02 15:22 [PATCH, CHKP] Fix static const bounds creation in LTO Ilya Enkovich
@ 2015-04-02 20:45 ` Jan Hubicka
2015-04-03 16:11 ` Ilya Enkovich
0 siblings, 1 reply; 7+ messages in thread
From: Jan Hubicka @ 2015-04-02 20:45 UTC (permalink / raw)
To: Ilya Enkovich; +Cc: gcc-patches
> Hi,
>
> Current in LTO static const bounds are created as external symbol. It doesn't work in case original symbols were removed and privatized. This patch introduces a separate comdat symbol to be used in LTO. Bootstrapped and tested on x86_64-unknown-linux-gnu. Does this approach look OK?
As I understand it, you want to create a static variables, like __chkp_zero_bounds
which should be shared across translation units. Currently the function does:
static tree
chkp_make_static_const_bounds (HOST_WIDE_INT lb,
HOST_WIDE_INT ub,
const char *name)
{
tree var;
/* With LTO we may have constant bounds already in varpool.
Try to find it. */
var = chkp_find_const_bounds_var (lb, ub);
if (var)
return var;
var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier (name), pointer_bounds_type_node);
TREE_PUBLIC (var) = 1;
TREE_USED (var) = 1;
TREE_READONLY (var) = 1;
TREE_STATIC (var) = 1;
TREE_ADDRESSABLE (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_READ_P (var) = 1;
/* We may use this symbol during ctors generation in chkp_finish_file
when all symbols are emitted. Force output to avoid undefined
symbols in ctors. */
if (!in_lto_p)
{
DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
DECL_COMDAT (var) = 1;
varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
varpool_node::get_create (var)->force_output = 1;
}
else
DECL_EXTERNAL (var) = 1;
varpool_node::finalize_decl (var);
}
You should not set comdat group by hand, or we get into troubles on non-ELF
targets. Just call make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
Now in LTO I guess you want to check if the symbol is provided by the source
compilation unit, i.e. call symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME
(var)) and if it is there, check it have proper type and fatal_error otherwise
and if it does, discar var and use existing variable
This avoid a duplicate declaration of a symbol that is invalid in symtab.
(once we solve the transparent alias thing, I will add verification for that)
Because you already set force_output, the symbol should not be privatized and
renamed in any way.
If there are cases the symbol can get legally optimized out, I guess you
can also avoid setting force_output and we can stream references to the
decls into optimization summary in a case we want ot bind for it in WPA,
but that can wait for next stage1.
Honza
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2015-04-02 Ilya Enkovich <ilya.enkovich@intel.com>
>
> * tree-chkp.c (CHKP_LTO_SYMBOL_SUFFIX): New.
> (chkp_make_static_const_bounds): Use another
> symbol in LTO.
>
> gcc/testsuite/
>
> 2015-04-02 Ilya Enkovich <ilya.enkovich@intel.com>
>
> * gcc.dg/lto/chkp-static-bounds_0.c: New.
>
>
> diff --git a/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
> new file mode 100644
> index 0000000..e896eb1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
> @@ -0,0 +1,26 @@
> +/* { dg-lto-do link } */
> +/* { dg-require-effective-target mpx } */
> +/* { dg-lto-options { { -flto -flto-partition=max -fcheck-pointer-bounds -mmpx } } } */
> +
> +char *cc;
> +
> +int test1 (const char *c)
> +{
> + c = __builtin___bnd_init_ptr_bounds (c);
> + cc = c;
> + return c[0] * 2;
> +}
> +
> +struct S
> +{
> + int (*fnptr) (const char *);
> +} S;
> +
> +struct S s1 = {test1};
> +struct S s2 = {test1};
> +struct S s3 = {test1};
> +
> +int main (int argc, const char **argv)
> +{
> + return s1.fnptr (argv[0]) + s2.fnptr (argv[1]);
> +}
> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
> index d2df4ba..0578936 100644
> --- a/gcc/tree-chkp.c
> +++ b/gcc/tree-chkp.c
> @@ -421,6 +421,7 @@ static bool in_chkp_pass;
> #define CHKP_VAR_BOUNDS_PREFIX "__chkp_var_bounds_"
> #define CHKP_ZERO_BOUNDS_VAR_NAME "__chkp_zero_bounds"
> #define CHKP_NONE_BOUNDS_VAR_NAME "__chkp_none_bounds"
> +#define CHKP_LTO_SYMBOL_SUFFIX ".lto"
>
> /* Static checker constructors may become very large and their
> compilation with optimization may take too much time.
> @@ -1906,7 +1907,8 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
> HOST_WIDE_INT ub,
> const char *name)
> {
> - tree var;
> + tree var, id;
> + varpool_node *node;
>
> /* With LTO we may have constant bounds already in varpool.
> Try to find it. */
> @@ -1915,8 +1917,22 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
> if (var)
> return var;
>
> - var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
> - get_identifier (name), pointer_bounds_type_node);
> + /* In LTO we may have symbol with changed visibility, comdat
> + group etc. Therefore we shouldn't recreate the same symbol.
> + Use LTO version instead. */
> + if (in_lto_p)
> + {
> + int len = strlen (name) + strlen (CHKP_LTO_SYMBOL_SUFFIX) + 1;
> + char *new_name = XALLOCAVEC (char, len);
> + strcpy (new_name, name);
> + strcat (new_name, CHKP_LTO_SYMBOL_SUFFIX);
> + id = get_identifier (new_name);
> + }
> + else
> + id = get_identifier (name);
> +
> + var = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
> + pointer_bounds_type_node);
>
> TREE_PUBLIC (var) = 1;
> TREE_USED (var) = 1;
> @@ -1925,18 +1941,17 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
> TREE_ADDRESSABLE (var) = 0;
> DECL_ARTIFICIAL (var) = 1;
> DECL_READ_P (var) = 1;
> + DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
> + DECL_COMDAT (var) = 1;
> + DECL_WEAK (var) = 1;
> /* We may use this symbol during ctors generation in chkp_finish_file
> when all symbols are emitted. Force output to avoid undefined
> symbols in ctors. */
> - if (!in_lto_p)
> - {
> - DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
> - DECL_COMDAT (var) = 1;
> - varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
> - varpool_node::get_create (var)->force_output = 1;
> - }
> - else
> - DECL_EXTERNAL (var) = 1;
> + node = varpool_node::get_create (var);
> + node->set_comdat_group (DECL_ASSEMBLER_NAME (var));
> + node->force_output = 1;
> + node->externally_visible = 1;
> +
> varpool_node::finalize_decl (var);
>
> return var;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH, CHKP] Fix static const bounds creation in LTO
2015-04-02 20:45 ` Jan Hubicka
@ 2015-04-03 16:11 ` Ilya Enkovich
2015-04-03 17:01 ` Jan Hubicka
0 siblings, 1 reply; 7+ messages in thread
From: Ilya Enkovich @ 2015-04-03 16:11 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches
On 02 Apr 22:45, Jan Hubicka wrote:
> > Hi,
> >
> > Current in LTO static const bounds are created as external symbol. It doesn't work in case original symbols were removed and privatized. This patch introduces a separate comdat symbol to be used in LTO. Bootstrapped and tested on x86_64-unknown-linux-gnu. Does this approach look OK?
>
> As I understand it, you want to create a static variables, like __chkp_zero_bounds
> which should be shared across translation units. Currently the function does:
> static tree
> chkp_make_static_const_bounds (HOST_WIDE_INT lb,
> HOST_WIDE_INT ub,
> const char *name)
> {
> tree var;
>
> /* With LTO we may have constant bounds already in varpool.
> Try to find it. */
> var = chkp_find_const_bounds_var (lb, ub);
>
> if (var)
> return var;
>
> var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
> get_identifier (name), pointer_bounds_type_node);
>
> TREE_PUBLIC (var) = 1;
> TREE_USED (var) = 1;
> TREE_READONLY (var) = 1;
> TREE_STATIC (var) = 1;
> TREE_ADDRESSABLE (var) = 0;
> DECL_ARTIFICIAL (var) = 1;
> DECL_READ_P (var) = 1;
> /* We may use this symbol during ctors generation in chkp_finish_file
> when all symbols are emitted. Force output to avoid undefined
> symbols in ctors. */
> if (!in_lto_p)
> {
> DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
> DECL_COMDAT (var) = 1;
> varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
> varpool_node::get_create (var)->force_output = 1;
> }
> else
> DECL_EXTERNAL (var) = 1;
> varpool_node::finalize_decl (var);
> }
>
> You should not set comdat group by hand, or we get into troubles on non-ELF
> targets. Just call make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
>
> Now in LTO I guess you want to check if the symbol is provided by the source
> compilation unit, i.e. call symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME
> (var)) and if it is there, check it have proper type and fatal_error otherwise
> and if it does, discar var and use existing variable
>
> This avoid a duplicate declaration of a symbol that is invalid in symtab.
> (once we solve the transparent alias thing, I will add verification for that)
> Because you already set force_output, the symbol should not be privatized and
> renamed in any way.
>
> If there are cases the symbol can get legally optimized out, I guess you
> can also avoid setting force_output and we can stream references to the
> decls into optimization summary in a case we want ot bind for it in WPA,
> but that can wait for next stage1.
>
> Honza
Thanks a lot for looking into it! Seems originally I mostly got problems due to no DECL_WEAK for generated var, make_decl_one_only seems to work for my tests. Will run more testing to make sure it's OK. Here is a new patch version. Is it OK?
Thanks,
Ilya
--
gcc/
2015-04-03 Ilya Enkovich <ilya.enkovich@intel.com>
* tree-chkp.c (chkp_find_const_bounds_var): Search
by assembler name.
(chkp_make_static_const_bounds): Use make_decl_one_only.
gcc/testsuite/
2015-04-03 Ilya Enkovich <ilya.enkovich@intel.com>
* gcc.dg/lto/chkp-static-bounds_0.c: New.
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
new file mode 100644
index 0000000..596e551
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
@@ -0,0 +1,26 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -flto -flto-partition=max -fcheck-pointer-bounds -mmpx } } } */
+
+const char *cc;
+
+int test1 (const char *c)
+{
+ c = __builtin___bnd_init_ptr_bounds (c);
+ cc = c;
+ return c[0] * 2;
+}
+
+struct S
+{
+ int (*fnptr) (const char *);
+} S;
+
+struct S s1 = {test1};
+struct S s2 = {test1};
+struct S s3 = {test1};
+
+int main (int argc, const char **argv)
+{
+ return s1.fnptr (argv[0]) + s2.fnptr (argv[1]);
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 03f75b3..4daeab6 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -1876,26 +1876,17 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
/* Return constant static bounds var with specified LB and UB
if such var exists in varpool. Return NULL otherwise. */
static tree
-chkp_find_const_bounds_var (HOST_WIDE_INT lb,
- HOST_WIDE_INT ub)
+chkp_find_const_bounds_var (tree id)
{
- tree val = targetm.chkp_make_bounds_constant (lb, ub);
- struct varpool_node *node;
-
- /* We expect bounds constant is represented as a complex value
- of two pointer sized integers. */
- gcc_assert (TREE_CODE (val) == COMPLEX_CST);
+ struct symtab_node *node = symtab_node::get_for_asmname (id);
- FOR_EACH_VARIABLE (node)
- if (POINTER_BOUNDS_P (node->decl)
- && TREE_READONLY (node->decl)
- && DECL_INITIAL (node->decl)
- && TREE_CODE (DECL_INITIAL (node->decl)) == COMPLEX_CST
- && tree_int_cst_equal (TREE_REALPART (DECL_INITIAL (node->decl)),
- TREE_REALPART (val))
- && tree_int_cst_equal (TREE_IMAGPART (DECL_INITIAL (node->decl)),
- TREE_IMAGPART (val)))
+ if (node)
+ {
+ /* We don't allow this symbol usage for non bounds. */
+ gcc_assert (node->type == SYMTAB_VARIABLE);
+ gcc_assert (POINTER_BOUNDS_P (node->decl));
return node->decl;
+ }
return NULL;
}
@@ -1907,37 +1898,34 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
HOST_WIDE_INT ub,
const char *name)
{
+ tree id = get_identifier (name);
tree var;
+ varpool_node *node;
/* With LTO we may have constant bounds already in varpool.
Try to find it. */
- var = chkp_find_const_bounds_var (lb, ub);
+ var = chkp_find_const_bounds_var (id);
if (var)
return var;
- var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier (name), pointer_bounds_type_node);
+ var = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+ pointer_bounds_type_node);
- TREE_PUBLIC (var) = 1;
TREE_USED (var) = 1;
TREE_READONLY (var) = 1;
TREE_STATIC (var) = 1;
TREE_ADDRESSABLE (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_READ_P (var) = 1;
+ DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
+ make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
/* We may use this symbol during ctors generation in chkp_finish_file
when all symbols are emitted. Force output to avoid undefined
symbols in ctors. */
- if (!in_lto_p)
- {
- DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
- DECL_COMDAT (var) = 1;
- varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
- varpool_node::get_create (var)->force_output = 1;
- }
- else
- DECL_EXTERNAL (var) = 1;
+ node = varpool_node::get_create (var);
+ node->force_output = 1;
+
varpool_node::finalize_decl (var);
return var;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH, CHKP] Fix static const bounds creation in LTO
2015-04-03 16:11 ` Ilya Enkovich
@ 2015-04-03 17:01 ` Jan Hubicka
2015-04-07 8:10 ` Ilya Enkovich
0 siblings, 1 reply; 7+ messages in thread
From: Jan Hubicka @ 2015-04-03 17:01 UTC (permalink / raw)
To: Ilya Enkovich; +Cc: Jan Hubicka, gcc-patches
>
> Thanks a lot for looking into it! Seems originally I mostly got problems due to no DECL_WEAK for generated var, make_decl_one_only seems to work for my tests. Will run more testing to make sure it's OK. Here is a new patch version. Is it OK?
Good ;)
> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
> index 03f75b3..4daeab6 100644
> --- a/gcc/tree-chkp.c
> +++ b/gcc/tree-chkp.c
> @@ -1876,26 +1876,17 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
> /* Return constant static bounds var with specified LB and UB
> if such var exists in varpool. Return NULL otherwise. */
> static tree
> -chkp_find_const_bounds_var (HOST_WIDE_INT lb,
> - HOST_WIDE_INT ub)
> +chkp_find_const_bounds_var (tree id)
> {
> - tree val = targetm.chkp_make_bounds_constant (lb, ub);
> - struct varpool_node *node;
> -
> - /* We expect bounds constant is represented as a complex value
> - of two pointer sized integers. */
> - gcc_assert (TREE_CODE (val) == COMPLEX_CST);
> + struct symtab_node *node = symtab_node::get_for_asmname (id);
Sadly I think this won't work on targets that adds prefix to assembler name,
like djgpp/mingw.
To obtain mangled assembler name you need to call
id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl));
that in turn requires decl to already exist. That is why I guess you may want
to just build the new var and see if already exists....
Honza
>
> - FOR_EACH_VARIABLE (node)
> - if (POINTER_BOUNDS_P (node->decl)
> - && TREE_READONLY (node->decl)
> - && DECL_INITIAL (node->decl)
> - && TREE_CODE (DECL_INITIAL (node->decl)) == COMPLEX_CST
> - && tree_int_cst_equal (TREE_REALPART (DECL_INITIAL (node->decl)),
> - TREE_REALPART (val))
> - && tree_int_cst_equal (TREE_IMAGPART (DECL_INITIAL (node->decl)),
> - TREE_IMAGPART (val)))
> + if (node)
> + {
> + /* We don't allow this symbol usage for non bounds. */
> + gcc_assert (node->type == SYMTAB_VARIABLE);
> + gcc_assert (POINTER_BOUNDS_P (node->decl));
> return node->decl;
> + }
>
> return NULL;
> }
> @@ -1907,37 +1898,34 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
> HOST_WIDE_INT ub,
> const char *name)
> {
> + tree id = get_identifier (name);
> tree var;
> + varpool_node *node;
>
> /* With LTO we may have constant bounds already in varpool.
> Try to find it. */
> - var = chkp_find_const_bounds_var (lb, ub);
> + var = chkp_find_const_bounds_var (id);
>
> if (var)
> return var;
>
> - var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
> - get_identifier (name), pointer_bounds_type_node);
> + var = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
> + pointer_bounds_type_node);
>
> - TREE_PUBLIC (var) = 1;
> TREE_USED (var) = 1;
> TREE_READONLY (var) = 1;
> TREE_STATIC (var) = 1;
> TREE_ADDRESSABLE (var) = 0;
> DECL_ARTIFICIAL (var) = 1;
> DECL_READ_P (var) = 1;
> + DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
> + make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
> /* We may use this symbol during ctors generation in chkp_finish_file
> when all symbols are emitted. Force output to avoid undefined
> symbols in ctors. */
> - if (!in_lto_p)
> - {
> - DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
> - DECL_COMDAT (var) = 1;
> - varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
> - varpool_node::get_create (var)->force_output = 1;
> - }
> - else
> - DECL_EXTERNAL (var) = 1;
> + node = varpool_node::get_create (var);
> + node->force_output = 1;
> +
> varpool_node::finalize_decl (var);
>
> return var;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH, CHKP] Fix static const bounds creation in LTO
2015-04-03 17:01 ` Jan Hubicka
@ 2015-04-07 8:10 ` Ilya Enkovich
2015-04-07 20:43 ` Jan Hubicka
0 siblings, 1 reply; 7+ messages in thread
From: Ilya Enkovich @ 2015-04-07 8:10 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches
On 03 Apr 19:01, Jan Hubicka wrote:
>
> Sadly I think this won't work on targets that adds prefix to assembler name,
> like djgpp/mingw.
> To obtain mangled assembler name you need to call
> id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl));
> that in turn requires decl to already exist. That is why I guess you may want
> to just build the new var and see if already exists....
>
> Honza
I see. Thank you for review! Here is an updated version. Testing passed. Does it look OK?
Thanks,
Ilya
--
gcc/
2015-04-07 Ilya Enkovich <ilya.enkovich@intel.com>
* tree-chkp.c (chkp_find_const_bounds_var): Remove.
(chkp_make_static_const_bounds): Search existing
symbol by assembler name. Use make_decl_one_only.
gcc/testsuite/
2015-04-07 Ilya Enkovich <ilya.enkovich@intel.com>
* gcc.dg/lto/chkp-static-bounds_0.c: New.
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
new file mode 100644
index 0000000..596e551
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
@@ -0,0 +1,26 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -flto -flto-partition=max -fcheck-pointer-bounds -mmpx } } } */
+
+const char *cc;
+
+int test1 (const char *c)
+{
+ c = __builtin___bnd_init_ptr_bounds (c);
+ cc = c;
+ return c[0] * 2;
+}
+
+struct S
+{
+ int (*fnptr) (const char *);
+} S;
+
+struct S s1 = {test1};
+struct S s2 = {test1};
+struct S s3 = {test1};
+
+int main (int argc, const char **argv)
+{
+ return s1.fnptr (argv[0]) + s2.fnptr (argv[1]);
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 03f75b3..f5accce 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -1873,33 +1873,6 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
gimple_call_set_with_bounds (new_call, true);
}
-/* Return constant static bounds var with specified LB and UB
- if such var exists in varpool. Return NULL otherwise. */
-static tree
-chkp_find_const_bounds_var (HOST_WIDE_INT lb,
- HOST_WIDE_INT ub)
-{
- tree val = targetm.chkp_make_bounds_constant (lb, ub);
- struct varpool_node *node;
-
- /* We expect bounds constant is represented as a complex value
- of two pointer sized integers. */
- gcc_assert (TREE_CODE (val) == COMPLEX_CST);
-
- FOR_EACH_VARIABLE (node)
- if (POINTER_BOUNDS_P (node->decl)
- && TREE_READONLY (node->decl)
- && DECL_INITIAL (node->decl)
- && TREE_CODE (DECL_INITIAL (node->decl)) == COMPLEX_CST
- && tree_int_cst_equal (TREE_REALPART (DECL_INITIAL (node->decl)),
- TREE_REALPART (val))
- && tree_int_cst_equal (TREE_IMAGPART (DECL_INITIAL (node->decl)),
- TREE_IMAGPART (val)))
- return node->decl;
-
- return NULL;
-}
-
/* Return constant static bounds var with specified bounds LB and UB.
If such var does not exists then new var is created with specified NAME. */
static tree
@@ -1907,37 +1880,38 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
HOST_WIDE_INT ub,
const char *name)
{
+ tree id = get_identifier (name);
tree var;
+ varpool_node *node;
+ symtab_node *snode;
+
+ var = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+ pointer_bounds_type_node);
+ TREE_STATIC (var) = 1;
/* With LTO we may have constant bounds already in varpool.
Try to find it. */
- var = chkp_find_const_bounds_var (lb, ub);
-
- if (var)
- return var;
-
- var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier (name), pointer_bounds_type_node);
+ if ((snode = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (var))))
+ {
+ /* We don't allow this symbol usage for non bounds. */
+ gcc_assert (snode->type == SYMTAB_VARIABLE);
+ gcc_assert (POINTER_BOUNDS_P (snode->decl));
+ return snode->decl;
+ }
- TREE_PUBLIC (var) = 1;
TREE_USED (var) = 1;
TREE_READONLY (var) = 1;
- TREE_STATIC (var) = 1;
TREE_ADDRESSABLE (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_READ_P (var) = 1;
+ DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
+ make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
/* We may use this symbol during ctors generation in chkp_finish_file
when all symbols are emitted. Force output to avoid undefined
symbols in ctors. */
- if (!in_lto_p)
- {
- DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
- DECL_COMDAT (var) = 1;
- varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
- varpool_node::get_create (var)->force_output = 1;
- }
- else
- DECL_EXTERNAL (var) = 1;
+ node = varpool_node::get_create (var);
+ node->force_output = 1;
+
varpool_node::finalize_decl (var);
return var;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH, CHKP] Fix static const bounds creation in LTO
2015-04-07 8:10 ` Ilya Enkovich
@ 2015-04-07 20:43 ` Jan Hubicka
2015-04-08 19:39 ` Ilya Enkovich
0 siblings, 1 reply; 7+ messages in thread
From: Jan Hubicka @ 2015-04-07 20:43 UTC (permalink / raw)
To: Ilya Enkovich; +Cc: Jan Hubicka, gcc-patches
>
> 2015-04-07 Ilya Enkovich <ilya.enkovich@intel.com>
>
> * tree-chkp.c (chkp_find_const_bounds_var): Remove.
> (chkp_make_static_const_bounds): Search existing
> symbol by assembler name. Use make_decl_one_only.
>
> gcc/testsuite/
>
> 2015-04-07 Ilya Enkovich <ilya.enkovich@intel.com>
>
> * gcc.dg/lto/chkp-static-bounds_0.c: New.
OK, thanks!
> + if ((snode = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (var))))
> + {
> + /* We don't allow this symbol usage for non bounds. */
> + gcc_assert (snode->type == SYMTAB_VARIABLE);
> + gcc_assert (POINTER_BOUNDS_P (snode->decl));
This probably allows users to trigger ICE by declaring function of conflicting
name. What about sorry ("...") message instead?
> + return snode->decl;
> + }
>
> - TREE_PUBLIC (var) = 1;
> TREE_USED (var) = 1;
> TREE_READONLY (var) = 1;
> - TREE_STATIC (var) = 1;
> TREE_ADDRESSABLE (var) = 0;
> DECL_ARTIFICIAL (var) = 1;
> DECL_READ_P (var) = 1;
> + DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
> + make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
> /* We may use this symbol during ctors generation in chkp_finish_file
> when all symbols are emitted. Force output to avoid undefined
> symbols in ctors. */
> - if (!in_lto_p)
> - {
> - DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
> - DECL_COMDAT (var) = 1;
> - varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
> - varpool_node::get_create (var)->force_output = 1;
> - }
> - else
> - DECL_EXTERNAL (var) = 1;
> + node = varpool_node::get_create (var);
> + node->force_output = 1;
> +
> varpool_node::finalize_decl (var);
>
> return var;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH, CHKP] Fix static const bounds creation in LTO
2015-04-07 20:43 ` Jan Hubicka
@ 2015-04-08 19:39 ` Ilya Enkovich
0 siblings, 0 replies; 7+ messages in thread
From: Ilya Enkovich @ 2015-04-08 19:39 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches
On 07 Apr 22:43, Jan Hubicka wrote:
> >
> > 2015-04-07 Ilya Enkovich <ilya.enkovich@intel.com>
> >
> > * tree-chkp.c (chkp_find_const_bounds_var): Remove.
> > (chkp_make_static_const_bounds): Search existing
> > symbol by assembler name. Use make_decl_one_only.
> >
> > gcc/testsuite/
> >
> > 2015-04-07 Ilya Enkovich <ilya.enkovich@intel.com>
> >
> > * gcc.dg/lto/chkp-static-bounds_0.c: New.
>
> OK, thanks!
> > + if ((snode = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (var))))
> > + {
> > + /* We don't allow this symbol usage for non bounds. */
> > + gcc_assert (snode->type == SYMTAB_VARIABLE);
> > + gcc_assert (POINTER_BOUNDS_P (snode->decl));
> This probably allows users to trigger ICE by declaring function of conflicting
> name. What about sorry ("...") message instead?
Here is installed version.
Thanks,
Ilya
--
gcc/
2015-04-08 Ilya Enkovich <ilya.enkovich@intel.com>
* tree-chkp.c (chkp_find_const_bounds_var): Remove.
(chkp_make_static_const_bounds): Search existing
symbol by assembler name. Use make_decl_one_only.
(chkp_get_zero_bounds_var): Remove node search which
is now performed in chkp_make_static_const_bounds.
(chkp_get_none_bounds_var): Likewise.
gcc/testsuite/
2015-04-08 Ilya Enkovich <ilya.enkovich@intel.com>
* gcc.dg/lto/chkp-static-bounds_0.c: New.
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
new file mode 100644
index 0000000..596e551
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
@@ -0,0 +1,26 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -flto -flto-partition=max -fcheck-pointer-bounds -mmpx } } } */
+
+const char *cc;
+
+int test1 (const char *c)
+{
+ c = __builtin___bnd_init_ptr_bounds (c);
+ cc = c;
+ return c[0] * 2;
+}
+
+struct S
+{
+ int (*fnptr) (const char *);
+} S;
+
+struct S s1 = {test1};
+struct S s2 = {test1};
+struct S s3 = {test1};
+
+int main (int argc, const char **argv)
+{
+ return s1.fnptr (argv[0]) + s2.fnptr (argv[1]);
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 03f75b3..4c8379f 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -1873,33 +1873,6 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
gimple_call_set_with_bounds (new_call, true);
}
-/* Return constant static bounds var with specified LB and UB
- if such var exists in varpool. Return NULL otherwise. */
-static tree
-chkp_find_const_bounds_var (HOST_WIDE_INT lb,
- HOST_WIDE_INT ub)
-{
- tree val = targetm.chkp_make_bounds_constant (lb, ub);
- struct varpool_node *node;
-
- /* We expect bounds constant is represented as a complex value
- of two pointer sized integers. */
- gcc_assert (TREE_CODE (val) == COMPLEX_CST);
-
- FOR_EACH_VARIABLE (node)
- if (POINTER_BOUNDS_P (node->decl)
- && TREE_READONLY (node->decl)
- && DECL_INITIAL (node->decl)
- && TREE_CODE (DECL_INITIAL (node->decl)) == COMPLEX_CST
- && tree_int_cst_equal (TREE_REALPART (DECL_INITIAL (node->decl)),
- TREE_REALPART (val))
- && tree_int_cst_equal (TREE_IMAGPART (DECL_INITIAL (node->decl)),
- TREE_IMAGPART (val)))
- return node->decl;
-
- return NULL;
-}
-
/* Return constant static bounds var with specified bounds LB and UB.
If such var does not exists then new var is created with specified NAME. */
static tree
@@ -1907,37 +1880,43 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
HOST_WIDE_INT ub,
const char *name)
{
+ tree id = get_identifier (name);
tree var;
+ varpool_node *node;
+ symtab_node *snode;
+
+ var = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+ pointer_bounds_type_node);
+ TREE_STATIC (var) = 1;
+ TREE_PUBLIC (var) = 1;
/* With LTO we may have constant bounds already in varpool.
Try to find it. */
- var = chkp_find_const_bounds_var (lb, ub);
-
- if (var)
- return var;
-
- var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier (name), pointer_bounds_type_node);
+ if ((snode = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (var))))
+ {
+ /* We don't allow this symbol usage for non bounds. */
+ if (snode->type != SYMTAB_VARIABLE
+ || !POINTER_BOUNDS_P (snode->decl))
+ sorry ("-fcheck-pointer-bounds requires '%s' "
+ "name for internal usage",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (var)));
+
+ return snode->decl;
+ }
- TREE_PUBLIC (var) = 1;
TREE_USED (var) = 1;
TREE_READONLY (var) = 1;
- TREE_STATIC (var) = 1;
TREE_ADDRESSABLE (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_READ_P (var) = 1;
+ DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
+ make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
/* We may use this symbol during ctors generation in chkp_finish_file
when all symbols are emitted. Force output to avoid undefined
symbols in ctors. */
- if (!in_lto_p)
- {
- DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
- DECL_COMDAT (var) = 1;
- varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME (var));
- varpool_node::get_create (var)->force_output = 1;
- }
- else
- DECL_EXTERNAL (var) = 1;
+ node = varpool_node::get_create (var);
+ node->force_output = 1;
+
varpool_node::finalize_decl (var);
return var;
@@ -2001,14 +1980,6 @@ tree
chkp_get_zero_bounds_var (void)
{
if (!chkp_zero_bounds_var)
- {
- tree id = get_identifier (CHKP_ZERO_BOUNDS_VAR_NAME);
- symtab_node *node = symtab_node::get_for_asmname (id);
- if (node)
- chkp_zero_bounds_var = node->decl;
- }
-
- if (!chkp_zero_bounds_var)
chkp_zero_bounds_var
= chkp_make_static_const_bounds (0, -1,
CHKP_ZERO_BOUNDS_VAR_NAME);
@@ -2020,14 +1991,6 @@ tree
chkp_get_none_bounds_var (void)
{
if (!chkp_none_bounds_var)
- {
- tree id = get_identifier (CHKP_NONE_BOUNDS_VAR_NAME);
- symtab_node *node = symtab_node::get_for_asmname (id);
- if (node)
- chkp_none_bounds_var = node->decl;
- }
-
- if (!chkp_none_bounds_var)
chkp_none_bounds_var
= chkp_make_static_const_bounds (-1, 0,
CHKP_NONE_BOUNDS_VAR_NAME);
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-04-08 19:39 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-02 15:22 [PATCH, CHKP] Fix static const bounds creation in LTO Ilya Enkovich
2015-04-02 20:45 ` Jan Hubicka
2015-04-03 16:11 ` Ilya Enkovich
2015-04-03 17:01 ` Jan Hubicka
2015-04-07 8:10 ` Ilya Enkovich
2015-04-07 20:43 ` Jan Hubicka
2015-04-08 19:39 ` Ilya Enkovich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).