Discussion:
[PATCH, Pointer Bounds Checker 14/x] Pointer Bounds Checker passes
Ilya Enkovich
2014-05-30 12:25:56 UTC
Permalink
Hi,

This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.

Bootstrapped and tested on linux-x86_64.

Thanks,
Ilya
--
gcc/

2014-05-29 Ilya Enkovich <***@intel.com>

* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_before_local_optimization_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(pass_data_before_local_optimization_passes): New.
(pass_before_local_optimization_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
Richard Biener
2014-06-02 11:35:41 UTC
Permalink
Post by Ilya Enkovich
Hi,
This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.
That looks artificial to me. If you need to split up early_local_passes
then do that - nesting three IPA pass groups inside it looks odd to me.
Btw - doing this in three "IPA phases" makes things possibly slower
due to cache effects. It might be worth pursuing to move the early
stage completely to the lowering pipeline.

Btw, fixup_cfg only needs to run once local_pure_const was run
on a callee, thus it shouldn't be neccessary to run it from the
first group.

void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->next->next->sub);
}

is gross - it should be enough to execute the early local pass list
(obsolete comment with the suggestion above).

Richard.
Post by Ilya Enkovich
Bootstrapped and tested on linux-x86_64.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_before_local_optimization_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(pass_data_before_local_optimization_passes): New.
(pass_before_local_optimization_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
Ilya Enkovich
2014-06-02 12:44:36 UTC
Permalink
Post by Richard Biener
Post by Ilya Enkovich
Hi,
This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.
That looks artificial to me. If you need to split up early_local_passes
then do that - nesting three IPA pass groups inside it looks odd to me.
Btw - doing this in three "IPA phases" makes things possibly slower
due to cache effects. It might be worth pursuing to move the early
stage completely to the lowering pipeline.
Early local passes is some special case because these passes are
executed separately for new functions. I did not want to get three
special passes instead and therefore made split inside.

If you prefer split pass itself, I suppose pass_early_local_passes may
be replaced with something like pass_build_ssa_passes +
pass_chkp_instrumentation_passes + pass_ipa_chkp_produce_thunks +
pass_local_optimization_passes. execute_early_local_passes would
execute gimple passes lists of pass_build_ssa_passes,
pass_chkp_instrumentation_passes and pass_local_optimization_passes.

I think we cannot have the first stage moved into lowering passes
because it should be executed for newly created functions.
Post by Richard Biener
Btw, fixup_cfg only needs to run once local_pure_const was run
on a callee, thus it shouldn't be neccessary to run it from the
first group.
OK. Will try to remove it from the first group.
Post by Richard Biener
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->next->next->sub);
}
is gross - it should be enough to execute the early local pass list
(obsolete comment with the suggestion above).
This function should call only gimple passes for cfun. Therefore we
cannot call IPA passes here and has to execute each gimple passes list
separately.

Ilya
Post by Richard Biener
Richard.
Post by Ilya Enkovich
Bootstrapped and tested on linux-x86_64.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_before_local_optimization_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(pass_data_before_local_optimization_passes): New.
(pass_before_local_optimization_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
Richard Biener
2014-06-02 13:37:46 UTC
Permalink
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Hi,
This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.
That looks artificial to me. If you need to split up early_local_passes
then do that - nesting three IPA pass groups inside it looks odd to me.
Btw - doing this in three "IPA phases" makes things possibly slower
due to cache effects. It might be worth pursuing to move the early
stage completely to the lowering pipeline.
Early local passes is some special case because these passes are
executed separately for new functions. I did not want to get three
special passes instead and therefore made split inside.
Yeah, but all passes are already executed via execute_early_local_passes,
so it would be only an implementation detail.
Post by Ilya Enkovich
If you prefer split pass itself, I suppose pass_early_local_passes may
be replaced with something like pass_build_ssa_passes +
pass_chkp_instrumentation_passes + pass_ipa_chkp_produce_thunks +
pass_local_optimization_passes. execute_early_local_passes would
execute gimple passes lists of pass_build_ssa_passes,
pass_chkp_instrumentation_passes and pass_local_optimization_passes.
I think we cannot have the first stage moved into lowering passes
because it should be executed for newly created functions.
Well, let's defer that then.
Post by Ilya Enkovich
Post by Richard Biener
Btw, fixup_cfg only needs to run once local_pure_const was run
on a callee, thus it shouldn't be neccessary to run it from the
first group.
OK. Will try to remove it from the first group.
Post by Richard Biener
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->next->next->sub);
}
is gross - it should be enough to execute the early local pass list
(obsolete comment with the suggestion above).
This function should call only gimple passes for cfun. Therefore we
cannot call IPA passes here and has to execute each gimple passes list
separately.
Ok, given a different split this would then become somewhat more sane
anyway.

Richard.
Post by Ilya Enkovich
Ilya
Post by Richard Biener
Richard.
Post by Ilya Enkovich
Bootstrapped and tested on linux-x86_64.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_before_local_optimization_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(pass_data_before_local_optimization_passes): New.
(pass_before_local_optimization_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
Ilya Enkovich
2014-06-02 15:13:52 UTC
Permalink
Post by Richard Biener
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Hi,
This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.
That looks artificial to me. If you need to split up early_local_passes
then do that - nesting three IPA pass groups inside it looks odd to me.
Btw - doing this in three "IPA phases" makes things possibly slower
due to cache effects. It might be worth pursuing to move the early
stage completely to the lowering pipeline.
Early local passes is some special case because these passes are
executed separately for new functions. I did not want to get three
special passes instead and therefore made split inside.
Yeah, but all passes are already executed via execute_early_local_passes,
so it would be only an implementation detail.
Post by Ilya Enkovich
If you prefer split pass itself, I suppose pass_early_local_passes may
be replaced with something like pass_build_ssa_passes +
pass_chkp_instrumentation_passes + pass_ipa_chkp_produce_thunks +
pass_local_optimization_passes. execute_early_local_passes would
execute gimple passes lists of pass_build_ssa_passes,
pass_chkp_instrumentation_passes and pass_local_optimization_passes.
I think we cannot have the first stage moved into lowering passes
because it should be executed for newly created functions.
Well, let's defer that then.
Post by Ilya Enkovich
Post by Richard Biener
Btw, fixup_cfg only needs to run once local_pure_const was run
on a callee, thus it shouldn't be neccessary to run it from the
first group.
OK. Will try to remove it from the first group.
Post by Richard Biener
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->next->next->sub);
}
is gross - it should be enough to execute the early local pass list
(obsolete comment with the suggestion above).
This function should call only gimple passes for cfun. Therefore we
cannot call IPA passes here and has to execute each gimple passes list
separately.
Ok, given a different split this would then become somewhat more sane
anyway.
Sorry, didn't catch it. Should I try a different split or defer it? :)

Ilya
Post by Richard Biener
Richard.
Post by Ilya Enkovich
Ilya
Post by Richard Biener
Richard.
Post by Ilya Enkovich
Bootstrapped and tested on linux-x86_64.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_before_local_optimization_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(pass_data_before_local_optimization_passes): New.
(pass_before_local_optimization_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
Richard Biener
2014-06-03 08:59:36 UTC
Permalink
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Hi,
This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.
That looks artificial to me. If you need to split up early_local_passes
then do that - nesting three IPA pass groups inside it looks odd to me.
Btw - doing this in three "IPA phases" makes things possibly slower
due to cache effects. It might be worth pursuing to move the early
stage completely to the lowering pipeline.
Early local passes is some special case because these passes are
executed separately for new functions. I did not want to get three
special passes instead and therefore made split inside.
Yeah, but all passes are already executed via execute_early_local_passes,
so it would be only an implementation detail.
Post by Ilya Enkovich
If you prefer split pass itself, I suppose pass_early_local_passes may
be replaced with something like pass_build_ssa_passes +
pass_chkp_instrumentation_passes + pass_ipa_chkp_produce_thunks +
pass_local_optimization_passes. execute_early_local_passes would
execute gimple passes lists of pass_build_ssa_passes,
pass_chkp_instrumentation_passes and pass_local_optimization_passes.
I think we cannot have the first stage moved into lowering passes
because it should be executed for newly created functions.
Well, let's defer that then.
Post by Ilya Enkovich
Post by Richard Biener
Btw, fixup_cfg only needs to run once local_pure_const was run
on a callee, thus it shouldn't be neccessary to run it from the
first group.
OK. Will try to remove it from the first group.
Post by Richard Biener
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->next->next->sub);
}
is gross - it should be enough to execute the early local pass list
(obsolete comment with the suggestion above).
This function should call only gimple passes for cfun. Therefore we
cannot call IPA passes here and has to execute each gimple passes list
separately.
Ok, given a different split this would then become somewhat more sane
anyway.
Sorry, didn't catch it. Should I try a different split or defer it? :)
Please try a different split. Defer moving the first part to the
lowering stage.

