summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2014-10-01 17:55:39 +0000
committerAdrian Prantl <aprantl@apple.com>2014-10-01 17:55:39 +0000
commit25a7174e7a2ef0267486170570380a4dc2d0dd32 (patch)
tree5ee77fa5bc3d02a48871c8e348970ebfa5ef73bc /llvm/lib/CodeGen
parent1400aaf8c82d439d5ca322519b29ff12b19338d3 (diff)
downloadbcm5719-llvm-25a7174e7a2ef0267486170570380a4dc2d0dd32.tar.gz
bcm5719-llvm-25a7174e7a2ef0267486170570380a4dc2d0dd32.zip
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics. Previously, DIVariable was a variable-length field that has an optional reference to a Metadata array consisting of a variable number of complex address expressions. In the case of OpPiece expressions this is wasting a lot of storage in IR, because when an aggregate type is, e.g., SROA'd into all of its n individual members, the IR will contain n copies of the DIVariable, all alike, only differing in the complex address reference at the end. By making the complex address into an extra argument of the dbg.value/dbg.declare intrinsics, all of the pieces can reference the same variable and the complex address expressions can be uniqued across the CU, too. Down the road, this will allow us to move other flags, such as "indirection" out of the DIVariable, too. The new intrinsics look like this: declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr) declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr) This patch adds a new LLVM-local tag to DIExpressions, so we can detect and pretty-print DIExpression metadata nodes. What this patch doesn't do: This patch does not touch the "Indirect" field in DIVariable; but moving that into the expression would be a natural next step. http://reviews.llvm.org/D4919 rdar://problem/17994491 Thanks to dblaikie and dexonsmith for reviewing this patch! llvm-svn: 218778
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp12
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp6
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h46
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp94
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h21
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp24
-rw-r--r--llvm/lib/CodeGen/InlineSpiller.cpp8
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp48
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp9
-rw-r--r--llvm/lib/CodeGen/RegAllocFast.cpp17
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp21
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp11
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h34
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp34
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp58
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp17
18 files changed, 269 insertions, 195 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 4eb289afc18..faba9f17c5f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -614,8 +614,8 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {
/// of DBG_VALUE, returning true if it was able to do so. A false return
/// means the target will need to handle MI in EmitInstruction.
static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
- // This code handles only the 3-operand target-independent form.
- if (MI->getNumOperands() != 3)
+ // This code handles only the 4-operand target-independent form.
+ if (MI->getNumOperands() != 4)
return false;
SmallString<128> Str;
@@ -629,9 +629,11 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
OS << Name << ":";
}
OS << V.getName();
- if (V.isVariablePiece())
- OS << " [piece offset=" << V.getPieceOffset()
- << " size="<<V.getPieceSize()<<"]";
+
+ DIExpression Expr = MI->getDebugExpression();
+ if (Expr.isVariablePiece())
+ OS << " [piece offset=" << Expr.getPieceOffset()
+ << " size=" << Expr.getPieceSize() << "]";
OS << " <- ";
// The second operand is only an offset if it's an immediate.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
index 998c396924b..a258d621a6a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
@@ -27,7 +27,7 @@ namespace llvm {
// In the other case, returns 0.
static unsigned isDescribedByReg(const MachineInstr &MI) {
assert(MI.isDebugValue());
- assert(MI.getNumOperands() == 3);
+ assert(MI.getNumOperands() == 4);
// If location of variable is described using a register (directly or
// indirecltly), this register is always a first operand.
return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
@@ -37,7 +37,7 @@ void DbgValueHistoryMap::startInstrRange(const MDNode *Var,
const MachineInstr &MI) {
// Instruction range should start with a DBG_VALUE instruction for the
// variable.
- assert(MI.isDebugValue() && getEntireVariable(MI.getDebugVariable()) == Var);
+ assert(MI.isDebugValue() && "not a DBG_VALUE");
auto &Ranges = VarInstrRanges[Var];
if (!Ranges.empty() && Ranges.back().second == nullptr &&
Ranges.back().first->isIdenticalTo(&MI)) {
@@ -193,7 +193,7 @@ void calculateDbgValueHistory(const MachineFunction *MF,
// Use the base variable (without any DW_OP_piece expressions)
// as index into History. The full variables including the
// piece expressions are attached to the MI.
- DIVariable Var = getEntireVariable(MI.getDebugVariable());
+ DIVariable Var = MI.getDebugVariable();
if (unsigned PrevReg = Result.getRegisterForVar(Var))
dropRegDescribedVar(RegVars, PrevReg, Var);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 6af049ad683..6cca985cfce 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -26,25 +26,30 @@ class DebugLocEntry {
public:
/// A single location or constant.
struct Value {
- Value(const MDNode *Var, int64_t i)
- : Variable(Var), EntryKind(E_Integer) {
+ Value(const MDNode *Var, const MDNode *Expr, int64_t i)
+ : Variable(Var), Expression(Expr), EntryKind(E_Integer) {
Constant.Int = i;
}
- Value(const MDNode *Var, const ConstantFP *CFP)
- : Variable(Var), EntryKind(E_ConstantFP) {
+ Value(const MDNode *Var, const MDNode *Expr, const ConstantFP *CFP)
+ : Variable(Var), Expression(Expr), EntryKind(E_ConstantFP) {
Constant.CFP = CFP;
}
- Value(const MDNode *Var, const ConstantInt *CIP)
- : Variable(Var), EntryKind(E_ConstantInt) {
+ Value(const MDNode *Var, const MDNode *Expr, const ConstantInt *CIP)
+ : Variable(Var), Expression(Expr), EntryKind(E_ConstantInt) {
Constant.CIP = CIP;
}
- Value(const MDNode *Var, MachineLocation Loc)
- : Variable(Var), EntryKind(E_Location), Loc(Loc) {
+ Value(const MDNode *Var, const MDNode *Expr, MachineLocation Loc)
+ : Variable(Var), Expression(Expr), EntryKind(E_Location), Loc(Loc) {
+ assert(DIVariable(Var).Verify());
+ assert(DIExpression(Expr).Verify());
}
// The variable to which this location entry corresponds.
const MDNode *Variable;
+ // Any complex address location expression for this Value.
+ const MDNode *Expression;
+
// Type of entry that this represents.
enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
enum EntryType EntryKind;
@@ -69,7 +74,8 @@ public:
MachineLocation getLoc() const { return Loc; }
const MDNode *getVariableNode() const { return Variable; }
DIVariable getVariable() const { return DIVariable(Variable); }
- bool isVariablePiece() const { return getVariable().isVariablePiece(); }
+ bool isVariablePiece() const { return getExpression().isVariablePiece(); }
+ DIExpression getExpression() const { return DIExpression(Expression); }
friend bool operator==(const Value &, const Value &);
friend bool operator<(const Value &, const Value &);
};
@@ -90,11 +96,13 @@ public:
// list of values.
// Return true if the merge was successful.
bool MergeValues(const DebugLocEntry &Next) {
- if (Begin == Next.Begin && Values.size() > 0 && Next.Values.size() > 0) {
+ if (Begin == Next.Begin) {
+ DIExpression Expr(Values[0].Expression);
DIVariable Var(Values[0].Variable);
+ DIExpression NextExpr(Next.Values[0].Expression);
DIVariable NextVar(Next.Values[0].Variable);
- if (Var.getName() == NextVar.getName() &&
- Var.isVariablePiece() && NextVar.isVariablePiece()) {
+ if (Var == NextVar && Expr.isVariablePiece() &&
+ NextExpr.isVariablePiece()) {
addValues(Next.Values);
End = Next.End;
return true;
@@ -133,8 +141,10 @@ public:
std::sort(Values.begin(), Values.end());
Values.erase(std::unique(Values.begin(), Values.end(),
[](const Value &A, const Value &B) {
- return A.getVariable() == B.getVariable();
- }), Values.end());
+ return A.getVariable() == B.getVariable() &&
+ A.getExpression() == B.getExpression();
+ }),
+ Values.end());
}
};
@@ -144,7 +154,10 @@ inline bool operator==(const DebugLocEntry::Value &A,
if (A.EntryKind != B.EntryKind)
return false;
- if (A.getVariable() != B.getVariable())
+ if (A.Expression != B.Expression)
+ return false;
+
+ if (A.Variable != B.Variable)
return false;
switch (A.EntryKind) {
@@ -163,7 +176,8 @@ inline bool operator==(const DebugLocEntry::Value &A,
/// Compare two pieces based on their offset.
inline bool operator<(const DebugLocEntry::Value &A,
const DebugLocEntry::Value &B) {
- return A.getVariable().getPieceOffset() < B.getVariable().getPieceOffset();
+ return A.getExpression().getPieceOffset() <
+ B.getExpression().getPieceOffset();
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 4745974a3d2..c54fc989569 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -901,7 +901,7 @@ void DwarfDebug::collectDeadVariables() {
for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) {
DIVariable DV(Variables.getElement(vi));
assert(DV.isVariable());
- DbgVariable NewVar(DV, this);
+ DbgVariable NewVar(DV, DIExpression(nullptr), this);
auto VariableDie = SPCU->constructVariableDIE(NewVar);
SPCU->applyVariableAttributes(NewVar, *VariableDie);
SPDIE->addChild(std::move(VariableDie));
@@ -1121,7 +1121,7 @@ DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV) {
void DwarfDebug::createAbstractVariable(const DIVariable &Var,
LexicalScope *Scope) {
- auto AbsDbgVariable = make_unique<DbgVariable>(Var, this);
+ auto AbsDbgVariable = make_unique<DbgVariable>(Var, DIExpression(), this);
addScopeVariable(Scope, AbsDbgVariable.get());
AbstractVariables[Var] = std::move(AbsDbgVariable);
}
@@ -1177,6 +1177,7 @@ void DwarfDebug::collectVariableInfoFromMMITable(
continue;
Processed.insert(VI.Var);
DIVariable DV(VI.Var);
+ DIExpression Expr(VI.Expr);
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
// If variable scope is not found then skip this variable.
@@ -1184,7 +1185,7 @@ void DwarfDebug::collectVariableInfoFromMMITable(
continue;
ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
- ConcreteVariables.push_back(make_unique<DbgVariable>(DV, this));
+ ConcreteVariables.push_back(make_unique<DbgVariable>(DV, Expr, this));
DbgVariable *RegVar = ConcreteVariables.back().get();
RegVar->setFrameIndex(VI.Slot);
addScopeVariable(Scope, RegVar);
@@ -1193,9 +1194,10 @@ void DwarfDebug::collectVariableInfoFromMMITable(
// Get .debug_loc entry for the instruction range starting at MI.
static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
+ const MDNode *Expr = MI->getDebugExpression();
const MDNode *Var = MI->getDebugVariable();
- assert(MI->getNumOperands() == 3);
+ assert(MI->getNumOperands() == 4);
if (MI->getOperand(0).isReg()) {
MachineLocation MLoc;
// If the second operand is an immediate, this is a
@@ -1204,20 +1206,20 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
MLoc.set(MI->getOperand(0).getReg());
else
MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
- return DebugLocEntry::Value(Var, MLoc);
+ return DebugLocEntry::Value(Var, Expr, MLoc);
}
if (MI->getOperand(0).isImm())
- return DebugLocEntry::Value(Var, MI->getOperand(0).getImm());
+ return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getImm());
if (MI->getOperand(0).isFPImm())
- return DebugLocEntry::Value(Var, MI->getOperand(0).getFPImm());
+ return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getFPImm());
if (MI->getOperand(0).isCImm())
- return DebugLocEntry::Value(Var, MI->getOperand(0).getCImm());
+ return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getCImm());
- llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!");
+ llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
}
/// Determine whether two variable pieces overlap.
-static bool piecesOverlap(DIVariable P1, DIVariable P2) {
+static bool piecesOverlap(DIExpression P1, DIExpression P2) {
if (!P1.isVariablePiece() || !P2.isVariablePiece())
return true;
unsigned l1 = P1.getPieceOffset();
@@ -1268,11 +1270,11 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
}
// If this piece overlaps with any open ranges, truncate them.
- DIVariable DIVar = Begin->getDebugVariable();
+ DIExpression DIExpr = Begin->getDebugExpression();
auto Last = std::remove_if(OpenRanges.begin(), OpenRanges.end(),
[&](DebugLocEntry::Value R) {
- return piecesOverlap(DIVar, R.getVariable());
- });
+ return piecesOverlap(DIExpr, R.getExpression());
+ });
OpenRanges.erase(Last, OpenRanges.end());
const MCSymbol *StartLabel = getLabelBeforeInsn(Begin);
@@ -1294,7 +1296,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
bool couldMerge = false;
// If this is a piece, it may belong to the current DebugLocEntry.
- if (DIVar.isVariablePiece()) {
+ if (DIExpr.isVariablePiece()) {
// Add this value to the list of open ranges.
OpenRanges.push_back(Value);
@@ -1320,10 +1322,14 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
DebugLoc.pop_back();
- DEBUG(dbgs() << "Values:\n";
- for (auto Value : CurEntry->getValues())
- Value.getVariable()->dump();
- dbgs() << "-----\n");
+ DEBUG({
+ dbgs() << CurEntry->getValues().size() << " Values:\n";
+ for (auto Value : CurEntry->getValues()) {
+ Value.getVariable()->dump();
+ Value.getExpression()->dump();
+ }
+ dbgs() << "-----\n";
+ });
}
}
@@ -1358,7 +1364,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl<const MDNode *> &Processed) {
if (!Scope)
continue;
- Processed.insert(getEntireVariable(DV));
+ Processed.insert(DV);
const MachineInstr *MInsn = Ranges.front().first;
assert(MInsn->isDebugValue() && "History must begin with debug value");
ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
@@ -1392,7 +1398,8 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl<const MDNode *> &Processed) {
continue;
if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) {
ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
- ConcreteVariables.push_back(make_unique<DbgVariable>(DV, this));
+ DIExpression NoExpr;
+ ConcreteVariables.push_back(make_unique<DbgVariable>(DV, NoExpr, this));
addScopeVariable(Scope, ConcreteVariables.back().get());
}
}
@@ -1580,18 +1587,17 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
// The first mention of a function argument gets the FunctionBeginSym
// label, so arguments are visible when breaking at function entry.
- DIVariable DV(Ranges.front().first->getDebugVariable());
- if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable &&
- getDISubprogram(DV.getContext()).describes(MF->getFunction())) {
- if (!DV.isVariablePiece())
- LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym;
- else {
+ DIVariable DIVar(Ranges.front().first->getDebugVariable());
+ if (DIVar.isVariable() && DIVar.getTag() == dwarf::DW_TAG_arg_variable &&
+ getDISubprogram(DIVar.getContext()).describes(MF->getFunction())) {
+ LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym;
+ if (Ranges.front().first->getDebugExpression().isVariablePiece()) {
// Mark all non-overlapping initial pieces.
for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
- DIVariable Piece = I->first->getDebugVariable();
+ DIExpression Piece = I->first->getDebugExpression();
if (std::all_of(Ranges.begin(), I,
- [&](DbgValueHistoryMap::InstrRange Pred){
- return !piecesOverlap(Piece, Pred.first->getDebugVariable());
+ [&](DbgValueHistoryMap::InstrRange Pred) {
+ return !piecesOverlap(Piece, Pred.first->getDebugExpression());
}))
LabelsBeforeInsn[I->first] = FunctionBeginSym;
else
@@ -2089,9 +2095,9 @@ void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,
unsigned Offset = 0;
for (auto Piece : Values) {
- DIVariable Var = Piece.getVariable();
- unsigned PieceOffset = Var.getPieceOffset();
- unsigned PieceSize = Var.getPieceSize();
+ DIExpression Expr = Piece.getExpression();
+ unsigned PieceOffset = Expr.getPieceOffset();
+ unsigned PieceSize = Expr.getPieceSize();
assert(Offset <= PieceOffset && "overlapping or duplicate pieces");
if (Offset < PieceOffset) {
// The DWARF spec seriously mandates pieces with no locations for gaps.
@@ -2102,8 +2108,9 @@ void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,
Offset += PieceSize;
const unsigned SizeOfByte = 8;
- assert(!Var.isIndirect() && "indirect address for piece");
#ifndef NDEBUG
+ DIVariable Var = Piece.getVariable();
+ assert(!Var.isIndirect() && "indirect address for piece");
unsigned VarSize = Var.getSizeInBits(Map);
assert(PieceSize+PieceOffset <= VarSize/SizeOfByte
&& "piece is larger than or outside of variable");
@@ -2149,24 +2156,25 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,
}
} else if (Value.isLocation()) {
MachineLocation Loc = Value.getLoc();
- if (!DV.hasComplexAddress())
+ DIExpression Expr = Value.getExpression();
+ if (!Expr)
// Regular entry.
Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());
else {
// Complex address entry.
- unsigned N = DV.getNumAddrElements();
+ unsigned N = Expr.getNumElements();
unsigned i = 0;
- if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
+ if (N >= 2 && Expr.getElement(0) == dwarf::DW_OP_plus) {
if (Loc.getOffset()) {
i = 2;
Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());
Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref");
Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst");
- Streamer.EmitSLEB128(DV.getAddrElement(1));
+ Streamer.EmitSLEB128(Expr.getElement(1));
} else {
// If first address element is OpPlus then emit
// DW_OP_breg + Offset instead of DW_OP_reg + Offset.
- MachineLocation TLoc(Loc.getReg(), DV.getAddrElement(1));
+ MachineLocation TLoc(Loc.getReg(), Expr.getElement(1));
Asm->EmitDwarfRegOp(Streamer, TLoc, DV.isIndirect());
i = 2;
}
@@ -2176,14 +2184,14 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,
// Emit remaining complex address elements.
for (; i < N; ++i) {
- uint64_t Element = DV.getAddrElement(i);
- if (Element == DIBuilder::OpPlus) {
+ uint64_t Element = Expr.getElement(i);
+ if (Element == dwarf::DW_OP_plus) {
Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst");
- Streamer.EmitULEB128(DV.getAddrElement(++i));
- } else if (Element == DIBuilder::OpDeref) {
+ Streamer.EmitULEB128(Expr.getElement(++i));
+ } else if (Element == dwarf::DW_OP_deref) {
if (!Loc.isReg())
Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref");
- } else if (Element == DIBuilder::OpPiece) {
+ } else if (Element == dwarf::DW_OP_piece) {
i += 3;
// handled in emitDebugLocEntry.
} else
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 80f81853ddd..1432ecd58ae 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -70,6 +70,7 @@ public:
/// \brief This class is used to track local variable information.
class DbgVariable {
DIVariable Var; // Variable Descriptor.
+ DIExpression Expr; // Complex address location expression.
DIE *TheDIE; // Variable DIE.
unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries.
const MachineInstr *MInsn; // DBG_VALUE instruction of the variable.
@@ -78,18 +79,22 @@ class DbgVariable {
public:
/// Construct a DbgVariable from a DIVariable.
- DbgVariable(DIVariable V, DwarfDebug *DD)
- : Var(V), TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(nullptr),
- FrameIndex(~0), DD(DD) {}
+ DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD)
+ : Var(V), Expr(E), TheDIE(nullptr), DotDebugLocOffset(~0U),
+ MInsn(nullptr), FrameIndex(~0), DD(DD) {
+ assert(Var.Verify() && Expr.Verify());
+ }
/// Construct a DbgVariable from a DEBUG_VALUE.
/// AbstractVar may be NULL.
DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD)
- : Var(DbgValue->getDebugVariable()), TheDIE(nullptr),
- DotDebugLocOffset(~0U), MInsn(DbgValue), FrameIndex(~0), DD(DD) {}
+ : Var(DbgValue->getDebugVariable()), Expr(DbgValue->getDebugExpression()),
+ TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue),
+ FrameIndex(~0), DD(DD) {}
// Accessors.
DIVariable getVariable() const { return Var; }
+ DIExpression getExpression() const { return Expr; }
void setDIE(DIE &D) { TheDIE = &D; }
DIE *getDIE() const { return TheDIE; }
void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; }
@@ -124,14 +129,14 @@ public:
bool variableHasComplexAddress() const {
assert(Var.isVariable() && "Invalid complex DbgVariable!");
- return Var.hasComplexAddress();
+ return Expr.getNumElements() > 0;
}
bool isBlockByrefVariable() const;
unsigned getNumAddrElements() const {
assert(Var.isVariable() && "Invalid complex DbgVariable!");
- return Var.getNumAddrElements();
+ return Expr.getNumElements();
}
- uint64_t getAddrElement(unsigned i) const { return Var.getAddrElement(i); }
+ uint64_t getAddrElement(unsigned i) const { return Expr.getElement(i); }
DIType getType() const;
private:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 806b0e76fc6..b19b576cdf3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -607,16 +607,20 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
unsigned N = DV.getNumAddrElements();
unsigned i = 0;
if (Location.isReg()) {
- if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
+ if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_plus) {
+ assert(!DV.getVariable().isIndirect() &&
+ "double indirection not handled");
// If first address element is OpPlus then emit
// DW_OP_breg + Offset instead of DW_OP_reg + Offset.
addRegisterOffset(*Loc, Location.getReg(), DV.getAddrElement(1));
i = 2;
- } else if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpDeref) {
- addRegisterOpPiece(*Loc, Location.getReg(),
- DV.getVariable().getPieceSize(),
- DV.getVariable().getPieceOffset());
- i = 3;
+ } else if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_deref) {
+ assert(!DV.getVariable().isIndirect() &&
+ "double indirection not handled");
+ addRegisterOpPiece(*Loc, Location.getReg(),
+ DV.getExpression().getPieceSize(),
+ DV.getExpression().getPieceOffset());
+ i = 3;
} else
addRegisterOpPiece(*Loc, Location.getReg());
} else
@@ -624,15 +628,15 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
for (; i < N; ++i) {
uint64_t Element = DV.getAddrElement(i);
- if (Element == DIBuilder::OpPlus) {
+ if (Element == dwarf::DW_OP_plus) {
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
addUInt(*Loc, dwarf::DW_FORM_udata, DV.getAddrElement(++i));
- } else if (Element == DIBuilder::OpDeref) {
+ } else if (Element == dwarf::DW_OP_deref) {
if (!Location.isReg())
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
- } else if (Element == DIBuilder::OpPiece) {
+ } else if (Element == dwarf::DW_OP_piece) {
const unsigned SizeOfByte = 8;
unsigned PieceOffsetInBits = DV.getAddrElement(++i)*SizeOfByte;
unsigned PieceSizeInBits = DV.getAddrElement(++i)*SizeOfByte;
@@ -1861,7 +1865,7 @@ std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV,
// Check if variable is described by a DBG_VALUE instruction.
if (const MachineInstr *DVInsn = DV.getMInsn()) {
- assert(DVInsn->getNumOperands() == 3);
+ assert(DVInsn->getNumOperands() == 4);
if (DVInsn->getOperand(0).isReg()) {
const MachineOperand RegOp = DVInsn->getOperand(0);
// If the second operand is an immediate, this is an indirect value.
diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp
index c868cab6c15..4064d131239 100644
--- a/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/llvm/lib/CodeGen/InlineSpiller.cpp
@@ -1224,12 +1224,16 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
// Modify DBG_VALUE now that the value is in a spill slot.
bool IsIndirect = MI->isIndirectDebugValue();
uint64_t Offset = IsIndirect ? MI->getOperand(1).getImm() : 0;
- const MDNode *MDPtr = MI->getOperand(2).getMetadata();
+ const MDNode *Var = MI->getDebugVariable();
+ const MDNode *Expr = MI->getDebugExpression();
DebugLoc DL = MI->getDebugLoc();
DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI);
MachineBasicBlock *MBB = MI->getParent();
BuildMI(*MBB, MBB->erase(MI), DL, TII.get(TargetOpcode::DBG_VALUE))
- .addFrameIndex(StackSlot).addImm(Offset).addMetadata(MDPtr);
+ .addFrameIndex(StackSlot)
+ .addImm(Offset)
+ .addMetadata(Var)
+ .addMetadata(Expr);
continue;
}
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 2790008b92c..72d0e138a3f 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -110,7 +110,8 @@ public:
namespace {
class LDVImpl;
class UserValue {
- const MDNode *variable; ///< The debug info variable we are part of.
+ const MDNode *Variable; ///< The debug info variable we are part of.
+ const MDNode *Expression; ///< Any complex address expression.
unsigned offset; ///< Byte offset into variable.
bool IsIndirect; ///< true if this is a register-indirect+offset value.
DebugLoc dl; ///< The debug location for the variable. This is
@@ -140,11 +141,10 @@ class UserValue {
public:
/// UserValue - Create a new UserValue.
- UserValue(const MDNode *var, unsigned o, bool i, DebugLoc L,
- LocMap::Allocator &alloc)
- : variable(var), offset(o), IsIndirect(i), dl(L), leader(this),
- next(nullptr), locInts(alloc)
- {}
+ UserValue(const MDNode *var, const MDNode *expr, unsigned o, bool i,
+ DebugLoc L, LocMap::Allocator &alloc)
+ : Variable(var), Expression(expr), offset(o), IsIndirect(i), dl(L),
+ leader(this), next(nullptr), locInts(alloc) {}
/// getLeader - Get the leader of this value's equivalence class.
UserValue *getLeader() {
@@ -158,8 +158,10 @@ public:
UserValue *getNext() const { return next; }
/// match - Does this UserValue match the parameters?
- bool match(const MDNode *Var, unsigned Offset, bool indirect) const {
- return Var == variable && Offset == offset && indirect == IsIndirect;
+ bool match(const MDNode *Var, const MDNode *Expr, unsigned Offset,
+ bool indirect) const {
+ return Var == Variable && Expr == Expression && Offset == offset &&
+ indirect == IsIndirect;
}
/// merge - Merge equivalence classes.
@@ -307,8 +309,8 @@ class LDVImpl {
UVMap userVarMap;
/// getUserValue - Find or create a UserValue.
- UserValue *getUserValue(const MDNode *Var, unsigned Offset,
- bool IsIndirect, DebugLoc DL);
+ UserValue *getUserValue(const MDNode *Var, const MDNode *Expr,
+ unsigned Offset, bool IsIndirect, DebugLoc DL);
/// lookupVirtReg - Find the EC leader for VirtReg or null.
UserValue *lookupVirtReg(unsigned VirtReg);
@@ -361,7 +363,7 @@ public:
} // namespace
void UserValue::print(raw_ostream &OS, const TargetMachine *TM) {
- DIVariable DV(variable);
+ DIVariable DV(Variable);
OS << "!\"";
DV.printExtendedName(OS);
OS << "\"\t";
@@ -422,19 +424,20 @@ void UserValue::mapVirtRegs(LDVImpl *LDV) {
LDV->mapVirtReg(locations[i].getReg(), this);
}
-UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset,
- bool IsIndirect, DebugLoc DL) {
+UserValue *LDVImpl::getUserValue(const MDNode *Var, const MDNode *Expr,
+ unsigned Offset, bool IsIndirect,
+ DebugLoc DL) {
UserValue *&Leader = userVarMap[Var];
if (Leader) {
UserValue *UV = Leader->getLeader();
Leader = UV;
for (; UV; UV = UV->getNext())
- if (UV->match(Var, Offset, IsIndirect))
+ if (UV->match(Var, Expr, Offset, IsIndirect))
return UV;
}
userValues.push_back(
- make_unique<UserValue>(Var, Offset, IsIndirect, DL, allocator));
+ make_unique<UserValue>(Var, Expr, Offset, IsIndirect, DL, allocator));
UserValue *UV = userValues.back().get();
Leader = UserValue::merge(Leader, UV);
return UV;
@@ -454,7 +457,7 @@ UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) {
bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) {
// DBG_VALUE loc, offset, variable
- if (MI->getNumOperands() != 3 ||
+ if (MI->getNumOperands() != 4 ||
!(MI->getOperand(1).isReg() || MI->getOperand(1).isImm()) ||
!MI->getOperand(2).isMetadata()) {
DEBUG(dbgs() << "Can't handle " << *MI);
@@ -464,9 +467,11 @@ bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) {
// Get or create the UserValue for (variable,offset).
bool IsIndirect = MI->isIndirectDebugValue();
unsigned Offset = IsIndirect ? MI->getOperand(1).getImm() : 0;
- const MDNode *Var = MI->getOperand(2).getMetadata();
+ const MDNode *Var = MI->getDebugVariable();
+ const MDNode *Expr = MI->getDebugExpression();
//here.
- UserValue *UV = getUserValue(Var, Offset, IsIndirect, MI->getDebugLoc());
+ UserValue *UV =
+ getUserValue(Var, Expr, Offset, IsIndirect, MI->getDebugLoc());
UV->addDef(Idx, MI->getOperand(0));
return true;
}
@@ -951,10 +956,13 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
if (Loc.isReg())
BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE),
- IsIndirect, Loc.getReg(), offset, variable);
+ IsIndirect, Loc.getReg(), offset, Variable, Expression);
else
BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
- .addOperand(Loc).addImm(offset).addMetadata(variable);
+ .addOperand(Loc)
+ .addImm(offset)
+ .addMetadata(Variable)
+ .addMetadata(Expression);
}
void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 493f5ee0977..d33d4a9d26a 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -1643,8 +1643,11 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,
if (isDebugValue() && MO.isMetadata()) {
// Pretty print DBG_VALUE instructions.
const MDNode *MD = MO.getMetadata();
- if (const MDString *MDS = dyn_cast<MDString>(MD->getOperand(2)))
- OS << "!\"" << MDS->getString() << '\"';
+ if (MD->getNumOperands() >= 2)
+ if (const MDString *MDS = dyn_cast<MDString>(MD->getOperand(2)))
+ OS << "!\"" << MDS->getString() << '\"';
+ else
+ MO.print(OS, TM);
else
MO.print(OS, TM);
} else if (TM && (isInsertSubreg() || isRegSequence()) && MO.isImm()) {
@@ -1747,6 +1750,8 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,
OS << " ]";
}
}
+ if (isIndirectDebugValue())
+ OS << " indirect";
} else if (!debugLoc.isUnknown() && MF) {
if (!HaveSemi) OS << ";";
OS << " dbg:";
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index 6e7e2c7e8ca..5efbb6306b6 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -299,7 +299,8 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI,
LiveDbgValueMap[LRI->VirtReg];
for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) {
MachineInstr *DBG = LRIDbgValues[li];
- const MDNode *MDPtr = DBG->getOperand(2).getMetadata();
+ const MDNode *Var = DBG->getDebugVariable();
+ const MDNode *Expr = DBG->getDebugExpression();
bool IsIndirect = DBG->isIndirectDebugValue();
uint64_t Offset = IsIndirect ? DBG->getOperand(1).getImm() : 0;
DebugLoc DL;
@@ -311,7 +312,10 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI,
DL = MI->getDebugLoc();
MachineInstr *NewDV =
BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::DBG_VALUE))
- .addFrameIndex(FI).addImm(Offset).addMetadata(MDPtr);
+ .addFrameIndex(FI)
+ .addImm(Offset)
+ .addMetadata(Var)
+ .addMetadata(Expr);
assert(NewDV->getParent() == MBB && "dangling parent pointer");
(void)NewDV;
DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV);
@@ -863,13 +867,16 @@ void RAFast::AllocateBasicBlock() {
// Modify DBG_VALUE now that the value is in a spill slot.
bool IsIndirect = MI->isIndirectDebugValue();
uint64_t Offset = IsIndirect ? MI->getOperand(1).getImm() : 0;
- const MDNode *MDPtr =
- MI->getOperand(MI->getNumOperands()-1).getMetadata();
+ const MDNode *Var = MI->getDebugVariable();
+ const MDNode *Expr = MI->getDebugExpression();
DebugLoc DL = MI->getDebugLoc();
MachineBasicBlock *MBB = MI->getParent();
MachineInstr *NewDV = BuildMI(*MBB, MBB->erase(MI), DL,
TII->get(TargetOpcode::DBG_VALUE))
- .addFrameIndex(SS).addImm(Offset).addMetadata(MDPtr);
+ .addFrameIndex(SS)
+ .addImm(Offset)
+ .addMetadata(Var)
+ .addMetadata(Expr);
DEBUG(dbgs() << "Modifying debug info due to spill:"
<< "\t" << *NewDV);
// Scan NewDV operands from the beginning.
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 7b656bfe34e..72390a94bfe 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1125,13 +1125,14 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
Op->setIsDebug(true);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::DBG_VALUE), false, Op->getReg(), 0,
- DI->getVariable());
+ DI->getVariable(), DI->getExpression());
} else
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::DBG_VALUE))
.addOperand(*Op)
.addImm(0)
- .addMetadata(DI->getVariable());
+ .addMetadata(DI->getVariable())
+ .addMetadata(DI->getExpression());
} else {
// We can't yet handle anything else here because it would require
// generating code, thus altering codegen because of debug info.
@@ -1150,28 +1151,32 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
.addReg(0U)
.addImm(DI->getOffset())
- .addMetadata(DI->getVariable());
+ .addMetadata(DI->getVariable())
+ .addMetadata(DI->getExpression());
} else if (const auto *CI = dyn_cast<ConstantInt>(V)) {
if (CI->getBitWidth() > 64)
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
.addCImm(CI)
.addImm(DI->getOffset())
- .addMetadata(DI->getVariable());
+ .addMetadata(DI->getVariable())
+ .addMetadata(DI->getExpression());
else
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
.addImm(CI->getZExtValue())
.addImm(DI->getOffset())
- .addMetadata(DI->getVariable());
+ .addMetadata(DI->getVariable())
+ .addMetadata(DI->getExpression());
} else if (const auto *CF = dyn_cast<ConstantFP>(V)) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
.addFPImm(CF)
.addImm(DI->getOffset())
- .addMetadata(DI->getVariable());
+ .addMetadata(DI->getVariable())
+ .addMetadata(DI->getExpression());
} else if (unsigned Reg = lookUpRegForValue(V)) {
// FIXME: This does not handle register-indirect values at offset 0.
bool IsIndirect = DI->getOffset() != 0;
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, IsIndirect, Reg,
- DI->getOffset(), DI->getVariable());
+ DI->getOffset(), DI->getVariable(), DI->getExpression());
} else {
// We can't yet handle anything else here because it would require
// generating code, thus altering codegen because of debug info.
@@ -2181,4 +2186,4 @@ CmpInst::Predicate FastISel::optimizeCmpPredicate(const CmpInst *CI) const {
}
return Predicate;
-} \ No newline at end of file
+}
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index c06612dcfa2..d1fcbe54f26 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -197,7 +197,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
StaticAllocaMap.find(AI);
if (SI != StaticAllocaMap.end()) { // Check for VLAs.
int FI = SI->second;
- MMI.setVariableDbgInfo(DI->getVariable(),
+ MMI.setVariableDbgInfo(DI->getVariable(), DI->getExpression(),
FI, DI->getDebugLoc());
}
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 4d6de12161c..32d5ddca615 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -649,14 +649,18 @@ MachineInstr *
InstrEmitter::EmitDbgValue(SDDbgValue *SD,
DenseMap<SDValue, unsigned> &VRBaseMap) {
uint64_t Offset = SD->getOffset();
- MDNode* MDPtr = SD->getMDPtr();
+ MDNode *Var = SD->getVariable();
+ MDNode *Expr = SD->getExpression();
DebugLoc DL = SD->getDebugLoc();
if (SD->getKind() == SDDbgValue::FRAMEIX) {
// Stack address; this needs to be lowered in target-dependent fashion.
// EmitTargetCodeForFrameDebugValue is responsible for allocation.
return BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE))
- .addFrameIndex(SD->getFrameIx()).addImm(Offset).addMetadata(MDPtr);
+ .addFrameIndex(SD->getFrameIx())
+ .addImm(Offset)
+ .addMetadata(Var)
+ .addMetadata(Expr);
}
// Otherwise, we're going to create an instruction here.
const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
@@ -702,7 +706,8 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
MIB.addReg(0U, RegState::Debug);
}
- MIB.addMetadata(MDPtr);
+ MIB.addMetadata(Var);
+ MIB.addMetadata(Expr);
return &*MIB;
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h b/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
index 307808e3578..c8bb3d8831c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
@@ -44,7 +44,8 @@ private:
const Value *Const; // valid for constants
unsigned FrameIx; // valid for stack objects
} u;
- MDNode *mdPtr;
+ MDNode *Var;
+ MDNode *Expr;
bool IsIndirect;
uint64_t Offset;
DebugLoc DL;
@@ -52,29 +53,29 @@ private:
bool Invalid;
public:
// Constructor for non-constants.
- SDDbgValue(MDNode *mdP, SDNode *N, unsigned R,
- bool indir, uint64_t off, DebugLoc dl,
- unsigned O) : mdPtr(mdP), IsIndirect(indir),
- Offset(off), DL(dl), Order(O),
- Invalid(false) {
+ SDDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R, bool indir,
+ uint64_t off, DebugLoc dl, unsigned O)
+ : Var(Var), Expr(Expr), IsIndirect(indir), Offset(off), DL(dl), Order(O),
+ Invalid(false) {
kind = SDNODE;
u.s.Node = N;
u.s.ResNo = R;
}
// Constructor for constants.
- SDDbgValue(MDNode *mdP, const Value *C, uint64_t off, DebugLoc dl,
- unsigned O) :
- mdPtr(mdP), IsIndirect(false), Offset(off), DL(dl), Order(O),
- Invalid(false) {
+ SDDbgValue(MDNode *Var, MDNode *Expr, const Value *C, uint64_t off,
+ DebugLoc dl, unsigned O)
+ : Var(Var), Expr(Expr), IsIndirect(false), Offset(off), DL(dl), Order(O),
+ Invalid(false) {
kind = CONST;
u.Const = C;
}
// Constructor for frame indices.
- SDDbgValue(MDNode *mdP, unsigned FI, uint64_t off, DebugLoc dl, unsigned O) :
- mdPtr(mdP), IsIndirect(false), Offset(off), DL(dl), Order(O),
- Invalid(false) {
+ SDDbgValue(MDNode *Var, MDNode *Expr, unsigned FI, uint64_t off, DebugLoc dl,
+ unsigned O)
+ : Var(Var), Expr(Expr), IsIndirect(false), Offset(off), DL(dl), Order(O),
+ Invalid(false) {
kind = FRAMEIX;
u.FrameIx = FI;
}
@@ -82,8 +83,11 @@ public:
// Returns the kind.
DbgValueKind getKind() { return kind; }
- // Returns the MDNode pointer.
- MDNode *getMDPtr() { return mdPtr; }
+ // Returns the MDNode pointer for the variable.
+ MDNode *getVariable() { return Var; }
+
+ // Returns the MDNode pointer for the expression.
+ MDNode *getExpression() { return Expr; }
// Returns the SDNode* for a register ref
SDNode *getSDNode() { assert (kind==SDNODE); return u.s.Node; }
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e2ead476fae..2322ce0104c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5764,26 +5764,24 @@ SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
/// getDbgValue - Creates a SDDbgValue node.
///
/// SDNode
-SDDbgValue *
-SelectionDAG::getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R,
- bool IsIndirect, uint64_t Off,
- DebugLoc DL, unsigned O) {
- return new (Allocator) SDDbgValue(MDPtr, N, R, IsIndirect, Off, DL, O);
+SDDbgValue *SelectionDAG::getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N,
+ unsigned R, bool IsIndirect, uint64_t Off,
+ DebugLoc DL, unsigned O) {
+ return new (Allocator) SDDbgValue(Var, Expr, N, R, IsIndirect, Off, DL, O);
}
/// Constant
-SDDbgValue *
-SelectionDAG::getConstantDbgValue(MDNode *MDPtr, const Value *C,
- uint64_t Off,
- DebugLoc DL, unsigned O) {
- return new (Allocator) SDDbgValue(MDPtr, C, Off, DL, O);
+SDDbgValue *SelectionDAG::getConstantDbgValue(MDNode *Var, MDNode *Expr,
+ const Value *C, uint64_t Off,
+ DebugLoc DL, unsigned O) {
+ return new (Allocator) SDDbgValue(Var, Expr, C, Off, DL, O);
}
/// FrameIndex
-SDDbgValue *
-SelectionDAG::getFrameIndexDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off,
- DebugLoc DL, unsigned O) {
- return new (Allocator) SDDbgValue(MDPtr, FI, Off, DL, O);
+SDDbgValue *SelectionDAG::getFrameIndexDbgValue(MDNode *Var, MDNode *Expr,
+ unsigned FI, uint64_t Off,
+ DebugLoc DL, unsigned O) {
+ return new (Allocator) SDDbgValue(Var, Expr, FI, Off, DL, O);
}
namespace {
@@ -6189,10 +6187,10 @@ void SelectionDAG::TransferDbgValues(SDValue From, SDValue To) {
I != E; ++I) {
SDDbgValue *Dbg = *I;
if (Dbg->getKind() == SDDbgValue::SDNODE) {
- SDDbgValue *Clone = getDbgValue(Dbg->getMDPtr(), ToNode, To.getResNo(),
- Dbg->isIndirect(),
- Dbg->getOffset(), Dbg->getDebugLoc(),
- Dbg->getOrder());
+ SDDbgValue *Clone =
+ getDbgValue(Dbg->getVariable(), Dbg->getExpression(), ToNode,
+ To.getResNo(), Dbg->isIndirect(), Dbg->getOffset(),
+ Dbg->getDebugLoc(), Dbg->getOrder());
ClonedDVs.push_back(Clone);
}
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 6a8cd2eb3b1..9bd5dfea0a6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -993,15 +993,16 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
DebugLoc dl = DDI.getdl();
unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
MDNode *Variable = DI->getVariable();
+ MDNode *Expr = DI->getExpression();
uint64_t Offset = DI->getOffset();
// A dbg.value for an alloca is always indirect.
bool IsIndirect = isa<AllocaInst>(V) || Offset != 0;
SDDbgValue *SDV;
if (Val.getNode()) {
- if (!EmitFuncArgumentDbgValue(V, Variable, Offset, IsIndirect, Val)) {
- SDV = DAG.getDbgValue(Variable, Val.getNode(),
- Val.getResNo(), IsIndirect,
- Offset, dl, DbgSDNodeOrder);
+ if (!EmitFuncArgumentDbgValue(V, Variable, Expr, Offset, IsIndirect,
+ Val)) {
+ SDV = DAG.getDbgValue(Variable, Expr, Val.getNode(), Val.getResNo(),
+ IsIndirect, Offset, dl, DbgSDNodeOrder);
DAG.AddDbgValue(SDV, Val.getNode(), false);
}
} else
@@ -4603,10 +4604,11 @@ static unsigned getTruncatedArgReg(const SDValue &N) {
/// EmitFuncArgumentDbgValue - If the DbgValueInst is a dbg_value of a function
/// argument, create the corresponding DBG_VALUE machine instruction for it now.
/// At the end of instruction selection, they will be inserted to the entry BB.
-bool
-SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
- int64_t Offset, bool IsIndirect,
- const SDValue &N) {
+bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V,
+ MDNode *Variable,
+ MDNode *Expr, int64_t Offset,
+ bool IsIndirect,
+ const SDValue &N) {
const Argument *Arg = dyn_cast<Argument>(V);
if (!Arg)
return false;
@@ -4658,14 +4660,16 @@ SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
return false;
if (Op->isReg())
- FuncInfo.ArgDbgValues.push_back(BuildMI(MF, getCurDebugLoc(),
- TII->get(TargetOpcode::DBG_VALUE),
- IsIndirect,
- Op->getReg(), Offset, Variable));
+ FuncInfo.ArgDbgValues.push_back(
+ BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE),
+ IsIndirect, Op->getReg(), Offset, Variable, Expr));
else
FuncInfo.ArgDbgValues.push_back(
- BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE))
- .addOperand(*Op).addImm(Offset).addMetadata(Variable));
+ BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE))
+ .addOperand(*Op)
+ .addImm(Offset)
+ .addMetadata(Variable)
+ .addMetadata(Expr));
return true;
}
@@ -4785,6 +4789,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
case Intrinsic::dbg_declare: {
const DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
MDNode *Variable = DI.getVariable();
+ MDNode *Expression = DI.getExpression();
const Value *Address = DI.getAddress();
DIVariable DIVar(Variable);
assert((!DIVar || DIVar.isVariable()) &&
@@ -4820,16 +4825,16 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N.getNode());
if (FINode)
// Byval parameter. We have a frame index at this point.
- SDV = DAG.getFrameIndexDbgValue(Variable, FINode->getIndex(),
- 0, dl, SDNodeOrder);
+ SDV = DAG.getFrameIndexDbgValue(
+ Variable, Expression, FINode->getIndex(), 0, dl, SDNodeOrder);
else {
// Address is an argument, so try to emit its dbg value using
// virtual register info from the FuncInfo.ValueMap.
- EmitFuncArgumentDbgValue(Address, Variable, 0, false, N);
+ EmitFuncArgumentDbgValue(Address, Variable, Expression, 0, false, N);
return nullptr;
}
} else if (AI)
- SDV = DAG.getDbgValue(Variable, N.getNode(), N.getResNo(),
+ SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(),
true, 0, dl, SDNodeOrder);
else {
// Can't do anything with other non-AI cases yet.
@@ -4842,7 +4847,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
} else {
// If Address is an argument then try to emit its dbg value using
// virtual register info from the FuncInfo.ValueMap.
- if (!EmitFuncArgumentDbgValue(Address, Variable, 0, false, N)) {
+ if (!EmitFuncArgumentDbgValue(Address, Variable, Expression, 0, false,
+ N)) {
// If variable is pinned by a alloca in dominating bb then
// use StaticAllocaMap.
if (const AllocaInst *AI = dyn_cast<AllocaInst>(Address)) {
@@ -4850,7 +4856,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
DenseMap<const AllocaInst*, int>::iterator SI =
FuncInfo.StaticAllocaMap.find(AI);
if (SI != FuncInfo.StaticAllocaMap.end()) {
- SDV = DAG.getFrameIndexDbgValue(Variable, SI->second,
+ SDV = DAG.getFrameIndexDbgValue(Variable, Expression, SI->second,
0, dl, SDNodeOrder);
DAG.AddDbgValue(SDV, nullptr, false);
return nullptr;
@@ -4871,6 +4877,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
return nullptr;
MDNode *Variable = DI.getVariable();
+ MDNode *Expression = DI.getExpression();
uint64_t Offset = DI.getOffset();
const Value *V = DI.getValue();
if (!V)
@@ -4878,7 +4885,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
SDDbgValue *SDV;
if (isa<ConstantInt>(V) || isa<ConstantFP>(V) || isa<UndefValue>(V)) {
- SDV = DAG.getConstantDbgValue(Variable, V, Offset, dl, SDNodeOrder);
+ SDV = DAG.getConstantDbgValue(Variable, Expression, V, Offset, dl,
+ SDNodeOrder);
DAG.AddDbgValue(SDV, nullptr, false);
} else {
// Do not use getValue() in here; we don't want to generate code at
@@ -4890,10 +4898,10 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
if (N.getNode()) {
// A dbg.value for an alloca is always indirect.
bool IsIndirect = isa<AllocaInst>(V) || Offset != 0;
- if (!EmitFuncArgumentDbgValue(V, Variable, Offset, IsIndirect, N)) {
- SDV = DAG.getDbgValue(Variable, N.getNode(),
- N.getResNo(), IsIndirect,
- Offset, dl, SDNodeOrder);
+ if (!EmitFuncArgumentDbgValue(V, Variable, Expression, Offset,
+ IsIndirect, N)) {
+ SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(),
+ IsIndirect, Offset, dl, SDNodeOrder);
DAG.AddDbgValue(SDV, N.getNode(), false);
}
} else if (!V->use_empty() ) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 45dd55412d2..6ecddc1608a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -791,7 +791,7 @@ private:
/// EmitFuncArgumentDbgValue - If V is an function argument then create
/// corresponding DBG_VALUE machine instruction for it now. At the end of
/// instruction selection, they will be inserted to the entry BB.
- bool EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
+ bool EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable, MDNode *Expr,
int64_t Offset, bool IsIndirect,
const SDValue &N);
};
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 4ef3e6f94f5..df2c6b8de0b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -486,15 +486,14 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
"- add if needed");
MachineInstr *Def = RegInfo->getVRegDef(LDI->second);
MachineBasicBlock::iterator InsertPos = Def;
- const MDNode *Variable =
- MI->getOperand(MI->getNumOperands()-1).getMetadata();
+ const MDNode *Variable = MI->getDebugVariable();
+ const MDNode *Expr = MI->getDebugExpression();
bool IsIndirect = MI->isIndirectDebugValue();
unsigned Offset = IsIndirect ? MI->getOperand(1).getImm() : 0;
// Def is never a terminator here, so it is ok to increment InsertPos.
BuildMI(*EntryMBB, ++InsertPos, MI->getDebugLoc(),
- TII.get(TargetOpcode::DBG_VALUE),
- IsIndirect,
- LDI->second, Offset, Variable);
+ TII.get(TargetOpcode::DBG_VALUE), IsIndirect, LDI->second, Offset,
+ Variable, Expr);
// If this vreg is directly copied into an exported register then
// that COPY instructions also need DBG_VALUE, if it is the only
@@ -513,11 +512,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
}
if (CopyUseMI) {
MachineInstr *NewMI =
- BuildMI(*MF, CopyUseMI->getDebugLoc(),
- TII.get(TargetOpcode::DBG_VALUE),
- IsIndirect,
- CopyUseMI->getOperand(0).getReg(),
- Offset, Variable);
+ BuildMI(*MF, CopyUseMI->getDebugLoc(),
+ TII.get(TargetOpcode::DBG_VALUE), IsIndirect,
+ CopyUseMI->getOperand(0).getReg(), Offset, Variable, Expr);
MachineBasicBlock::iterator Pos = CopyUseMI;
EntryMBB->insertAfter(Pos, NewMI);
}
OpenPOWER on IntegriCloud