From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.theobroma-systems.com (vegas.theobroma-systems.com [144.76.126.164]) by sourceware.org (Postfix) with ESMTPS id B2A8E3972C20 for ; Fri, 4 Dec 2020 09:59:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B2A8E3972C20 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=theobroma-systems.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=erick.ochoa@theobroma-systems.com Received: from [185.143.182.3] (port=55328 helo=Martins-MacBook-Air.local) by mail.theobroma-systems.com with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from ) id 1kl7rr-000236-5t; Fri, 04 Dec 2020 10:59:11 +0100 To: gcc-patches@gcc.gnu.org Subject: [PATCH 8/8 v4] The Great STL migration Cc: =?UTF-8?Q?Christoph_M=c3=bcllner?= , Philipp Tomsich From: Erick Ochoa Message-ID: <4cff193f-8f0b-d4ae-a698-4db307cd7846@theobroma-systems.com> Date: Fri, 4 Dec 2020 10:59:11 +0100 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:78.0) Gecko/20100101 Thunderbird/78.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, FILL_THIS_FORM, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, KAM_SOMETLD_ARE_BAD_TLD, PDS_OTHER_BAD_TLD, SPF_HELO_NONE, SPF_PASS, TXREP, T_FILL_THIS_FORM_LOAN autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Dec 2020 09:59:21 -0000 --- gcc/ipa-dfe.c | 262 +++++++------- gcc/ipa-dfe.h | 108 +++--- gcc/ipa-field-reorder.c | 134 +++---- gcc/ipa-type-escape-analysis.c | 636 ++++++++++++++++----------------- gcc/ipa-type-escape-analysis.h | 160 ++++----- 5 files changed, 643 insertions(+), 657 deletions(-) diff --git a/gcc/ipa-dfe.c b/gcc/ipa-dfe.c index 7ab718c3628..98427e8e423 100644 --- a/gcc/ipa-dfe.c +++ b/gcc/ipa-dfe.c @@ -129,31 +129,31 @@ along with GCC; see the file COPYING3. If not see * Find all non_escaping types which point to RECORD_TYPEs in * record_field_offset_map. */ -std::set -get_all_types_pointing_to (record_field_offset_map_t record_field_offset_map, - tpartitions_t casting) +void +get_all_types_pointing_to (record_field_offset_map4_t &record_field_offset_map2, + tpartitions2_t casting, + hash_set &to_modify2) { - const tset_t &non_escaping = casting.non_escaping; + tset2_t &non_escaping = casting.non_escaping; - std::set specific_types; type_stringifier stringifier; + hash_set specific_types2; // Here we are just placing the types of interest in a set. - for (std::map::const_iterator i - = record_field_offset_map.begin (), - e = record_field_offset_map.end (); + for (hash_map::iterator i + = record_field_offset_map2.begin (), + e = record_field_offset_map2.end (); i != e; ++i) { - tree record = i->first; - std::string name = stringifier.stringify (record); - specific_types.insert (record); + tree record = (*i).first; + specific_types2.add (record); } - specific_type_collector specifier (specific_types); + specific_type_collector specifier (&specific_types2); // SpecificTypeCollector will collect all types which point to the types in // the set. - for (std::set::const_iterator i = non_escaping.begin (), + for (auto i = non_escaping.begin (), e = non_escaping.end (); i != e; ++i) { @@ -162,8 +162,11 @@ get_all_types_pointing_to (record_field_offset_map_t record_field_offset_map, } // These are all the types which need modifications. - std::set to_modify = specifier.get_set (); - return to_modify; + hash_set to_modify = specifier.get_set2 (); + for (hash_set::iterator i = to_modify.begin(), e = to_modify.end(); i != e; ++i) + { + to_modify2.add (*i); + } } /* record_field_offset_map holds information on which FIELD_DECLs might be @@ -180,13 +183,13 @@ get_all_types_pointing_to (record_field_offset_map_t record_field_offset_map, * The second maps old FIELD_DECLs trees to the new FIELD_DECLs. */ reorg_maps_t -get_types_replacement (record_field_offset_map_t record_field_offset_map, - std::set to_modify) +get_types_replacement (record_field_offset_map4_t &record_field_offset_map2, + hash_set &to_modify, reorg_record_map2_t &map2, reorg_field_map2_t &field_map2) { type_stringifier stringifier; - type_reconstructor reconstructor (record_field_offset_map, "reorg"); - for (std::set::const_iterator i = to_modify.begin (), + type_reconstructor reconstructor (record_field_offset_map2, "reorg", map2, field_map2); + for (hash_set::iterator i = to_modify.begin (), e = to_modify.end (); i != e; ++i) { @@ -194,7 +197,7 @@ get_types_replacement (record_field_offset_map_t record_field_offset_map, reconstructor.walk (TYPE_MAIN_VARIANT (record)); } - for (std::set::const_iterator i = to_modify.begin (), + for (hash_set::iterator i = to_modify.begin (), e = to_modify.end (); i != e; ++i) { @@ -202,20 +205,17 @@ get_types_replacement (record_field_offset_map_t record_field_offset_map, reconstructor.walk (record); } - reorg_record_map_t map = reconstructor.get_map (); - reorg_field_map_t field_map = reconstructor.get_field_map (); - // Here, we are just making sure that we are not doing anything too crazy. // Also, we found some types for which TYPE_CACHED_VALUES_P is not being // rewritten. This is probably indicative of a bug in TypeReconstructor. - for (std::map::const_iterator i = map.begin (), - e = map.end (); + for (hash_map::iterator i = map2.begin (), + e = map2.end (); i != e; ++i) { - tree o_record = i->first; + tree o_record = (*i).first; std::string o_name = stringifier.stringify (o_record); log ("original: %s\n", o_name.c_str ()); - tree r_record = i->second; + tree r_record = (*i).second; std::string r_name = r_record ? stringifier.stringify (r_record) : std::string (""); log ("modified: %s\n", r_name.c_str ()); @@ -227,16 +227,17 @@ get_types_replacement (record_field_offset_map_t record_field_offset_map, TYPE_CACHED_VALUES_P (_o_record) = false; TYPE_CACHED_VALUES_P (m_record) = false; - bool in_map = map.find (m_record) != map.end (); + bool in_map = map2.get (m_record); if (!in_map) continue; - tree mm_record = map[m_record]; + tree mm_record = *map2.get (m_record); // Info: I think this is no longer needed... // Please verify TYPE_MAIN_VARIANT (r_record) = mm_record; } - return std::make_pair (map, field_map); + // TODO: Ok, we will need to change this some time... + return std::make_pair (&map2, &field_map2); } /* Walk the gimple program and substitute @@ -244,8 +245,8 @@ get_types_replacement (record_field_offset_map_t record_field_offset_map, * * the trees in field_map with field_map's values. */ void -substitute_types_in_program (reorg_record_map_t map, - reorg_field_map_t field_map, bool _delete) +substitute_types_in_program (reorg_record_map2_t &map, + reorg_field_map2_t &field_map, bool _delete) { gimple_type_rewriter rewriter (map, field_map, _delete); rewriter.walk (); @@ -255,46 +256,46 @@ substitute_types_in_program (reorg_record_map_t map, /* Return a set of trees which point to the set of trees * that can be modified. */ -std::set -specific_type_collector::get_set () +hash_set +specific_type_collector::get_set2 () { - return to_return; + return to_return2; } void specific_type_collector::_walk_POINTER_TYPE_pre (tree t) { - path.insert (t); + path2.add (t); } void specific_type_collector::_walk_POINTER_TYPE_post (tree t) { - path.erase (t); + path2.remove (t); } void specific_type_collector::_walk_ARRAY_TYPE_pre (tree t) { - path.insert (t); + path2.add (t); } void specific_type_collector::_walk_ARRAY_TYPE_post (tree t) { - path.erase (t); + path2.remove (t); } void specific_type_collector::_walk_UNION_TYPE_pre (tree t) { - path.insert (t); + path2.add (t); } void specific_type_collector::_walk_UNION_TYPE_post (tree t) { - path.erase (t); + path2.remove (t); } /* If we find a RECORD_TYPE which is of interest, place @@ -304,51 +305,32 @@ void specific_type_collector::_walk_RECORD_TYPE_pre (tree t) { const bool in_set - = _collect_these_types.find (t) != _collect_these_types.end (); + = _collect_these_types2->contains (t); const bool must_collect = in_set; - path.insert (t); + path2.add (t); if (!must_collect) return; - for (std::set::const_iterator i = path.begin (), - e = path.end (); - i != e; ++i) - { + for (hash_set::iterator i = path2.begin(), e = path2.end(); i != e; ++i) + { tree type = *i; - to_return.insert (type); - } + to_return2.add (type); + } + } void specific_type_collector::_walk_RECORD_TYPE_post (tree t) { - path.erase (t); -} - -/* - * old RECORD_TYPE -> new RECORD_TYPE. - */ -reorg_record_map_t -type_reconstructor::get_map () -{ - return _reorg_map; -} - -/* - * old FIELD_DECL -> new FIELD_DECL. - */ -reorg_field_map_t -type_reconstructor::get_field_map () -{ - return _reorg_fields; + path2.remove (t); } void type_reconstructor::set_is_not_modified_yet (tree t) { gcc_assert (t); - const bool is_in_reorg_map = _reorg_map.find (t) != _reorg_map.end (); - modified_map[t] = false; + const bool is_in_reorg_map = _reorg_map2.get (t); + modified_map2->put(t, false); if (is_in_reorg_map) mark_all_pointing_here_as_modified (); @@ -356,11 +338,11 @@ type_reconstructor::set_is_not_modified_yet (tree t) if (!tt) return; - const bool is_in_reorg_map_2 = _reorg_map.find (tt) != _reorg_map.end (); + const bool is_in_reorg_map_2 = _reorg_map2.get (tt); if (!is_in_reorg_map_2) return; - tree type = _reorg_map[tt]; + tree type = *_reorg_map2.get(tt); bool is_modified = strstr (type_stringifier::get_type_identifier (type).c_str (), ".reorg"); is_modified @@ -375,10 +357,10 @@ type_reconstructor::set_is_not_modified_yet (tree t) void type_reconstructor::mark_all_pointing_here_as_modified () { - for (is_modified_map_t::iterator i = modified_map.begin (), - e = modified_map.end (); i != e; ++i) + for (is_modified_map2_t::iterator i = modified_map2->begin (), + e = modified_map2->end (); i != e; ++i) { - i->second = true; + (*i).second = true; } } @@ -386,10 +368,10 @@ bool type_reconstructor::get_is_modified (tree t) { gcc_assert (t); - const bool in_map = modified_map.find (t) != modified_map.end (); + const bool in_map = modified_map2->get(t); gcc_assert (in_map); - bool retval = modified_map[t]; - modified_map.erase (t); + bool retval = *modified_map2->get(t); + modified_map2->remove (t); bool points_to_record = false; tree _t = tree_to_tree (t); @@ -406,7 +388,7 @@ type_reconstructor::get_is_modified (tree t) bool type_reconstructor::is_memoized (tree t) { - const bool already_changed = _reorg_map.find (t) != _reorg_map.end (); + const bool already_changed = _reorg_map2.get (t); mark_all_pointing_here_as_modified (); return already_changed; } @@ -449,7 +431,7 @@ get_new_identifier (tree type, const char *suffix) void type_reconstructor::_walk_ARRAY_TYPE_pre (tree t) { - for_reference.push (t); + for_reference2.safe_push(t); set_is_not_modified_yet (t); tree _t = tree_to_tree (t); @@ -463,23 +445,23 @@ type_reconstructor::_walk_ARRAY_TYPE_pre (tree t) TYPE_MIN_VALUE (copy_domain) = copy_node (min); TYPE_MAX_VALUE (copy_domain) = copy_node (max); } - in_progress.push (copy); + in_progress2.safe_push (copy); } void type_reconstructor::_walk_ARRAY_TYPE_post (tree t) { - tree t2 = for_reference.top (); + tree t2 = for_reference2.last (); gcc_assert (t2 == t); - for_reference.pop (); - tree copy = in_progress.top (); - in_progress.pop (); + for_reference2.pop (); + tree copy = in_progress2.last (); + in_progress2.pop (); bool is_modified = get_is_modified (t); TREE_TYPE (copy) = build_variant_type_copy (TREE_TYPE (copy)); copy = is_modified ? build_distinct_type_copy (copy) : copy; - TREE_TYPE (copy) = is_modified ? _reorg_map[TREE_TYPE (t)] : TREE_TYPE (copy); + TREE_TYPE (copy) = is_modified ? *_reorg_map2.get(TREE_TYPE (t)) : TREE_TYPE (copy); TYPE_NAME (copy) = is_modified ? get_new_identifier (copy, this->get_new_suffix ()) : TYPE_NAME (copy); @@ -508,33 +490,33 @@ type_reconstructor::_walk_ARRAY_TYPE_post (tree t) if (!points_to_record) return; - _reorg_map[t] = is_modified ? copy : _t; + _reorg_map2.put (t, is_modified ? copy : _t); } void type_reconstructor::_walk_POINTER_TYPE_pre (tree t) { - for_reference.push (t); + for_reference2.safe_push (t); set_is_not_modified_yet (t); tree _t = tree_to_tree (t); tree copy = build_variant_type_copy (_t); - in_progress.push (copy); + in_progress2.safe_push (copy); } void type_reconstructor::_walk_POINTER_TYPE_post (tree t) { - tree t2 = for_reference.top (); + tree t2 = for_reference2.last (); gcc_assert (t2 == t); - for_reference.pop (); - tree copy = in_progress.top (); - in_progress.pop (); + for_reference2.pop (); + tree copy = in_progress2.last (); + in_progress2.pop (); bool is_modified = get_is_modified (t); copy = is_modified ? build_variant_type_copy (copy) : copy; - TREE_TYPE (copy) = is_modified ? _reorg_map[TREE_TYPE (t)] : TREE_TYPE (copy); + TREE_TYPE (copy) = is_modified ? *_reorg_map2.get(TREE_TYPE (t)) : TREE_TYPE (copy); TYPE_NAME (copy) = is_modified ? get_new_identifier (copy, this->get_new_suffix ()) : TYPE_NAME (copy); @@ -550,7 +532,7 @@ type_reconstructor::_walk_POINTER_TYPE_post (tree t) if (!points_to_record) return; - _reorg_map[t] = is_modified ? copy : _t; + _reorg_map2.put(t, is_modified ? copy : _t); } void @@ -566,26 +548,26 @@ type_reconstructor::_walk_RECORD_TYPE_pre (tree t) } set_is_not_modified_yet (t); - for_reference.push (t); + for_reference2.safe_push (t); // We don't know if we will modify this type t // So, let's make a copy. Just in case. tree _t = tree_to_tree (t); tree copy = build_variant_type_copy (_t); - in_progress.push (copy); - field_list_stack.push (field_tuple_list_t ()); + in_progress2.safe_push (copy); + field_list2_stack2.safe_push (vNULL); } void type_reconstructor::_walk_RECORD_TYPE_post (tree t) { - tree t2 = for_reference.top (); + tree t2 = for_reference2.last (); gcc_assert (t2 == t); - for_reference.pop (); + for_reference2.pop (); - tree copy = in_progress.top (); - in_progress.pop (); - field_tuple_list_t field_tuple_list = field_list_stack.top (); - field_list_stack.pop (); + tree copy = in_progress2.last (); + in_progress2.pop (); + field_tuple_list2_t field_tuple_list2 = field_list2_stack2.last (); + field_list2_stack2.pop (); // So, here all the work has been done to make sure // that the fields produced a field_tuple_list_t @@ -596,8 +578,8 @@ type_reconstructor::_walk_RECORD_TYPE_post (tree t) // of the copy bool is_modified = get_is_modified (t); tree prev_field = NULL; - for (field_tuple_list_t::iterator i = field_tuple_list.begin (), - e = field_tuple_list.end (); i != e; ++i) + for (auto i = field_tuple_list2.begin (), + e = field_tuple_list2.end (); i != e; ++i) { field_tuple_t field_tuple = *i; tree modified_field = field_tuple.second; @@ -630,7 +612,7 @@ type_reconstructor::_walk_RECORD_TYPE_post (tree t) if (!is_main_variant) { tree main = TYPE_MAIN_VARIANT (t); - tree main_reorg = _reorg_map[main]; + tree main_reorg = *_reorg_map2.get(main); tree copy_variant = build_variant_type_copy (main_reorg); TYPE_NAME (copy_variant) = get_new_identifier (copy, this->get_new_suffix ()); @@ -638,7 +620,7 @@ type_reconstructor::_walk_RECORD_TYPE_post (tree t) TYPE_MAIN_VARIANT (copy_variant) = main_reorg; TYPE_SIZE (main_reorg) = NULL; layout_type (copy_variant); - _reorg_map[t] = copy_variant; + _reorg_map2.put(t, copy_variant); } else { @@ -654,10 +636,10 @@ type_reconstructor::_walk_RECORD_TYPE_post (tree t) if (is_modified) layout_type (copy); tree _t = tree_to_tree (t); - _reorg_map[t] = is_modified ? copy : _t; + _reorg_map2.put(t, is_modified ? copy : _t); } - tree record = _reorg_map[t]; + tree record = *_reorg_map2.get(t); for (tree field = TYPE_FIELDS (record); field; field = DECL_CHAIN (field)) { relayout_decl (field); @@ -667,7 +649,7 @@ type_reconstructor::_walk_RECORD_TYPE_post (tree t) void type_reconstructor::_walk_field_pre (tree t) { - for_reference.push (t); + for_reference2.safe_push (t); // We don't know if we will rewrite the field // that we are working on. So proactively, let's make // a copy. @@ -677,49 +659,51 @@ type_reconstructor::_walk_field_pre (tree t) TREE_TYPE (copy) = type_copy; // To communicate this field to the other methods, // let's put it in the "in_progress" stack. - in_progress.push (copy); + in_progress2.safe_push (copy); } void type_reconstructor::_walk_field_post (tree t) { - tree t2 = for_reference.top (); + tree t2 = for_reference2.last (); gcc_assert (t2 == t); - for_reference.pop (); + for_reference2.pop (); // Let's get the copy we were working on. - tree copy = in_progress.top (); + tree copy = in_progress2.last (); // Let's put the stack in the same position... - in_progress.pop (); + in_progress2.pop (); // What record does this field belongs to? - tree record = for_reference.top (); + tree record = for_reference2.last (); - field_offsets_t field_offsets = _records[record]; + field_offsets2_t **field_offsets_ptr = _records2.get(record); + if (!field_offsets_ptr) return; + field_offsets2_t *field_offsets = *field_offsets_ptr; // What's the field offset? unsigned f_byte_offset = tree_to_uhwi (DECL_FIELD_OFFSET (t)); unsigned f_bit_offset = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (t)); unsigned f_offset = 8 * f_byte_offset + f_bit_offset; const bool can_field_be_deleted - = field_offsets.find (f_offset) != field_offsets.end (); + = field_offsets->contains (f_offset); if (can_field_be_deleted) mark_all_pointing_here_as_modified (); tree original_type = TREE_TYPE (t); const bool type_memoized = is_memoized (original_type); TREE_TYPE (copy) - = type_memoized ? _reorg_map[original_type] : TREE_TYPE (copy); + = type_memoized ? *_reorg_map2.get(original_type) : TREE_TYPE (copy); field_tuple_t tuple = std::make_pair (t, can_field_be_deleted ? NULL : copy); // Put the field into the vector - field_tuple_list_t &field_tuple_list = field_list_stack.top (); - field_tuple_list.push_back (tuple); - const bool already_has_field = _reorg_fields.find (t) != _reorg_fields.end (); + field_tuple_list2_t &field_tuple_list2 = field_list2_stack2.last (); + field_tuple_list2.safe_push (tuple); + const bool already_has_field = _reorg_fields2.get (t); if (already_has_field) return; - _reorg_fields[t] = std::make_pair (copy, can_field_be_deleted); + _reorg_fields2.put(t, std::make_pair (copy, can_field_be_deleted)); } // Relayout parameters @@ -755,11 +739,11 @@ expr_type_rewriter::_walk_FUNCTION_DECL_post (tree t) // Therefore it is awkward to do this in the expr-walker... // const bool is_interesting = is_interesting_type (ret_type); // Instead use the following map - const bool is_interesting = _map.find (ret_type) != _map.end (); + const bool is_interesting = _map2.get (ret_type); if (!is_interesting) return; - tree r_t = _map[ret_type]; + tree r_t = *_map2.get(ret_type); TREE_TYPE (fn_type) = r_t; } @@ -769,7 +753,7 @@ expr_type_rewriter::_walk_MEM_REF_post (tree e) { tree op0 = TREE_OPERAND (e, 0); tree t2 = TREE_TYPE (op0); - const bool in_map2 = _map.find (t2) != _map.end (); + const bool in_map2 = _map2.get(t2); log ("trying out substituting expression in component_Ref directly\n"); type_stringifier stringifier; @@ -778,7 +762,7 @@ expr_type_rewriter::_walk_MEM_REF_post (tree e) if (in_map2) { log ("success\n"); - tree r_t = _map[t2]; + tree r_t = *_map2.get(t2); tree _e = tree_to_tree (op0); TREE_TYPE (_e) = r_t; } @@ -794,7 +778,7 @@ expr_type_rewriter::_walk_MEM_REF_post (tree e) if (!already_rewritten) return; - tree old_type = _imap[t]; + tree old_type = *_imap2.get(t); assert_is_type (old_type, POINTER_TYPE); tree old_base_type = TREE_TYPE (old_type); tree old_type_size_tree = TYPE_SIZE_UNIT (old_base_type); @@ -823,12 +807,12 @@ expr_type_rewriter::_walk_MEM_REF_post (tree e) bool expr_type_rewriter::is_interesting_type (tree t) { - const bool in_imap = _imap.find (t) != _imap.end (); - bool interesting = in_imap; + const bool in_imap2 = _imap2.get(t); + bool interesting = in_imap2; if (!interesting) return false; - tree const_possibly_copy = _imap[t]; + tree const_possibly_copy = *_imap2.get(t); tree possibly_copy = tree_to_tree (const_possibly_copy); const bool is_copy = possibly_copy == t; interesting = !is_copy; @@ -870,7 +854,7 @@ expr_type_rewriter::handle_pointer_arithmetic_diff (gimple *s, tree op_0) tree reorg_type_size_tree = TYPE_SIZE_UNIT (inner_reorg_type); int reorg_type_size_int = tree_to_shwi (reorg_type_size_tree); - tree const_old_type = _imap[reorg_type]; + tree const_old_type = *_imap2.get(reorg_type); tree old_type = tree_to_tree (const_old_type); tree inner_old_type = TREE_TYPE (old_type); gcc_assert (old_type); @@ -985,7 +969,7 @@ expr_type_rewriter::handle_pointer_arithmetic_nonconstant (gimple *s, tree op_0, tree reorg_type_size_tree = TYPE_SIZE_UNIT (reorg_inner_type); int reorg_type_size_int = tree_to_shwi (reorg_type_size_tree); // That means that the old type is - tree const_old_type_tree = _imap[reorg_type_tree]; + tree const_old_type_tree = *_imap2.get(reorg_type_tree); tree old_type_tree = tree_to_tree (const_old_type_tree); tree old_inner_type = TREE_TYPE (old_type_tree); tree old_type_size_tree = TYPE_SIZE_UNIT (old_inner_type); @@ -1061,7 +1045,7 @@ expr_type_rewriter::handle_pointer_arithmetic_constants (gimple *s, tree p, return; tree reorg_type = possibly_reorged_type; // this is the type of the variable - tree original_type = _imap[reorg_type]; + tree original_type = *_imap2.get(reorg_type); // If we are here, that means that our type has the ".reorg" suffix // Let's add a sanity check bool has_suffix @@ -1110,11 +1094,11 @@ expr_type_rewriter::_walk_post (tree e) { gcc_assert (e); tree t = TREE_TYPE (e); - const bool in_map = _map.find (t) != _map.end (); + const bool in_map = _map2.get(t); if (!in_map) return; - tree r_t = _map[t]; + tree r_t = *_map2.get(t); tree _e = tree_to_tree (e); TREE_TYPE (_e) = r_t; } @@ -1127,11 +1111,11 @@ expr_type_rewriter::_walk_COMPONENT_REF_post (tree e) tree f = TREE_OPERAND (e, 1); // So, what we need is a map between this field and the new field - const bool in_map = _map2.find (f) != _map2.end (); + const bool in_map = _fields2.get(f); if (!in_map) return; - std::pair p = _map2[f]; + std::pair p = *_fields2.get(f); tree n_f = p.first; bool is_deleted = p.second; tree _e = tree_to_tree (e); diff --git a/gcc/ipa-dfe.h b/gcc/ipa-dfe.h index 45a68f9039a..180fdc9e2db 100644 --- a/gcc/ipa-dfe.h +++ b/gcc/ipa-dfe.h @@ -29,21 +29,20 @@ class specific_type_collector : public type_walker { public: /* C is the set of types that are to be looked for. */ - specific_type_collector (std::set &c) : _collect_these_types (c) + specific_type_collector (hash_set *c2) : _collect_these_types2 (c2) {}; /* Get final result of all types which point to types in C. */ - std::set get_set (); + hash_set get_set2 (); private: - /* _collect_these_types holds the input. */ - const std::set &_collect_these_types; + hash_set *_collect_these_types2; /* Working set that holds final result. */ - std::set to_return; + hash_set to_return2; /* Sets which reach current subtype. */ - std::set path; + hash_set path2; /* Push or pop from path. */ virtual void _walk_ARRAY_TYPE_pre (tree t); @@ -59,68 +58,68 @@ private: }; /* Map old RECORD_TYPE -> new RECORD_TYPE. */ -typedef std::map reorg_record_map_t; +typedef hash_map reorg_record_map2_t; /* Map RECORD_TYPE -> (FIELD_DECL -> delete). */ -typedef std::map > reorg_field_map_t; +typedef hash_map > reorg_field_map2_t; /* Class used to create new types derived from types that have fields * that can be deleted. */ class type_reconstructor : public type_walker { public: - type_reconstructor (record_field_offset_map_t records, const char *suffix) - : _records (records), _suffix (suffix) - {}; + type_reconstructor (record_field_offset_map4_t &records, const char *suffix, reorg_record_map2_t &a, reorg_field_map2_t &b) + : _records2(records), _suffix (suffix), in_progress2(vNULL), for_reference2(vNULL), field_list2_stack2 (vNULL), _reorg_map2(a), _reorg_fields2(b) + { + modified_map2 = new is_modified_map2_t; + }; + ~type_reconstructor() + { + delete modified_map2; + } /* Whether a type has already been modified. */ virtual bool is_memoized (tree t); - // Final result for record map. - reorg_record_map_t get_map (); - - /* Final result for field map. */ - reorg_field_map_t get_field_map (); - /* Map RECORD_TYPE -> is_modified. */ - typedef std::map is_modified_map_t; + typedef hash_map is_modified_map2_t; protected: - const char *get_new_suffix (); + // Which records can be modified. + record_field_offset_map4_t& _records2; + + // The new suffix + const char *_suffix; // Modifications to the current sub_type - std::stack in_progress; + vec in_progress2; // Path to current subtype - std::stack for_reference; + vec for_reference2; // OLD FIELD -> new FIELD typedef std::pair field_tuple_t; // list of fields for new type - typedef std::vector field_tuple_list_t; + typedef vec field_tuple_list2_t; // to deal with nested structures we need to have a stack // of field_tuple_list_t - typedef std::stack field_tuple_list_stack_t; + typedef vec field_tuple_list2_stack2_t; - // Which records can be modified. - record_field_offset_map_t _records; - - // The new suffix - const char *_suffix; + const char *get_new_suffix (); // Which fields will be deleted. - field_tuple_list_stack_t field_list_stack; + field_tuple_list2_stack2_t field_list2_stack2; // old RECORD_TYPE -> new RECORD_TYPE - reorg_record_map_t _reorg_map; + reorg_record_map2_t &_reorg_map2; // old FIELD_DECL -> new FIELD_DECL - reorg_field_map_t _reorg_fields; + reorg_field_map2_t &_reorg_fields2; // old RECORD_TYPE -> is_modified - is_modified_map_t modified_map; + is_modified_map2_t *modified_map2; // Keep track of which types may need to be modified // defaults to not modified. @@ -156,20 +155,23 @@ private: class expr_type_rewriter : public expr_walker { public: - expr_type_rewriter (reorg_record_map_t map, reorg_field_map_t map2, + expr_type_rewriter (reorg_record_map2_t &map, reorg_field_map2_t &map2, bool can_delete) - : _delete (false), _can_delete (can_delete), _map (map), _map2 (map2) + : _delete (false), _can_delete (can_delete), _map2(map), _fields2(map2) { /* Create an inverse map new RECORD_TYPE -> old RECORD_TYPE. */ - for (reorg_record_map_t::iterator i = map.begin (), - e = map.end (); i != e; ++i) + for (auto i = map.begin (), e = map.end (); i != e; ++i) { - tree original = i->first; - tree modified = i->second; - _imap[modified] = original; + tree original = (*i).first; + tree modified = (*i).second; + _imap2.put (modified, original); } }; + ~expr_type_rewriter() + { + }; + // Handle pointer arithmetic with constants. void handle_pointer_arithmetic_constants (gimple *s, tree p, tree i); @@ -189,13 +191,14 @@ public: private: // Old RECORD_TYPE -> new RECORD_TYPE. - reorg_record_map_t _map; + reorg_record_map2_t& _map2; // Old FIELD_DECL -> new FIELD_DECL. - reorg_field_map_t _map2; + reorg_field_map2_t& _fields2; // New RECORD_TYPE -> old RECORD_TYPE. - std::map _imap; + hash_map _imap2; + void _walk_post (tree e); // Substitute types and create new offset. @@ -215,7 +218,7 @@ private: class gimple_type_rewriter : public gimple_walker { public: - gimple_type_rewriter (reorg_record_map_t map, reorg_field_map_t map2, + gimple_type_rewriter (reorg_record_map2_t &map, reorg_field_map2_t &map2, bool can_delete) : exprTypeRewriter (map, map2, can_delete) {}; @@ -237,21 +240,24 @@ private: }; // Get a set of all types pointing to types in RECORD_FIELD_OFFSET_MAP. -std::set -get_all_types_pointing_to (record_field_offset_map_t record_field_offset_map, - tpartitions_t casting); +void +get_all_types_pointing_to (record_field_offset_map4_t &record_field_offset_map, + tpartitions2_t casting, + hash_set &to_modify); -typedef std::pair reorg_maps_t; +typedef std::pair reorg_maps_t; // Compute the replacement types. reorg_maps_t -get_types_replacement (record_field_offset_map_t record_field_offset_map, - std::set to_modify); +get_types_replacement (record_field_offset_map4_t &record_field_offset_map, + hash_set &to_modify, + reorg_record_map2_t &, + reorg_field_map2_t &); // Substitute types. void -substitute_types_in_program (reorg_record_map_t map, - reorg_field_map_t field_map, bool _delete); +substitute_types_in_program (reorg_record_map2_t &map, + reorg_field_map2_t &field_map, bool _delete); tree get_new_identifier (tree type, const char *suffix); diff --git a/gcc/ipa-field-reorder.c b/gcc/ipa-field-reorder.c index 70d26d71324..e4c2ff4a62b 100644 --- a/gcc/ipa-field-reorder.c +++ b/gcc/ipa-field-reorder.c @@ -142,7 +142,7 @@ bitpos_of_field (const tree fdecl) class GimpleAccesserFieldReordering : public gimple_accessor { public: - GimpleAccesserFieldReordering () + GimpleAccesserFieldReordering (record_field_map4_t &map) : gimple_accessor (map) {}; private: @@ -170,9 +170,10 @@ private: class TypeReconstructorFieldReordering : public type_reconstructor { public: - TypeReconstructorFieldReordering (record_field_offset_map_t records, - const char *suffix) - : type_reconstructor (records, suffix) + TypeReconstructorFieldReordering (record_field_offset_map4_t &records, + const char *suffix, + reorg_record_map2_t &a, reorg_field_map2_t &b) + : type_reconstructor (records, suffix, a, b) {}; private: @@ -221,14 +222,14 @@ compare_FIELD_DECLs_TYPE_SIZE (tree _l, tree _r) void TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) { - tree t2 = for_reference.top (); + tree t2 = for_reference2.last (); gcc_assert (t2 == t); - for_reference.pop (); + for_reference2.pop (); - tree copy = in_progress.top (); - in_progress.pop (); - field_tuple_list_t field_tuple_list = field_list_stack.top (); - field_list_stack.pop (); + tree copy = in_progress2.last (); + in_progress2.pop (); + field_tuple_list2_t field_tuple_list2 = field_list2_stack2.last (); + field_list2_stack2.pop (); // So, here all the work has been done to make sure // that the fields produced a field_tuple_list_t @@ -237,10 +238,10 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) // So, now we want to do a couple of things. // First, collect all fields in a struct and make a copy of them bool is_modified = get_is_modified (t); - std::vector to_reorder; + vec to_reorder2 = vNULL; is_modified = true; - for (field_tuple_list_t::iterator i = field_tuple_list.begin (), - e = field_tuple_list.end (); + for (auto i = field_tuple_list2.begin (), + e = field_tuple_list2.end (); i != e; ++i) { field_tuple_t field_tuple = *i; @@ -255,7 +256,7 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) log ("we can reorder %s ? %s\n", type_stringifier::get_field_identifier (field_tuple.first).c_str (), !modified_field ? "true" : "false"); - to_reorder.push_back ( + to_reorder2.safe_push( (tree) copy_node (tree_to_tree (field_tuple.first))); } @@ -264,12 +265,12 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) tree prev_field = NULL; bool entered_loop = false; // Sort them - std::sort (to_reorder.begin (), to_reorder.end (), + std::sort (to_reorder2.begin (), to_reorder2.end (), compare_FIELD_DECLs_TYPE_SIZE); is_modified = false; - for (field_tuple_list_t::iterator i = field_tuple_list.begin (), - e = field_tuple_list.end (); + for (auto i = field_tuple_list2.begin (), + e = field_tuple_list2.end (); i != e; ++i) { field_tuple_t field_tuple = *i; @@ -290,8 +291,8 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) gcc_assert (!modified_field && is_modified); // Create new TYPE_FIELDS with the order we want - for (std::vector::iterator j = to_reorder.begin (), - f = to_reorder.end (); j != f; ++j) + for (auto j = to_reorder2.begin (), + f = to_reorder2.end (); j != f; ++j) { entered_loop = true; tree current_field_inner = *j; @@ -313,8 +314,8 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) } // Modify _reorg_fields map - for (std::vector::iterator i = to_reorder.begin (), - e = to_reorder.end (); i != e; ++i) + for (auto i = to_reorder2.begin (), + e = to_reorder2.end (); i != e; ++i) { tree to_find = *i; unsigned to_find_i = bitpos_of_field (tree_to_tree (to_find)); @@ -329,8 +330,7 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) unsigned haystack_i = bitpos_of_field (field); if (haystack_i == to_find_i) { - _reorg_fields[field] - = std::make_pair (tree_to_tree (to_find), false); + _reorg_fields2.put(field, std::make_pair (tree_to_tree (to_find), false)); log ("substituting %s for %s\n", to_find_str, haystack); } } @@ -342,7 +342,7 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) if (!is_main_variant) { tree main = TYPE_MAIN_VARIANT (t); - tree main_reorg = _reorg_map[main]; + tree main_reorg = *_reorg_map2.get(main); tree copy_variant = build_distinct_type_copy (main_reorg); TYPE_NAME (copy_variant) = get_new_identifier (copy, this->get_new_suffix ()); @@ -350,7 +350,7 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) TYPE_ALIAS_SET (copy_variant) = -1; layout_type (copy_variant); TYPE_MAIN_VARIANT (copy_variant) = main_reorg; - _reorg_map[t] = copy_variant; + _reorg_map2.put (t, copy_variant); } else { @@ -366,10 +366,10 @@ TypeReconstructorFieldReordering::_walk_RECORD_TYPE_post (tree t) if (is_modified) layout_type (copy); tree _t = tree_to_tree (t); - _reorg_map[t] = is_modified ? copy : _t; + _reorg_map2.put (t, is_modified ? copy : _t); } - tree record = _reorg_map[t]; + tree record = *_reorg_map2.get(t); for (tree field = TYPE_FIELDS (record); field; field = DECL_CHAIN (field)) { relayout_decl (field); @@ -461,8 +461,8 @@ GimpleAccesserFieldReordering::_walk_pre_gcond (gcond *s) static unsigned int lto_fr_execute (); -static record_field_map_t -find_fields_accessed (); +static void +find_fields_accessed (record_field_map4_t &f); namespace { const pass_data pass_data_ipa_field_reorder = { @@ -495,15 +495,10 @@ public: }; } // namespace -record_field_map_t static find_fields_accessed () +static void find_fields_accessed (record_field_map4_t &r) { - GimpleAccesserFieldReordering accesser; + GimpleAccesserFieldReordering accesser (r); accesser.walk (); - - // This record_field_map holds - // RECORD_TYPE -> (FIELD_DECL -> how field is accessed) - record_field_map_t record_field_map = accesser.get_map (); - return record_field_map; } /* record_field_offset_map holds information on which FIELD_DECLs might be @@ -520,14 +515,15 @@ record_field_map_t static find_fields_accessed () * The second maps old FIELD_DECLs trees to the new FIELD_DECLs. */ reorg_maps_t -get_reordered_field_maps (record_field_offset_map_t record_field_offset_map, - std::set to_modify) +get_reordered_field_maps (record_field_offset_map4_t &record_field_offset_map2, + hash_set & to_modify, + reorg_record_map2_t &map2, reorg_field_map2_t &field_map2) { type_stringifier stringifier; - TypeReconstructorFieldReordering reconstructor (record_field_offset_map, - "reorder"); - for (std::set::const_iterator i = to_modify.begin (), + TypeReconstructorFieldReordering reconstructor (record_field_offset_map2, + "reorder", map2, field_map2); + for (hash_set::iterator i = to_modify.begin (), e = to_modify.end (); i != e; ++i) { @@ -535,7 +531,7 @@ get_reordered_field_maps (record_field_offset_map_t record_field_offset_map, reconstructor.walk (TYPE_MAIN_VARIANT (record)); } - for (std::set::const_iterator i = to_modify.begin (), + for (hash_set::iterator i = to_modify.begin (), e = to_modify.end (); i != e; ++i) { @@ -543,21 +539,20 @@ get_reordered_field_maps (record_field_offset_map_t record_field_offset_map, reconstructor.walk (record); } - reorg_record_map_t map = reconstructor.get_map (); - reorg_field_map_t field_map = reconstructor.get_field_map (); + typedef hash_map reorg_record_map2_t; // Here, we are just making sure that we are not doing anything too crazy. // Also, we found some types for which TYPE_CACHED_VALUES_P is not being // rewritten. This is probably indicative of a bug in // TypeReconstructorFieldReordering. - for (std::map::const_iterator i = map.begin (), - e = map.end (); + for (reorg_record_map2_t::iterator i = map2.begin (), + e = map2.end (); i != e; ++i) { - tree o_record = i->first; + tree o_record = (*i).first; std::string o_name = stringifier.stringify (o_record); log ("original: %s\n", o_name.c_str ()); - tree r_record = i->second; + tree r_record = (*i).second; std::string r_name = r_record ? stringifier.stringify (r_record) : std::string (""); log ("modified: %s\n", r_name.c_str ()); @@ -569,16 +564,17 @@ get_reordered_field_maps (record_field_offset_map_t record_field_offset_map, TYPE_CACHED_VALUES_P (_o_record) = false; TYPE_CACHED_VALUES_P (m_record) = false; - bool in_map = map.find (m_record) != map.end (); + bool in_map = map2.get (m_record); if (!in_map) continue; - tree mm_record = map[m_record]; + tree mm_record = *map2.get(m_record); // Info: I think this is no longer needed... // Please verify TYPE_MAIN_VARIANT (r_record) = mm_record; } - return std::make_pair (map, field_map); + // TODO: change this to return the GCC types... + return std::make_pair (&map2, &field_map2); } /* Top level function. */ @@ -588,27 +584,31 @@ lto_fr_execute () log ("here in field reordering \n"); // Analysis. detected_incompatible_syntax = false; - std::map whitelisted = get_whitelisted_nodes(); - tpartitions_t escaping_nonescaping_sets - = partition_types_into_escaping_nonescaping (whitelisted); - record_field_map_t record_field_map = find_fields_accessed (); - record_field_offset_map_t record_field_offset_map - = obtain_nonescaping_unaccessed_fields (escaping_nonescaping_sets, - record_field_map, 0); - - if (detected_incompatible_syntax || record_field_offset_map.empty ()) + hash_map *whitelisted2 = get_whitelisted_nodes2(); + tpartitions2_t escaping_nonescaping_sets; + partition_types_into_escaping_nonescaping (escaping_nonescaping_sets, whitelisted2); + record_field_map4_t record_field_map; + find_fields_accessed (record_field_map); + record_field_offset_map4_t record_field_offset_map; + obtain_nonescaping_unaccessed_fields (escaping_nonescaping_sets, + record_field_map, 0, record_field_offset_map); + + if (detected_incompatible_syntax || record_field_offset_map.is_empty ()) return 0; // Prepare for transformation. - std::set to_modify - = get_all_types_pointing_to (record_field_offset_map, - escaping_nonescaping_sets); + hash_set to_modify; + get_all_types_pointing_to (record_field_offset_map, + escaping_nonescaping_sets, to_modify); + reorg_record_map2_t a; + reorg_field_map2_t b; reorg_maps_t replacements - = get_reordered_field_maps (record_field_offset_map, to_modify); - reorg_record_map_t map = replacements.first; - reorg_field_map_t field_map = replacements.second; - substitute_types_in_program (map, field_map, false); + = get_reordered_field_maps (record_field_offset_map, to_modify, a, b); + reorg_record_map2_t *map = replacements.first; + reorg_field_map2_t *field_map = replacements.second; + gcc_assert(map && field_map); + substitute_types_in_program (*map, *field_map, false); gimple_walker walker; walker.walk (); diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c index 8ccb2991090..f4917a96b54 100644 --- a/gcc/ipa-type-escape-analysis.c +++ b/gcc/ipa-type-escape-analysis.c @@ -181,8 +181,8 @@ static unsigned int lto_dfe_execute (); // Partition types into reching record or non reaching record sets. -static tpartitions_t -partition_types_into_record_reaching_or_non_record_reaching (); +static void +partition_types_into_record_reaching_or_non_record_reaching (tpartitions2_t &p); // Perform dead field elimination. static void @@ -190,11 +190,11 @@ lto_dead_field_elimination (); // Fixed point calculating to determine escaping types. static void -fix_escaping_types_in_set (tpartitions_t &types); +fix_escaping_types_in_set (tpartitions2_t &types); // Find which fields are accessed. -static record_field_map_t -find_fields_accessed (); +static void +find_fields_accessed (record_field_map4_t &f); // TODO: // This was copy pasted from tree-ssa-structalias.c @@ -271,58 +271,54 @@ lto_dfe_execute () * call graph as ``safe'' or ``unsafe''. The color is propagated to the * callers of the functions until a fixed point is reached. */ -std::map -get_whitelisted_nodes () +hash_map* +get_whitelisted_nodes2 () { cgraph_node *node = NULL; - std::set nodes; - std::set leaf_nodes; - std::set leaf_nodes_decl; + hash_set nodes; + hash_set leaf_nodes; + hash_set leaf_nodes_decl; + FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) { - node->get_untransformed_body (); - nodes.insert(node); + node->get_untransformed_body(); + nodes.add(node); if (node->callees) continue; - leaf_nodes.insert (node); - leaf_nodes_decl.insert (node->decl); + leaf_nodes.add (node); + leaf_nodes_decl.add (node->decl); } - std::queue worklist; - for (std::set::iterator i = leaf_nodes.begin (), - e = leaf_nodes.end (); i != e; ++i) + vec worklist = vNULL; + for (hash_set::iterator i = leaf_nodes.begin(), e = leaf_nodes.end (); i != e; ++i) { if (dump_file) fprintf (dump_file, "is a leaf node %s\n", (*i)->name ()); - worklist.push (*i); + worklist.safe_push (*i); } - for (std::set::iterator i = nodes.begin (), + for (hash_set::iterator i = nodes.begin (), e = nodes.end (); i != e; ++i) { - worklist.push (*i); + worklist.safe_push (*i); } - std::map map; - while (!worklist.empty ()) + hash_map *map = new hash_map; + while (!worklist.is_empty ()) { if (detected_incompatible_syntax) return map; - cgraph_node *i = worklist.front (); - worklist.pop (); + cgraph_node *i = worklist[0]; + worklist.ordered_remove (0); if (dump_file) fprintf (dump_file, "analyzing %s %p\n", i->name (), (void*)i); - gimple_white_lister whitelister; + tpartitions2_t temp; + gimple_white_lister whitelister(temp); whitelister._walk_cnode (i); - bool no_external = whitelister.does_not_call_external_functions (i, map); - bool before_in_map = map.find (i->decl) != map.end (); + bool no_external = whitelister.does_not_call_external_functions2 (i, map); + bool before_in_map = map->get (i->decl); bool place_callers_in_worklist = !before_in_map; - if (!before_in_map) - { - map.insert(std::pair(i->decl, no_external)); - } else - { - map[i->decl] = no_external; - } - bool previous_value = map[i->decl]; + map->put(i->decl, no_external); + bool *previous_value_ptr = map->get(i->decl); + bool previous_value = *previous_value_ptr; place_callers_in_worklist |= previous_value != no_external; if (previous_value != no_external) { @@ -335,12 +331,11 @@ get_whitelisted_nodes () for (cgraph_edge *e = i->callers; place_callers_in_worklist && e; e = e->next_caller) { - worklist.push (e->caller); + worklist.safe_push (e->caller); } } return map; - } /* @@ -361,28 +356,32 @@ lto_dead_field_elimination () cnode->get_body(); } detected_incompatible_syntax = false; - std::map whitelisted = get_whitelisted_nodes (); - tpartitions_t escaping_nonescaping_sets - = partition_types_into_escaping_nonescaping (whitelisted); + hash_map *whitelisted2 = get_whitelisted_nodes2 (); + tpartitions2_t escaping_nonescaping_sets; + partition_types_into_escaping_nonescaping (escaping_nonescaping_sets, whitelisted2); if (detected_incompatible_syntax) return; - record_field_map_t record_field_map = find_fields_accessed (); + record_field_map4_t record_field_map; + find_fields_accessed (record_field_map); if (detected_incompatible_syntax) return; - record_field_offset_map_t record_field_offset_map - = obtain_nonescaping_unaccessed_fields (escaping_nonescaping_sets, - record_field_map, OPT_Wdfa); - if (detected_incompatible_syntax || record_field_offset_map.empty ()) + record_field_offset_map4_t record_field_offset_map; + obtain_nonescaping_unaccessed_fields (escaping_nonescaping_sets, + record_field_map, OPT_Wdfa, record_field_offset_map); + if (detected_incompatible_syntax || record_field_offset_map.is_empty ()) return; // Prepare for transformation. - std::set to_modify - = get_all_types_pointing_to (record_field_offset_map, - escaping_nonescaping_sets); + hash_set to_modify2; + get_all_types_pointing_to (record_field_offset_map, + escaping_nonescaping_sets, to_modify2); + reorg_record_map2_t a; + reorg_field_map2_t b; reorg_maps_t replacements - = get_types_replacement (record_field_offset_map, to_modify); - reorg_record_map_t map = replacements.first; - reorg_field_map_t field_map = replacements.second; + = get_types_replacement (record_field_offset_map, to_modify2, a, b); + reorg_record_map2_t *map = replacements.first; + reorg_field_map2_t *field_map = replacements.second; + gcc_assert(map && field_map); // Transformation. - substitute_types_in_program (map, field_map, true); + substitute_types_in_program (*map, *field_map, true); } /* Iterate all gimple bodies and collect trees @@ -391,48 +390,39 @@ lto_dead_field_elimination () * pointer, array, reference, union, field, etc...). * Let's call these trees record_reaching_trees. */ -static tpartitions_t -partition_types_into_record_reaching_or_non_record_reaching () +void +partition_types_into_record_reaching_or_non_record_reaching (tpartitions2_t &partitions) { - gimple_type_collector collector; + gimple_type_collector collector(partitions); collector.walk (); - tpartitions_t partitions = collector.get_record_reaching_trees (); - return partitions; } /* Iterate over all gimple bodies and find out * which types are escaping AND are being casted. */ -tpartitions_t -partition_types_into_escaping_nonescaping (std::map &whitelisted) +void +partition_types_into_escaping_nonescaping (tpartitions2_t &partitions, hash_map *whitelisted2) { - tpartitions_t partitions - = partition_types_into_record_reaching_or_non_record_reaching (); - if (detected_incompatible_syntax) return partitions; - gimple_caster caster (partitions, whitelisted); + partition_types_into_record_reaching_or_non_record_reaching (partitions); + if (detected_incompatible_syntax) return; + gimple_caster caster (partitions, whitelisted2); caster.walk (); caster.print_reasons (); - partitions = caster.get_sets (); + caster.fix_sets (); // Unify results from different trees representing the same type // until a fixed point is reached. fix_escaping_types_in_set (partitions); - return partitions; } /* Iterate over all gimple bodies and find out * which fields are accessed for all RECORD_TYPE * types. */ -record_field_map_t static find_fields_accessed () +static void find_fields_accessed (record_field_map4_t &record_field_map) { - gimple_accessor accesser; + gimple_accessor accesser (record_field_map) ; accesser.walk (); - - // This record_field_map holds - // RECORD_TYPE -> (FIELD_DECL -> how field is accessed) - record_field_map_t record_field_map = accesser.get_map (); - return record_field_map; } /* Find equivalent RECORD_TYPE trees to tree r_i. @@ -443,22 +433,21 @@ record_field_map_t static find_fields_accessed () * and it is a tree for which this method is going to find the rest of * equivalent trees found in record_field_map. */ -static std::vector -find_equivalent_trees (tree r_i, record_field_map_t record_field_map, - tpartitions_t casting) +static vec* +find_equivalent_trees (tree r_i, record_field_map4_t &record_field_map, + tpartitions2_t casting) { type_incomplete_equality equality; - std::vector equivalence; + vec *equivalence = new vec (); bool is_rin_record = casting.in_points_to_record (r_i); if (!is_rin_record) return equivalence; - for (std::map::const_iterator j - = record_field_map.begin (), + for (auto j = record_field_map.begin (), f = record_field_map.end (); - j != f; j++) + j != f; ++j) { - tree r_j = j->first; + tree r_j = (*j).first; const bool pointer_equal = r_i == r_j; if (pointer_equal) continue; @@ -472,7 +461,7 @@ find_equivalent_trees (tree r_i, record_field_map_t record_field_map, if (!are_equal) continue; - equivalence.push_back (r_j); + equivalence->safe_push(r_j); } return equivalence; } @@ -484,8 +473,9 @@ find_equivalent_trees (tree r_i, record_field_map_t record_field_map, */ static void add_offset_only_if_read (tree field, unsigned access, - field_offsets_t &field_offset) + field_offsets2_t &field_offset2) { + gcc_assert(field); assert_is_type (field, FIELD_DECL); const bool is_read = access & Read; if (!is_read) @@ -493,7 +483,7 @@ add_offset_only_if_read (tree field, unsigned access, tree _field = tree_to_tree (field); unsigned f_offset = bitpos_of_field (_field); - field_offset.insert (f_offset); + field_offset2.add (f_offset); } /* @@ -504,14 +494,12 @@ add_offset_only_if_read (tree field, unsigned access, * tree (RECORD_TYPE) -> bitpos_of_field for read fields). */ static void -keep_only_read_fields_from_field_map (field_access_map_t &field_map, - field_offsets_t &field_offset) +keep_only_read_fields_from_field_map (field_access_map2_t &field_map, + field_offsets2_t &field_offset2) { - for (std::map::iterator j = field_map.begin (), - f = field_map.end (); - j != f; ++j) + for (auto j = field_map.begin (), f = field_map.end (); j != f; ++j) { - add_offset_only_if_read (j->first, j->second, field_offset); + add_offset_only_if_read ((*j).first, (*j).second, field_offset2); } } @@ -521,16 +509,16 @@ keep_only_read_fields_from_field_map (field_access_map_t &field_map, */ static void keep_only_read_fields_from_equivalent_field_maps ( - std::vector equivalent, record_field_map_t &record_field_map, - field_offsets_t &field_offset) + vec *equivalent, record_field_map4_t &record_field_map, + field_offsets2_t &field_offset2) { - for (std::vector::iterator j = equivalent.begin (), - f = equivalent.end (); + for (auto j = equivalent->begin (), + f = equivalent->end (); j != f; j++) { tree r_j = *j; - field_access_map_t equivalent_field_map = record_field_map[r_j]; - keep_only_read_fields_from_field_map (equivalent_field_map, field_offset); + field_access_map2_t *equivalent_field_map = *record_field_map.get(r_j); + keep_only_read_fields_from_field_map (*equivalent_field_map, field_offset2); } } @@ -540,28 +528,27 @@ keep_only_read_fields_from_equivalent_field_maps ( */ static void erase_if_no_fields_can_be_deleted ( - record_field_offset_map_t &record_field_offset_map, - std::set &to_keep, std::set &to_erase) + record_field_offset_map4_t &record_field_offset_map, + hash_set &to_keep, hash_set &to_erase) { - for (std::map::iterator i + for (hash_map::iterator i = record_field_offset_map.begin (), e = record_field_offset_map.end (); i != e; ++i) { - tree record = i->first; - const bool keep = to_keep.find (record) != to_keep.end (); + tree record = (*i).first; + const bool keep = to_keep.contains (record); if (keep) continue; - to_erase.insert (record); + to_erase.add (record); } - for (std::set::iterator i = to_erase.begin (), - e = to_erase.end (); + for (auto i = to_erase.begin (), e = to_erase.end (); i != e; ++i) { tree record = *i; - record_field_offset_map.erase (record); + record_field_offset_map.remove (record); } } @@ -571,82 +558,84 @@ erase_if_no_fields_can_be_deleted ( */ static void mark_escaping_types_to_be_deleted ( - record_field_offset_map_t &record_field_offset_map, - std::set &to_erase, tpartitions_t casting) + record_field_offset_map4_t &record_field_offset_map, + hash_set &to_erase, tpartitions2_t casting) { - const tset_t &non_escaping = casting.non_escaping; - for (std::map::iterator i + tset2_t &non_escaping = casting.non_escaping; + for (hash_map::iterator i = record_field_offset_map.begin (), e = record_field_offset_map.end (); i != e; ++i) { - tree record = i->first; - const bool in_set = non_escaping.find (record) != non_escaping.end (); + tree record = (*i).first; + const bool in_set = non_escaping.contains (record); if (in_set) continue; - to_erase.insert (record); + to_erase.add (record); } } // Obtain nonescaping unaccessed fields -record_field_offset_map_t -obtain_nonescaping_unaccessed_fields (tpartitions_t casting, - record_field_map_t record_field_map, - int _warning) +void +obtain_nonescaping_unaccessed_fields (tpartitions2_t casting, + record_field_map4_t &record_field_map, + int _warning, + record_field_offset_map4_t &record_field_offset_map) { bool has_fields_that_can_be_deleted = false; - record_field_offset_map_t record_field_offset_map; - for (std::map::iterator i + for (hash_map::iterator i = record_field_map.begin (), e = record_field_map.end (); i != e; ++i) { - tree r_i = i->first; - std::vector equivalence + tree r_i = (*i).first; + vec* equivalence = find_equivalent_trees (r_i, record_field_map, casting); - field_offsets_t field_offset; - field_access_map_t original_field_map = record_field_map[r_i]; - keep_only_read_fields_from_field_map (original_field_map, field_offset); + field_offsets2_t *field_offset = new field_offsets2_t; + field_access_map2_t *original_field_map = (*i).second; + gcc_assert(original_field_map); + keep_only_read_fields_from_field_map (*original_field_map, *field_offset); keep_only_read_fields_from_equivalent_field_maps (equivalence, record_field_map, - field_offset); + *field_offset); // These map holds the following: // RECORD_TYPE -> unsigned (bit_pos_offset which has been read) - record_field_offset_map[r_i] = field_offset; + record_field_offset_map.put(r_i, field_offset); + delete equivalence; } // So now that we only have the FIELDS which are read, // we need to compute the complement... // Improve: This is tightly coupled, I need to decouple it... - std::set to_erase; - std::set to_keep; + hash_set to_erase; + hash_set to_keep; mark_escaping_types_to_be_deleted (record_field_offset_map, to_erase, casting); - for (std::map::iterator i + for (auto i = record_field_offset_map.begin (), e = record_field_offset_map.end (); i != e; ++i) { - tree record = i->first; - const bool will_be_erased = to_erase.find (record) != to_erase.end (); + tree record = (*i).first; + const bool will_be_erased = to_erase.contains (record); // No need to compute which fields can be deleted if type is escaping if (will_be_erased) continue; - field_offsets_t field_offset = i->second; + field_offsets2_t *field_offset = (*i).second; for (tree field = TYPE_FIELDS (record); field; field = DECL_CHAIN (field)) { unsigned f_offset = bitpos_of_field (field); - bool in_set2 = field_offset.find (f_offset) != field_offset.end (); + bool in_set2 = field_offset->contains(f_offset); if (in_set2) { - field_offset.erase (f_offset); + field_offset->remove (f_offset); continue; } - to_keep.insert (record); - field_offset.insert (f_offset); + to_keep.add (record); + field_offset->add (f_offset); has_fields_that_can_be_deleted = true; // NOTE: With anonymous fields this might be weird to print. log ("%s.%s may be deleted\n", @@ -659,20 +648,17 @@ obtain_nonescaping_unaccessed_fields (tpartitions_t casting, warning (_warning, "RECORD_TYPE %qE has dead field %qE in LTO.\n", record, field); } - record_field_offset_map[record] = field_offset; + record_field_offset_map.put(record, field_offset); } - // Improve: Make this more elegant. - if (!has_fields_that_can_be_deleted) - { - record_field_offset_map_t empty; - return empty; - } + if (!has_fields_that_can_be_deleted) { + record_field_offset_map.empty(); + return; + } erase_if_no_fields_can_be_deleted (record_field_offset_map, to_keep, to_erase); - return record_field_offset_map; } // Main interface to TypeWalker @@ -681,7 +667,7 @@ void type_walker::walk (tree t) { gcc_assert (t); - this->tset.clear (); + this->tset2.empty (); this->_walk (t); } @@ -707,11 +693,11 @@ type_walker::_walk (tree type) // of trees and therefore we need a way to // avoid loops in this graph. // Imrpove: Outline finding if it is recursive? - const bool is_recursing = tset.find (type) != tset.end (); + const bool is_recursing = tset2.contains (type); if (is_recursing) return; - tset.insert (type); + tset2.add (type); const enum tree_code code = TREE_CODE (type); switch (code) { @@ -778,7 +764,7 @@ type_walker::_walk (tree type) } break; } - tset.erase (type); + tset2.remove (type); } // This is used to walk over subtrees. @@ -1275,7 +1261,7 @@ void gimple_walker::walk () { _walk_globals (); - std::set fndecls; + hash_set fndecls2; cgraph_node *node = NULL; FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) { @@ -1283,7 +1269,7 @@ gimple_walker::walk () node->get_untransformed_body (); tree decl = node->decl; gcc_assert (decl); - const bool already_in_set = fndecls.find (decl) != fndecls.end (); + const bool already_in_set = fndecls2.contains (decl); // I think it is possible for different nodes to point to the same // declaration. if (already_in_set) @@ -1293,7 +1279,7 @@ gimple_walker::walk () dump_function_to_file (node->decl, dump_file, TDF_NONE); _walk_cnode (node); - fndecls.insert (decl); + fndecls2.add (decl); } } @@ -1636,7 +1622,7 @@ gimple_walker::_walk_gphi (__attribute__((unused)) gphi *g) void type_collector::collect (tree t) { - const bool in_set = ptrset.in_universe (t); + const bool in_set = ptrset2.in_universe (t); // Early memoization... if (in_set) @@ -1653,7 +1639,7 @@ type_collector::collect (tree t) // The boolean will be updated to show // whether a record is reachable from // the type. - gcc_assert (ptr.empty ()); + gcc_assert (ptr2.is_empty ()); walk (t); } @@ -1661,12 +1647,12 @@ type_collector::collect (tree t) void type_collector::_sanity_check () { - for (tset_t::iterator i = ptrset.points_to_record.begin (), - e = ptrset.points_to_record.end (); + for (auto i = ptrset2.points_to_record.begin (), + e = ptrset2.points_to_record.end (); i != e; ++i) { - for (tset_t::iterator j = ptrset.complement.begin (), - f = ptrset.complement.end (); + for (auto j = ptrset2.complement.begin (), + f = ptrset2.complement.end (); j != f; ++j) { tree type_ptr = *i; @@ -1692,18 +1678,18 @@ bool type_collector::is_memoized (tree t) { /* If we haven't seen it then no. */ - const bool in_set = ptrset.in_universe (t); + const bool in_set = ptrset2.in_universe (t); if (!in_set) return false; // If the memoized type points to a record // we must update all types that can refer // to memoized type. - const bool points_to_record = ptrset.in_points_to_record (t); - for (std::map::iterator i = ptr.begin (), - e = ptr.end (); i != e; ++i) + const bool points_to_record = ptrset2.in_points_to_record (t); + for (auto i = ptr2.begin (), + e = ptr2.end (); i != e; ++i) { - i->second |= points_to_record; + (*i).second |= points_to_record; } return true; } @@ -1711,7 +1697,7 @@ type_collector::is_memoized (tree t) void type_collector::_walk_VOID_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1723,7 +1709,7 @@ type_collector::_walk_VOID_TYPE_post (tree t) void type_collector::_walk_INTEGER_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1735,7 +1721,7 @@ type_collector::_walk_INTEGER_TYPE_post (tree t) void type_collector::_walk_REAL_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1747,7 +1733,7 @@ type_collector::_walk_REAL_TYPE_post (tree t) void type_collector::_walk_FIXED_POINT_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1759,7 +1745,7 @@ type_collector::_walk_FIXED_POINT_TYPE_post (tree t) void type_collector::_walk_COMPLEX_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1771,7 +1757,7 @@ type_collector::_walk_COMPLEX_TYPE_post (tree t) void type_collector::_walk_ENUMERAL_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1783,7 +1769,7 @@ type_collector::_walk_ENUMERAL_TYPE_post (tree t) void type_collector::_walk_BOOLEAN_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1796,15 +1782,15 @@ void type_collector::_collect_simple (tree t) { // Insert into persistent set. - ptrset.insert (t, ptr[t]); + ptrset2.insert (t, *ptr2.get(t)); // erase from current working set. - ptr.erase (t); + ptr2.remove (t); } void type_collector::_walk_ARRAY_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1816,7 +1802,7 @@ type_collector::_walk_ARRAY_TYPE_post (tree t) void type_collector::_walk_POINTER_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1828,7 +1814,7 @@ type_collector::_walk_POINTER_TYPE_post (tree t) void type_collector::_walk_REFERENCE_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1841,10 +1827,10 @@ void type_collector::_walk_RECORD_TYPE_post (tree t) { // All in ptr point to record - for (std::map::iterator i = ptr.begin (), - e = ptr.end (); i != e; ++i) + for (auto i = ptr2.begin (), + e = ptr2.end (); i != e; ++i) { - i->second = true; + (*i).second = true; } _collect_simple (t); @@ -1853,13 +1839,13 @@ type_collector::_walk_RECORD_TYPE_post (tree t) void type_collector::_walk_RECORD_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void type_collector::_walk_UNION_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1877,7 +1863,7 @@ type_collector::_walk_FUNCTION_TYPE_post (tree t) void type_collector::_walk_FUNCTION_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } void @@ -1889,7 +1875,7 @@ type_collector::_walk_METHOD_TYPE_post (tree t) void type_collector::_walk_METHOD_TYPE_pre (tree t) { - ptr[t] = false; + ptr2.put(t, false); } inline void @@ -1902,14 +1888,14 @@ expr_collector::_walk_pre (tree e) if (RECORD_TYPE != TREE_CODE (t)) return; - if (_type_collector.ptrset.records.empty ()) { - _type_collector.ptrset.records.insert (TYPE_MAIN_VARIANT (t)); + if (_type_collector.ptrset2.records.is_empty ()) { + _type_collector.ptrset2.records.add (TYPE_MAIN_VARIANT (t)); return; } - for (std::set::iterator - i = _type_collector.ptrset.records.begin (), - e = _type_collector.ptrset.records.end (); i != e; ++i) + for (auto + i = _type_collector.ptrset2.records.begin (), + e = _type_collector.ptrset2.records.end (); i != e; ++i) { tree r = *i; type_incomplete_equality structuralEquality; @@ -1917,7 +1903,7 @@ expr_collector::_walk_pre (tree e) if (is_same) continue; type_stringifier stringifier; - _type_collector.ptrset.records.insert (TYPE_MAIN_VARIANT (t)); + _type_collector.ptrset2.records.add (TYPE_MAIN_VARIANT (t)); } } @@ -2024,7 +2010,7 @@ gimple_type_collector::_walk_pre_gdebug (gdebug *s) void gimple_type_collector::print_collected () { - tpartitions_t sets = get_record_reaching_trees (); + tpartitions2_t sets = get_record_reaching_trees (); // TODO: I think previously we were printing info here for tests } @@ -2047,13 +2033,14 @@ type_escaper::is_memoized (__attribute__ ((unused)) tree t) return false; } -tpartitions_t -type_escaper::get_sets () +void +type_escaper::fix_sets () { place_escaping_types_in_set (); - return _ptrset; + //return _ptrset2; } + /* From a map of TREE -> BOOL, the key represents a tree type * and the value represents whether the tree escapes. * Partition this map into sets. @@ -2062,20 +2049,20 @@ void type_escaper::place_escaping_types_in_set () { type_stringifier stringifier; - for (typemap::iterator i = calc.begin (), e = calc.end (); i != e; ++i) + for (auto i = calc2.begin (), e = calc2.end (); i != e; ++i) { - tree type = i->first; + tree type = (*i).first; // We should only track interesting types // Types which are not in points_to_record are the ones // that are pointed to by records. // I think it is possible to prune them ahead of time... - if (!_ptrset.in_points_to_record (type)) + if (!_ptrset2.in_points_to_record (type)) continue; - const Reason reason = i->second; - reason.is_escaping () ? _ptrset.escaping.insert (type) - : _ptrset.non_escaping.insert (type); + const Reason reason = (*i).second; + reason.is_escaping () ? _ptrset2.escaping.add (type) + : _ptrset2.non_escaping.add (type); } } @@ -2099,7 +2086,7 @@ void type_escaper::_update (tree t) { gcc_assert (t); - const bool already_in_typemap = calc.find (t) != calc.end (); + const bool already_in_typemap = calc2.get (t); // Do we have to invalidate all types which point to a volatile type? // Or do we have to invalidate all types pointed to by a volatile type? // Or do we only invalidate all types which are volatile. @@ -2109,7 +2096,9 @@ type_escaper::_update (tree t) _is_volatile.type_is_volatile = is_volatile; Reason _inner = _reason | _is_volatile; // always OR - already_in_typemap ? calc[t] |= _inner : calc[t] = _inner; + Reason temp; + temp = already_in_typemap ? *calc2.get(t) | _inner : _inner; + calc2.put(t, temp); } void @@ -2209,20 +2198,20 @@ void type_escaper::print_reasons () { type_stringifier stringifier; - for (typemap::iterator i = calc.begin (), e = calc.end (); i != e; ++i) + for (auto i = calc2.begin (), e = calc2.end (); i != e; ++i) { - tree t = i->first; + tree t = (*i).first; std::string name = stringifier.stringify (t); - Reason r = i->second; + Reason r = (*i).second; log ("%s reason: ", name.c_str ()); r.print (); } } -tpartitions_t -expr_escaper::get_sets () +void +expr_escaper::fix_sets () { - return _type_escaper.get_sets (); + _type_escaper.fix_sets (); } void @@ -2244,7 +2233,7 @@ expr_escaper::update (tree t, Reason r) void expr_escaper::_walk_pre (tree e) { - _stack.push (e); + _stack2.safe_push (e); tree t = TREE_TYPE (e); gcc_assert (t); @@ -2254,7 +2243,7 @@ expr_escaper::_walk_pre (tree e) void expr_escaper::_walk_post (__attribute__ ((unused)) tree e) { - _stack.pop (); + _stack2.pop (); } /* Capture casting on LHS. */ @@ -2264,16 +2253,16 @@ expr_escaper::_walk_SSA_NAME_pre (tree e) tree ssa_type = TREE_TYPE (e); - if (_stack.size () < 4) + if (_stack2.length () < 4) return; - tree this_expr = _stack.top (); - _stack.pop (); - tree twice = _stack.top (); - _stack.pop (); - tree prev_expr = _stack.top (); - _stack.push (twice); - _stack.push (this_expr); + tree this_expr = _stack2.last (); + _stack2.pop (); + tree twice = _stack2.last (); + _stack2.pop (); + tree prev_expr = _stack2.last (); + _stack2.safe_push (twice); + _stack2.safe_push (this_expr); if (TREE_CODE (prev_expr) != MEM_REF) return; @@ -2287,8 +2276,8 @@ expr_escaper::_walk_SSA_NAME_pre (tree e) if (TREE_CODE (TREE_TYPE (mref_type)) == INTEGER_TYPE) return; - bool in_map = curr_node && _whitelisted.find (curr_node->decl) != _whitelisted.end (); - bool whitelisted = in_map && _whitelisted[curr_node->decl]; + bool in_map = curr_node && _whitelisted2->get (curr_node->decl); + bool whitelisted = in_map && *_whitelisted2->get (curr_node->decl); if (whitelisted) return; if (dump_file) print_generic_stmt(dump_file, e); @@ -2321,11 +2310,11 @@ expr_escaper::_walk_CONSTRUCTOR_pre (tree e) _type_escaper.update (t, _r); } -tpartitions_t -gimple_escaper::get_sets () +void +gimple_escaper::fix_sets () { _expr_escaper.curr_node = NULL; - return _expr_escaper.get_sets (); + return _expr_escaper.fix_sets (); } void @@ -2349,7 +2338,8 @@ gimple_escaper::_init () tree decl = cnode->decl; gcc_assert (decl); - undefined.insert (decl); + //undefined.insert (decl); + undefined2.add (decl); } FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode) @@ -2358,7 +2348,8 @@ gimple_escaper::_init () cnode->get_untransformed_body (); tree decl = cnode->decl; gcc_assert (decl); - undefined.erase (decl); + //undefined.erase (decl); + undefined2.remove (decl); } } @@ -2548,7 +2539,7 @@ gimple_escaper::_walk_pre_gcall (gcall *s) type_stringifier stringifier; const bool _is_function_escaping = node ? is_function_escaping (node) : is_function_escaping (fn); - const bool is_undefined = undefined.find (fn) != undefined.end (); + const bool is_undefined = undefined2.contains (fn); log ("is undefined %s\n", is_undefined ? "t" : "f"); const bool _is_escaping = is_undefined || _is_function_escaping; @@ -2626,8 +2617,8 @@ gimple_caster::_walk_pre_gassign (gassign *s) log ("is_casted %s = %s\n", stringifier.stringify(t_rhs).c_str(), is_cast ? "T" : "F"); log ("is_casted %s = %s\n", stringifier.stringify(t_lhs).c_str(), is_cast ? "T" : "F"); reason.type_is_casted = is_cast; - bool in_map = _whitelisted.find (currently_walking->decl) != _whitelisted.end (); - bool whitelisted = in_map && _whitelisted[currently_walking->decl]; + bool in_map = _whitelisted2->get (currently_walking->decl); + bool whitelisted = in_map && *_whitelisted2->get(currently_walking->decl); if (whitelisted) goto escaper_label; _expr_escaper.curr_node = currently_walking; _expr_escaper._type_escaper.update (TREE_TYPE (lhs), reason); @@ -2656,9 +2647,9 @@ gimple_caster::_walk_pre_gcall (gcall *s) return; tree f_t = TREE_TYPE (fn); - if (_whitelisted.find(fn) != _whitelisted.end() && _whitelisted[fn]) return; - bool in_map = _whitelisted.find(currently_walking->decl) != _whitelisted.end(); - bool whitelisted = in_map && _whitelisted[currently_walking->decl]; + if (_whitelisted2->get(fn) && *_whitelisted2->get(fn)) return; + bool in_map = _whitelisted2->get (currently_walking->decl); + bool whitelisted = in_map && *_whitelisted2->get(currently_walking->decl); if (whitelisted) return; if (!currently_walking->callers) return; @@ -2703,10 +2694,34 @@ gimple_caster::_walk_pre_gcall (gcall *s) _expr_escaper.update (lhs, ret_reason); } +bool +type_accessor::is_in_record_field_map(tree t) +{ + return _map4.get (t); +} + +field_access_map2_t* +type_accessor::get_from_record_field_map(tree t) +{ + gcc_assert (_map4.get (t)); + field_access_map2_t *value = *_map4.get(t); + return value; +} + +void +type_accessor::put_in_record_field_map(tree t, field_access_map2_t* f) +{ + if (_map4.get (t) && (*_map4.get (t) != f)) + { + delete *(_map4.get(t)); + } + _map4.put(t, f); +} + bool type_accessor::is_memoized (tree t) { - return memoized_map.find (t) != memoized_map.end (); + return memoized_map2.contains (t); } /* Add all fields in struct to memoized map. */ @@ -2714,7 +2729,7 @@ void type_accessor::_walk_RECORD_TYPE_pre (tree t) { add_all_fields_in_struct (t); - memoized_map.insert (t); + memoized_map2.add (t); } /* Initialize all fields as neither read nor written. */ @@ -2726,27 +2741,21 @@ type_accessor::add_all_fields_in_struct (tree t) if (!is_record) return; - const bool record_already_in_map = _map.find (t) != _map.end (); - field_access_map_t field_map; - field_map = record_already_in_map ? _map[t] : field_map; + const bool record_already_in_map = is_in_record_field_map(t); + field_access_map2_t *field_map; + field_map = record_already_in_map ? get_from_record_field_map(t) : new field_access_map2_t; // Let's add all fields to the field map as empty. for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { const bool field_already_in_map_2 - = field_map.find (field) != field_map.end (); + = field_map->get (field); if (field_already_in_map_2) continue; - field_map[field] = Empty; + field_map->put(field, Empty); } - _map[t] = field_map; -} - -record_field_map_t -expr_accessor::get_map () -{ - return record_field_map; + put_in_record_field_map(t, field_map); } void @@ -2758,7 +2767,7 @@ expr_accessor::add_all_fields_in_struct (tree t) void expr_accessor::_walk_pre (tree e) { - _stack.push (e); + _stack2.safe_push (e); tree t = TREE_TYPE (e); add_all_fields_in_struct (t); } @@ -2766,7 +2775,7 @@ expr_accessor::_walk_pre (tree e) void expr_accessor::_walk_post (__attribute__ ((unused)) tree e) { - _stack.pop (); + _stack2.pop (); } void @@ -2792,19 +2801,19 @@ void expr_accessor::_walk_ADDR_EXPR_pre (__attribute__ ((unused)) tree e) { log ("expr accessor mem ref\n"); - log ("stack size = %d\n", _stack.size ()); + log ("stack size = %d\n", _stack2.length ()); - if (_stack.size () < 4) + if (_stack2.length () < 4) return; // TODO: Fix error with double pushing - tree addr_expr = _stack.top (); - _stack.pop (); - tree twice = _stack.top (); - _stack.pop (); - tree prev_expr = _stack.top (); - _stack.push (addr_expr); - _stack.push (twice); + tree addr_expr = _stack2.last (); + _stack2.pop (); + tree twice = _stack2.last (); + _stack2.pop (); + tree prev_expr = _stack2.last (); + _stack2.safe_push (addr_expr); + _stack2.safe_push (twice); log ("prev_expr code = %s\n", get_tree_code_name (TREE_CODE (prev_expr))); if (TREE_CODE (prev_expr) != MEM_REF) return; @@ -2830,9 +2839,9 @@ expr_accessor::_walk_ADDR_EXPR_pre (__attribute__ ((unused)) tree e) unsigned offset_int = tree_to_uhwi (offset) % type_size_int; // We need to get the field that corresponds to the offset_int const bool record_already_in_map - = record_field_map.find (addr_expr_t) != record_field_map.end (); - field_access_map_t field_map; - field_map = record_already_in_map ? record_field_map[addr_expr_t] : field_map; + = _type_accessor.is_in_record_field_map (addr_expr_t); + field_access_map2_t *field_map; + field_map = record_already_in_map ? _type_accessor.get_from_record_field_map(addr_expr_t) : new field_access_map2_t; // UNSAFE! But it is necesseary for testing... // Unless there is someone who is smarter that finds another way to test this. @@ -2855,13 +2864,13 @@ expr_accessor::_walk_ADDR_EXPR_pre (__attribute__ ((unused)) tree e) // Otherwise, this pointer arithmetic is invalid... // After the transformation const bool field_already_in_map - = field_map.find (field) != field_map.end (); - unsigned prev_access = field_already_in_map ? field_map[field] : Empty; + = field_map->get (field); + unsigned prev_access = field_already_in_map ? *field_map->get(field) : Empty; prev_access |= Read; - field_map[field] = prev_access; + field_map->put(field, prev_access); add_all_fields_in_struct (addr_expr_t); - record_field_map[addr_expr_t] = field_map; + _type_accessor.put_in_record_field_map(addr_expr_t, field_map); if (f_offset == offset_int) break; @@ -2893,27 +2902,27 @@ expr_accessor::_walk_COMPONENT_REF_pre (tree e) log ("%s.%s\n", type_stringifier::get_type_identifier (op0_t).c_str(), type_stringifier::get_field_identifier (op1).c_str()); const bool record_already_in_map - = record_field_map.find (op0_t) != record_field_map.end (); - field_access_map_t field_map; - field_map = record_already_in_map ? record_field_map[op0_t] : field_map; - const bool field_already_in_map = field_map.find (op1) != field_map.end (); - unsigned prev_access = field_already_in_map ? field_map[op1] : Empty; + = _type_accessor.is_in_record_field_map (op0_t); + field_access_map2_t *field_map; + field_map = record_already_in_map ? _type_accessor.get_from_record_field_map(op0_t) : new field_access_map2_t; + const bool field_already_in_map = field_map->get(op1); + unsigned prev_access = field_already_in_map ? *field_map->get(op1) : Empty; prev_access |= _access; - field_map[op1] = prev_access; + field_map->put(op1, prev_access); add_all_fields_in_struct (op0_t); - record_field_map[op0_t] = field_map; + _type_accessor.put_in_record_field_map(op0_t, field_map); - if (_stack.size () < 4) + if (_stack2.length () < 4) return; - tree this_expr = _stack.top (); - _stack.pop (); - tree twice = _stack.top (); - _stack.pop (); - tree prev_expr = _stack.top (); - _stack.push (twice); - _stack.push (this_expr); + tree this_expr = _stack2.last (); + _stack2.pop (); + tree twice = _stack2.last (); + _stack2.pop (); + tree prev_expr = _stack2.last (); + _stack2.safe_push (twice); + _stack2.safe_push (this_expr); if (TREE_CODE (prev_expr) != ADDR_EXPR) return; @@ -2936,13 +2945,13 @@ expr_accessor::_walk_COMPONENT_REF_pre (tree e) { log ("ever inside?\n"); const bool field_already_in_map - = field_map.find (field) != field_map.end (); - unsigned prev_access = field_already_in_map ? field_map[field] : Empty; + = field_map->get(field); + unsigned prev_access = field_already_in_map ? *field_map->get(field) : Empty; prev_access |= Read; - field_map[field] = prev_access; + field_map->put(field, prev_access); add_all_fields_in_struct (t); - record_field_map[t] = field_map; + _type_accessor.put_in_record_field_map(t, field_map); } } @@ -2950,9 +2959,10 @@ expr_accessor::_walk_COMPONENT_REF_pre (tree e) void expr_accessor::print_accesses () { + /* for (std::map::const_iterator i - = record_field_map.begin (), - e = record_field_map.end (); + = _type_accessor.get_map_ref().begin (), + e = _type_accessor.get_map_ref().end (); i != e; ++i) { tree record = i->first; @@ -2971,15 +2981,7 @@ expr_accessor::print_accesses () log ("%s.%s = 0x%04x\n", name_r.c_str (), name_f.c_str (), access); } } -} - -/* RECORD_TYPE -> (FIELD_DECL -> bitflag) - * bitflag specifies if field is read, written or neither. - */ -record_field_map_t -gimple_accessor::get_map () -{ - return _expr_accessor.get_map (); + */ } void @@ -3108,45 +3110,42 @@ Reason::operator|= (const Reason &other) /* Insert TYPE into a partition depending on IN_POINTS_TO_RECORD. */ void -type_partitions_s::insert (tree type, bool in_points_to_record) +type_partitions2_s::insert (tree type, bool in_points_to_record) { gcc_assert (type); - this->universe.insert (type); - in_points_to_record ? this->points_to_record.insert (type) - : this->complement.insert (type); - const bool in_points_to_set = this->in_points_to_record (type); + this->universe.add (type); + in_points_to_record ? this->points_to_record.add (type) + : this->complement.add (type); + const bool in_points_to_set = this->in_points_to_record(type); const bool in_complement = this->in_complement (type); const bool _xor = in_points_to_set != in_complement; - // sanity check... gcc_assert (_xor); } /* Find out whether TYPE is already in universe. */ bool -type_partitions_s::in_universe (tree type) const +type_partitions2_s::in_universe (tree type) { gcc_assert (type); - const bool seen_before = this->universe.find (type) != this->universe.end (); + const bool seen_before = this->universe.contains (type); return seen_before; } /* Find out whether TYPE is in points_to_record partition. */ bool -type_partitions_s::in_points_to_record (tree type) const +type_partitions2_s::in_points_to_record (tree type) { gcc_assert (type); - const bool seen_before - = this->points_to_record.find (type) != this->points_to_record.end (); + const bool seen_before = this->points_to_record.contains (type); return seen_before; } /* Find out whether TYPE is not in points to record partition. */ bool -type_partitions_s::in_complement (tree type) const +type_partitions2_s::in_complement (tree type) { gcc_assert (type); - const bool seen_before - = this->complement.find (type) != this->complement.end (); + const bool seen_before = this->complement.contains (type); return seen_before; } @@ -3398,15 +3397,14 @@ type_structural_equality::_equal (tree l, tree r) if (!equal_codes) return equal_codes; - bool recurse_l = set_l.find (l) != set_l.end (); - bool recurse_r = set_r.find (r) != set_r.end (); - // Verify that this the case every time. - bool recurse = recurse_l || recurse_r; + bool recurse2_l = set2_l.contains (l); + bool recurse2_r = set2_r.contains (r); + bool recurse = recurse2_l || recurse2_r; if (recurse) return recurse; - set_l.insert (l); - set_r.insert (r); + set2_l.add (l); + set2_r.add (r); const enum tree_code code = TREE_CODE (l); bool equal_children = false; switch (code) @@ -3441,8 +3439,8 @@ type_structural_equality::_equal (tree l, tree r) break; } - set_l.erase (l); - set_r.erase (r); + set2_l.remove (l); + set2_r.remove (r); return equal_children; } @@ -3598,19 +3596,19 @@ type_incomplete_equality::_equal (tree l, tree r) * Perform this until a fixed point is reached. */ static void -fix_escaping_types_in_set (tpartitions_t &types) +fix_escaping_types_in_set (tpartitions2_t &types) { bool fixed_point_reached = false; type_incomplete_equality structuralEquality; do { - std::vector fixes; + vec fixes2 = vNULL; fixed_point_reached = true; - for (std::set::const_iterator i = types.escaping.begin (), + for (auto i = types.escaping.begin (), e = types.escaping.end (); i != e; ++i) { - for (std::set::const_iterator j + for (auto j = types.non_escaping.begin (), f = types.non_escaping.end (); j != f; ++j) @@ -3630,17 +3628,15 @@ fix_escaping_types_in_set (tpartitions_t &types) // Add incomplete to escaping // delete incomplete from non_escaping // We shouldn't do that inside our iteration loop. - fixes.push_back (type_non); + fixes2.safe_push (type_non); } } - for (std::vector::const_iterator i = fixes.begin (), - e = fixes.end (); - i != e; ++i) + for (auto i = fixes2.begin (), e = fixes2.end (); i != e; ++i) { tree escaping_type = *i; - types.escaping.insert (escaping_type); - types.non_escaping.erase (escaping_type); + types.escaping.add (escaping_type); + types.non_escaping.remove (escaping_type); } } while (!fixed_point_reached); diff --git a/gcc/ipa-type-escape-analysis.h b/gcc/ipa-type-escape-analysis.h index 0bf24eb7c23..702e13e62ba 100644 --- a/gcc/ipa-type-escape-analysis.h +++ b/gcc/ipa-type-escape-analysis.h @@ -106,7 +106,7 @@ tree_to_tree (tree t) // TODO: Rename? // TSET_T stands for type set. -typedef std::set tset_t; +typedef hash_set tset2_t; /* Base class used for visiting tree nodes starting with root T. * It can handle recursive cases in the tree graph by holding @@ -130,7 +130,7 @@ public: protected: /* Typeset holds previously visited nodes. */ - tset_t tset; + tset2_t tset2; /* Inner walking method, used to recurse. */ void _walk (tree t); @@ -421,40 +421,40 @@ protected: * Ideally 1 union 2 should be universe and 3 union 4 should be universe. */ -struct type_partitions_s +struct type_partitions2_s { /* The set of all types which have been seen. */ - tset_t universe; + tset2_t universe; /* The set of all types which somehow refer to a RECORD_TYPE. */ - tset_t points_to_record; + tset2_t points_to_record; /* The complement of points_to_record. */ - tset_t complement; + tset2_t complement; /* The set of all escaping types. */ - tset_t escaping; + tset2_t escaping; /* The set of all non escaping types. */ - tset_t non_escaping; + tset2_t non_escaping; /* The set of all records. */ - tset_t records; + tset2_t records; /* Determine if we have seen this type before. */ - bool in_universe (tree) const; + bool in_universe (tree); /* Determine if tree points to a record. */ - bool in_points_to_record (tree) const; + bool in_points_to_record (tree); /* Determine if tree does not point to a record. */ - bool in_complement (tree) const; + bool in_complement (tree); /* Insert either in points to record or complement. */ void insert (tree, bool); }; -typedef struct type_partitions_s tpartitions_t; +typedef struct type_partitions2_s tpartitions2_t; /* TypeCollector is a derived class from TypeWalker * that collects all types reachable from T into the partitions @@ -463,17 +463,17 @@ typedef struct type_partitions_s tpartitions_t; class type_collector : public type_walker { public: - type_collector () + type_collector (tpartitions2_t &ptrset) + : ptrset2(ptrset) {}; /* Main interface. */ void collect (tree t); /* Collect the result after walking all trees. */ - tpartitions_t get_record_reaching_trees () + tpartitions2_t& get_record_reaching_trees () { - _sanity_check (); - return ptrset; + return ptrset2; } private: @@ -488,7 +488,7 @@ private: * In other words, the contents are reset after every * call to collect. */ - std::map ptr; + hash_map ptr2; /* The type partition set that will hold partitions for * points to record or does not point to record. @@ -497,7 +497,7 @@ private: * This datastructure persists across calls to collect. */ public: - tpartitions_t ptrset; + tpartitions2_t& ptrset2; private: @@ -644,11 +644,12 @@ private: class expr_collector : public expr_walker { public: - expr_collector () + expr_collector (tpartitions2_t &p) + : _type_collector (p) {}; /* Holds the result after collecting from all trees. */ - tpartitions_t get_record_reaching_trees () + tpartitions2_t get_record_reaching_trees () { return _type_collector.get_record_reaching_trees (); } @@ -668,11 +669,12 @@ private: class gimple_type_collector : public gimple_walker { public: - gimple_type_collector () + gimple_type_collector (tpartitions2_t &p) + : _expr_collector(p) {}; /* This holds the result after walking the whole program. */ - tpartitions_t get_record_reaching_trees () + tpartitions2_t get_record_reaching_trees () { return _expr_collector.get_record_reaching_trees (); } @@ -708,12 +710,12 @@ private: class gimple_white_lister : gimple_type_collector { public: - gimple_white_lister () + gimple_white_lister (tpartitions2_t &t) + : gimple_type_collector (t) {}; bool _no_external = true; - bool does_not_call_external_functions (cgraph_node *c, - std::map &whitelisted) + bool does_not_call_external_functions2 (cgraph_node *c, hash_map *whitelisted) { gcc_assert(c); @@ -721,18 +723,15 @@ public: { cgraph_node *callee = edge->callee; if (callee == c) continue; - bool in_map = whitelisted.find (callee->decl) != whitelisted.end(); + bool in_map = whitelisted->get (callee->decl); if (!in_map) { return false; } - bool w = whitelisted[callee->decl]; - if (!w) { - return false; - } + return *whitelisted->get(callee->decl); } unsigned int how_many_records = - _expr_collector._type_collector.ptrset.records.size (); + _expr_collector._type_collector.ptrset2.records.elements (); return how_many_records <= 1; } @@ -804,7 +803,7 @@ struct Reason {}; }; -typedef std::map typemap; +typedef hash_map typemap2; /* Type Escaper propagates information on whether a type escapes * to all types reachable by a root type. It also propagates @@ -817,19 +816,19 @@ typedef std::map typemap; class type_escaper : public type_walker { public: - type_escaper (tpartitions_t &p) - : _ptrset (p), _inside_union (0), _inside_record (0) + type_escaper (tpartitions2_t &p) + : _ptrset2 (p), _inside_union (0), _inside_record (0) {}; // Hold the partitions for escaping non escaping. - tpartitions_t &_ptrset; + tpartitions2_t &_ptrset2; // Have information that matches a tree type with // why a type is escaping. - typemap calc; + typemap2 calc2; // Get partitions after calculating escaping types. - tpartitions_t get_sets (); + void fix_sets (); // Print reasons why a type is escaping. void print_reasons (); @@ -885,7 +884,7 @@ private: class expr_escaper : public expr_walker { public: - expr_escaper (tpartitions_t &types, std::map &whitelisted) : _type_escaper (types), _whitelisted(whitelisted) + expr_escaper (tpartitions2_t &types, hash_map *whitelisted2) : _type_escaper (types), _whitelisted2(whitelisted2), _stack2(vNULL) {}; /* Main interface: T escapes because R. */ @@ -894,10 +893,10 @@ public: /* Will be used to propagate escaping reasons to Types. */ type_escaper _type_escaper; - std::map &_whitelisted; + hash_map *_whitelisted2; /* Holds the end result. */ - tpartitions_t get_sets (); + void fix_sets (); /* Print end result. */ void print_reasons (); @@ -909,7 +908,7 @@ private: // is the subexpression being examined. // The bottom of the stack is the expression called on the update // function. - std::stack _stack; + vec _stack2; // Reason to propagate across all subexpressions. Reason _r; @@ -947,13 +946,13 @@ protected: private: // Use to limit recursion if we are revisiting a node - typedef std::set tset_t; + typedef hash_set tset2_t; // Limit recursion for LHS - tset_t set_l; + tset2_t set2_l; // Limit recursion for RHS - tset_t set_r; + tset2_t set2_r; // Determine if the code is equal bool _equal_code (tree a, tree b); @@ -1002,7 +1001,7 @@ protected: class gimple_escaper : public gimple_walker { public: - gimple_escaper (tpartitions_t &types, std::map &whitelisted) : _expr_escaper (types, whitelisted) + gimple_escaper (tpartitions2_t &types, hash_map *whitelisted2) : _expr_escaper (types, whitelisted2) { _init (); }; @@ -1011,7 +1010,7 @@ public: expr_escaper _expr_escaper; /* Obtain final result. */ - tpartitions_t get_sets (); + void fix_sets (); /* Print final result. */ void print_reasons (); @@ -1019,8 +1018,8 @@ public: protected: /* Set of undefined functions, this set is filled with * functions obtained via FOR_EACH_FUNCTION_WITH_GIMPLE_BODY. */ - typedef std::set undefset; - undefset undefined; + typedef hash_set undefset2; + undefset2 undefined2; /* Initializes undefined. */ void _init (); @@ -1068,12 +1067,12 @@ protected: class gimple_caster : public gimple_escaper { public: - gimple_caster (tpartitions_t &types, std::map &whitelisted) : gimple_escaper (types, whitelisted), _whitelisted(whitelisted) + gimple_caster (tpartitions2_t &types, hash_map *whitelisted2) : gimple_escaper (types, whitelisted2), _whitelisted2(whitelisted2) {}; private: - std::map &_whitelisted; + hash_map *_whitelisted2; /* Determine if cast comes from a known function. */ static bool follow_def_to_find_if_really_cast (tree); @@ -1099,24 +1098,33 @@ const unsigned Read = 0x01u; const unsigned Write = 0x02u; // maps FIELD_DECL -> bitflag. -typedef std::map field_access_map_t; +typedef hash_map field_access_map2_t; // maps RECORD_TYPE -> (FIELD_DECL -> bitflag). -typedef std::map record_field_map_t; +typedef hash_map record_field_map4_t; // Class used to determine if a FIELD is read, written or never accessed. class type_accessor : public type_walker { public: - type_accessor (record_field_map_t &map) : _map (map) + type_accessor (record_field_map4_t &map) : _map4(map) {}; + ~type_accessor() + { + }; + + bool is_in_record_field_map(tree t); + field_access_map2_t* get_from_record_field_map(tree t); + void put_in_record_field_map(tree t, field_access_map2_t*); + private: + // maps RECORD -> (FIELD_DECL -> bitflag). - record_field_map_t &_map; + record_field_map4_t &_map4; // set of trees which are memoized and we don't need to look into them. - std::set memoized_map; + hash_set memoized_map2; // If a RECORD_TYPE is walked into, add all fields in struct to // record_field_map. @@ -1131,7 +1139,7 @@ private: class expr_accessor : public expr_walker { public: - expr_accessor () : _type_accessor (record_field_map) + expr_accessor (record_field_map4_t &map) : _type_accessor (map), _stack2 (vNULL) {}; // Expr E is accessed in A manner. @@ -1143,21 +1151,15 @@ public: // Add all fields to map. Initialize with empty. void add_all_fields_in_struct (tree t); - // Get final results. - record_field_map_t get_map (); + // Aids expr-accessor in updating types. + type_accessor _type_accessor; private: // Access {"Read", "Write", "Neither"} to propagate to all subexpressions. unsigned _access; // Stack to keep track of how current subexpression was reached. - std::stack _stack; - - // Holds main results. - record_field_map_t record_field_map; - - // Aids expr-accessor in updating types. - type_accessor _type_accessor; + vec _stack2; // Mark FIELD_DECL as read. // If ADDR_EXPR is parent expression that means @@ -1186,15 +1188,13 @@ private: class gimple_accessor : public gimple_walker { public: - gimple_accessor () + gimple_accessor (record_field_map4_t &map) + : _expr_accessor(map) {}; /* Print final results. */ void print_accesses (); - /* Get final results. */ - record_field_map_t get_map (); - protected: /* Navigate expressions in gimple statements. */ expr_accessor _expr_accessor; @@ -1218,21 +1218,21 @@ private: // But we might need a gswitch. }; -typedef std::set field_offsets_t; - -typedef std::map record_field_offset_map_t; +typedef hash_set> field_offsets2_t; +typedef hash_map record_field_offset_map4_t; // Partition types into escaping or non escaping sets. -tpartitions_t -partition_types_into_escaping_nonescaping (std::map&); +void +partition_types_into_escaping_nonescaping (tpartitions2_t &p, hash_map*); // Compute set of not escaping unaccessed fields -record_field_offset_map_t -obtain_nonescaping_unaccessed_fields (tpartitions_t casting, - record_field_map_t record_field_map, - int warning); +void +obtain_nonescaping_unaccessed_fields (tpartitions2_t casting, + record_field_map4_t& record_field_map, + int warning, + record_field_offset_map4_t &a); extern bool detected_incompatible_syntax; -std::map get_whitelisted_nodes(); +hash_map *get_whitelisted_nodes2(); #endif /* GCC_IPA_TYPE_ESCAPE_ANALYSIS_H */ -- 2.18.1