mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-12 12:33:17 +00:00
[DebugInfo] Make InstrRange into a class, NFC
Summary: Replace use of std::pair by creating a class for the debug value instruction ranges instead. This is a preparatory refactoring for improving handling of clobbered fragments. In an upcoming commit the Begin pointer will become a PointerIntPair, so it will be cleaner to have a getter for that. Reviewers: aprantl Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59938 llvm-svn: 358059
This commit is contained in:
parent
3886fc50e9
commit
168d2344ce
@ -24,13 +24,28 @@ class TargetRegisterInfo;
|
||||
// For each user variable, keep a list of instruction ranges where this variable
|
||||
// is accessible. The variables are listed in order of appearance.
|
||||
class DbgValueHistoryMap {
|
||||
// Each instruction range starts with a DBG_VALUE instruction, specifying the
|
||||
// location of a variable, which is assumed to be valid until the end of the
|
||||
// range. If end is not specified, location is valid until the start
|
||||
// instruction of the next instruction range, or until the end of the
|
||||
// function.
|
||||
public:
|
||||
using InstrRange = std::pair<const MachineInstr *, const MachineInstr *>;
|
||||
/// Specifies an instruction range where a DBG_VALUE is valid.
|
||||
///
|
||||
/// \p Begin is a DBG_VALUE instruction, specifying the location of a
|
||||
/// variable, which is assumed to be valid until the end of the range. If \p
|
||||
/// End is not specified, the location is valid until the first overlapping
|
||||
/// DBG_VALUE if any such DBG_VALUE exists, otherwise it is valid until the
|
||||
/// end of the function.
|
||||
class InstrRange {
|
||||
const MachineInstr *Begin;
|
||||
const MachineInstr *End;
|
||||
|
||||
public:
|
||||
InstrRange(const MachineInstr *Begin) : Begin(Begin), End(nullptr) {}
|
||||
|
||||
const MachineInstr *getBegin() const { return Begin; }
|
||||
const MachineInstr *getEnd() const { return End; }
|
||||
|
||||
bool isClosed() const { return End; }
|
||||
|
||||
void endRange(const MachineInstr &End);
|
||||
};
|
||||
using InstrRanges = SmallVector<InstrRange, 4>;
|
||||
using InlinedEntity = std::pair<const DINode *, const DILocation *>;
|
||||
using InstrRangesMap = MapVector<InlinedEntity, InstrRanges>;
|
||||
|
@ -1159,8 +1159,8 @@ void CodeViewDebug::calculateRanges(
|
||||
|
||||
// Calculate the definition ranges.
|
||||
for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
|
||||
const InsnRange &Range = *I;
|
||||
const MachineInstr *DVInst = Range.first;
|
||||
const auto &Range = *I;
|
||||
const MachineInstr *DVInst = Range.getBegin();
|
||||
assert(DVInst->isDebugValue() && "Invalid History entry");
|
||||
// FIXME: Find a way to represent constant variables, since they are
|
||||
// relatively common.
|
||||
@ -1215,18 +1215,18 @@ void CodeViewDebug::calculateRanges(
|
||||
}
|
||||
|
||||
// Compute the label range.
|
||||
const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
|
||||
const MCSymbol *End = getLabelAfterInsn(Range.second);
|
||||
const MCSymbol *Begin = getLabelBeforeInsn(Range.getBegin());
|
||||
const MCSymbol *End = getLabelAfterInsn(Range.getEnd());
|
||||
if (!End) {
|
||||
// This range is valid until the next overlapping bitpiece. In the
|
||||
// common case, ranges will not be bitpieces, so they will overlap.
|
||||
auto J = std::next(I);
|
||||
const DIExpression *DIExpr = DVInst->getDebugExpression();
|
||||
while (J != E &&
|
||||
!DIExpr->fragmentsOverlap(J->first->getDebugExpression()))
|
||||
!DIExpr->fragmentsOverlap(J->getBegin()->getDebugExpression()))
|
||||
++J;
|
||||
if (J != E)
|
||||
End = getLabelBeforeInsn(J->first);
|
||||
End = getLabelBeforeInsn(J->getBegin());
|
||||
else
|
||||
End = Asm->getFunctionEnd();
|
||||
}
|
||||
|
@ -47,24 +47,29 @@ void DbgValueHistoryMap::startInstrRange(InlinedEntity Var,
|
||||
// variable.
|
||||
assert(MI.isDebugValue() && "not a DBG_VALUE");
|
||||
auto &Ranges = VarInstrRanges[Var];
|
||||
if (!Ranges.empty() && Ranges.back().second == nullptr &&
|
||||
Ranges.back().first->isIdenticalTo(MI)) {
|
||||
if (!Ranges.empty() && !Ranges.back().isClosed() &&
|
||||
Ranges.back().getBegin()->isIdenticalTo(MI)) {
|
||||
LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
|
||||
<< "\t" << Ranges.back().first << "\t" << MI << "\n");
|
||||
<< "\t" << Ranges.back().getBegin() << "\t" << MI
|
||||
<< "\n");
|
||||
return;
|
||||
}
|
||||
Ranges.push_back(std::make_pair(&MI, nullptr));
|
||||
Ranges.emplace_back(&MI);
|
||||
}
|
||||
|
||||
void DbgValueHistoryMap::endInstrRange(InlinedEntity Var,
|
||||
const MachineInstr &MI) {
|
||||
auto &Ranges = VarInstrRanges[Var];
|
||||
// Verify that the current instruction range is not yet closed.
|
||||
assert(!Ranges.empty() && Ranges.back().second == nullptr);
|
||||
assert(!Ranges.empty() && "No range exists for variable!");
|
||||
Ranges.back().endRange(MI);
|
||||
}
|
||||
|
||||
void DbgValueHistoryMap::InstrRange::endRange(const MachineInstr &MI) {
|
||||
// For now, instruction ranges are not allowed to cross basic block
|
||||
// boundaries.
|
||||
assert(Ranges.back().first->getParent() == MI.getParent());
|
||||
Ranges.back().second = &MI;
|
||||
assert(Begin->getParent() == MI.getParent());
|
||||
assert(!isClosed() && "Range is already closed!");
|
||||
End = &MI;
|
||||
}
|
||||
|
||||
unsigned DbgValueHistoryMap::getRegisterForVar(InlinedEntity Var) const {
|
||||
@ -72,9 +77,9 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedEntity Var) const {
|
||||
if (I == VarInstrRanges.end())
|
||||
return 0;
|
||||
const auto &Ranges = I->second;
|
||||
if (Ranges.empty() || Ranges.back().second != nullptr)
|
||||
if (Ranges.empty() || Ranges.back().isClosed())
|
||||
return 0;
|
||||
return isDescribedByReg(*Ranges.back().first);
|
||||
return isDescribedByReg(*Ranges.back().getBegin());
|
||||
}
|
||||
|
||||
void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) {
|
||||
@ -304,9 +309,9 @@ LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const {
|
||||
dbgs() << " --\n";
|
||||
|
||||
for (const InstrRange &Range : Ranges) {
|
||||
dbgs() << " Begin: " << *Range.first;
|
||||
if (Range.second)
|
||||
dbgs() << " End : " << *Range.second;
|
||||
dbgs() << " Begin: " << *Range.getBegin();
|
||||
if (Range.getEnd())
|
||||
dbgs() << " End : " << *Range.getEnd();
|
||||
dbgs() << "\n";
|
||||
}
|
||||
}
|
||||
|
@ -228,31 +228,32 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
|
||||
// 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 = Ranges.front().first->getDebugVariable();
|
||||
const DILocalVariable *DIVar =
|
||||
Ranges.front().getBegin()->getDebugVariable();
|
||||
if (DIVar->isParameter() &&
|
||||
getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
|
||||
if (!IsDescribedByReg(Ranges.front().first))
|
||||
LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
|
||||
if (Ranges.front().first->getDebugExpression()->isFragment()) {
|
||||
if (!IsDescribedByReg(Ranges.front().getBegin()))
|
||||
LabelsBeforeInsn[Ranges.front().getBegin()] = Asm->getFunctionBegin();
|
||||
if (Ranges.front().getBegin()->getDebugExpression()->isFragment()) {
|
||||
// Mark all non-overlapping initial fragments.
|
||||
for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
|
||||
const DIExpression *Fragment = I->first->getDebugExpression();
|
||||
const DIExpression *Fragment = I->getBegin()->getDebugExpression();
|
||||
if (std::any_of(Ranges.begin(), I,
|
||||
[&](DbgValueHistoryMap::InstrRange Pred) {
|
||||
return Fragment->fragmentsOverlap(
|
||||
Pred.first->getDebugExpression());
|
||||
Pred.getBegin()->getDebugExpression());
|
||||
}))
|
||||
break;
|
||||
if (!IsDescribedByReg(I->first))
|
||||
LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();
|
||||
if (!IsDescribedByReg(I->getBegin()))
|
||||
LabelsBeforeInsn[I->getBegin()] = Asm->getFunctionBegin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &Range : Ranges) {
|
||||
requestLabelBeforeInsn(Range.first);
|
||||
if (Range.second)
|
||||
requestLabelAfterInsn(Range.second);
|
||||
requestLabelBeforeInsn(Range.getBegin());
|
||||
if (Range.getEnd())
|
||||
requestLabelAfterInsn(Range.getEnd());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1123,8 +1123,8 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
|
||||
SmallVector<DebugLocEntry::Value, 4> OpenRanges;
|
||||
|
||||
for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
|
||||
const MachineInstr *Begin = I->first;
|
||||
const MachineInstr *End = I->second;
|
||||
const MachineInstr *Begin = I->getBegin();
|
||||
const MachineInstr *End = I->getEnd();
|
||||
assert(Begin->isDebugValue() && "Invalid History entry");
|
||||
|
||||
// Check if a variable is inaccessible in this range.
|
||||
@ -1150,7 +1150,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
|
||||
else if (std::next(I) == Ranges.end())
|
||||
EndLabel = Asm->getFunctionEnd();
|
||||
else
|
||||
EndLabel = getLabelBeforeInsn(std::next(I)->first);
|
||||
EndLabel = getLabelBeforeInsn(std::next(I)->getBegin());
|
||||
assert(EndLabel && "Forgot label after instruction ending a range!");
|
||||
|
||||
LLVM_DEBUG(dbgs() << "DotDebugLoc: " << *Begin << "\n");
|
||||
@ -1293,12 +1293,12 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
||||
DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
|
||||
*Scope, LocalVar, IV.second));
|
||||
|
||||
const MachineInstr *MInsn = Ranges.front().first;
|
||||
const MachineInstr *MInsn = Ranges.front().getBegin();
|
||||
assert(MInsn->isDebugValue() && "History must begin with debug value");
|
||||
|
||||
// Check if there is a single DBG_VALUE, valid throughout the var's scope.
|
||||
if (Ranges.size() == 1 &&
|
||||
validThroughout(LScopes, MInsn, Ranges.front().second)) {
|
||||
validThroughout(LScopes, MInsn, Ranges.front().getEnd())) {
|
||||
RegVar->initializeDbgValue(MInsn);
|
||||
continue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user