Commit 3828fe01 authored by Samuel Huang's avatar Samuel Huang Committed by Commit Bot

[SuperSize] Ignore LLVM promoted global names suffix (.llvm.1234).

Under LLD ThinLTO, if thin_lto_enable_optimizations is enabled then
"promoted global names" can appear. For these, mangled symbol names get
the suffix '.llvm.1234' or '.1.llvm.1234', where '1' is a small number,
and '1234' is a hash. When demangled, the suffix becomes ' (.llvm.1324)'
or ' (.1.llvm.1324)' if successful; and is left alone otherwise.

These suffix interferes with name comparison, leading to secondary
problems like symbols losing path info.

This CL makes SuperSize detect and strip these suffixes, to reduce
spurious diffs from enabling ThinLTO optimization. The transformation
is applied when parsing .map and nm output. Details:
* Add demangle.StripLlvmPromotedGlobalNames(), which performs a
  quick-reject substring test for '.llvm.', followed by RegExp
  string substitution.
* Print the number of promoted global names found in .map file.
* Minor updates to comments and tests.

Bug: 902723
Change-Id: I4ca4142c891c948894c10180b31ff65b759cccfe
Reviewed-on: https://chromium-review.googlesource.com/c/1324192
Commit-Queue: Samuel Huang <huangs@chromium.org>
Reviewed-by: default avatarEric Stevenson <estevenson@chromium.org>
Reviewed-by: default avatarSamuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606487}
parent f0a7efc1
......@@ -6,17 +6,39 @@
import collections
import logging
import re
import subprocess
import path_util
_PROMOTED_GLOBAL_NAME_DEMANGLED_PATTERN = re.compile(
r' \((\.\d+)?\.llvm\.\d+\)$')
_PROMOTED_GLOBAL_NAME_RAW_PATTERN = re.compile(r'(\.\d+)?\.llvm\.\d+$')
def StripLlvmPromotedGlobalNames(name):
"""Strips LLVM promoted global names suffix, and returns the result.
LLVM can promote global names by adding the suffix '.llvm.1234', or
'.1.llvm.1234', where the last numeric suffix is a hash. If demangle is
sucessful, the suffix transforms into, e.g., ' (.llvm.1234)' or
' (.1.llvm.1234)'. Otherwise the suffix is left as is. This function strips
the suffix to prevent it from intefering with name comparison.
"""
llvm_pos = name.find('.llvm.')
if llvm_pos < 0:
return name # Handles most cases.
if name.endswith(')'):
return _PROMOTED_GLOBAL_NAME_DEMANGLED_PATTERN.sub('', name)
return _PROMOTED_GLOBAL_NAME_RAW_PATTERN.sub('', name)
def _DemangleNames(names, tool_prefix):
"""Uses c++filt to demangle a list of names."""
proc = subprocess.Popen([path_util.GetCppFiltPath(tool_prefix)],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdout = proc.communicate('\n'.join(names))[0]
assert proc.returncode == 0
ret = stdout.splitlines()
ret = [StripLlvmPromotedGlobalNames(line) for line in stdout.splitlines()]
if logging.getLogger().isEnabledFor(logging.INFO):
fail_count = sum(1 for s in ret if s.startswith('_Z'))
if fail_count:
......
......@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import demangle
import logging
import os
import re
......@@ -320,6 +321,11 @@ class MapFileParserLld(object):
# 600 600 14 4 obj/...:(.text.OUTLINED_FUNCTION_0)
# 600 600 0 1 $x.3
# 600 600 14 1 OUTLINED_FUNCTION_0
# 123800 123800 20000 256 .rodata
# 123800 123800 4 4 ...:o:(.rodata._ZN3fooE.llvm.1234)
# 123800 123800 4 1 foo (.llvm.1234)
# 123804 123804 4 4 ...:o:(.rodata.bar.llvm.1234)
# 123804 123804 4 1 bar.llvm.1234
# Older format:
# Address Size Align Out In Symbol
# 00000000002002a8 000000000000001c 1 .interp
......@@ -343,6 +349,7 @@ class MapFileParserLld(object):
sym_maker = _SymbolMaker()
cur_section = None
cur_section_is_useful = None
promoted_name_count = 0
for line in lines:
m = pattern.match(line)
......@@ -399,12 +406,17 @@ class MapFileParserLld(object):
# renaming them to '** outlined function'.
if tok.startswith('OUTLINED_FUNCTION_'):
tok = '** outlined function'
stripped_tok = demangle.StripLlvmPromotedGlobalNames(tok)
if len(tok) != len(stripped_tok):
promoted_name_count += 1
tok = stripped_tok
sym_maker.cur_sym.full_name = tok
else:
logging.error('Problem line: %r', line)
sym_maker.Flush()
if promoted_name_count:
logging.info('Found %d promoted global names', promoted_name_count)
return self._section_sizes, sym_maker.syms
......
......@@ -80,14 +80,14 @@ _OBJECT_OUTPUTS = {
'01010101 t extFromUUseMapping(signed char, unsigned int, int)',
'01010101 t Name',
'01010101 v vtable for mojo::MessageReceiver',
'01010101 r kMethodsAnimationFrameTimeHistogram',
'01010101 r kMethodsAnimationFrameTimeHistogram (.llvm.12341234)',
'01010101 r google::protobuf::internal::pLinuxKernelCmpxchg',
],
'obj/third_party/ffmpeg/libffmpeg_internal.a': [
'',
'fft_float.o:',
'01010101 b ff_cos_65536',
'01010101 b ff_cos_131072',
'01010101 b ff_cos_131072.1.llvm.43214321',
'002a0010 t FooAlias()',
'002b6bb8 t $t',
'002a0010 t BarAlias()',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment