From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3356 invoked by alias); 17 Oct 2014 09:06:03 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 3224 invoked by uid 48); 17 Oct 2014 09:05:59 -0000 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug debug/63572] New: [5 Regression] ICF breaks user debugging experience Date: Fri, 17 Oct 2014 09:06:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: debug X-Bugzilla-Version: 5.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter cc dependson blocked Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-10/txt/msg01343.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63572 Bug ID: 63572 Summary: [5 Regression] ICF breaks user debugging experience Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org CC: hubicka at gcc dot gnu.org, jakub at gcc dot gnu.org, jakub at redhat dot com, mliska at suse dot cz, uros at gcc dot gnu.org Depends on: 63566 Blocks: 63571 +++ This bug was initially created as a clone of Bug #63566 +++ On -O2 -g: #define A \ x += y * z; \ y = (y << ((z & 2) + 1)) \ ^ (y >> (__SIZEOF_INT__ * __CHAR_BIT__ - (z & 2) - 1)); \ z *= 7; #define B A A A A A A A A A A #define C B B B B B B B B B B static unsigned int f1 (unsigned int x, unsigned int y, unsigned int z) { C return x + y + z; } static unsigned int f2 (unsigned int x, unsigned int y, unsigned int z) { C return x + y + z; } __attribute__((noinline, noclone)) unsigned int f3 (unsigned int x, unsigned int y, unsigned int z) { return f1 (x, z, y) + 6; } __attribute__((noinline, noclone)) unsigned int f4 (unsigned int x, unsigned int y, unsigned int z) { return f2 (y, x, z) + 7; } __attribute__((noinline, noclone, used)) unsigned int f5 (unsigned int x, unsigned int y, unsigned int z) { return f1 (2 * x, z / 2, y + 3) - 6; } __attribute__((noinline, noclone, used)) unsigned int f6 (unsigned int x, unsigned int y, unsigned int z) { return f2 (y + 2, x | 1, z / 73) + 1; } int main () { unsigned int x = f3 (0x173214, 0x182172, 0x9314); unsigned int y = f4 (0x173214, 0x182172, 0x9314); #if __SIZEOF_INT__ * __CHAR_BIT__ == 32 if (x != 0xd8e56f78U || y != 0x494c6699U) __builtin_abort (); #endif return 0; } GCC emits incomplete DW_TAG_GNU_call_site DIEs for the f1 calls (that have been optimized into ICF alias to f2) - no DW_AT_abstract_origin is provided, and does not emit any DW_TAG_subprogram for f1 at all, just f2. The question is how exactly do we want to emit the DW_TAG_subprogram for icf_merged aliases. Name/abstract origin/function type/names of arguments must be it's own, I guess ICF will happily merge functions where the arguments have e.g. different argument names, or different DECL_ABSTRACT_ORIGIN etc. My question is mainly about DW_TAG_lexical_block/DW_TAG_inlined_subroutine, but as even names of local variables can differ, or it can have different functions inlined, I bet we need to fully populate DW_TAG_subprogram for the ICF aliases, and have some mapping between BLOCKs in the ICF alias and BLOCKs in the kept definition, so that we can reconstruct ranges. Then, when we emit DW_TAG_subprogram details for the kept original function definition when finalizing its RTL, we also need to handle similarly all the ICF aliases. Which is going to be non-fun. Also, supposedly not just that, but we also need a way to track multiple locations, not just blocks. E.g. in one function, first 3 statements can have one location_t, say line 31, and last 3 statements can have another location_t, say line 38. Now, in another function ICF merged with that, the similar first 2 statements can have one location_t, say line 47, the second 2 statements can have location_t line 49 and last 2 statements location_t line 53. So, it might be impossible to create e.g. a pointer_map from one set of locations to another set, we'd need to analyze the correspondence between location_t's in between all the spots in the function (gimple_location, EXPR_LOCATION) where they appear, and perhaps create some artificial locations to make sure there is a 1-1 mapping between all ICF merged functions. Another problem is that we emit these days .debug_line using .file/.loc directives and gas constructs that. Not sure if we can have multiple .debug_line proglets describing the same area of code (perhaps we need some DWARF extension for that?) and if we had that possibility, the question is how to emit it. As for the DW_AT_abstract_origin of DW_TAG_GNU_call_site, that should probably be just very easy, if there is a DIE for the ICF merged alias, supposedly it will be found normally. And, then we'll certainly need some GDB changes (and systemtap/elfutils etc.) - if some code range has multiple DW_TAG_subprogram DIEs covering that range, e.g. if you want to put a breakpoint into a line in one of the functions