summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorBob Haarman <llvm@inglorion.net>2017-08-29 04:08:31 +0000
committerBob Haarman <llvm@inglorion.net>2017-08-29 04:08:31 +0000
commit0bf0d666823a5e6cfbe2e54c33b1792eb202ae81 (patch)
tree1094683de09cc6aa05b0ab2a13eba1902d7d678e /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parent858d0983830cfbfdd269a4b72e7fb45f12909beb (diff)
downloadbcm5719-llvm-0bf0d666823a5e6cfbe2e54c33b1792eb202ae81.tar.gz
bcm5719-llvm-0bf0d666823a5e6cfbe2e54c33b1792eb202ae81.zip
Revert "[codeview] support more DW_OPs for more complete debug info"
This reverts commit e160912f53f047bc97e572add179e08e33f4df48. llvm-svn: 311977
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp191
1 files changed, 86 insertions, 105 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index ed2c263d320..8879f6b1f3e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -949,103 +949,13 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
}
}
-void CodeViewDebug::calculateRanges(
- LocalVariable &Var, const DbgValueHistoryMap::InstrRanges &Ranges) {
- const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();
-
- // calculate the definition ranges.
- for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
- const InsnRange &Range = *I;
- const MachineInstr *DVInst = Range.first;
- assert(DVInst->isDebugValue() && "Invalid History entry");
- // FIXME: Find a way to represent constant variables, since they are
- // relatively common.
- DbgVariableLocation Location;
- bool Supported =
- DbgVariableLocation::extractFromMachineInstruction(Location, *DVInst);
-
- // Because we cannot express DW_OP_deref in CodeView directly,
- // we use a trick: we encode the type as a reference to the
- // real type.
- if (Var.Deref) {
- // When we're encoding the type as a reference to the original type,
- // we need to remove a level of indirection from incoming locations.
- // E.g. [RSP+8] with DW_OP_deref becomes [RSP+8],
- // and [RCX+0] without DW_OP_deref becomes RCX.
- if (!Location.Deref) {
- if (Location.InMemory)
- Location.InMemory = false;
- else
- Supported = false;
- }
- } else if (Location.Deref) {
- // We've encountered a Deref range when we had not applied the
- // reference encoding. Start over using reference encoding.
- Var.Deref = true;
- Var.DefRanges.clear();
- calculateRanges(Var, Ranges);
- return;
- }
-
- // If we don't know how to handle this range, skip past it.
- if (!Supported || (Location.Offset && !Location.InMemory))
- continue;
-
- // Handle the two cases we can handle: indirect in memory and in register.
- {
- LocalVarDefRange DR;
- DR.CVRegister = TRI->getCodeViewRegNum(Location.Register);
- DR.InMemory = Location.InMemory;
- DR.DataOffset = Location.Offset;
- if (Location.FragmentInfo) {
- DR.IsSubfield = true;
- DR.StructOffset = Location.FragmentInfo->OffsetInBits / 8;
- } else {
- DR.IsSubfield = false;
- DR.StructOffset = 0;
- }
-
- if (Var.DefRanges.empty() ||
- Var.DefRanges.back().isDifferentLocation(DR)) {
- Var.DefRanges.emplace_back(std::move(DR));
- }
- }
-
- // Compute the label range.
- const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
- const MCSymbol *End = getLabelAfterInsn(Range.second);
- 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 &&
- !fragmentsOverlap(DIExpr, J->first->getDebugExpression()))
- ++J;
- if (J != E)
- End = getLabelBeforeInsn(J->first);
- else
- End = Asm->getFunctionEnd();
- }
-
- // If the last range end is our begin, just extend the last range.
- // Otherwise make a new range.
- SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R =
- Var.DefRanges.back().Ranges;
- if (!R.empty() && R.back().second == Begin)
- R.back().second = End;
- else
- R.emplace_back(Begin, End);
-
- // FIXME: Do more range combining.
- }
-}
-
void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
DenseSet<InlinedVariable> Processed;
// Grab the variable info that was squirreled away in the MMI side-table.
collectVariableInfoFromMFTable(Processed);
+ const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();
+
for (const auto &I : DbgValues) {
InlinedVariable IV = I.first;
if (Processed.count(IV))
@@ -1068,7 +978,89 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
LocalVariable Var;
Var.DIVar = DIVar;
- calculateRanges(Var, Ranges);
+ // Calculate the definition ranges.
+ for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
+ const InsnRange &Range = *I;
+ const MachineInstr *DVInst = Range.first;
+ assert(DVInst->isDebugValue() && "Invalid History entry");
+ const DIExpression *DIExpr = DVInst->getDebugExpression();
+ bool InMemory = DVInst->getOperand(1).isImm();
+ bool IsSubfield = false;
+ unsigned StructOffset = 0;
+ // Recognize a +Offset expression.
+ int Offset = 0;
+ DIExpressionCursor Ops(DIExpr);
+ auto Op = Ops.peek();
+ if (Op && Op->getOp() == dwarf::DW_OP_plus_uconst) {
+ Offset = Op->getArg(0);
+ Ops.take();
+ }
+
+ // Handle fragments.
+ auto Fragment = Ops.getFragmentInfo();
+ if (Fragment) {
+ IsSubfield = true;
+ StructOffset = Fragment->OffsetInBits / 8;
+ }
+ // Ignore unrecognized exprs.
+ if (Ops.peek() && Ops.peek()->getOp() != dwarf::DW_OP_LLVM_fragment)
+ continue;
+ if (!InMemory && Offset)
+ continue;
+
+ // Bail if operand 0 is not a valid register. This means the variable is a
+ // simple constant, or is described by a complex expression.
+ // FIXME: Find a way to represent constant variables, since they are
+ // relatively common.
+ unsigned Reg =
+ DVInst->getOperand(0).isReg() ? DVInst->getOperand(0).getReg() : 0;
+ if (Reg == 0)
+ continue;
+
+ // Handle the two cases we can handle: indirect in memory and in register.
+ unsigned CVReg = TRI->getCodeViewRegNum(Reg);
+ {
+ LocalVarDefRange DR;
+ DR.CVRegister = CVReg;
+ DR.InMemory = InMemory;
+ DR.DataOffset = Offset;
+ DR.IsSubfield = IsSubfield;
+ DR.StructOffset = StructOffset;
+
+ if (Var.DefRanges.empty() ||
+ Var.DefRanges.back().isDifferentLocation(DR)) {
+ Var.DefRanges.emplace_back(std::move(DR));
+ }
+ }
+
+ // Compute the label range.
+ const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
+ const MCSymbol *End = getLabelAfterInsn(Range.second);
+ 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);
+ while (J != E &&
+ !fragmentsOverlap(DIExpr, J->first->getDebugExpression()))
+ ++J;
+ if (J != E)
+ End = getLabelBeforeInsn(J->first);
+ else
+ End = Asm->getFunctionEnd();
+ }
+
+ // If the last range end is our begin, just extend the last range.
+ // Otherwise make a new range.
+ SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &Ranges =
+ Var.DefRanges.back().Ranges;
+ if (!Ranges.empty() && Ranges.back().second == Begin)
+ Ranges.back().second = End;
+ else
+ Ranges.emplace_back(Begin, End);
+
+ // FIXME: Do more range combining.
+ }
+
recordLocalVariable(std::move(Var), InlinedAt);
}
}
@@ -1995,16 +1987,6 @@ TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) {
return recordTypeIndexForDINode(Ty, TI, ClassTy);
}
-TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(DITypeRef TypeRef) {
- DIType *Ty = TypeRef.resolve();
- PointerRecord PR(getTypeIndex(Ty),
- getPointerSizeInBytes() == 8 ? PointerKind::Near64
- : PointerKind::Near32,
- PointerMode::LValueReference, PointerOptions::None,
- Ty->getSizeInBits() / 8);
- return TypeTable.writeKnownType(PR);
-}
-
TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) {
const DIType *Ty = TypeRef.resolve();
@@ -2112,8 +2094,7 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
Flags |= LocalSymFlags::IsOptimizedOut;
OS.AddComment("TypeIndex");
- TypeIndex TI = Var.Deref ? getTypeIndexForReferenceTo(Var.DIVar->getType())
- : getCompleteTypeIndex(Var.DIVar->getType());
+ TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType());
OS.EmitIntValue(TI.getIndex(), 4);
OS.AddComment("Flags");
OS.EmitIntValue(static_cast<uint16_t>(Flags), 2);
OpenPOWER on IntegriCloud