diff --git a/src/wasm/wasm-debug.cpp b/src/wasm/wasm-debug.cpp index 557d6a58a4a..d08362106dd 100644 --- a/src/wasm/wasm-debug.cpp +++ b/src/wasm/wasm-debug.cpp @@ -69,9 +69,9 @@ struct BinaryenDWARFInfo { BinaryenDWARFInfo(const Module& wasm) { // Get debug sections from the wasm. for (auto& section : wasm.customSections) { - if (Name(section.name).startsWith(".debug_") && section.data.data()) { + if (llvm::StringRef(section.name).startswith(".debug_") && section.data.data()) { // TODO: efficiency - sections[section.name.substr(1)] = llvm::MemoryBuffer::getMemBufferCopy( + sections[llvm::StringRef(section.name).substr(1)] = llvm::MemoryBuffer::getMemBufferCopy( llvm::StringRef(section.data.data(), section.data.size())); } } @@ -290,7 +290,7 @@ struct LineState { // FIXME: look at AddrSize on the Unit. auto item = makeItem(llvm::dwarf::DW_LNE_set_address, 5); item.Data = addr; - newOpcodes.push_back(item); + newOpcodes.push_back(std::move(item)); } if (line != old.line && !useSpecial) { auto item = makeItem(llvm::dwarf::DW_LNS_advance_line); @@ -298,28 +298,28 @@ struct LineState { // negative (note that SData is 64-bit, as LLVM supports 64-bit // addresses too). item.SData = int32_t(line - old.line); - newOpcodes.push_back(item); + newOpcodes.push_back(std::move(item)); } if (col != old.col) { auto item = makeItem(llvm::dwarf::DW_LNS_set_column); item.Data = col; - newOpcodes.push_back(item); + newOpcodes.push_back(std::move(item)); } if (file != old.file) { auto item = makeItem(llvm::dwarf::DW_LNS_set_file); item.Data = file; - newOpcodes.push_back(item); + newOpcodes.push_back(std::move(item)); } if (isa != old.isa) { auto item = makeItem(llvm::dwarf::DW_LNS_set_isa); item.Data = isa; - newOpcodes.push_back(item); + newOpcodes.push_back(std::move(item)); } if (discriminator != old.discriminator) { // len = 1 (subopcode) + 4 (wasm32 address) auto item = makeItem(llvm::dwarf::DW_LNE_set_discriminator, 5); item.Data = discriminator; - newOpcodes.push_back(item); + newOpcodes.push_back(std::move(item)); } if (isStmt != old.isStmt) { newOpcodes.push_back(makeItem(llvm::dwarf::DW_LNS_negate_stmt)); @@ -391,6 +391,19 @@ struct AddrExprMap { // Construct the map from the binaryLocations loaded from the wasm. AddrExprMap(const Module& wasm) { + size_t numExprs = 0, numDelims = 0; + for (auto& func : wasm.functions) { + numExprs += func->expressionLocations.size(); + + for (auto& [expr, delim] : func->delimiterLocations) { + // May be a little large if 0-delimiters exist + numDelims += delim.size(); + } + } + startMap.reserve(numExprs); + endMap.reserve(numExprs); + delimiterMap.reserve(numDelims); + for (auto& func : wasm.functions) { for (auto& [expr, span] : func->expressionLocations) { add(expr, span); @@ -427,18 +440,22 @@ struct AddrExprMap { private: void add(Expression* expr, const BinaryLocations::Span span) { - assert(startMap.count(span.start) == 0); - startMap[span.start] = expr; - assert(endMap.count(span.end) == 0); - endMap[span.end] = expr; + { + [[maybe_unused]] bool inserted = startMap.emplace(span.start, expr).second; + assert(inserted); + } + { + [[maybe_unused]] bool inserted = endMap.emplace(span.end, expr).second; + assert(inserted); + } } void add(Expression* expr, const BinaryLocations::DelimiterLocations& delimiter) { for (Index i = 0; i < delimiter.size(); i++) { if (delimiter[i] != 0) { - assert(delimiterMap.count(delimiter[i]) == 0); - delimiterMap[delimiter[i]] = DelimiterInfo{expr, i}; + [[maybe_unused]] bool inserted = delimiterMap.emplace(delimiter[i], DelimiterInfo{expr, i}).second; + assert(inserted); } } } @@ -622,23 +639,27 @@ struct LocationUpdater { // TODO: should we track the start and end of delimiters, even though they // are just one byte? BinaryLocation getNewStart(BinaryLocation oldStart) const { - if (hasOldExprStart(oldStart)) { - return getNewExprStart(oldStart); - } else if (hasOldFuncStart(oldStart)) { - return getNewFuncStart(oldStart); - } else if (hasOldDelimiter(oldStart)) { - return getNewDelimiter(oldStart); + if (auto loc = getNewExprStart(oldStart)) { + return loc; + } + if (auto loc = getNewFuncStart(oldStart)) { + return loc; + } + if (auto loc = getNewDelimiter(oldStart)) { + return loc; } return 0; } BinaryLocation getNewEnd(BinaryLocation oldEnd) const { - if (hasOldExprEnd(oldEnd)) { - return getNewExprEnd(oldEnd); - } else if (hasOldFuncEnd(oldEnd)) { - return getNewFuncEnd(oldEnd); - } else if (hasOldDelimiter(oldEnd)) { - return getNewDelimiter(oldEnd); + if (auto loc = getNewExprEnd(oldEnd)) { + return loc; + } + if (auto loc = getNewFuncEnd(oldEnd)) { + return loc; + } + if (auto loc = getNewDelimiter(oldEnd)) { + return loc; } return 0; } @@ -706,21 +727,21 @@ static void updateDebugLines(llvm::DWARFYAML::Data& data, // it away. BinaryLocation oldAddr = state.addr; BinaryLocation newAddr = 0; - if (locationUpdater.hasOldExprStart(oldAddr)) { - newAddr = locationUpdater.getNewExprStart(oldAddr); + if (auto loc = locationUpdater.getNewExprStart(oldAddr)) { + newAddr = loc; } // Test for a function's end address first, as LLVM output appears to // use 1-past-the-end-of-the-function as a location in that function, // and not the next (but the first byte of the next function, which is // ambiguously identical to that value, is used at least in low_pc). - else if (locationUpdater.hasOldFuncEnd(oldAddr)) { - newAddr = locationUpdater.getNewFuncEnd(oldAddr); - } else if (locationUpdater.hasOldFuncStart(oldAddr)) { - newAddr = locationUpdater.getNewFuncStart(oldAddr); - } else if (locationUpdater.hasOldDelimiter(oldAddr)) { - newAddr = locationUpdater.getNewDelimiter(oldAddr); - } else if (locationUpdater.hasOldExprEnd(oldAddr)) { - newAddr = locationUpdater.getNewExprEnd(oldAddr); + else if ((loc = locationUpdater.getNewFuncEnd(oldAddr))) { + newAddr = loc; + } else if ((loc = locationUpdater.getNewFuncStart(oldAddr))) { + newAddr = loc; + } else if ((loc = locationUpdater.getNewDelimiter(oldAddr))) { + newAddr = loc; + } else if ((loc = locationUpdater.getNewExprEnd(oldAddr))) { + newAddr = loc; } if (newAddr && state.needToEmit()) { // LLVM sometimes emits the same address more than once. We should @@ -1075,36 +1096,42 @@ static void updateLoc(llvm::DWARFYAML::Data& yaml, } void writeDWARFSections(Module& wasm, const BinaryLocations& newLocations) { - BinaryenDWARFInfo info(wasm); - - // Convert to Data representation, which YAML can use to write. - llvm::DWARFYAML::Data data; - if (dwarf2yaml(*info.context, data)) { - Fatal() << "Failed to parse DWARF to YAML"; - } + llvm::StringMap> newSections; + { + BinaryenDWARFInfo info(wasm); + + // Convert to Data representation, which YAML can use to write. + llvm::DWARFYAML::Data data; + if (dwarf2yaml(*info.context, data)) { + Fatal() << "Failed to parse DWARF to YAML"; + } - LocationUpdater locationUpdater(wasm, newLocations); + { + LocationUpdater locationUpdater(wasm, newLocations); - updateDebugLines(data, locationUpdater); + updateDebugLines(data, locationUpdater); - bool is64 = wasm.memories.size() > 0 ? wasm.memories[0]->is64() : false; - updateCompileUnits(info, data, locationUpdater, is64); + bool is64 = wasm.memories.size() > 0 ? wasm.memories[0]->is64() : false; + updateCompileUnits(info, data, locationUpdater, is64); - updateRanges(data, locationUpdater); + updateRanges(data, locationUpdater); - updateLoc(data, locationUpdater); + updateLoc(data, locationUpdater); + } - // Convert to binary sections. - auto newSections = - EmitDebugSections(data, false /* EmitFixups for debug_info */); + // Convert to binary sections. + newSections = + EmitDebugSections(data, false /* EmitFixups for debug_info */); + } // Update the custom sections in the wasm. // TODO: efficiency for (auto& section : wasm.customSections) { - if (Name(section.name).startsWith(".debug_")) { - auto llvmName = section.name.substr(1); - if (newSections.count(llvmName)) { - auto llvmData = newSections[llvmName]->getBuffer(); + if (llvm::StringRef(section.name).startswith(".debug_")) { + auto llvmName = llvm::StringRef(section.name).substr(1); + auto it = newSections.find(llvmName); + if (it != newSections.end()) { + auto llvmData = it->second->getBuffer(); section.data.resize(llvmData.size()); std::copy(llvmData.begin(), llvmData.end(), section.data.data()); } diff --git a/third_party/llvm-project/dwarf2yaml.cpp b/third_party/llvm-project/dwarf2yaml.cpp index 13f5b968c0f..3c5cb507c2c 100644 --- a/third_party/llvm-project/dwarf2yaml.cpp +++ b/third_party/llvm-project/dwarf2yaml.cpp @@ -26,14 +26,21 @@ void dumpInitialLength(DataExtractor &Data, uint64_t &Offset, void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) { auto AbbrevSetPtr = DCtx.getDebugAbbrev(); if (AbbrevSetPtr) { - for (auto AbbrvDeclSet : *AbbrevSetPtr) { + size_t ReserveAttrs = 0; + for (const auto &AbbrvDeclSet : *AbbrevSetPtr) { + ReserveAttrs += AbbrvDeclSet.second.end() - AbbrvDeclSet.second.begin() + 1; + } + Y.AbbrevDecls.reserve(Y.AbbrevDecls.size() + ReserveAttrs); + + for (const auto &AbbrvDeclSet : *AbbrevSetPtr) { auto ListOffset = AbbrvDeclSet.second.getOffset(); - for (auto AbbrvDecl : AbbrvDeclSet.second) { + for (const auto &AbbrvDecl : AbbrvDeclSet.second) { DWARFYAML::Abbrev Abbrv; Abbrv.Code = AbbrvDecl.getCode(); Abbrv.Tag = AbbrvDecl.getTag(); Abbrv.Children = AbbrvDecl.hasChildren() ? dwarf::DW_CHILDREN_yes : dwarf::DW_CHILDREN_no; + Abbrv.Attributes.reserve(AbbrvDecl.getNumAttributes()); for (auto Attribute : AbbrvDecl.attributes()) { DWARFYAML::AttributeAbbrev AttAbrv; AttAbrv.Attribute = Attribute.Attr; @@ -43,7 +50,7 @@ void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) { Abbrv.Attributes.push_back(AttAbrv); } Abbrv.ListOffset = ListOffset; - Y.AbbrevDecls.push_back(Abbrv); + Y.AbbrevDecls.push_back(std::move(Abbrv)); } // XXX BINARYEN: null-terminate the DeclSet. This is needed to separate // DeclSets from each other, and to null-terminate the entire list @@ -52,7 +59,7 @@ void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) { DWARFYAML::Abbrev Abbrv; Abbrv.Code = 0; Abbrv.Tag = dwarf::Tag(0); - Y.AbbrevDecls.push_back(Abbrv); + Y.AbbrevDecls.push_back(std::move(Abbrv)); } } } @@ -79,13 +86,15 @@ void dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) { Range.CuOffset = Set.getHeader().CuOffset; Range.AddrSize = Set.getHeader().AddrSize; Range.SegSize = Set.getHeader().SegSize; + + Range.Descriptors.reserve(Set.descriptors().end() - Set.descriptors().begin()); for (auto Descriptor : Set.descriptors()) { DWARFYAML::ARangeDescriptor Desc; Desc.Address = Descriptor.Address; Desc.Length = Descriptor.Length; Range.Descriptors.push_back(Desc); } - Y.ARanges.push_back(Range); + Y.ARanges.push_back(std::move(Range)); } } @@ -139,17 +148,18 @@ void dumpDebugLoc(DWARFContext &DCtx, DWARFYAML::Data &Y) { // XXX BINARYEN DWARFYAML::Loc loc; loc.Start = entry.Begin; loc.End = entry.End; + loc.Location.reserve(entry.Loc.size()); for (auto x : entry.Loc) { loc.Location.push_back(x); } loc.CompileUnitOffset = locListOffset; // XXX BINARYEN - Y.Locs.push_back(loc); + Y.Locs.push_back(std::move(loc)); } DWARFYAML::Loc loc; loc.Start = 0; loc.End = 0; loc.CompileUnitOffset = locListOffset; // XXX BINARYEN - Y.Locs.push_back(loc); + Y.Locs.push_back(std::move(loc)); } } @@ -188,6 +198,7 @@ void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) { } void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) { + Y.CompileUnits.reserve(DCtx.getNumCompileUnits()); for (const auto &CU : DCtx.compile_units()) { DWARFYAML::Unit NewUnit; NewUnit.Length.setLength(CU->getLength()); @@ -198,6 +209,7 @@ void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) { NewUnit.AbbrOffset = Abbreviations->getOffset(); } NewUnit.AddrSize = CU->getAddressByteSize(); + NewUnit.Entries.reserve(CU->getNumDIEs()); for (auto DIE : CU->dies()) { DWARFYAML::Entry NewEntry; DataExtractor EntryData = CU->getDebugInfoExtractor(); @@ -211,6 +223,7 @@ void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) { auto AbbrevDecl = DIE.getAbbreviationDeclarationPtr(); if (AbbrevDecl) { + NewEntry.Values.reserve(AbbrevDecl->getNumAttributes()); for (const auto &AttrSpec : AbbrevDecl->attributes()) { DWARFYAML::FormValue NewValue; NewValue.Value = 0xDEADBEEFDEADBEEF; @@ -297,13 +310,13 @@ void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) { break; } } while (indirect); - NewEntry.Values.push_back(NewValue); + NewEntry.Values.push_back(std::move(NewValue)); } } - NewUnit.Entries.push_back(NewEntry); + NewUnit.Entries.push_back(std::move(NewEntry)); } - Y.CompileUnits.push_back(NewUnit); + Y.CompileUnits.push_back(std::move(NewUnit)); } } @@ -422,9 +435,9 @@ void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) { NewOp.StandardOpcodeData.push_back(LineData.getULEB128(&Offset)); } } - DebugLines.Opcodes.push_back(NewOp); + DebugLines.Opcodes.push_back(std::move(NewOp)); } - Y.DebugLines.push_back(DebugLines); + Y.DebugLines.push_back(std::move(DebugLines)); } } }