Richard.
Post by Ilya Enkovich
Ilya
Post by Richard Biener
Richard.
Post by Ilya Enkovich
Ilya
Post by Richard Biener
Richard.
Post by Ilya Enkovich
Bootstrapped and tested on linux-x86_64.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_before_local_optimization_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(pass_data_before_local_optimization_passes): New.
(pass_before_local_optimization_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_before_local_optimization_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
Ilya Enkovich
2014-06-06 06:54:50 UTC
Permalink
Post by Richard Biener
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Hi,
This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.
That looks artificial to me. If you need to split up early_local_passes
then do that - nesting three IPA pass groups inside it looks odd to me.
Btw - doing this in three "IPA phases" makes things possibly slower
due to cache effects. It might be worth pursuing to move the early
stage completely to the lowering pipeline.
Early local passes is some special case because these passes are
executed separately for new functions. I did not want to get three
special passes instead and therefore made split inside.
Yeah, but all passes are already executed via execute_early_local_passes,
so it would be only an implementation detail.
Post by Ilya Enkovich
If you prefer split pass itself, I suppose pass_early_local_passes may
be replaced with something like pass_build_ssa_passes +
pass_chkp_instrumentation_passes + pass_ipa_chkp_produce_thunks +
pass_local_optimization_passes. execute_early_local_passes would
execute gimple passes lists of pass_build_ssa_passes,
pass_chkp_instrumentation_passes and pass_local_optimization_passes.
I think we cannot have the first stage moved into lowering passes
because it should be executed for newly created functions.
Well, let's defer that then.
Post by Ilya Enkovich
Post by Richard Biener
Btw, fixup_cfg only needs to run once local_pure_const was run
on a callee, thus it shouldn't be neccessary to run it from the
first group.
OK. Will try to remove it from the first group.
Post by Richard Biener
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->next->next->sub);
}
is gross - it should be enough to execute the early local pass list
(obsolete comment with the suggestion above).
This function should call only gimple passes for cfun. Therefore we
cannot call IPA passes here and has to execute each gimple passes list
separately.
Ok, given a different split this would then become somewhat more sane
anyway.
Sorry, didn't catch it. Should I try a different split or defer it? :)
Please try a different split. Defer moving the first part to the
lowering stage.
Richard.
Here is a new version with new split with pass_early_local_passes replaced with new three passes. Left execute_early_local_passes unrenamed. Had to fix test gcc.dg/pr37858.c which uses -fdump-ipa-early_local_cleanups option.

I could not get rid of additional pass_fixup_cfg. Its removal caused wrong CFG (call to nonreturn function in a middle of BB) which confused checker logic. I moved this pass into checker passes list.

Bootstrapped and tested on linux-x86_64.

Thanks,
Ilya
--
gcc/

2014-06-05 Ilya Enkovich <***@intel.com>

* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_early_local_passes): Removed.
(pass_build_ssa_passes): New.
(pass_fixup_cfg): Moved to pass_chkp_instrumentation_passes.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(execute_all_early_local_passes): Removed.
(pass_data_early_local_passes): Removed.
(pass_early_local_passes): Removed.
(execute_build_ssa_passes): New.
(pass_data_build_ssa_passes): New.
(pass_build_ssa_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(-make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.

gcc/testsuite

2014-06-05 Ilya Enkovich <***@intel.com>

* gcc.dg/pr37858.c: Replace early_local_cleanups pass name
with build_ssa_passes.
Ilya Enkovich
2014-09-26 10:08:33 UTC
Permalink
Ping
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Post by Richard Biener
Post by Ilya Enkovich
Hi,
This patch adds Pointer Bounds Checker passes. Versioning happens before early local passes. Earply local passes are split into 3 stages to have everything instrumented before any optimization applies.
That looks artificial to me. If you need to split up early_local_passes
then do that - nesting three IPA pass groups inside it looks odd to me.
Btw - doing this in three "IPA phases" makes things possibly slower
due to cache effects. It might be worth pursuing to move the early
stage completely to the lowering pipeline.
Early local passes is some special case because these passes are
executed separately for new functions. I did not want to get three
special passes instead and therefore made split inside.
Yeah, but all passes are already executed via execute_early_local_passes,
so it would be only an implementation detail.
Post by Ilya Enkovich
If you prefer split pass itself, I suppose pass_early_local_passes may
be replaced with something like pass_build_ssa_passes +
pass_chkp_instrumentation_passes + pass_ipa_chkp_produce_thunks +
pass_local_optimization_passes. execute_early_local_passes would
execute gimple passes lists of pass_build_ssa_passes,
pass_chkp_instrumentation_passes and pass_local_optimization_passes.
I think we cannot have the first stage moved into lowering passes
because it should be executed for newly created functions.
Well, let's defer that then.
Post by Ilya Enkovich
Post by Richard Biener
Btw, fixup_cfg only needs to run once local_pure_const was run
on a callee, thus it shouldn't be neccessary to run it from the
first group.
OK. Will try to remove it from the first group.
Post by Richard Biener
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->sub);
+ execute_pass_list (pass_early_local_passes_1->sub->next->next->next->sub);
}
is gross - it should be enough to execute the early local pass list
(obsolete comment with the suggestion above).
This function should call only gimple passes for cfun. Therefore we
cannot call IPA passes here and has to execute each gimple passes list
separately.
Ok, given a different split this would then become somewhat more sane
anyway.
Sorry, didn't catch it. Should I try a different split or defer it? :)
Please try a different split. Defer moving the first part to the
lowering stage.
Richard.
Here is a new version with new split with pass_early_local_passes replaced with new three passes. Left execute_early_local_passes unrenamed. Had to fix test gcc.dg/pr37858.c which uses -fdump-ipa-early_local_cleanups option.
I could not get rid of additional pass_fixup_cfg. Its removal caused wrong CFG (call to nonreturn function in a middle of BB) which confused checker logic. I moved this pass into checker passes list.
Bootstrapped and tested on linux-x86_64.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_early_local_passes): Removed.
(pass_build_ssa_passes): New.
(pass_fixup_cfg): Moved to pass_chkp_instrumentation_passes.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(execute_all_early_local_passes): Removed.
(pass_data_early_local_passes): Removed.
(pass_early_local_passes): Removed.
(execute_build_ssa_passes): New.
(pass_data_build_ssa_passes): New.
(pass_build_ssa_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(-make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
gcc/testsuite
* gcc.dg/pr37858.c: Replace early_local_cleanups pass name
with build_ssa_passes.
Ilya Enkovich
2014-10-03 08:50:51 UTC
Permalink
Attached is an updated version of the patch. It has disabled instrumenttation for builtin calls.

Thanks,
Ilya
--
gcc/

2014-10-02 Ilya Enkovich <***@intel.com>

* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_early_local_passes): Removed.
(pass_build_ssa_passes): New.
(pass_fixup_cfg): Moved to pass_chkp_instrumentation_passes.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(execute_all_early_local_passes): Removed.
(pass_data_early_local_passes): Removed.
(pass_early_local_passes): Removed.
(execute_build_ssa_passes): New.
(pass_data_build_ssa_passes): New.
(pass_build_ssa_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.

gcc/testsuite

2014-10-02 Ilya Enkovich <***@intel.com>

* gcc.dg/pr37858.c: Replace early_local_cleanups pass name
with build_ssa_passes.
Jeff Law
2014-10-03 19:59:15 UTC
Permalink
Post by Ilya Enkovich
Attached is an updated version of the patch. It has disabled instrumenttation for builtin calls.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_early_local_passes): Removed.
(pass_build_ssa_passes): New.
(pass_fixup_cfg): Moved to pass_chkp_instrumentation_passes.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(execute_all_early_local_passes): Removed.
(pass_data_early_local_passes): Removed.
(pass_early_local_passes): Removed.
(execute_build_ssa_passes): New.
(pass_data_build_ssa_passes): New.
(pass_build_ssa_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
gcc/testsuite
* gcc.dg/pr37858.c: Replace early_local_cleanups pass name
with build_ssa_passes.
General question. At the RTL level you represent the bounds with an RTX
which is perfectly reasonable. What are the structure sharing
assumptions of those values? Do they follow the existing RTL structure
sharing assumptions?

Minor nit 2014 in the copyright year for all these files ;-)

So, for example if there are two references to the same bounds in RTL,
are they distinct RTXs with the same underlying values? Or is it a
single rtx object that is shared? It looks like you generally create
new RTXs, but I'm a bit concerned that you might shove those things into
a hash table and return them and embed a single reference into multiple
hunks of parent RTL.
Post by Ilya Enkovich
mpx-9-pass.patch
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 17754e5..78ac91f 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -255,7 +255,7 @@ is_builtin_fn (tree decl)
of the optimization level. This means whenever a function is invoked with
its "internal" name, which normally contains the prefix "__builtin". */
-static bool
+bool
called_as_built_in (tree node)
{
/* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
Is there some reason you put the new prototype in tree.h rather than
builtins.h?
Post by Ilya Enkovich
+void
+chkp_emit_bounds_store (rtx bounds, rtx value, rtx mem)
+{
[ ... ]
Post by Ilya Enkovich
+ else
+ ptr = gen_rtx_SUBREG (Pmode, value, INTVAL (offs));
I'm a bit concerned about the SUBREG use here. Are you really trying to
look at a different part of a REG expression here? ISTM at the least
you want to use one of the simplify routines to collapse this down in
cases where it's useful to do so.

I see a fair amount of "tree" things in rtl-chkp.c. We're trying to
untangle trees from the rest of the compiler. Can you look at see if
any of that stuff could be rewritten to avoid a tree interface?
chkp_copy_bounds_for_stack_parm comes to mind here.

chkp_expand_bounds_for_reset_mem really looks like it belongs elsewhere.
It operates entirely on trees. tree-chkp.c perhaps?
Post by Ilya Enkovich
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
[ ... ]
Post by Ilya Enkovich
+
+ Instrumentation clones have pointer bounds arguments added rigth after
s/rigth/right/
Post by Ilya Enkovich
+
+ d) Calls.
+
+ For each call in the code we should add additional arguments to pass
s/should//
Post by Ilya Enkovich
+
+ 3. Bounds computation.
+
+ Compiler is fully responsible for computing bounds to be used for each
+ memory access. The first step for bounds computation is to find the
+ origin of pointer dereferenced for memory access. Basing on pointer
+ origin we define a way to compute its bounds. There are just few
+
+ a) Pointer is returned by call.
+
+ In this case we use corresponding checker builtin method to obtain returned
+ bounds.
+
+
+ buf_1 = malloc (size_2);
+ foo (buf_1);
+
+
+ buf_1 = malloc (size_2);
+ __bound_tmp.1_3 = __builtin___chkp_bndret (buf_1);
+ foo (buf_1, __bound_tmp.1_3);
Q. Have you checked that nested return values work correctly? ie
Post by Ilya Enkovich
+
+ b) Pointer is an address of an object.
+
+ In this case compiler tries to compute objects size and create corresponding
+ bounds. If object has incomplete type then special checker builtin is used to
+ obtain its size at runtime.
So what happens if we have a pointer outside the object, but in the
memory reference we add a value so that the final effective address is
inside the object?

I continue to try and stamp out that kind of pointer manipulation
because it doesn't work on some architectures. However, I believe it
still occurs.
Post by Ilya Enkovich
+
+
+ d) Pointer is the result of pointer arithmetic or type cast.
+
+ In this case bounds of the base pointer are used.
And you can always get to the base?!?
Post by Ilya Enkovich
+
+static vec<struct bb_checks, va_heap, vl_ptr> check_infos = vNULL;
+
+static GTY (()) tree chkp_uintptr_type;
+
+static GTY (()) tree chkp_zero_bounds_var;
+static GTY (()) tree chkp_none_bounds_var;
+
+static GTY (()) basic_block entry_block;
+static GTY (()) tree zero_bounds;
+static GTY (()) tree none_bounds;
+static GTY (()) tree incomplete_bounds;
+static GTY (()) tree tmp_var;
+static GTY (()) tree size_tmp_var;
+static GTY (()) bitmap chkp_abnormal_copies;
+
+struct hash_set<tree> *chkp_invalid_bounds;
+struct hash_set<tree> *chkp_completed_bounds_set;
+struct hash_map<tree, tree> *chkp_reg_bounds;
+struct hash_map<tree, tree> *chkp_bound_vars;
+struct hash_map<tree, tree> *chkp_reg_addr_bounds;
+struct hash_map<tree, tree> *chkp_incomplete_bounds_map;
+struct hash_map<tree, tree> *chkp_bounds_map;
+struct hash_map<tree, tree> *chkp_static_var_bounds;
+
+static bool in_chkp_pass;
That's a whole lot of static variables. Do some of those belong
elsewhere? Perhaps in cfun?
Post by Ilya Enkovich
+
+/* Static checker constructors may become very large and their
+ compilation with optimization may take too much time.
+ Therefore we put a limit to number of statements in one
+ construcor. Tests with 100 000 statically initialized
+ pointers showed following compilation times on Sandy Bridge
+ limit 100 => ~18 sec.
+ limit 300 => ~22 sec.
+ limit 1000 => ~30 sec.
+ limit 3000 => ~49 sec.
+ limit 5000 => ~55 sec.
+ limit 10000 => ~76 sec.
+ limit 100000 => ~532 sec. */
+#define MAX_STMTS_IN_STATIC_CHKP_CTOR (optimize > 0 ? 5000 : 100000)
Well, it seems to be growing at a reasonable rate. ie, you've got 1000
times more statements in the last case when compared to the first. But
it's only ~30 times slower. So I'm not sure this is really necessary or
helpful. If you feel it needs to be kept, then use a --param rather
than magic numbers.
Post by Ilya Enkovich
+
+
+/* Fix operands of attribute from ATTRS list named ATTR_NAME.
+ Integer operands are replaced with values according to
+ INDEXES map having LEN elements. For operands out of len
+ we just add DELTA. */
+
+static void
+chkp_map_attr_arg_indexes (tree attrs, const char *attr_name,
+ unsigned *indexes, int len, int delta)
+{
+ tree attr = lookup_attribute (attr_name, attrs);
+ tree op;
+
+ if (!attr)
+ return;
+
+ TREE_VALUE (attr) = copy_list (TREE_VALUE (attr));
+ for (op = TREE_VALUE (attr); op; op = TREE_CHAIN (op))
+ {
+ int idx;
+
+ if (TREE_CODE (TREE_VALUE (op)) != INTEGER_CST)
+ continue;
+
+ idx = TREE_INT_CST_LOW (TREE_VALUE (op));
+
+ /* If idx exceeds indexes length then we just
+ keep it at the same distance from the last
+ known arg. */
+ if (idx > len)
+ idx += delta;
+ else
+ idx = indexes[idx - 1] + 1;
+ TREE_VALUE (op) = build_int_cst (TREE_TYPE (TREE_VALUE (op)), idx);
+ }
+}
+
+
+/* For given function NODE add bounds arguments to arguments
+ list. */
+static void
+chkp_add_bounds_params_to_function (tree fndecl)
+{
+ tree arg;
+
+ for (arg = DECL_ARGUMENTS (fndecl); arg; arg = DECL_CHAIN (arg))
+ if (BOUNDED_P (arg))
+ {
+ std::string new_name = CHKP_BOUNDS_OF_SYMBOL_PREFIX;
+ if (DECL_NAME (arg))
+ new_name += IDENTIFIER_POINTER (DECL_NAME (arg));
+ else
+ {
+ char uid[10];
+ snprintf (uid, 10, "D.%u", DECL_UID (arg));
+ new_name += uid;
+ }
10 digits really enough here? Why not go ahead and bullet-proof this
code so that we don't ever run the chance of a buffer overflow.
Post by Ilya Enkovich
+
+ /* Mark instrumentation clones created fo aliases and thunks
s/fo/of/

It feels like you've got a lot of stuff in tree-chkp. Please consider
separating it a bit. There's some basic helpers, some expansion related
stuff, argument twiddling and much more. It feels like it's where you
dumped everything remotely related to checking that touched trees rather
than thinking about where each function naturally fit. The size also
makes review hard.

Can you discuss all the PHI node handling for incomplete bounds in this
file? What problem are you trying to solve with this code?

Without looking at it closely, if we need to keep it, you may find it
works better as a worklist rather than traversing the entire map. Or
does this code remove objects from the map when complete (I scanned, but
didn't immediately see them getting removed). It also feels like this
code should probably break out of this file and be put elsewhere.

In fact, looking at things, I'm less than 5% through this patchkit.
Clearly this patchkit needs to be broken down into more manageable hunks
for review purposes.

Please address the issues noted above, then find logical ways to
partition this patch into smaller pieces.

Jeff
Ilya Enkovich
2014-10-07 15:32:50 UTC
Permalink
Post by Jeff Law
Post by Ilya Enkovich
Attached is an updated version of the patch. It has disabled
instrumenttation for builtin calls.
Thanks,
Ilya
--
gcc/
* tree-chkp.c: New.
* tree-chkp.h: New.
* rtl-chkp.c: New.
* rtl-chkp.h: New.
* Makefile.in (OBJS): Add tree-chkp.o, rtl-chkp.o.
(GTFILES): Add tree-chkp.c.
* c-family/c.opt (fchkp-check-incomplete-type): New.
(fchkp-zero-input-bounds-for-main): New.
(fchkp-first-field-has-own-bounds): New.
(fchkp-narrow-bounds): New.
(fchkp-narrow-to-innermost-array): New.
(fchkp-optimize): New.
(fchkp-use-fast-string-functions): New.
(fchkp-use-nochk-string-functions): New.
(fchkp-use-static-bounds): New.
(fchkp-use-static-const-bounds): New.
(fchkp-treat-zero-dynamic-size-as-infinite): New.
(fchkp-check-read): New.
(fchkp-check-write): New.
(fchkp-store-bounds): New.
(fchkp-instrument-calls): New.
(fchkp-instrument-marked-only): New.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add
__CHKP__ macro when Pointer Bounds Checker is on.
* passes.def (pass_ipa_chkp_versioning): New.
(pass_early_local_passes): Removed.
(pass_build_ssa_passes): New.
(pass_fixup_cfg): Moved to pass_chkp_instrumentation_passes.
(pass_chkp_instrumentation_passes): New.
(pass_ipa_chkp_produce_thunks): New.
(pass_local_optimization_passes): New.
(pass_chkp_opt): New.
* toplev.c: include tree-chkp.h.
(compile_file): Add chkp_finish_file call.
* tree-pass.h (make_pass_ipa_chkp_versioning): New.
(make_pass_ipa_chkp_produce_thunks): New.
(make_pass_chkp): New.
(make_pass_chkp_opt): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
* tree.h (called_as_built_in): New.
* builtins.c (called_as_built_in): Not static anymore.
* passes.c (pass_manager::execute_early_local_passes): Execute
early passes in three steps.
(execute_all_early_local_passes): Removed.
(pass_data_early_local_passes): Removed.
(pass_early_local_passes): Removed.
(execute_build_ssa_passes): New.
(pass_data_build_ssa_passes): New.
(pass_build_ssa_passes): New.
(pass_data_chkp_instrumentation_passes): New.
(pass_chkp_instrumentation_passes): New.
(pass_data_local_optimization_passes): New.
(pass_local_optimization_passes): New.
(make_pass_early_local_passes): Removed.
(make_pass_build_ssa_passes): New.
(make_pass_chkp_instrumentation_passes): New.
(make_pass_local_optimization_passes): New.
gcc/testsuite
* gcc.dg/pr37858.c: Replace early_local_cleanups pass name
with build_ssa_passes.
General question. At the RTL level you represent the bounds with an RTX
which is perfectly reasonable. What are the structure sharing assumptions
of those values? Do they follow the existing RTL structure sharing
assumptions?
Minor nit 2014 in the copyright year for all these files ;-)
So, for example if there are two references to the same bounds in RTL, are
they distinct RTXs with the same underlying values? Or is it a single rtx
object that is shared? It looks like you generally create new RTXs, but I'm
a bit concerned that you might shove those things into a hash table and
return them and embed a single reference into multiple hunks of parent RTL.
For expander bounds are quite regular vars and SSA names which are
expanded as all other values and therefore I believe regular sharing
assumptions are followed.

Hash tables are used just to link pointer values returned by call with
returned bounds. It is required to expand retbnd calls. Similarly
returned bounds are associated with DECL_RESULT using
SET_DECL_BOUNDS_RTL.
Post by Jeff Law
Post by Ilya Enkovich
mpx-9-pass.patch
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 17754e5..78ac91f 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -255,7 +255,7 @@ is_builtin_fn (tree decl)
of the optimization level. This means whenever a function is invoked with
its "internal" name, which normally contains the prefix "__builtin".
*/
-static bool
+bool
called_as_built_in (tree node)
{
/* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
Is there some reason you put the new prototype in tree.h rather than
builtins.h?
It was made at time when everything was in tree.h :)
Since current version doesn't work with builtins, there is no need in
this change at all. I remove it for now.
Post by Jeff Law
Post by Ilya Enkovich
+void
+chkp_emit_bounds_store (rtx bounds, rtx value, rtx mem)
+{
[ ... ]
Post by Ilya Enkovich
+ else
+ ptr = gen_rtx_SUBREG (Pmode, value, INTVAL (offs));
I'm a bit concerned about the SUBREG use here. Are you really trying to
look at a different part of a REG expression here? ISTM at the least you
want to use one of the simplify routines to collapse this down in cases
where it's useful to do so.
This is for case when a small structure is represented as a long
register and SUBREG here accesses structure field.
Post by Jeff Law
I see a fair amount of "tree" things in rtl-chkp.c. We're trying to
untangle trees from the rest of the compiler. Can you look at see if any of
that stuff could be rewritten to avoid a tree interface?
chkp_copy_bounds_for_stack_parm comes to mind here.
Expand codes inevitably use both rtx and tree interfaces. Don't see
it can be separated further.
Post by Jeff Law
chkp_expand_bounds_for_reset_mem really looks like it belongs elsewhere. It
operates entirely on trees. tree-chkp.c perhaps?
OK
Post by Jeff Law
Post by Ilya Enkovich
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
[ ... ]
Post by Ilya Enkovich
+
+ Instrumentation clones have pointer bounds arguments added rigth after
s/rigth/right/
Post by Ilya Enkovich
+
+ d) Calls.
+
+ For each call in the code we should add additional arguments to pass
s/should//
Post by Ilya Enkovich
+
+ 3. Bounds computation.
+
+ Compiler is fully responsible for computing bounds to be used for each
+ memory access. The first step for bounds computation is to find the
+ origin of pointer dereferenced for memory access. Basing on pointer
+ origin we define a way to compute its bounds. There are just few
+
+ a) Pointer is returned by call.
+
+ In this case we use corresponding checker builtin method to obtain returned
+ bounds.
+
+
+ buf_1 = malloc (size_2);
+ foo (buf_1);
+
+
+ buf_1 = malloc (size_2);
+ __bound_tmp.1_3 = __builtin___chkp_bndret (buf_1);
+ foo (buf_1, __bound_tmp.1_3);
Q. Have you checked that nested return values work correctly? ie
What is a nested return value and when does it appear?
Post by Jeff Law
Post by Ilya Enkovich
+
+ b) Pointer is an address of an object.
+
+ In this case compiler tries to compute objects size and create corresponding
+ bounds. If object has incomplete type then special checker builtin is used to
+ obtain its size at runtime.
So what happens if we have a pointer outside the object, but in the memory
reference we add a value so that the final effective address is inside the
object?
I continue to try and stamp out that kind of pointer manipulation because it
doesn't work on some architectures. However, I believe it still occurs.
For bounds it matters only how pointer is produced and what value it
has before de-reference. Pointer may have any intermediate values.
So it would be OK to have: p1 = &buf + 100000; return p1[-100000];
Post by Jeff Law
Post by Ilya Enkovich
+
+
+ d) Pointer is the result of pointer arithmetic or type cast.
+
+ In this case bounds of the base pointer are used.
And you can always get to the base?!?
We can always follow DF searching for a valid base. This is the
reason we instrument code before optimization which makes base search
impossible. Default bounds are used in case we cannot find valid
pointer source.
Post by Jeff Law
Post by Ilya Enkovich
+
+static vec<struct bb_checks, va_heap, vl_ptr> check_infos = vNULL;
+
+static GTY (()) tree chkp_uintptr_type;
+
+static GTY (()) tree chkp_zero_bounds_var;
+static GTY (()) tree chkp_none_bounds_var;
+
+static GTY (()) basic_block entry_block;
+static GTY (()) tree zero_bounds;
+static GTY (()) tree none_bounds;
+static GTY (()) tree incomplete_bounds;
+static GTY (()) tree tmp_var;
+static GTY (()) tree size_tmp_var;
+static GTY (()) bitmap chkp_abnormal_copies;
+
+struct hash_set<tree> *chkp_invalid_bounds;
+struct hash_set<tree> *chkp_completed_bounds_set;
+struct hash_map<tree, tree> *chkp_reg_bounds;
+struct hash_map<tree, tree> *chkp_bound_vars;
+struct hash_map<tree, tree> *chkp_reg_addr_bounds;
+struct hash_map<tree, tree> *chkp_incomplete_bounds_map;
+struct hash_map<tree, tree> *chkp_bounds_map;
+struct hash_map<tree, tree> *chkp_static_var_bounds;
+
+static bool in_chkp_pass;
That's a whole lot of static variables. Do some of those belong elsewhere?
Perhaps in cfun?
This data is pass local and therefore shouldn't belong anything like
function structure.
Post by Jeff Law
Post by Ilya Enkovich
+
+/* Static checker constructors may become very large and their
+ compilation with optimization may take too much time.
+ Therefore we put a limit to number of statements in one
+ construcor. Tests with 100 000 statically initialized
+ pointers showed following compilation times on Sandy Bridge
+ limit 100 => ~18 sec.
+ limit 300 => ~22 sec.
+ limit 1000 => ~30 sec.
+ limit 3000 => ~49 sec.
+ limit 5000 => ~55 sec.
+ limit 10000 => ~76 sec.
+ limit 100000 => ~532 sec. */
+#define MAX_STMTS_IN_STATIC_CHKP_CTOR (optimize > 0 ? 5000 : 100000)
Well, it seems to be growing at a reasonable rate. ie, you've got 1000
times more statements in the last case when compared to the first. But it's
only ~30 times slower. So I'm not sure this is really necessary or helpful.
If you feel it needs to be kept, then use a --param rather than magic
numbers.
These numbers are for the same test and thus the same amount of
statements in total. The difference is in how statements are split
into separate functions.
Post by Jeff Law
Post by Ilya Enkovich
+
+
+/* Fix operands of attribute from ATTRS list named ATTR_NAME.
+ Integer operands are replaced with values according to
+ INDEXES map having LEN elements. For operands out of len
+ we just add DELTA. */
+
+static void
+chkp_map_attr_arg_indexes (tree attrs, const char *attr_name,
+ unsigned *indexes, int len, int delta)
+{
+ tree attr = lookup_attribute (attr_name, attrs);
+ tree op;
+
+ if (!attr)
+ return;
+
+ TREE_VALUE (attr) = copy_list (TREE_VALUE (attr));
+ for (op = TREE_VALUE (attr); op; op = TREE_CHAIN (op))
+ {
+ int idx;
+
+ if (TREE_CODE (TREE_VALUE (op)) != INTEGER_CST)
+ continue;
+
+ idx = TREE_INT_CST_LOW (TREE_VALUE (op));
+
+ /* If idx exceeds indexes length then we just
+ keep it at the same distance from the last
+ known arg. */
+ if (idx > len)
+ idx += delta;
+ else
+ idx = indexes[idx - 1] + 1;
+ TREE_VALUE (op) = build_int_cst (TREE_TYPE (TREE_VALUE (op)), idx);
+ }
+}
+
+
+/* For given function NODE add bounds arguments to arguments
+ list. */
+static void
+chkp_add_bounds_params_to_function (tree fndecl)
+{
+ tree arg;
+
+ for (arg = DECL_ARGUMENTS (fndecl); arg; arg = DECL_CHAIN (arg))
+ if (BOUNDED_P (arg))
+ {
+ std::string new_name = CHKP_BOUNDS_OF_SYMBOL_PREFIX;
+ if (DECL_NAME (arg))
+ new_name += IDENTIFIER_POINTER (DECL_NAME (arg));
+ else
+ {
+ char uid[10];
+ snprintf (uid, 10, "D.%u", DECL_UID (arg));
+ new_name += uid;
+ }
10 digits really enough here? Why not go ahead and bullet-proof this code
so that we don't ever run the chance of a buffer overflow.
snprintf will never fail. Will change it to 25 to have enough for MAX_ULONG.
Post by Jeff Law
Post by Ilya Enkovich
+
+ /* Mark instrumentation clones created fo aliases and thunks
s/fo/of/
It feels like you've got a lot of stuff in tree-chkp. Please consider
separating it a bit. There's some basic helpers, some expansion related
stuff, argument twiddling and much more. It feels like it's where you
dumped everything remotely related to checking that touched trees rather
than thinking about where each function naturally fit. The size also makes
review hard.
I think it would be reasonable to put IPA passes into a separate file.
Don't see much reason to split tree stuff (and actually was asked last
year to put it into a single file). I'll try to split it into few
patches (within a single file) to make it simpler.
Post by Jeff Law
Can you discuss all the PHI node handling for incomplete bounds in this
file? What problem are you trying to solve with this code?
Incomplete bounds are used to walk through cyclic DF dependencies. I
added more comments for pointers arithmetic handling.
Post by Jeff Law
Without looking at it closely, if we need to keep it, you may find it works
better as a worklist rather than traversing the entire map. Or does this
code remove objects from the map when complete (I scanned, but didn't
immediately see them getting removed). It also feels like this code should
probably break out of this file and be put elsewhere.
This is a part of a bounds computation algorithm and shouldn't be put
apart. We keep phi bounds incomplete until all its args are computed.
Map fits better because for given bounds we should have an ability to
check if bounds are completed. Also a pointer is associated with each
incomplete bounds to perform bounds re-computation.
Post by Jeff Law
In fact, looking at things, I'm less than 5% through this patchkit. Clearly
this patchkit needs to be broken down into more manageable hunks for review
purposes.
Please address the issues noted above, then find logical ways to partition
this patch into smaller pieces.
I fixed issues you mentioned and will send a result as a new series.

Thanks,
Ilya
Post by Jeff Law
Jeff
Loading...