From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17976 invoked by alias); 6 Jan 2020 16:07:16 -0000 Mailing-List: contact dwz-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: dwz-owner@sourceware.org Received: (qmail 17945 invoked by uid 89); 6 Jan 2020 16:07:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.100.3 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.1 spammy=profit, Todo, Detected, sk:dw_at_d X-Spam-Status: No, score=-25.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on sourceware.org X-Spam-Level: X-HELO: mx2.suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Date: Wed, 01 Jan 2020 00:00:00 -0000 From: Tom de Vries To: dwz@sourceware.org, jakub@redhat.com Subject: [committed 4/13][odr] Add die_odr_state field to struct dw_die Message-ID: <20200106160709.GA19886@delia> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-SW-Source: 2020-q1/txt/msg00004.txt Hi, Add a die_odr_state field that determines whether and how a DIE participates in the odr optimization, as well as functions that get and initialize the state. Committed to trunk. Thanks, - Tom [odr] Add die_odr_state field to struct dw_die 2020-01-06 Tom de Vries * dwz.c (struct dw_die): Add die_odr_state field. (set_die_odr_state, die_odr_state): New function. --- dwz.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/dwz.c b/dwz.c index c9dc56b..c82f5c9 100644 --- a/dwz.c +++ b/dwz.c @@ -791,6 +791,8 @@ struct dw_die unsigned int die_collapsed_child : 1; /* Set if die_parent field is reused for struct dw_cu pointer. */ unsigned int die_root : 1; + /* State for ODR optimization. */ + enum { ODR_UNKNOWN, ODR_NONE, ODR_DEF, ODR_DECL } die_odr_state : 2; /* Tree pointer to parent. */ dw_die_ref die_parent; @@ -2339,6 +2341,104 @@ read_loclist (DSO *dso, dw_die_ref die, GElf_Addr offset) return 0; } +/* Initialize die_odr_state field for DIE with CU. */ +static void +set_die_odr_state (dw_cu_ref cu, dw_die_ref die) +{ + unsigned char *ptr; + struct abbrev_tag *t; + unsigned int i; + bool decl_p; + bool name_p; + bool other_p; + + die->die_odr_state = ODR_NONE; + + if (low_mem) + /* Todo: allow low-mem mode. */ + return; + + if (multifile_mode == 0) + /* We're in regular mode, enable the ODR optimization. */ + ; + else + /* One definition rule does not hold across executables and shared + libraries, so disable. */ + return; + + if (!die->die_toplevel) + /* A nested struct is not uniquely identified by its name. There may be a + different type with the same name nested in a different struct. */ + return; + + switch (cu->lang) + { + case DW_LANG_C_plus_plus: + /* c++ defines one-definition-rule. */ + if (die->die_tag == DW_TAG_structure_type + || die->die_tag == DW_TAG_class_type + || die->die_tag == DW_TAG_union_type) + /* ODR holds for all types, but we limit the optimization to these + tags, which are the ones likely to profit from it. */ + ; + else + return; + break; + default: + return; + } + + ptr = debug_sections[DEBUG_INFO].data + die->die_offset; + read_uleb128 (ptr); + + t = die->die_abbrev; + + decl_p = false; + name_p = false; + other_p = false; + for (i = 0; i < t->nattr; ++i) + { + if (t->attr[i].attr == DW_AT_name) + { + name_p = true; + continue; + } + + if (t->attr[i].attr == DW_AT_declaration) + { + decl_p = true; + continue; + } + + other_p = true; + } + + if (!name_p) + /* Ignore anonymous types. */ + return; + + if (decl_p && !other_p && die->die_child == NULL) + { + /* Detected a declaration with no attributes other than DW_AT_name and + DW_AT_declaration, and no children. */ + die->die_odr_state = ODR_DECL; + return; + } + + die->die_odr_state = ODR_DEF; +} + +/* Return the initialized die_odr_state field for DIE with CU. */ +static unsigned int UNUSED +die_odr_state (dw_cu_ref cu, dw_die_ref die) +{ + if (die->die_odr_state != ODR_UNKNOWN) + return die->die_odr_state; + + set_die_odr_state (cu, die); + return die->die_odr_state; +} + /* This function computes u.p1.die_hash and die_ck_state of DIE. The field u.p1.die_hash is an iterative hash of: - the die_tag,