summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp191
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h6
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp51
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h30
4 files changed, 86 insertions, 192 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);
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 4345bb4d1c2..91f691c635e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -94,7 +94,6 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
struct LocalVariable {
const DILocalVariable *DIVar = nullptr;
SmallVector<LocalVarDefRange, 1> DefRanges;
- bool Deref = false;
};
struct InlineSite {
@@ -148,9 +147,6 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP);
- void calculateRanges(LocalVariable &Var,
- const DbgValueHistoryMap::InstrRanges &Ranges);
-
static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,
const FunctionInfo &FI,
const InlineSite &Site);
@@ -263,8 +259,6 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex getTypeIndex(DITypeRef TypeRef,
DITypeRef ClassTyRef = DITypeRef());
- codeview::TypeIndex getTypeIndexForReferenceTo(DITypeRef TypeRef);
-
codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP,
const DICompositeType *Class);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 4f647de1ed2..0971c594220 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -23,57 +23,6 @@
using namespace llvm;
-bool DbgVariableLocation::extractFromMachineInstruction(
- DbgVariableLocation &Location, const MachineInstr &Instruction) {
- if (!Instruction.isDebugValue())
- return false;
- if (!Instruction.getOperand(0).isReg())
- return false;
- Location.Register = Instruction.getOperand(0).getReg();
- Location.InMemory = Instruction.getOperand(1).isImm();
- Location.Deref = false;
- Location.FragmentInfo.reset();
- // We only handle expressions generated by DIExpression::appendOffset,
- // which doesn't require a full stack machine.
- int64_t Offset = 0;
- const DIExpression *DIExpr = Instruction.getDebugExpression();
- auto Op = DIExpr->expr_op_begin();
- while (Op != DIExpr->expr_op_end()) {
- switch (Op->getOp()) {
- case dwarf::DW_OP_constu: {
- int Value = Op->getArg(0);
- ++Op;
- if (Op != DIExpr->expr_op_end()) {
- switch (Op->getOp()) {
- case dwarf::DW_OP_minus:
- Offset -= Value;
- break;
- case dwarf::DW_OP_plus:
- Offset += Value;
- default:
- continue;
- }
- }
- } break;
- case dwarf::DW_OP_plus_uconst:
- Offset += Op->getArg(0);
- break;
- case dwarf::DW_OP_LLVM_fragment:
- Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
- break;
- case dwarf::DW_OP_deref:
- Location.Deref = true;
- break;
- default:
- return false;
- }
- ++Op;
- }
-
- Location.Offset = Offset;
- return true;
-}
-
DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
// Each LexicalScope has first instruction and last instruction to mark
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
index 670300cd7a6..659a921e1fc 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
@@ -17,44 +17,14 @@
#include "AsmPrinterHandler.h"
#include "DbgValueHistoryCalculator.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/IR/DebugInfoMetadata.h"
namespace llvm {
class AsmPrinter;
-class MachineInstr;
class MachineModuleInfo;
-/// Represents the location at which a variable is stored.
-struct DbgVariableLocation {
- /// Offset relative to base register.
- int64_t Offset;
-
- /// Base register.
- unsigned Register;
-
- /// If false, Register is the location. If true,
- /// Register+Offset point at the location.
- unsigned InMemory : 1;
-
- /// If false, the location holds the variable's value.
- /// If true, the location holds the variable's address.
- unsigned Deref : 1;
-
- /// Present if the location is part of a larger variable.
- llvm::Optional<llvm::DIExpression::FragmentInfo> FragmentInfo;
-
- /// Extract a VariableLocation from a MachineInstr. The struct passed in as
- /// Location is populated. The MachineInstr must be a debug value
- /// instruction.
- /// @return true if successful and false if not.
- static bool extractFromMachineInstruction(DbgVariableLocation &Location,
- const MachineInstr &Instruction);
-};
-
/// Base class for debug information backends. Common functionality related to
/// tracking which variables and scopes are alive at a given PC live here.
class DebugHandlerBase : public AsmPrinterHandler {
OpenPOWER on IntegriCloud