Skip to content

Commit

Permalink
[DebugInfo] Move Value struct out of DebugLocEntry as DbgValueLoc (NFC)
Browse files Browse the repository at this point in the history
Since the DebugLocEntry::Value is used as part of DwarfDebug and
DebugLocEntry make it as the separate class.

Reviewers: aprantl, dstenb

Reviewed By: aprantl

Differential Revision: https://reviews.llvm.org/D63213

llvm-svn: 363246
  • Loading branch information
Nikola Prica committed Jun 13, 2019
1 parent 181bf0c commit 076ae0d
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 106 deletions.
178 changes: 87 additions & 91 deletions llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
Expand Up @@ -20,91 +20,89 @@
namespace llvm {
class AsmPrinter;

/// A single location or constant.
class DbgValueLoc {
/// Any complex address location expression for this DbgValueLoc.
const DIExpression *Expression;

/// Type of entry that this represents.
enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
enum EntryType EntryKind;

/// Either a constant,
union {
int64_t Int;
const ConstantFP *CFP;
const ConstantInt *CIP;
} Constant;

/// Or a location in the machine frame.
MachineLocation Loc;

public:
DbgValueLoc(const DIExpression *Expr, int64_t i)
: Expression(Expr), EntryKind(E_Integer) {
Constant.Int = i;
}
DbgValueLoc(const DIExpression *Expr, const ConstantFP *CFP)
: Expression(Expr), EntryKind(E_ConstantFP) {
Constant.CFP = CFP;
}
DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP)
: Expression(Expr), EntryKind(E_ConstantInt) {
Constant.CIP = CIP;
}
DbgValueLoc(const DIExpression *Expr, MachineLocation Loc)
: Expression(Expr), EntryKind(E_Location), Loc(Loc) {
assert(cast<DIExpression>(Expr)->isValid());
}

bool isLocation() const { return EntryKind == E_Location; }
bool isInt() const { return EntryKind == E_Integer; }
bool isConstantFP() const { return EntryKind == E_ConstantFP; }
bool isConstantInt() const { return EntryKind == E_ConstantInt; }
int64_t getInt() const { return Constant.Int; }
const ConstantFP *getConstantFP() const { return Constant.CFP; }
const ConstantInt *getConstantInt() const { return Constant.CIP; }
MachineLocation getLoc() const { return Loc; }
bool isFragment() const { return getExpression()->isFragment(); }
const DIExpression *getExpression() const { return Expression; }
friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void dump() const {
if (isLocation()) {
llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
if (Loc.isIndirect())
llvm::dbgs() << "+0";
llvm::dbgs() << "} ";
} else if (isConstantInt())
Constant.CIP->dump();
else if (isConstantFP())
Constant.CFP->dump();
if (Expression)
Expression->dump();
}
#endif
};

