Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/814410/?format=api
{ "id": 814410, "url": "http://patchwork.ozlabs.org/api/1.2/patches/814410/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/CADzB+2n4mtiYNocfZYCE7xKwEf6aZW+QX9FdR05zf2a-9Qi4TQ@mail.gmail.com/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/1.2/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<CADzB+2n4mtiYNocfZYCE7xKwEf6aZW+QX9FdR05zf2a-9Qi4TQ@mail.gmail.com>", "list_archive_url": null, "date": "2017-09-15T21:45:13", "name": "RFA (hash-map): PATCH to support GTY((cache)) with hash_map", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "8840b190ff3e93561a9ba6655c0134b2559d45fb", "submitter": { "id": 4337, "url": "http://patchwork.ozlabs.org/api/1.2/people/4337/?format=api", "name": "Jason Merrill", "email": "jason@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/CADzB+2n4mtiYNocfZYCE7xKwEf6aZW+QX9FdR05zf2a-9Qi4TQ@mail.gmail.com/mbox/", "series": [ { "id": 3390, "url": "http://patchwork.ozlabs.org/api/1.2/series/3390/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=3390", "date": "2017-09-15T21:45:13", "name": "RFA (hash-map): PATCH to support GTY((cache)) with hash_map", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/3390/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/814410/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/814410/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-return-462304-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "mailing list gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=gcc-patches-return-462304-incoming=patchwork.ozlabs.org@gcc.gnu.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org\n\theader.b=\"ZlbomE7z\"; dkim-atps=neutral", "sourceware.org; auth=none" ], "Received": [ "from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xv88z4p0Jz9sNc\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat, 16 Sep 2017 07:45:55 +1000 (AEST)", "(qmail 97757 invoked by alias); 15 Sep 2017 21:45:41 -0000", "(qmail 97564 invoked by uid 89); 15 Sep 2017 21:45:39 -0000", "from mail-io0-f177.google.com (HELO mail-io0-f177.google.com)\n\t(209.85.223.177) by sourceware.org\n\t(qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP;\n\tFri, 15 Sep 2017 21:45:36 +0000", "by mail-io0-f177.google.com with SMTP id d16so11561779ioj.3 for\n\t<gcc-patches@gcc.gnu.org>; Fri, 15 Sep 2017 14:45:36 -0700 (PDT)", "by 10.107.166.140 with HTTP; Fri, 15 Sep 2017 14:45:13 -0700 (PDT)" ], "DomainKey-Signature": "a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender\n\t:mime-version:from:date:message-id:subject:to:content-type; q=\n\tdns; s=default; b=LY+KIf8iy+16AOxnGTG/zO1VOw+hBa+tn+E3qDL+ITqXLX\n\tUl2IWLMY+tIvGUF8WhLCiTu23O/6WZ5qeAEfPgLefylw07pvJgM4QbeE2w3FVg9b\n\t8tKJIatd1GL1V4ZUO0j8RM0MRRMt0H5D0+uaH65sIdJ41ohpHdSQrzaIN3je8=", "DKIM-Signature": "v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender\n\t:mime-version:from:date:message-id:subject:to:content-type; s=\n\tdefault; bh=8v6BbIoU6DqpALLB+tzmJF4S2MQ=; b=ZlbomE7z5fUCEW+B0+CF\n\tR/uXYw6jr+DikmyLN6p4N8/lltKaR2g82WnpyrVRUbDWPwcGXw/CZfU6q3lB6uSd\n\tUXdTASlw2qd8r0gdZ1vLsr+8hgQaCQebIPOOtkAt/OSRnC4WVyb53y1zBhOYWmos\n\tfdS1K8anyb+c/3TmYMgJNqk=", "Mailing-List": "contact gcc-patches-help@gcc.gnu.org; run by ezmlm", "Precedence": "bulk", "List-Id": "<gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<mailto:gcc-patches-unsubscribe-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "List-Archive": "<http://gcc.gnu.org/ml/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-help@gcc.gnu.org>", "Sender": "gcc-patches-owner@gcc.gnu.org", "X-Virus-Found": "No", "X-Spam-SWARE-Status": "No, score=-25.0 required=5.0 tests=AWL, BAYES_00,\n\tGIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3,\n\tRCVD_IN_DNSWL_NONE,\n\tRCVD_IN_SORBS_SPAM autolearn=ham version=3.3.2 spammy=MEMBER,\n\tFriend, traits, swept", "X-HELO": "mail-io0-f177.google.com", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net;\n\ts=20161025;\n\th=x-gm-message-state:mime-version:from:date:message-id:subject:to;\n\tbh=v5lxp5ndFb35IcC3kX+Pqu8Huxbyrlwwtnt93g2QB7Y=;\n\tb=hlIjCcr31M/Qvoh9tdjGs31p/u83imcSskikICavXUoDo4ObnfWNXebC2zsMT52Rrh\n\t/c7kU6hBPqj0nXsf5r7a7L48iEC1eOFTFAEa0iCtHHgm5HFz2SIZizcxoAMJXqTZLrwn\n\tW9P7DHBibF7AZEvHuu+awPtQ24jab5Zdia63TDy942lqfvyw4QYYbrbDHL/465YLJxx/\n\tnepy8DGKyZu4FZ0oxiHoUIAgughKk+dn2RdsjdgKtR5yFf9OlC0G6FQ6HZ0NQPQdcdJN\n\tJ1nxInpQMeO1VdJaQzXTE1Tz/e686At6AY6tc29e+tna5g5szZ7yn49y3PlZCMcDZZCj\n\tR0+g==", "X-Gm-Message-State": "AHPjjUjGih88CxWCx3P7AUOq7LGg8//3EfDGF6xSSMILpaKXVapKGe2c\tPw7MBDhg3yMNPTQZAQiuGFWW8/OW7ztD0sNywqJp78ldsIQ=", "X-Google-Smtp-Source": "AOwi7QARDICkTILEDEZU1zLkyUk7inpK5yXRQ9q//RhMQoBSyCiQEL3XzOC4PmrdU6fqeTPvwTczHilx+fru41t/1II=", "X-Received": "by 10.107.69.20 with SMTP id s20mr3777462ioa.113.1505511934453;\n\tFri, 15 Sep 2017 14:45:34 -0700 (PDT)", "MIME-Version": "1.0", "From": "Jason Merrill <jason@redhat.com>", "Date": "Fri, 15 Sep 2017 17:45:13 -0400", "Message-ID": "<CADzB+2n4mtiYNocfZYCE7xKwEf6aZW+QX9FdR05zf2a-9Qi4TQ@mail.gmail.com>", "Subject": "RFA (hash-map): PATCH to support GTY((cache)) with hash_map", "To": "gcc-patches List <gcc-patches@gcc.gnu.org>", "Content-Type": "multipart/mixed; boundary=\"089e082866a80f313b0559415024\"", "X-IsSubscribed": "yes" }, "content": "The hash_map interface is a lot more convenient than that of\nhash_table for cases where it makes sense, but there hasn't been a way\nto get the ggc_cache_remove behavior with a hash_map. In other words,\nnot marking elements during the initial ggc marking phase, but maybe\nmarking them during the clear_caches phase based on keep_cache_entry.\n\nThis patch implements that by:\n\nAdding a ggc_maybe_mx member function to ggc_remove, and overriding\nthat instead of ggc_mx in ggc_cache_remove.\nCalling H::ggc_maybe_mx instead of H::ggc_mx in gt_ggc_mx (hash_table *).\nCalling H::ggc_mx in gt_cleare_caches (hash_table *) rather than\nrelying on an extern declaration of a plain function that cannot be\ndeclared for hash_map::hash_entry.\nAdding ggc_maybe_mx and keep_cache_entry to hash_map::hash_entry.\nAdding gt_cleare_cache for hash_map.\nAdding a boolean constant to the hash-map traits indicating whether we\nwant the cache behavior above.\n\nI then define a typedef tree_cache_map to use this functionality, and\nuse it in a few places in the C++ front end.\n\nTested x86_64-pc-linux-gnu, OK for trunk?\ncommit 29a77538437442915ecb85516e3710c918d0e8ac\nAuthor: Jason Merrill <jason@redhat.com>\nDate: Wed Sep 13 14:33:33 2017 -0400\n\n Support GTY((cache)) on hash_map.\n \n gcc/\n * hash-traits.h (ggc_remove): Add ggc_maybe_mx member function.\n (ggc_cache_remove): Override it instead of ggc_mx.\n * hash-table.h (gt_ggc_mx): Call it instead of ggc_mx.\n (gt_cleare_cache): Call ggc_mx instead of gt_ggc_mx.\n * hash-map-traits.h (simple_hashmap_traits): Add maybe_mx member.\n (simple_cache_map_traits): Override maybe_mx.\n * hash-map.h (hash_entry): Add ggc_maybe_mx and keep_cache_entry.\n (hash_map): Friend gt_cleare_cache.\n (gt_cleare_cache): New.\n * tree.h (tree_cache_traits): New hash_map traits class.\n (tree_cache_map): New typedef.\n gcc/cp/\n * decl.c (decomp_type_table): Use tree_cache_map.\n * init.c (nsdmi_inst): Likewise.\n * pt.c (defarg_ints): Likewise.\n * cp-objcp-common.c (cp_get_debug_type): Likewise.", "diff": "diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c\nindex 183e7f7bf57..27f0b985378 100644\n--- a/gcc/cp/cp-objcp-common.c\n+++ b/gcc/cp/cp-objcp-common.c\n@@ -131,19 +131,7 @@ cxx_types_compatible_p (tree x, tree y)\n return same_type_ignoring_top_level_qualifiers_p (x, y);\n }\n \n-struct debug_type_hasher : ggc_cache_ptr_hash<tree_map>\n-{\n- static hashval_t hash (tree_map *m) { return tree_map_hash (m); }\n- static bool equal (tree_map *a, tree_map *b) { return tree_map_eq (a, b); }\n-\n- static int\n- keep_cache_entry (tree_map *&e)\n- {\n- return ggc_marked_p (e->base.from);\n- }\n-};\n-\n-static GTY((cache)) hash_table<debug_type_hasher> *debug_type_hash;\n+static GTY((cache)) tree_cache_map *debug_type_map;\n \n /* Return a type to use in the debug info instead of TYPE, or NULL_TREE to\n keep TYPE. */\n@@ -151,38 +139,29 @@ static GTY((cache)) hash_table<debug_type_hasher> *debug_type_hash;\n tree\n cp_get_debug_type (const_tree type)\n {\n+ tree dtype = NULL_TREE;\n+\n if (TYPE_PTRMEMFUNC_P (type) && !typedef_variant_p (type))\n+ dtype = build_offset_type (TYPE_PTRMEMFUNC_OBJECT_TYPE (type),\n+\t\t\t TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type)));\n+\n+ /* We cannot simply return the debug type here because the function uses\n+ the type canonicalization hashtable, which is GC-ed, so its behavior\n+ depends on the actual collection points. Since we are building these\n+ types on the fly for the debug info only, they would not be attached\n+ to any GC root and always be swept, so we would make the contents of\n+ the debug info depend on the collection points. */\n+ if (dtype)\n {\n- if (debug_type_hash == NULL)\n-\tdebug_type_hash = hash_table<debug_type_hasher>::create_ggc (512);\n-\n- /* We cannot simply use build_offset_type here because the function uses\n-\t the type canonicalization hashtable, which is GC-ed, so its behavior\n-\t depends on the actual collection points. Since we are building these\n-\t types on the fly for the debug info only, they would not be attached\n-\t to any GC root and always be swept, so we would make the contents of\n-\t the debug info depend on the collection points. */\n- struct tree_map in, *h;\n-\n- in.base.from = CONST_CAST_TREE (type);\n- in.hash = htab_hash_pointer (type);\n- h = debug_type_hash->find_with_hash (&in, in.hash);\n- if (h)\n-\treturn h->to;\n-\n- tree t = build_offset_type (TYPE_PTRMEMFUNC_OBJECT_TYPE (type),\n-\t\t\t\t TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type)));\n-\n- h = ggc_alloc<tree_map> ();\n- h->base.from = CONST_CAST_TREE (type);\n- h->hash = htab_hash_pointer (type);\n- h->to = t;\n- *debug_type_hash->find_slot_with_hash (h, h->hash, INSERT) = h;\n-\n- return t;\n+ tree ktype = CONST_CAST_TREE (type);\n+ if (debug_type_map == NULL)\n+\tdebug_type_map = tree_cache_map::create_ggc (512);\n+ else if (tree *slot = debug_type_map->get (ktype))\n+\treturn *slot;\n+ debug_type_map->put (ktype, dtype);\n }\n \n- return NULL_TREE;\n+ return dtype;\n }\n \n /* Return -1 if dwarf ATTR shouldn't be added for DECL, or the attribute\ndiff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h\nindex f4d6f802cbe..06a4a7d22cc 100644\n--- a/gcc/cp/cp-tree.h\n+++ b/gcc/cp/cp-tree.h\n@@ -5117,7 +5117,6 @@ extern GTY(()) vec<tree, va_gc> *static_decls;\n /* An array of vtable-needing types that have no key function, or have\n an emitted key function. */\n extern GTY(()) vec<tree, va_gc> *keyed_classes;\n-\n \f\n /* Here's where we control how name mangling takes place. */\n \ndiff --git a/gcc/cp/decl.c b/gcc/cp/decl.c\nindex 6101bdf2bc8..bfb0ebe9642 100644\n--- a/gcc/cp/decl.c\n+++ b/gcc/cp/decl.c\n@@ -7303,12 +7303,13 @@ get_tuple_decomp_init (tree decl, unsigned i)\n \n /* It's impossible to recover the decltype of a tuple decomposition variable\n based on the actual type of the variable, so store it in a hash table. */\n-static GTY(()) hash_map<tree,tree> *decomp_type_table;\n+\n+static GTY((cache)) tree_cache_map *decomp_type_table;\n static void\n store_decomp_type (tree v, tree t)\n {\n if (!decomp_type_table)\n- decomp_type_table = hash_map<tree,tree>::create_ggc (13);\n+ decomp_type_table = tree_cache_map::create_ggc (13);\n decomp_type_table->put (v, t);\n }\n \ndiff --git a/gcc/cp/init.c b/gcc/cp/init.c\nindex b01d662fef2..d6241d29379 100644\n--- a/gcc/cp/init.c\n+++ b/gcc/cp/init.c\n@@ -535,7 +535,7 @@ perform_target_ctor (tree init)\n \n /* Return the non-static data initializer for FIELD_DECL MEMBER. */\n \n-static GTY(()) hash_map<tree, tree> *nsdmi_inst;\n+static GTY((cache)) tree_cache_map *nsdmi_inst;\n \n tree\n get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)\n@@ -590,7 +590,7 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)\n \t if (init != error_mark_node)\n \t {\n \t if (!nsdmi_inst)\n-\t\tnsdmi_inst = hash_map<tree,tree>::create_ggc (37);\n+\t\tnsdmi_inst = tree_cache_map::create_ggc (37);\n \t nsdmi_inst->put (member, init);\n \t }\n \ndiff --git a/gcc/cp/pt.c b/gcc/cp/pt.c\nindex ec7bbc890c6..aa158dc939d 100644\n--- a/gcc/cp/pt.c\n+++ b/gcc/cp/pt.c\n@@ -12008,7 +12008,7 @@ tsubst_aggr_type (tree t,\n }\n }\n \n-static GTY(()) hash_map<tree, tree> *defarg_inst;\n+static GTY((cache)) tree_cache_map *defarg_inst;\n \n /* Substitute into the default argument ARG (a default argument for\n FN), which has the indicated TYPE. */\n@@ -12095,7 +12095,7 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,\n if (arg != error_mark_node && !cp_unevaluated_operand)\n {\n if (!defarg_inst)\n-\tdefarg_inst = hash_map<tree,tree>::create_ggc (37);\n+\tdefarg_inst = tree_cache_map::create_ggc (37);\n defarg_inst->put (parm, arg);\n }\n \ndiff --git a/gcc/hash-map-traits.h b/gcc/hash-map-traits.h\nindex 2b5fddf2d09..a92f0cb00f4 100644\n--- a/gcc/hash-map-traits.h\n+++ b/gcc/hash-map-traits.h\n@@ -32,6 +32,7 @@ template <typename H, typename Value>\n struct simple_hashmap_traits\n {\n typedef typename H::value_type key_type;\n+ static const bool maybe_mx = true;\n static inline hashval_t hash (const key_type &);\n static inline bool equal_keys (const key_type &, const key_type &);\n template <typename T> static inline void remove (T &);\n@@ -97,6 +98,12 @@ simple_hashmap_traits <H, Value>::mark_deleted (T &entry)\n H::mark_deleted (entry.m_key);\n }\n \n+template <typename H, typename Value>\n+struct simple_cache_map_traits: public simple_hashmap_traits<H,Value>\n+{\n+ static const bool maybe_mx = false;\n+};\n+\n /* Implement traits for a hash_map with values of type Value for cases\n in which the key cannot represent empty and deleted slots. Instead\n record empty and deleted entries in Value. Derived classes must\ndiff --git a/gcc/hash-map.h b/gcc/hash-map.h\nindex 73f1c5427a0..6b8365a9d0a 100644\n--- a/gcc/hash-map.h\n+++ b/gcc/hash-map.h\n@@ -62,6 +62,12 @@ class GTY((user)) hash_map\n \tgt_ggc_mx (e.m_value);\n }\n \n+ static void ggc_maybe_mx (hash_entry &e)\n+ {\n+\tif (Traits::maybe_mx)\n+\t ggc_mx (e);\n+ }\n+\n static void pch_nx (hash_entry &e)\n {\n \tgt_pch_nx (e.m_key);\n@@ -74,6 +80,11 @@ class GTY((user)) hash_map\n \tpch_nx_helper (e.m_value, op, c);\n }\n \n+ static int keep_cache_entry (hash_entry &e)\n+ {\n+\treturn ggc_marked_p (e.m_key);\n+ }\n+\n private:\n template<typename T>\n static void\n@@ -237,7 +248,8 @@ private:\n \n template<typename T, typename U, typename V> friend void gt_ggc_mx (hash_map<T, U, V> *);\n template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *);\n- template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);\n+ template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);\n+ template<typename T, typename U, typename V> friend void gt_cleare_cache (hash_map<T, U, V> *);\n \n hash_table<hash_entry> m_table;\n };\n@@ -260,6 +272,13 @@ gt_pch_nx (hash_map<K, V, H> *h)\n \n template<typename K, typename V, typename H>\n static inline void\n+gt_cleare_cache (hash_map<K, V, H> *h)\n+{\n+ gt_cleare_cache (&h->m_table);\n+}\n+\n+template<typename K, typename V, typename H>\n+static inline void\n gt_pch_nx (hash_map<K, V, H> *h, gt_pointer_operator op, void *cookie)\n {\n op (&h->m_table.m_entries, cookie);\ndiff --git a/gcc/hash-table.h b/gcc/hash-table.h\nindex 64d3157953c..b86a1d1b278 100644\n--- a/gcc/hash-table.h\n+++ b/gcc/hash-table.h\n@@ -1044,7 +1044,9 @@ gt_ggc_mx (hash_table<E> *h)\n \t || table::is_deleted (h->m_entries[i]))\n \tcontinue;\n \n- E::ggc_mx (h->m_entries[i]);\n+ /* Use ggc_maxbe_mx so we don't mark right away for cache tables; we'll\n+\t mark in gt_cleare_cache if appropriate. */\n+ E::ggc_maybe_mx (h->m_entries[i]);\n }\n }\n \n@@ -1094,7 +1096,6 @@ template<typename H>\n inline void\n gt_cleare_cache (hash_table<H> *h)\n {\n- extern void gt_ggc_mx (typename H::value_type &t);\n typedef hash_table<H> table;\n if (!h)\n return;\n@@ -1106,7 +1107,7 @@ gt_cleare_cache (hash_table<H> *h)\n \tif (res == 0)\n \t h->clear_slot (&*iter);\n \telse if (res != -1)\n-\t gt_ggc_mx (*iter);\n+\t H::ggc_mx (*iter);\n }\n }\n \ndiff --git a/gcc/hash-traits.h b/gcc/hash-traits.h\nindex a5c4f103474..6a613c45811 100644\n--- a/gcc/hash-traits.h\n+++ b/gcc/hash-traits.h\n@@ -235,6 +235,13 @@ struct ggc_remove\n gt_ggc_mx (p);\n }\n \n+ /* Overridden in ggc_cache_remove. */\n+ static void\n+ ggc_maybe_mx (T &p)\n+ {\n+ ggc_mx (p);\n+ }\n+\n static void\n pch_nx (T &p)\n {\n@@ -256,7 +263,7 @@ template<typename T>\n struct ggc_cache_remove : ggc_remove<T>\n {\n /* Entries are weakly held because this is for caches. */\n- static void ggc_mx (T &) {}\n+ static void ggc_maybe_mx (T &) {}\n \n static int\n keep_cache_entry (T &e)\ndiff --git a/gcc/tree.h b/gcc/tree.h\nindex caa4a69977d..6845953c09c 100644\n--- a/gcc/tree.h\n+++ b/gcc/tree.h\n@@ -4873,6 +4873,13 @@ struct tree_decl_map_cache_hasher : ggc_cache_ptr_hash<tree_decl_map>\n #define tree_vec_map_hash tree_decl_map_hash\n #define tree_vec_map_marked_p tree_map_base_marked_p\n \n+/* A hash_map of two trees for use with GTY((cache)). Garbage collection for\n+ such a map will not mark keys, and will mark values if the key is already\n+ marked. */\n+struct tree_cache_traits\n+ : simple_cache_map_traits<default_hash_traits<tree>, tree> { };\n+typedef hash_map<tree,tree,tree_cache_traits> tree_cache_map;\n+\n /* Initialize the abstract argument list iterator object ITER with the\n arguments from CALL_EXPR node EXP. */\n static inline void\n", "prefixes": [] }