summaryrefslogtreecommitdiff
path: root/gcc/ipa-chkp.c
diff options
context:
space:
mode:
authorienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-05 12:42:03 +0000
committerienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-05 12:42:03 +0000
commit058a1b7aa18100b0cabbfa6c4b1fb6c97b8131a2 (patch)
treedf7b4d3afe0e30fdad56e3feeb2db22600eaaec8 /gcc/ipa-chkp.c
parent6fe9a05b73f4b5671a42b2a7e05d01329f7424e0 (diff)
downloadgcc-058a1b7aa18100b0cabbfa6c4b1fb6c97b8131a2.tar.gz
gcc/
2014-11-05 Ilya Enkovich <ilya.enkovich@intel.com> * ipa-chkp.c: New. * ipa-chkp.h: New. * tree-chkp.c: New. * tree-chkp.h: New. * tree-chkp-opt.c: New. * rtl-chkp.c: New. * rtl-chkp.h: New. * Makefile.in (OBJS): Add ipa-chkp.o, rtl-chkp.o, tree-chkp.o tree-chkp-opt.o. (GTFILES): Add tree-chkp.c. * mode-classes.def (MODE_POINTER_BOUNDS): New. * tree.def (POINTER_BOUNDS_TYPE): New. * genmodes.c (complete_mode): Support MODE_POINTER_BOUNDS. (POINTER_BOUNDS_MODE): New. (make_pointer_bounds_mode): New. * machmode.h (POINTER_BOUNDS_MODE_P): New. * stor-layout.c (int_mode_for_mode): Support MODE_POINTER_BOUNDS. (layout_type): Support POINTER_BOUNDS_TYPE. * tree-pretty-print.c (dump_generic_node): Support POINTER_BOUNDS_TYPE. * tree-core.h (tree_index): Add TI_POINTER_BOUNDS_TYPE. * tree.c (build_int_cst_wide): Support POINTER_BOUNDS_TYPE. (type_contains_placeholder_1): Likewise. (build_common_tree_nodes): Initialize pointer_bounds_type_node. * tree.h (POINTER_BOUNDS_TYPE_P): New. (pointer_bounds_type_node): New. (POINTER_BOUNDS_P): New. (BOUNDED_TYPE_P): New. (BOUNDED_P): New. (CALL_WITH_BOUNDS_P): New. * gimple.h (gf_mask): Add GF_CALL_WITH_BOUNDS. (gimple_call_with_bounds_p): New. (gimple_call_set_with_bounds): New. (gimple_return_retbnd): New. (gimple_return_set_retbnd): New * gimple.c (gimple_build_return): Increase number of ops for return statement. (gimple_build_call_from_tree): Propagate CALL_WITH_BOUNDS_P flag. * gimple-pretty-print.c (dump_gimple_return): Print second op. * rtl.h (CALL_EXPR_WITH_BOUNDS_P): New. * gimplify.c (gimplify_init_constructor): Avoid infinite loop during gimplification of bounds initializer. * calls.c: Include tree-chkp.h, rtl-chkp.h, bitmap.h. (special_function_p): Use original decl name when analyzing instrumentation clone. (arg_data): Add fields special_slot, pointer_arg and pointer_offset. (store_bounds): New. (emit_call_1): Propagate instrumentation flag for CALL. (initialize_argument_information): Compute pointer_arg, pointer_offset and special_slot for pointer bounds arguments. (finalize_must_preallocate): Preallocate when storing bounds in bounds table. (compute_argument_addresses): Skip pointer bounds. (expand_call): Store bounds into tables separately. Return result joined with resulting bounds. * cfgexpand.c: Include tree-chkp.h, rtl-chkp.h. (expand_call_stmt): Propagate bounds flag for CALL_EXPR. (expand_return): Add returned bounds arg. Handle returned bounds. (expand_gimple_stmt_1): Adjust to new expand_return signature. (gimple_expand_cfg): Reset rtx bounds map. * expr.c: Include tree-chkp.h, rtl-chkp.h. (expand_assignment): Handle returned bounds. (store_expr_with_bounds): New. Replaces store_expr with new bounds target argument. Handle bounds returned by calls. (store_expr): Now wraps store_expr_with_bounds. * expr.h (store_expr_with_bounds): New. * function.c: Include tree-chkp.h, rtl-chkp.h. (bounds_parm_data): New. (use_register_for_decl): Do not registerize decls used for bounds stores and loads. (assign_parms_augmented_arg_list): Add bounds of the result structure pointer as the second argument. (assign_parm_find_entry_rtl): Mark bounds are never passed on the stack. (assign_parm_is_stack_parm): Likewise. (assign_parm_load_bounds): New. (assign_bounds): New. (assign_parms): Load bounds and determine a location for returned bounds. (diddle_return_value_1): New. (diddle_return_value): Handle returned bounds. * function.h (rtl_data): Add field for returned bounds. * varasm.c: Include tree-chkp.h. (output_constant): Support POINTER_BOUNDS_TYPE. (output_constant_pool_2): Support MODE_POINTER_BOUNDS. (ultimate_transparent_alias_target): Move up. (make_decl_rtl): For instrumented function use name of the original decl. (assemble_start_function): Mark function as global in case it is instrumentation clone of the global function. (do_assemble_alias): Follow transparent alias chain for identifier. Check if original alias is public. (maybe_assemble_visibility): Use visibility of the original function for instrumented version. (default_unique_section): Likewise. * emit-rtl.c (immed_double_const): Support MODE_POINTER_BOUNDS. (init_emit_once): Build pointer bounds zero constants. * explow.c (trunc_int_for_mode): Support MODE_POINTER_BOUNDS. * target.def (builtin_chkp_function): New. (chkp_bound_type): New. (chkp_bound_mode): New. (chkp_make_bounds_constant): New. (chkp_initialize_bounds): New. (load_bounds_for_arg): New. (store_bounds_for_arg): New. (load_returned_bounds): New. (store_returned_bounds): New. (chkp_function_value_bounds): New. (setup_incoming_vararg_bounds): New. (function_arg): Update hook description with new possible return value CONST_INT. * targhooks.h (default_load_bounds_for_arg): New. (default_store_bounds_for_arg): New. (default_load_returned_bounds): New. (default_store_returned_bounds): New. (default_chkp_bound_type): New. (default_chkp_bound_mode): New. (default_builtin_chkp_function): New. (default_chkp_function_value_bounds): New. (default_chkp_make_bounds_constant): New. (default_chkp_initialize_bounds): New. (default_setup_incoming_vararg_bounds): New. * targhooks.c (default_load_bounds_for_arg): New. (default_store_bounds_for_arg): New. (default_load_returned_bounds): New. (default_store_returned_bounds): New. (default_chkp_bound_type): New. (default_chkp_bound_mode); New. (default_builtin_chkp_function): New. (default_chkp_function_value_bounds): New. (default_chkp_make_bounds_constant): New. (default_chkp_initialize_bounds): New. (default_setup_incoming_vararg_bounds): New. * builtin-types.def (BT_BND): New. (BT_FN_PTR_CONST_PTR): New. (BT_FN_CONST_PTR_CONST_PTR): New. (BT_FN_BND_CONST_PTR): New. (BT_FN_CONST_PTR_BND): New. (BT_FN_PTR_CONST_PTR_SIZE): New. (BT_FN_PTR_CONST_PTR_CONST_PTR): New. (BT_FN_VOID_PTRPTR_CONST_PTR): New. (BT_FN_VOID_CONST_PTR_SIZE): New. (BT_FN_VOID_PTR_BND): New. (BT_FN_CONST_PTR_CONST_PTR_CONST_PTR): New. (BT_FN_BND_CONST_PTR_SIZE): New. (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE): New. (BT_FN_VOID_CONST_PTR_BND_CONST_PTR): New. * chkp-builtins.def: New. * builtins.def: include chkp-builtins.def. (DEF_CHKP_BUILTIN): New. * builtins.c: Include tree-chkp.h and rtl-chkp.h. (expand_builtin): Support BUILT_IN_CHKP_INIT_PTR_BOUNDS, BUILT_IN_CHKP_NULL_PTR_BOUNDS, BUILT_IN_CHKP_COPY_PTR_BOUNDS, BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, BUILT_IN_CHKP_CHECK_PTR_UBOUNDS, BUILT_IN_CHKP_CHECK_PTR_BOUNDS, BUILT_IN_CHKP_SET_PTR_BOUNDS, BUILT_IN_CHKP_NARROW_PTR_BOUNDS, BUILT_IN_CHKP_STORE_PTR_BOUNDS, BUILT_IN_CHKP_GET_PTR_LBOUND, BUILT_IN_CHKP_GET_PTR_UBOUND, BUILT_IN_CHKP_BNDMK, BUILT_IN_CHKP_BNDSTX, BUILT_IN_CHKP_BNDCL, BUILT_IN_CHKP_BNDCU, BUILT_IN_CHKP_BNDLDX, BUILT_IN_CHKP_BNDRET, BUILT_IN_CHKP_INTERSECT, BUILT_IN_CHKP_NARROW, BUILT_IN_CHKP_EXTRACT_LOWER, BUILT_IN_CHKP_EXTRACT_UPPER. (std_expand_builtin_va_start): Init bounds for va_list. * cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add __CHKP__ macro when Pointer Bounds Checker is on. * params.def (PARAM_CHKP_MAX_CTOR_SIZE): New. * passes.def (pass_ipa_chkp_versioning): New. (pass_early_local_passes): Renamed to pass_build_ssa_passes. (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. * 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): Renamed to ... (make_pass_build_ssa_passes): This. (make_pass_chkp_instrumentation_passes): New. (make_pass_local_optimization_passes): New. * passes.c (pass_manager::execute_early_local_passes): Execute early passes in three steps. (execute_all_early_local_passes): Renamed to ... (execute_build_ssa_passes): This. (pass_data_early_local_passes): Renamed to ... (pass_data_build_ssa_passes): This. (pass_early_local_passes): Renamed to ... (pass_build_ssa_passes): This. (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): Renamed to ... (make_pass_build_ssa_passes): This. (make_pass_chkp_instrumentation_passes): New. (make_pass_local_optimization_passes): New. * c-family/c.opt (fcheck-pointer-bounds): New. (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. (Wchkp): New. * c-family/c-common.c (handle_bnd_variable_size_attribute): New. (handle_bnd_legacy): New. (handle_bnd_instrument): New. (c_common_attribute_table): Add bnd_variable_size, bnd_legacy and bnd_instrument. Fix documentation. (c_common_format_attribute_table): Likewsie. * toplev.c: include tree-chkp.h. (process_options): Check Pointer Bounds Checker is supported. (compile_file): Add chkp_finish_file call. * ipa-cp.c (initialize_node_lattices): Use cgraph_local_p to handle instrumentation clones properly. (propagate_constants_accross_call): Do not propagate through instrumentation thunks. * ipa-pure-const.c (propagate_pure_const): Support IPA_REF_CHKP. * ipa-inline.c (early_inliner): Check edge has summary allocated. * ipa-split.c: Include tree-chkp.h. (find_retbnd): New. (split_part_set_ssa_name_p): New. (consider_split): Do not split retbnd and retval producers. (insert_bndret_call_after): new. (split_function): Propagate Pointer Bounds Checker instrumentation marks and handle returned bounds. * tree-ssa-sccvn.h (vn_reference_op_struct): Transform opcode into bit field and add with_bounds field. * tree-ssa-sccvn.c (copy_reference_ops_from_call): Set with_bounds field for instrumented calls. * tree-ssa-pre.c (create_component_ref_by_pieces_1): Restore CALL_WITH_BOUNDS_P flag for calls. * tree-ssa-ccp.c: Include tree-chkp.h. (insert_clobber_before_stack_restore): Handle BUILT_IN_CHKP_BNDRET calls. * tree-ssa-dce.c: Include tree-chkp.h. (propagate_necessity): For free call fed by alloc check bounds are also provided by the same alloc. (eliminate_unnecessary_stmts): Handle BUILT_IN_CHKP_BNDRET used by free calls. * tree-inline.c: Include tree-chkp.h. (declare_return_variable): Add arg holding returned bounds slot. Create and initialize returned bounds var. (remap_gimple_stmt): Handle returned bounds. Return sequence of statements instead of a single statement. (insert_init_stmt): Add declaration. (remap_gimple_seq): Adjust to new remap_gimple_stmt signature. (copy_bb): Adjust to changed return type of remap_gimple_stmt. Properly handle bounds in va_arg_pack and va_arg_pack_len. (expand_call_inline): Handle returned bounds. Add bounds copy for generated mem to mem assignments. * tree-inline.h (copy_body_data): Add fields retbnd and assign_stmts. * value-prof.c: Include tree-chkp.h. (gimple_ic): Support returned bounds. * ipa.c (cgraph_build_static_cdtor_1): Support contructors with "chkp ctor" and "bnd_legacy" attributes. (symtab_remove_unreachable_nodes): Keep initial values for pointer bounds to be used for checks eliminations. (process_references): Handle IPA_REF_CHKP. (walk_polymorphic_call_targets): Likewise. * ipa-visibility.c (cgraph_externally_visible_p): Mark instrumented 'main' as externally visible. (function_and_variable_visibility): Filter instrumentation thunks. * cgraph.h (cgraph_thunk_info): Add add_pointer_bounds_args field. (cgraph_node): Add instrumented_version, orig_decl and instrumentation_clone fields. (symtab_node::get_alias_target): Allow IPA_REF_CHKP reference. (varpool_node): Add need_bounds_init field. (cgraph_local_p): New. * cgraph.c: Include tree-chkp.h. (cgraph_node::remove): Fix instrumented_version of the referenced node if any. (cgraph_node::dump): Dump instrumentation_clone and instrumented_version fields. (cgraph_node::verify_node): Check correctness of IPA_REF_CHKP references and instrumentation thunks. (cgraph_can_remove_if_no_direct_calls_and_refs_p): Keep all not instrumented instrumentation clones alive. (cgraph_redirect_edge_call_stmt_to_callee): Support returned bounds. * cgraphbuild.c (rebuild_cgraph_edges): Rebuild IPA_REF_CHKP reference. (cgraph_rebuild_references): Likewise. * cgraphunit.c: Include tree-chkp.h. (assemble_thunks_and_aliases): Skip thunks calling instrumneted function version. (varpool_finalize_decl): Register statically initialized decls in Pointer Bounds Checker. (walk_polymorphic_call_targets): Do not mark generated call to __builtin_unreachable as with_bounds. (output_weakrefs): If there are both instrumented and original versions, output only one of them. (cgraph_node::expand_thunk): Set with_bounds flag for created call statement. * ipa-ref.h (ipa_ref_use): Add IPA_REF_CHKP. (ipa_ref): increase size of use field. * symtab.c (ipa_ref_use_name): Add element for IPA_REF_CHKP. * varpool.c (dump_varpool_node): Dump need_bounds_init field. (ctor_for_folding): Do not fold constant bounds vars. * lto-streamer.h (LTO_minor_version): Change minor version from 0 to 1. * lto-cgraph.c (compute_ltrans_boundary): Keep initial values for pointer bounds. (lto_output_node): Output instrumentation_clone, thunk.add_pointer_bounds_args and orig_decl field. (lto_output_ref): Adjust to new ipa_ref::use field size. (input_overwrite_node): Read instrumentation_clone field. (input_node): Read thunk.add_pointer_bounds_args and orig_decl fields. (input_ref): Adjust to new ipa_ref::use field size. (input_cgraph_1): Compute instrumented_version fields and restore IDENTIFIER_TRANSPARENT_ALIAS chains. (lto_output_varpool_node): Output need_bounds_init value. (input_varpool_node): Read need_bounds_init value. * lto-partition.c (add_symbol_to_partition_1): Keep original and instrumented versions together. (privatize_symbol_name): Restore transparent alias chain if required. (add_references_to_partition): Add references to pointer bounds vars. * dbxout.c (dbxout_type): Ignore POINTER_BOUNDS_TYPE. * dwarf2out.c (gen_subprogram_die): Ignore bound args. (gen_type_die_with_usage): Skip pointer bounds. (dwarf2out_global_decl): Likewise. (is_base_type): Support POINTER_BOUNDS_TYPE. (gen_formal_types_die): Skip pointer bounds. (gen_decl_die): Likewise. * var-tracking.c (vt_add_function_parameters): Skip bounds parameters. * ipa-icf.c (sem_function::merge): Do not merge when instrumentation thunk still exists. (sem_variable::merge): Reset need_bounds_init flag. * doc/extend.texi: Document Pointer Bounds Checker built-in functions and attributes. * doc/tm.texi.in (TARGET_LOAD_BOUNDS_FOR_ARG): New. (TARGET_STORE_BOUNDS_FOR_ARG): New. (TARGET_LOAD_RETURNED_BOUNDS): New. (TARGET_STORE_RETURNED_BOUNDS): New. (TARGET_CHKP_FUNCTION_VALUE_BOUNDS): New. (TARGET_SETUP_INCOMING_VARARG_BOUNDS): New. (TARGET_BUILTIN_CHKP_FUNCTION): New. (TARGET_CHKP_BOUND_TYPE): New. (TARGET_CHKP_BOUND_MODE): New. (TARGET_CHKP_MAKE_BOUNDS_CONSTANT): New. (TARGET_CHKP_INITIALIZE_BOUNDS): New. * doc/tm.texi: Regenerated. * doc/rtl.texi (MODE_POINTER_BOUNDS): New. (BND32mode): New. (BND64mode): New. * doc/invoke.texi (-mmpx): New. (-mno-mpx): New. (chkp-max-ctor-size): New. * config/i386/constraints.md (w): New. (Ti): New. (Tb): New. * config/i386/i386-c.c (ix86_target_macros_internal): Add __MPX__. * config/i386/i386-modes.def (BND32): New. (BND64): New. * config/i386/i386-protos.h (ix86_bnd_prefixed_insn_p): New. * config/i386/i386.c: Include tree-chkp.h, rtl-chkp.h, tree-iterator.h. (regclass_map): Add bound registers. (dbx_register_map): Likewise. (dbx64_register_map): Likewise. (svr4_dbx_register_map): Likewise. (isa_opts): Add -mmpx. (PTA_MPX): New. (ix86_option_override_internal): Support MPX ISA. (ix86_conditional_register_usage): Support bound registers. (ix86_code_end): Add MPX bnd prefix. (output_set_got): Likewise. (print_reg): Avoid prefixes for bound registers. (ix86_print_operand): Add '!' (MPX bnd) print prefix support. (ix86_print_operand_punct_valid_p): Likewise. (ix86_print_operand_address): Support UNSPEC_BNDMK_ADDR and UNSPEC_BNDLDX_ADDR. (ix86_output_call_insn): Add MPX bnd prefix to branch instructions. (ix86_class_likely_spilled_p): Add bound regs support. (ix86_hard_regno_mode_ok): Likewise. (x86_order_regs_for_local_alloc): Likewise. (ix86_bnd_prefixed_insn_p): New. (ix86_builtins): Add IX86_BUILTIN_BNDMK, IX86_BUILTIN_BNDSTX, IX86_BUILTIN_BNDLDX, IX86_BUILTIN_BNDCL, IX86_BUILTIN_BNDCU, IX86_BUILTIN_BNDRET, IX86_BUILTIN_BNDNARROW, IX86_BUILTIN_BNDINT, IX86_BUILTIN_SIZEOF, IX86_BUILTIN_BNDLOWER, IX86_BUILTIN_BNDUPPER. (builtin_isa): Add leaf_p and nothrow_p fields. (def_builtin): Initialize leaf_p and nothrow_p. (ix86_add_new_builtins): Handle leaf_p and nothrow_p flags. (bdesc_mpx): New. (bdesc_mpx_const): New. (ix86_init_mpx_builtins): New. (ix86_init_builtins): Call ix86_init_mpx_builtins. (ix86_emit_cmove): New. (ix86_emit_move_max): New. (ix86_expand_builtin): Expand IX86_BUILTIN_BNDMK, IX86_BUILTIN_BNDSTX, IX86_BUILTIN_BNDLDX, IX86_BUILTIN_BNDCL, IX86_BUILTIN_BNDCU, IX86_BUILTIN_BNDRET, IX86_BUILTIN_BNDNARROW, IX86_BUILTIN_BNDINT, IX86_BUILTIN_SIZEOF, IX86_BUILTIN_BNDLOWER, IX86_BUILTIN_BNDUPPER. (ix86_function_value_bounds): New. (ix86_builtin_mpx_function): New. (ix86_get_arg_address_for_bt): New. (ix86_load_bounds): New. (ix86_store_bounds): New. (ix86_load_returned_bounds): New. (ix86_store_returned_bounds): New. (ix86_mpx_bound_mode): New. (ix86_make_bounds_constant): New. (ix86_initialize_bounds): (TARGET_LOAD_BOUNDS_FOR_ARG): New. (TARGET_STORE_BOUNDS_FOR_ARG): New. (TARGET_LOAD_RETURNED_BOUNDS): New. (TARGET_STORE_RETURNED_BOUNDS): New. (TARGET_CHKP_BOUND_MODE): New. (TARGET_BUILTIN_CHKP_FUNCTION): New. (TARGET_CHKP_FUNCTION_VALUE_BOUNDS): New. (TARGET_CHKP_MAKE_BOUNDS_CONSTANT): New. (TARGET_CHKP_INITIALIZE_BOUNDS): New. (ix86_option_override_internal): Do not support x32 with MPX. (init_cumulative_args): Init stdarg, bnd_regno, bnds_in_bt and force_bnd_pass. (function_arg_advance_32): Return number of used integer registers. (function_arg_advance_64): Likewise. (function_arg_advance_ms_64): Likewise. (ix86_function_arg_advance): Handle pointer bounds. (ix86_function_arg): Likewise. (ix86_function_value_regno_p): Mark fisrt bounds registers as possible function value. (ix86_function_value_1): Handle pointer bounds type/mode (ix86_return_in_memory): Likewise. (ix86_print_operand): Analyse insn to decide abounf "bnd" prefix. (ix86_expand_call): Generate returned bounds. (ix86_setup_incoming_vararg_bounds): New. (ix86_va_start): Initialize bounds for pointers in va_list. (TARGET_SETUP_INCOMING_VARARG_BOUNDS): New. * config/i386/i386.h (TARGET_MPX): New. (TARGET_MPX_P): New. (FIRST_PSEUDO_REGISTER): Fix to new value. (FIXED_REGISTERS): Add bound registers. (CALL_USED_REGISTERS): Likewise. (REG_ALLOC_ORDER): Likewise. (HARD_REGNO_NREGS): Likewise. (VALID_BND_REG_MODE): New. (FIRST_BND_REG): New. (LAST_BND_REG): New. (reg_class): Add BND_REGS. (REG_CLASS_NAMES): Likewise. (REG_CLASS_CONTENTS): Likewise. (BND_REGNO_P): New. (ANY_BND_REG_P): New. (BNDmode): New. (HI_REGISTER_NAMES): Add bound registers. (ix86_args): Add bnd_regno, bnds_in_bt, force_bnd_pass and stdarg fields. * config/i386/i386.md (UNSPEC_BNDMK): New. (UNSPEC_BNDMK_ADDR): New. (UNSPEC_BNDSTX): New. (UNSPEC_BNDLDX): New. (UNSPEC_BNDLDX_ADDR): New. (UNSPEC_BNDCL): New. (UNSPEC_BNDCU): New. (UNSPEC_BNDCN): New. (UNSPEC_MPX_FENCE): New. (UNSPEC_SIZEOF): New. (BND0_REG): New. (BND1_REG): New. (type): Add mpxmov, mpxmk, mpxchk, mpxld, mpxst. (length_immediate): Support mpxmov, mpxmk, mpxchk, mpxld, mpxst. (prefix_rep): Check for bnd prefix. (prefix_0f): Support mpxmov, mpxmk, mpxchk, mpxld, mpxst. (length_nobnd): New. (length): Use length_nobnd when specified. (memory): Support mpxmov, mpxmk, mpxchk, mpxld, mpxst. (BND): New. (bnd_ptr): New. (BNDCHECK): New. (bndcheck): New. (*jcc_1): Add MPX bnd prefix. (*jcc_2): Likewise. (jump): Likewise. (*indirect_jump): Likewise. (*tablejump_1): Likewise. (simple_return_internal): Likewise. (simple_return_internal_long): Likewise. (simple_return_pop_internal): Likewise. (simple_return_indirect_internal): Likewise. (<mode>_mk): New. (*<mode>_mk): New. (mov<mode>): New. (*mov<mode>_internal_mpx): New. (<mode>_<bndcheck>): New. (*<mode>_<bndcheck>): New. (<mode>_ldx): New. (*<mode>_ldx): New. (<mode>_stx): New. (*<mode>_stx): New. move_size_reloc_<mode>): New. * config/i386/predicates.md (address_mpx_no_base_operand): New. (address_mpx_no_index_operand): New. (bnd_mem_operator): New. (symbol_operand): New. (x86_64_immediate_size_operand): New. * config/i386/i386.opt (mmpx): New. * config/i386/i386-builtin-types.def (BND): New. (ULONG): New. (BND_FTYPE_PCVOID_ULONG): New. (VOID_FTYPE_BND_PCVOID): New. (VOID_FTYPE_PCVOID_PCVOID_BND): New. (BND_FTYPE_PCVOID_PCVOID): New. (BND_FTYPE_PCVOID): New. (BND_FTYPE_BND_BND): New. (PVOID_FTYPE_PVOID_PVOID_ULONG): New. (PVOID_FTYPE_PCVOID_BND_ULONG): New. (ULONG_FTYPE_VOID): New. (PVOID_FTYPE_BND): New. gcc/testsuite/ 2014-11-05 Ilya Enkovich <ilya.enkovich@intel.com> * gcc.target/i386/chkp-builtins-1.c: New. * gcc.target/i386/chkp-builtins-2.c: New. * gcc.target/i386/chkp-builtins-3.c: New. * gcc.target/i386/chkp-builtins-4.c: New. * gcc.target/i386/chkp-remove-bndint-1.c: New. * gcc.target/i386/chkp-remove-bndint-2.c: New. * gcc.target/i386/chkp-const-check-1.c: New. * gcc.target/i386/chkp-const-check-2.c: New. * gcc.target/i386/chkp-lifetime-1.c: New. * gcc.dg/pr37858.c: Replace early_local_cleanups pass name with build_ssa_passes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217125 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-chkp.c')
-rw-r--r--gcc/ipa-chkp.c647
1 files changed, 647 insertions, 0 deletions
diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
new file mode 100644
index 00000000000..f910583907d
--- /dev/null
+++ b/gcc/ipa-chkp.c
@@ -0,0 +1,647 @@
+/* Pointer Bounds Checker IPA passes.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ Contributed by Ilya Enkovich (ilya.enkovich@intel.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree-core.h"
+#include "stor-layout.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "stringpool.h"
+#include "bitmap.h"
+#include "gimple-expr.h"
+#include "tm.h"
+#include "hard-reg-set.h"
+#include "function.h"
+#include "is-a.h"
+#include "tree-ssa-alias.h"
+#include "predict.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "ipa-ref.h"
+#include "lto-streamer.h"
+#include "cgraph.h"
+#include "tree-chkp.h"
+#include "ipa-chkp.h"
+#include <string>
+
+/* Pointer Bounds Checker has two IPA passes to support code instrumentation.
+
+ In instrumented code each pointer is provided with bounds. For input
+ pointer parameters it means we also have bounds passed. For calls it
+ means we have additional bounds arguments for pointer arguments.
+
+ To have all IPA optimizations working correctly we have to express
+ dataflow between passed and received bounds explicitly via additional
+ entries in function declaration arguments list and in function type.
+ Since we may have both instrumented and not instrumented code at the
+ same time, we cannot replace all original functions with their
+ instrumented variants. Therefore we create clones (versions) instead.
+
+ Instrumentation clones creation is a separate IPA pass which is a part
+ of early local passes. Clones are created after SSA is built (because
+ instrumentation pass works on SSA) and before any transformations
+ which may change pointer flow and therefore lead to incorrect code
+ instrumentation (possibly causing false bounds check failures).
+
+ Instrumentation clones have pointer bounds arguments added right after
+ pointer arguments. Clones have assembler name of the original
+ function with suffix added. New assembler name is in transparent
+ alias chain with the original name. Thus we expect all calls to the
+ original and instrumented functions look similar in assembler.
+
+ During instrumentation versioning pass we create instrumented versions
+ of all function with body and also for all their aliases and thunks.
+ Clones for functions with no body are created on demand (usually
+ during call instrumentation).
+
+ Original and instrumented function nodes are connected with IPA
+ reference IPA_REF_CHKP. It is mostly done to have reachability
+ analysis working correctly. We may have no references to the
+ instrumented function in the code but it still should be counted
+ as reachable if the original function is reachable.
+
+ When original function bodies are not needed anymore we release
+ them and transform functions into a special kind of thunks. Each
+ thunk has a call edge to the instrumented version. These thunks
+ help to keep externally visible instrumented functions visible
+ when linker resolution files are used. Linker has no info about
+ connection between original and instrumented function and
+ therefore we may wrongly decide (due to difference in assembler
+ names) that instrumented function version is local and can be
+ removed. */
+
+#define CHKP_BOUNDS_OF_SYMBOL_PREFIX "__chkp_bounds_of_"
+
+/* Build a clone of FNDECL with a modified name. */
+
+static tree
+chkp_build_instrumented_fndecl (tree fndecl)
+{
+ tree new_decl = copy_node (fndecl);
+ tree new_name;
+ std::string s;
+
+ /* called_as_built_in checks DECL_NAME to identify calls to
+ builtins. We want instrumented calls to builtins to be
+ recognized by called_as_built_in. Therefore use original
+ DECL_NAME for cloning with no prefixes. */
+ s = IDENTIFIER_POINTER (DECL_NAME (fndecl));
+ s += ".chkp";
+ DECL_NAME (new_decl) = get_identifier (s.c_str ());
+
+ /* References to the original and to the instrumented version
+ should look the same in the output assembly. And we cannot
+ use the same assembler name for the instrumented version
+ because it conflicts with decl merging algorithms in LTO.
+ Achieve the result by using transparent alias name for the
+ instrumented version. */
+ s = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl));
+ s += ".chkp";
+ new_name = get_identifier (s.c_str ());
+ IDENTIFIER_TRANSPARENT_ALIAS (new_name) = 1;
+ TREE_CHAIN (new_name) = DECL_ASSEMBLER_NAME (fndecl);
+ SET_DECL_ASSEMBLER_NAME (new_decl, new_name);
+
+ /* For functions with body versioning will make a copy of arguments.
+ For functions with no body we need to do it here. */
+ if (!gimple_has_body_p (fndecl))
+ DECL_ARGUMENTS (new_decl) = copy_list (DECL_ARGUMENTS (fndecl));
+
+ /* We are going to modify attributes list and therefore should
+ make own copy. */
+ DECL_ATTRIBUTES (new_decl) = copy_list (DECL_ATTRIBUTES (fndecl));
+
+ return new_decl;
+}
+
+
+/* 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);
+ }
+}
+
+/* Make a copy of function type ORIG_TYPE adding pointer
+ bounds as additional arguments. */
+
+tree
+chkp_copy_function_type_adding_bounds (tree orig_type)
+{
+ tree type;
+ tree arg_type, attrs, t;
+ unsigned len = list_length (TYPE_ARG_TYPES (orig_type));
+ unsigned *indexes = XALLOCAVEC (unsigned, len);
+ unsigned idx = 0, new_idx = 0;
+
+ for (arg_type = TYPE_ARG_TYPES (orig_type);
+ arg_type;
+ arg_type = TREE_CHAIN (arg_type))
+ if (TREE_VALUE (arg_type) == void_type_node)
+ continue;
+ else if (BOUNDED_TYPE_P (TREE_VALUE (arg_type))
+ || pass_by_reference (NULL, TYPE_MODE (TREE_VALUE (arg_type)),
+ TREE_VALUE (arg_type), true)
+ || chkp_type_has_pointer (TREE_VALUE (arg_type)))
+ break;
+
+ /* We may use original type if there are no bounds passed. */
+ if (!arg_type)
+ return orig_type;
+
+ type = copy_node (orig_type);
+ TYPE_ARG_TYPES (type) = copy_list (TYPE_ARG_TYPES (type));
+
+ for (arg_type = TYPE_ARG_TYPES (type);
+ arg_type;
+ arg_type = TREE_CHAIN (arg_type))
+ {
+ indexes[idx++] = new_idx++;
+
+ /* pass_by_reference returns 1 for void type,
+ so check for it first. */
+ if (TREE_VALUE (arg_type) == void_type_node)
+ continue;
+ else if (BOUNDED_TYPE_P (TREE_VALUE (arg_type))
+ || pass_by_reference (NULL, TYPE_MODE (TREE_VALUE (arg_type)),
+ TREE_VALUE (arg_type), true))
+ {
+ tree new_type = build_tree_list (NULL_TREE,
+ pointer_bounds_type_node);
+ TREE_CHAIN (new_type) = TREE_CHAIN (arg_type);
+ TREE_CHAIN (arg_type) = new_type;
+
+ arg_type = TREE_CHAIN (arg_type);
+ new_idx++;
+ }
+ else if (chkp_type_has_pointer (TREE_VALUE (arg_type)))
+ {
+ bitmap slots = BITMAP_ALLOC (NULL);
+ bitmap_iterator bi;
+ unsigned bnd_no;
+
+ chkp_find_bound_slots (TREE_VALUE (arg_type), slots);
+
+ EXECUTE_IF_SET_IN_BITMAP (slots, 0, bnd_no, bi)
+ {
+ tree new_type = build_tree_list (NULL_TREE,
+ pointer_bounds_type_node);
+ TREE_CHAIN (new_type) = TREE_CHAIN (arg_type);
+ TREE_CHAIN (arg_type) = new_type;
+
+ arg_type = TREE_CHAIN (arg_type);
+ new_idx++;
+ }
+ BITMAP_FREE (slots);
+ }
+ }
+
+ /* If function type has attribute with arg indexes then
+ we have to copy it fixing attribute ops. Map for
+ fixing is in indexes array. */
+ attrs = TYPE_ATTRIBUTES (type);
+ if (lookup_attribute ("nonnull", attrs)
+ || lookup_attribute ("format", attrs)
+ || lookup_attribute ("format_arg", attrs))
+ {
+ int delta = new_idx - len;
+ attrs = copy_list (TYPE_ATTRIBUTES (type));
+ chkp_map_attr_arg_indexes (attrs, "nonnull", indexes, len, delta);
+ chkp_map_attr_arg_indexes (attrs, "format", indexes, len, delta);
+ chkp_map_attr_arg_indexes (attrs, "format_arg", indexes, len, delta);
+ TYPE_ATTRIBUTES (type) = attrs;
+ }
+
+ t = TYPE_MAIN_VARIANT (orig_type);
+ if (orig_type != t)
+ {
+ TYPE_MAIN_VARIANT (type) = t;
+ TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (t);
+ TYPE_NEXT_VARIANT (t) = type;
+ }
+ else
+ {
+ TYPE_MAIN_VARIANT (type) = type;
+ TYPE_NEXT_VARIANT (type) = NULL;
+ }
+
+
+ return type;
+}
+
+/* For given function FNDECL 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;
+ tree new_arg;
+
+ if (DECL_NAME (arg))
+ new_name += IDENTIFIER_POINTER (DECL_NAME (arg));
+ else
+ {
+ char uid[25];
+ snprintf (uid, 25, "D.%u", DECL_UID (arg));
+ new_name += uid;
+ }
+
+ new_arg = build_decl (DECL_SOURCE_LOCATION (arg), PARM_DECL,
+ get_identifier (new_name.c_str ()),
+ pointer_bounds_type_node);
+ DECL_ARG_TYPE (new_arg) = pointer_bounds_type_node;
+ DECL_CONTEXT (new_arg) = DECL_CONTEXT (arg);
+ DECL_ARTIFICIAL (new_arg) = 1;
+ DECL_CHAIN (new_arg) = DECL_CHAIN (arg);
+ DECL_CHAIN (arg) = new_arg;
+
+ arg = DECL_CHAIN (arg);
+
+ }
+ else if (chkp_type_has_pointer (TREE_TYPE (arg)))
+ {
+ tree orig_arg = arg;
+ bitmap slots = BITMAP_ALLOC (NULL);
+ bitmap_iterator bi;
+ unsigned bnd_no;
+
+ chkp_find_bound_slots (TREE_TYPE (arg), slots);
+
+ EXECUTE_IF_SET_IN_BITMAP (slots, 0, bnd_no, bi)
+ {
+ std::string new_name = CHKP_BOUNDS_OF_SYMBOL_PREFIX;
+ tree new_arg;
+ char offs[25];
+
+ if (DECL_NAME (orig_arg))
+ new_name += IDENTIFIER_POINTER (DECL_NAME (orig_arg));
+ else
+ {
+ snprintf (offs, 25, "D.%u", DECL_UID (arg));
+ new_name += offs;
+ }
+ snprintf (offs, 25, "__%u", bnd_no * POINTER_SIZE / BITS_PER_UNIT);
+
+ new_arg = build_decl (DECL_SOURCE_LOCATION (orig_arg),
+ PARM_DECL,
+ get_identifier (new_name.c_str ()),
+ pointer_bounds_type_node);
+ DECL_ARG_TYPE (new_arg) = pointer_bounds_type_node;
+ DECL_CONTEXT (new_arg) = DECL_CONTEXT (orig_arg);
+ DECL_ARTIFICIAL (new_arg) = 1;
+ DECL_CHAIN (new_arg) = DECL_CHAIN (arg);
+ DECL_CHAIN (arg) = new_arg;
+
+ arg = DECL_CHAIN (arg);
+ }
+ BITMAP_FREE (slots);
+ }
+
+ TREE_TYPE (fndecl) =
+ chkp_copy_function_type_adding_bounds (TREE_TYPE (fndecl));
+}
+
+/* Return clone created for instrumentation of NODE or NULL. */
+
+cgraph_node *
+chkp_maybe_create_clone (tree fndecl)
+{
+ cgraph_node *node = cgraph_node::get_create (fndecl);
+ cgraph_node *clone = node->instrumented_version;
+
+ gcc_assert (!node->instrumentation_clone);
+
+ if (!clone)
+ {
+ tree new_decl = chkp_build_instrumented_fndecl (fndecl);
+ struct cgraph_edge *e;
+ struct ipa_ref *ref;
+ int i;
+
+ clone = node->create_version_clone (new_decl, vNULL, NULL);
+ clone->externally_visible = node->externally_visible;
+ clone->local = node->local;
+ clone->address_taken = node->address_taken;
+ clone->thunk = node->thunk;
+ clone->alias = node->alias;
+ clone->weakref = node->weakref;
+ clone->cpp_implicit_alias = node->cpp_implicit_alias;
+ clone->instrumented_version = node;
+ clone->orig_decl = fndecl;
+ clone->instrumentation_clone = true;
+ node->instrumented_version = clone;
+
+ if (gimple_has_body_p (fndecl))
+ {
+ /* If function will not be instrumented, then it's instrumented
+ version is a thunk for the original. */
+ if (lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (fndecl))
+ || (flag_chkp_instrument_marked_only
+ && !lookup_attribute ("bnd_instrument", DECL_ATTRIBUTES (fndecl))))
+ {
+ clone->thunk.thunk_p = true;
+ clone->thunk.add_pointer_bounds_args = true;
+ clone->create_edge (node, NULL, 0, CGRAPH_FREQ_BASE);
+ }
+ else
+ {
+ tree_function_versioning (fndecl, new_decl, NULL, false,
+ NULL, false, NULL, NULL);
+ clone->lowered = true;
+ }
+ }
+
+ /* New params are inserted after versioning because it
+ actually copies args list from the original decl. */
+ chkp_add_bounds_params_to_function (new_decl);
+
+ /* Clones have the same comdat group as originals. */
+ if (node->same_comdat_group
+ || DECL_ONE_ONLY (node->decl))
+ clone->add_to_same_comdat_group (node);
+
+ if (gimple_has_body_p (fndecl))
+ symtab->call_cgraph_insertion_hooks (clone);
+
+ /* Clone all aliases. */
+ for (i = 0; node->iterate_referring (i, ref); i++)
+ if (ref->use == IPA_REF_ALIAS)
+ {
+ struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+ struct cgraph_node *chkp_alias
+ = chkp_maybe_create_clone (alias->decl);
+ chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
+ }
+
+ /* Clone all thunks. */
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->caller->thunk.thunk_p)
+ {
+ struct cgraph_node *thunk
+ = chkp_maybe_create_clone (e->caller->decl);
+ /* Redirect thunk clone edge to the node clone. */
+ thunk->callees->redirect_callee (clone);
+ }
+
+ /* For aliases and thunks we should make sure target is cloned
+ to have proper references and edges. */
+ if (node->thunk.thunk_p)
+ chkp_maybe_create_clone (node->callees->callee->decl);
+ else if (node->alias)
+ {
+ struct cgraph_node *target;
+
+ ref = node->ref_list.first_reference ();
+ if (ref)
+ chkp_maybe_create_clone (ref->referred->decl);
+
+ if (node->alias_target)
+ {
+ if (TREE_CODE (node->alias_target) == FUNCTION_DECL)
+ {
+ target = chkp_maybe_create_clone (node->alias_target);
+ clone->alias_target = target->decl;
+ }
+ else
+ clone->alias_target = node->alias_target;
+ }
+ }
+
+ /* Add IPA reference. It's main role is to keep instrumented
+ version reachable while original node is reachable. */
+ ref = node->create_reference (clone, IPA_REF_CHKP, NULL);
+ }
+
+ return clone;
+}
+
+/* Create clone for all functions to be instrumented. */
+
+static unsigned int
+chkp_versioning (void)
+{
+ struct cgraph_node *node;
+
+ bitmap_obstack_initialize (NULL);
+
+ FOR_EACH_DEFINED_FUNCTION (node)
+ {
+ if (!node->instrumentation_clone
+ && !node->instrumented_version
+ && !node->alias
+ && !node->thunk.thunk_p
+ && !lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (node->decl))
+ && (!flag_chkp_instrument_marked_only
+ || lookup_attribute ("bnd_instrument",
+ DECL_ATTRIBUTES (node->decl)))
+ /* No builtins instrumentation for now. */
+ && DECL_BUILT_IN_CLASS (node->decl) == NOT_BUILT_IN)
+ chkp_maybe_create_clone (node->decl);
+ }
+
+ /* Mark all aliases and thunks of functions with no instrumented
+ version as legacy function. */
+ FOR_EACH_DEFINED_FUNCTION (node)
+ {
+ if (!node->instrumentation_clone
+ && !node->instrumented_version
+ && (node->alias || node->thunk.thunk_p)
+ && !lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (node->decl)))
+ DECL_ATTRIBUTES (node->decl)
+ = tree_cons (get_identifier ("bnd_legacy"), NULL,
+ DECL_ATTRIBUTES (node->decl));
+ }
+
+ bitmap_obstack_release (NULL);
+
+ return 0;
+}
+
+/* In this pass we remove bodies of functions having
+ instrumented version. Functions with removed bodies
+ become a special kind of thunks to provide a connection
+ between calls to the original version and instrumented
+ function. */
+
+static unsigned int
+chkp_produce_thunks (void)
+{
+ struct cgraph_node *node;
+
+ FOR_EACH_DEFINED_FUNCTION (node)
+ {
+ if (!node->instrumentation_clone
+ && node->instrumented_version
+ && gimple_has_body_p (node->decl)
+ && gimple_has_body_p (node->instrumented_version->decl))
+ {
+ node->release_body ();
+ node->remove_callees ();
+ node->remove_all_references ();
+
+ node->thunk.thunk_p = true;
+ node->thunk.add_pointer_bounds_args = true;
+ node->create_edge (node->instrumented_version, NULL,
+ 0, CGRAPH_FREQ_BASE);
+ node->create_reference (node->instrumented_version,
+ IPA_REF_CHKP, NULL);
+ }
+ }
+
+ /* Mark instrumentation clones created for aliases and thunks
+ as insttrumented so they could be removed as unreachable
+ now. */
+ FOR_EACH_DEFINED_FUNCTION (node)
+ {
+ if (node->instrumentation_clone
+ && (node->alias || node->thunk.thunk_p)
+ && !chkp_function_instrumented_p (node->decl))
+ chkp_function_mark_instrumented (node->decl);
+ }
+
+ symtab->remove_unreachable_nodes (true, dump_file);
+
+ return 0;
+}
+
+const pass_data pass_data_ipa_chkp_versioning =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "chkp_versioning", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+const pass_data pass_data_ipa_chkp_produce_thunks =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "chkp_cleanup", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+class pass_ipa_chkp_versioning : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_chkp_versioning (gcc::context *ctxt)
+ : simple_ipa_opt_pass (pass_data_ipa_chkp_versioning, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual opt_pass * clone ()
+ {
+ return new pass_ipa_chkp_versioning (m_ctxt);
+ }
+
+ virtual bool gate (function *)
+ {
+ return flag_check_pointer_bounds;
+ }
+
+ virtual unsigned int execute (function *)
+ {
+ return chkp_versioning ();
+ }
+
+}; // class pass_ipa_chkp_versioning
+
+class pass_ipa_chkp_produce_thunks : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_chkp_produce_thunks (gcc::context *ctxt)
+ : simple_ipa_opt_pass (pass_data_ipa_chkp_produce_thunks, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual opt_pass * clone ()
+ {
+ return new pass_ipa_chkp_produce_thunks (m_ctxt);
+ }
+
+ virtual bool gate (function *)
+ {
+ return flag_check_pointer_bounds;
+ }
+
+ virtual unsigned int execute (function *)
+ {
+ return chkp_produce_thunks ();
+ }
+
+}; // class pass_chkp_produce_thunks
+
+simple_ipa_opt_pass *
+make_pass_ipa_chkp_versioning (gcc::context *ctxt)
+{
+ return new pass_ipa_chkp_versioning (ctxt);
+}
+
+simple_ipa_opt_pass *
+make_pass_ipa_chkp_produce_thunks (gcc::context *ctxt)
+{
+ return new pass_ipa_chkp_produce_thunks (ctxt);
+}