/// This struct describes location entries emitted in the .debug_loc
/// section.
class DebugLocEntry {
/// Begin and end symbols for the address range that this location is valid.
const MCSymbol *Begin;
const MCSymbol *End;

public:
/// A single location or constant.
struct Value {
Value(const DIExpression *Expr, int64_t i)
: Expression(Expr), EntryKind(E_Integer) {
Constant.Int = i;
}
Value(const DIExpression *Expr, const ConstantFP *CFP)
: Expression(Expr), EntryKind(E_ConstantFP) {
Constant.CFP = CFP;
}
Value(const DIExpression *Expr, const ConstantInt *CIP)
: Expression(Expr), EntryKind(E_ConstantInt) {
Constant.CIP = CIP;
}
Value(const DIExpression *Expr, MachineLocation Loc)
: Expression(Expr), EntryKind(E_Location), Loc(Loc) {
assert(cast<DIExpression>(Expr)->isValid());
}

/// Any complex address location expression for this Value.
const DIExpression *Expression;

/// Type of entry that this represents.
enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
enum EntryType EntryKind;

/// Either a constant,
union {
int64_t Int;
const ConstantFP *CFP;
const ConstantInt *CIP;
} Constant;

// Or a location in the machine frame.
MachineLocation Loc;

bool isLocation() const { return EntryKind == E_Location; }
bool isInt() const { return EntryKind == E_Integer; }
bool isConstantFP() const { return EntryKind == E_ConstantFP; }
bool isConstantInt() const { return EntryKind == E_ConstantInt; }
int64_t getInt() const { return Constant.Int; }
const ConstantFP *getConstantFP() const { return Constant.CFP; }
const ConstantInt *getConstantInt() const { return Constant.CIP; }
MachineLocation getLoc() const { return Loc; }
bool isFragment() const { return getExpression()->isFragment(); }
const DIExpression *getExpression() const { return Expression; }
friend bool operator==(const Value &, const Value &);
friend bool operator<(const Value &, const Value &);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void dump() const {
if (isLocation()) {
llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
if (Loc.isIndirect())
llvm::dbgs() << "+0";
llvm::dbgs() << "} ";
}
else if (isConstantInt())
Constant.CIP->dump();
else if (isConstantFP())
Constant.CFP->dump();
if (Expression)
Expression->dump();
}
#endif
};

private:
/// A nonempty list of locations/constants belonging to this entry,
/// sorted by offset.
SmallVector<Value, 1> Values;
SmallVector<DbgValueLoc, 1> Values;

public:
/// Create a location list entry for the range [\p Begin, \p End).
///
/// \param Vals One or more values describing (parts of) the variable.
DebugLocEntry(const MCSymbol *Begin, const MCSymbol *End,
ArrayRef<Value> Vals)
ArrayRef<DbgValueLoc> Vals)
: Begin(Begin), End(End) {
addValues(Vals);
}
Expand All @@ -124,26 +122,24 @@ class DebugLocEntry {

const MCSymbol *getBeginSym() const { return Begin; }
const MCSymbol *getEndSym() const { return End; }
ArrayRef<Value> getValues() const { return Values; }
void addValues(ArrayRef<DebugLocEntry::Value> Vals) {
ArrayRef<DbgValueLoc> getValues() const { return Values; }
void addValues(ArrayRef<DbgValueLoc> Vals) {
Values.append(Vals.begin(), Vals.end());
sortUniqueValues();
assert((Values.size() == 1 ||
all_of(Values,
[](DebugLocEntry::Value V) { return V.isFragment(); })) &&
"must either have a single value or multiple pieces");
assert((Values.size() == 1 || all_of(Values, [](DbgValueLoc V) {
return V.isFragment();
})) && "must either have a single value or multiple pieces");
}

// Sort the pieces by offset.
// Remove any duplicate entries by dropping all but the first.
void sortUniqueValues() {
llvm::sort(Values);
Values.erase(
std::unique(
Values.begin(), Values.end(), [](const Value &A, const Value &B) {
return A.getExpression() == B.getExpression();
}),
Values.end());
Values.erase(std::unique(Values.begin(), Values.end(),
[](const DbgValueLoc &A, const DbgValueLoc &B) {
return A.getExpression() == B.getExpression();
}),
Values.end());
}

/// Lower this entry into a DWARF expression.
Expand All @@ -153,31 +149,31 @@ class DebugLocEntry {
DwarfCompileUnit &TheCU);
};

/// Compare two Values for equality.
inline bool operator==(const DebugLocEntry::Value &A,
const DebugLocEntry::Value &B) {
/// Compare two DbgValueLocs for equality.
inline bool operator==(const DbgValueLoc &A,
const DbgValueLoc &B) {
if (A.EntryKind != B.EntryKind)
return false;

if (A.Expression != B.Expression)
return false;

switch (A.EntryKind) {
case DebugLocEntry::Value::E_Location:
case DbgValueLoc::E_Location:
return A.Loc == B.Loc;
case DebugLocEntry::Value::E_Integer:
case DbgValueLoc::E_Integer:
return A.Constant.Int == B.Constant.Int;
case DebugLocEntry::Value::E_ConstantFP:
case DbgValueLoc::E_ConstantFP:
return A.Constant.CFP == B.Constant.CFP;
case DebugLocEntry::Value::E_ConstantInt:
case DbgValueLoc::E_ConstantInt:
return A.Constant.CIP == B.Constant.CIP;
}
llvm_unreachable("unhandled EntryKind");
}

/// Compare two fragments based on their offset.
inline bool operator<(const DebugLocEntry::Value &A,
const DebugLocEntry::Value &B) {
inline bool operator<(const DbgValueLoc &A,
const DbgValueLoc &B) {
return A.getExpression()->getFragmentInfo()->OffsetInBits <
B.getExpression()->getFragmentInfo()->OffsetInBits;
}
Expand Down
22 changes: 11 additions & 11 deletions llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Expand Up @@ -245,7 +245,7 @@ const DIType *DbgVariable::getType() const {
}

/// Get .debug_loc entry for the instruction range starting at MI.
static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
const DIExpression *Expr = MI->getDebugExpression();
assert(MI->getNumOperands() == 4);
if (MI->getOperand(0).isReg()) {
Expand All @@ -255,14 +255,14 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
// register-indirect address.
assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
return DebugLocEntry::Value(Expr, MLoc);
return DbgValueLoc(Expr, MLoc);
}
if (MI->getOperand(0).isImm())
return DebugLocEntry::Value(Expr, MI->getOperand(0).getImm());
return DbgValueLoc(Expr, MI->getOperand(0).getImm());
if (MI->getOperand(0).isFPImm())
return DebugLocEntry::Value(Expr, MI->getOperand(0).getFPImm());
return DbgValueLoc(Expr, MI->getOperand(0).getFPImm());
if (MI->getOperand(0).isCImm())
return DebugLocEntry::Value(Expr, MI->getOperand(0).getCImm());
return DbgValueLoc(Expr, MI->getOperand(0).getCImm());

llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
}
Expand All @@ -275,7 +275,7 @@ void DbgVariable::initializeDbgValue(const MachineInstr *DbgValue) {
assert(getInlinedAt() == DbgValue->getDebugLoc()->getInlinedAt() &&
"Wrong inlined-at");

ValueLoc = llvm::make_unique<DebugLocEntry::Value>(getDebugLocValue(DbgValue));
ValueLoc = llvm::make_unique<DbgValueLoc>(getDebugLocValue(DbgValue));
if (auto *E = DbgValue->getDebugExpression())
if (E->getNumElements())
FrameIndexExprs.push_back({0, E});
Expand Down Expand Up @@ -1206,7 +1206,7 @@ static bool validThroughout(LexicalScopes &LScopes,
bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
const DbgValueHistoryMap::Entries &Entries) {
using OpenRange =
std::pair<DbgValueHistoryMap::EntryIndex, DebugLocEntry::Value>;
std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
SmallVector<OpenRange, 4> OpenRanges;
bool isSafeForSingleLocation = true;
const MachineInstr *StartDebugMI = nullptr;
Expand Down Expand Up @@ -1279,7 +1279,7 @@ bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
continue;
}

SmallVector<DebugLocEntry::Value, 4> Values;
SmallVector<DbgValueLoc, 4> Values;
for (auto &R : OpenRanges)
Values.push_back(R.second);
DebugLoc.emplace_back(StartLabel, EndLabel, Values);
Expand Down Expand Up @@ -1995,7 +1995,7 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
}

static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
const DebugLocEntry::Value &Value,
const DbgValueLoc &Value,
DwarfExpression &DwarfExpr) {
auto *DIExpr = Value.getExpression();
DIExpressionCursor ExprCursor(DIExpr);
Expand Down Expand Up @@ -2033,10 +2033,10 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
DebugLocStream::EntryBuilder Entry(List, Begin, End);
BufferByteStreamer Streamer = Entry.getStreamer();
DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU);
const DebugLocEntry::Value &Value = Values[0];
const DbgValueLoc &Value = Values[0];
if (Value.isFragment()) {
// Emit all fragments that belong to the same variable and range.
assert(llvm::all_of(Values, [](DebugLocEntry::Value P) {
assert(llvm::all_of(Values, [](DbgValueLoc P) {
return P.isFragment();
}) && "all values are expected to be fragments");
assert(std::is_sorted(Values.begin(), Values.end()) &&
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
Expand Up @@ -118,7 +118,7 @@ class DbgVariable : public DbgEntity {
/// Offset in DebugLocs.
unsigned DebugLocListIndex = ~0u;
/// Single value location description.
std::unique_ptr<DebugLocEntry::Value> ValueLoc = nullptr;
std::unique_ptr<DbgValueLoc> ValueLoc = nullptr;

struct FrameIndexExpr {
int FI;
Expand Down Expand Up @@ -147,12 +147,12 @@ class DbgVariable : public DbgEntity {
}

// Initialize variable's location.
void initializeDbgValue(DebugLocEntry::Value Value) {
void initializeDbgValue(DbgValueLoc Value) {
assert(FrameIndexExprs.empty() && "Already initialized?");
assert(!ValueLoc && "Already initialized?");
assert(!Value.getExpression()->isFragment() && "Fragments not supported.");

ValueLoc = llvm::make_unique<DebugLocEntry::Value>(Value);
ValueLoc = llvm::make_unique<DbgValueLoc>(Value);
if (auto *E = ValueLoc->getExpression())
if (E->getNumElements())
FrameIndexExprs.push_back({0, E});
Expand All @@ -174,7 +174,7 @@ class DbgVariable : public DbgEntity {
void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; }
unsigned getDebugLocListIndex() const { return DebugLocListIndex; }
StringRef getName() const { return getVariable()->getName(); }
const DebugLocEntry::Value *getValueLoc() const { return ValueLoc.get(); }
const DbgValueLoc *getValueLoc() const { return ValueLoc.get(); }
/// Get the FI entries, sorted by fragment offset.
ArrayRef<FrameIndexExpr> getFrameIndexExprs() const;
bool hasFrameIndexExprs() const { return !FrameIndexExprs.empty(); }
Expand Down

0 comments on commit 076ae0d

Please sign in to comment.