diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index 551cd36d1984..22f458e4b03e 100644 --- a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -1,9 +1,8 @@ //===-- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp -------*- C++ -*--===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -141,10 +140,9 @@ DebugHandlerBase::getFunctionLocalOffsetAfterInsn(const MachineInstr *MI) { } /// If this type is derived from a base type then return base type size. -uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) { - DIType *Ty = TyRef.resolve(); +uint64_t DebugHandlerBase::getBaseTypeSize(const DIType *Ty) { assert(Ty); - DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty); + const DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty); if (!DDTy) return Ty->getSizeInBits(); @@ -155,7 +153,7 @@ uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) { Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type) return DDTy->getSizeInBits(); - DIType *BaseType = DDTy->getBaseType().resolve(); + DIType *BaseType = DDTy->getBaseType(); if (!BaseType) return 0; @@ -212,36 +210,58 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) { // Request labels for the full history. for (const auto &I : DbgValues) { - const auto &Ranges = I.second; - if (Ranges.empty()) + const auto &Entries = I.second; + if (Entries.empty()) continue; - // The first mention of a function argument gets the CurrentFnBegin - // label, so arguments are visible when breaking at function entry. - const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable(); + auto IsDescribedByReg = [](const MachineInstr *MI) { + return MI->getOperand(0).isReg() && MI->getOperand(0).getReg(); + }; + + // The first mention of a function argument gets the CurrentFnBegin label, + // so arguments are visible when breaking at function entry. + // + // We do not change the label for values that are described by registers, + // as that could place them above their defining instructions. We should + // ideally not change the labels for constant debug values either, since + // doing that violates the ranges that are calculated in the history map. + // However, we currently do not emit debug values for constant arguments + // directly at the start of the function, so this code is still useful. + const DILocalVariable *DIVar = + Entries.front().getInstr()->getDebugVariable(); if (DIVar->isParameter() && getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) { - LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin(); - if (Ranges.front().first->getDebugExpression()->isFragment()) { + if (!IsDescribedByReg(Entries.front().getInstr())) + LabelsBeforeInsn[Entries.front().getInstr()] = Asm->getFunctionBegin(); + if (Entries.front().getInstr()->getDebugExpression()->isFragment()) { // Mark all non-overlapping initial fragments. - for (auto I = Ranges.begin(); I != Ranges.end(); ++I) { - const DIExpression *Fragment = I->first->getDebugExpression(); - if (std::all_of(Ranges.begin(), I, - [&](DbgValueHistoryMap::InstrRange Pred) { - return !Fragment->fragmentsOverlap( - Pred.first->getDebugExpression()); + for (auto I = Entries.begin(); I != Entries.end(); ++I) { + if (!I->isDbgValue()) + continue; + const DIExpression *Fragment = I->getInstr()->getDebugExpression(); + if (std::any_of(Entries.begin(), I, + [&](DbgValueHistoryMap::Entry Pred) { + return Pred.isDbgValue() && + Fragment->fragmentsOverlap( + Pred.getInstr()->getDebugExpression()); })) - LabelsBeforeInsn[I->first] = Asm->getFunctionBegin(); - else break; + // The code that generates location lists for DWARF assumes that the + // entries' start labels are monotonically increasing, and since we + // don't change the label for fragments that are described by + // registers, we must bail out when encountering such a fragment. + if (IsDescribedByReg(I->getInstr())) + break; + LabelsBeforeInsn[I->getInstr()] = Asm->getFunctionBegin(); } } } - for (const auto &Range : Ranges) { - requestLabelBeforeInsn(Range.first); - if (Range.second) - requestLabelAfterInsn(Range.second); + for (const auto &Entry : Entries) { + if (Entry.isDbgValue()) + requestLabelBeforeInsn(Entry.getInstr()); + else + requestLabelAfterInsn(Entry.getInstr()); } } |