This is an archive of the discontinued LLVM Phabricator instance.

Optimize GetCompileUnitContainingDIE with a lookup table
ClosedPublic

Authored by clayborg on Jul 21 2015, 8:45 AM.

Details

Reviewers
tberghammer
Summary

Optimize GetCompileUnitContainingDIE with a lookup table

For large executable with debug symbols GetCompileUnitContainingDIE
took most of the time spent on DWARF parsing. Optimize it from linear
search to a logarithmic search with a lookup table.

Diff Detail

Event Timeline

tberghammer retitled this revision from to Optimize GetCompileUnitContainingDIE with a lookup table.
tberghammer updated this object.
tberghammer added a reviewer: clayborg.
tberghammer added a subscriber: lldb-commits.

I'll let Greg weigh in on the actual details, but if as I understand the patch, the m_die_to_index_map only stored CU dies, can you make the name of the ivar indicate that fact?

Yes it only contains compile unit indexes. The reason I haven't included in the name because the class focuses on compile units, but I can add it if you prefer it that way.

clayborg requested changes to this revision.Jul 21 2015, 1:31 PM
clayborg edited edge metadata.

No need for an extra map. A local C++ guru a while back told me about being able to use a comparison function with two different types if you use std::lower_bound() or std::upper_bound(). Since m_compiler_units is sorted, we can just do:

static bool CompileUnitOffsetLessThan (dw_offset_t die_offset, const DWARFCompileUnitSP& cu_sp)
{
    return die_offset < cu_sp->GetOffset();
}

DWARFCompileUnitSP
DWARFDebugInfo::GetCompileUnitContainingDIE(dw_offset_t die_offset)
{
    DWARFCompileUnitSP cu_sp;
    if (die_offset != DW_INVALID_OFFSET)
    {
        ParseCompileUnitHeadersIfNeeded();

        // Watch out for single compile unit executable as they are pretty common
        const size_t num_cus = m_compile_units.size();
        if (num_cus == 1)
        {
            if (m_compile_units[0]->ContainsDIEOffset(die_offset))
                cu_sp = m_compile_units[0];
        }
        else if (num_cus)
        {
            CompileUnitColl::const_iterator end_pos = m_compile_units.end();
            CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
            CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, die_offset, CompileUnitOffsetLessThan);
            if (pos != begin_pos)
            {
                --pos;
                if ((*pos)->ContainsDIEOffset(die_offset))
                    cu_sp = *pos;
            }
        }
    }
    return cu_sp;
}

Try out the changes and make sure they work and then switch to using the code above.

This revision now requires changes to proceed.Jul 21 2015, 1:31 PM
clayborg commandeered this revision.Jul 21 2015, 3:54 PM
clayborg edited reviewers, added: tberghammer; removed: clayborg.

I actually checked my changes in with:

% svn commit
Sending source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
Transmitting file data .
Committed revision 242852.

tberghammer accepted this revision.Jul 22 2015, 2:19 AM
tberghammer edited edge metadata.
This revision is now accepted and ready to land.Jul 22 2015, 2:19 AM
tberghammer closed this revision.Jul 22 2015, 2:19 AM