forked from OSchip/llvm-project
Refactor the DIExpression fragment query interface (NFC)
... so it becomes available to DIExpressionCursor. llvm-svn: 290322
This commit is contained in:
parent
b458841745
commit
49797ca6be
llvm
include/llvm/IR
lib
CodeGen/AsmPrinter
IR
Transforms
|
@ -1973,15 +1973,6 @@ public:
|
|||
return Elements[I];
|
||||
}
|
||||
|
||||
/// Return whether this is a piece of an aggregate variable.
|
||||
bool isFragment() const;
|
||||
|
||||
/// Return the offset of this fragment in bits.
|
||||
uint64_t getFragmentOffsetInBits() const;
|
||||
|
||||
/// Return the size of this fragment in bits.
|
||||
uint64_t getFragmentSizeInBits() const;
|
||||
|
||||
/// Determine whether this represents a standalone constant value.
|
||||
bool isConstant() const;
|
||||
|
||||
|
@ -2085,6 +2076,24 @@ public:
|
|||
bool startsWithDeref() const {
|
||||
return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
|
||||
}
|
||||
|
||||
/// Holds the characteristics of one fragment of a larger variable.
|
||||
struct FragmentInfo {
|
||||
uint64_t SizeInBits;
|
||||
uint64_t OffsetInBits;
|
||||
};
|
||||
|
||||
/// Retrieve the details of this fragment expression.
|
||||
static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
|
||||
expr_op_iterator End);
|
||||
|
||||
/// Retrieve the details of this fragment expression.
|
||||
Optional<FragmentInfo> getFragmentInfo() const {
|
||||
return getFragmentInfo(expr_op_begin(), expr_op_end());
|
||||
}
|
||||
|
||||
/// Return whether this is a piece of an aggregate variable.
|
||||
bool isFragment() const { return getFragmentInfo().hasValue(); }
|
||||
};
|
||||
|
||||
/// Global variables.
|
||||
|
|
|
@ -713,9 +713,10 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
|
|||
OS << V->getName();
|
||||
|
||||
const DIExpression *Expr = MI->getDebugExpression();
|
||||
if (Expr->isFragment())
|
||||
OS << " [fragment offset=" << Expr->getFragmentOffsetInBits()
|
||||
<< " size=" << Expr->getFragmentSizeInBits() << "]";
|
||||
auto Fragment = Expr->getFragmentInfo();
|
||||
if (Fragment)
|
||||
OS << " [fragment offset=" << Fragment->OffsetInBits
|
||||
<< " size=" << Fragment->SizeInBits << "]";
|
||||
OS << " <- ";
|
||||
|
||||
// The second operand is only an offset if it's an immediate.
|
||||
|
|
|
@ -944,9 +944,10 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
|
|||
unsigned StructOffset = 0;
|
||||
|
||||
// Handle fragments.
|
||||
if (DIExpr && DIExpr->isFragment()) {
|
||||
auto Fragment = DIExpr->getFragmentInfo();
|
||||
if (DIExpr && Fragment) {
|
||||
IsSubfield = true;
|
||||
StructOffset = DIExpr->getFragmentOffsetInBits() / 8;
|
||||
StructOffset = Fragment->OffsetInBits / 8;
|
||||
} else if (DIExpr && DIExpr->getNumElements() > 0) {
|
||||
continue; // Ignore unrecognized exprs.
|
||||
}
|
||||
|
|
|
@ -65,10 +65,12 @@ MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
|
|||
|
||||
int DebugHandlerBase::fragmentCmp(const DIExpression *P1,
|
||||
const DIExpression *P2) {
|
||||
unsigned l1 = P1->getFragmentOffsetInBits();
|
||||
unsigned l2 = P2->getFragmentOffsetInBits();
|
||||
unsigned r1 = l1 + P1->getFragmentSizeInBits();
|
||||
unsigned r2 = l2 + P2->getFragmentSizeInBits();
|
||||
auto Fragment1 = *P1->getFragmentInfo();
|
||||
auto Fragment2 = *P2->getFragmentInfo();
|
||||
unsigned l1 = Fragment1.OffsetInBits;
|
||||
unsigned l2 = Fragment2.OffsetInBits;
|
||||
unsigned r1 = l1 + Fragment1.SizeInBits;
|
||||
unsigned r2 = l2 + Fragment2.SizeInBits;
|
||||
if (r1 <= l2)
|
||||
return -1;
|
||||
else if (r2 <= l1)
|
||||
|
|
|
@ -175,8 +175,8 @@ inline bool operator==(const DebugLocEntry::Value &A,
|
|||
/// Compare two fragments based on their offset.
|
||||
inline bool operator<(const DebugLocEntry::Value &A,
|
||||
const DebugLocEntry::Value &B) {
|
||||
return A.getExpression()->getFragmentOffsetInBits() <
|
||||
B.getExpression()->getFragmentOffsetInBits();
|
||||
return A.getExpression()->getFragmentInfo()->OffsetInBits <
|
||||
B.getExpression()->getFragmentInfo()->OffsetInBits;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -469,10 +469,12 @@ static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &
|
|||
sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
|
||||
std::sort(GVEs.begin(), GVEs.end(),
|
||||
[](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) {
|
||||
if (A.Expr != B.Expr && A.Expr && B.Expr &&
|
||||
A.Expr->isFragment() && B.Expr->isFragment())
|
||||
return A.Expr->getFragmentOffsetInBits() <
|
||||
B.Expr->getFragmentOffsetInBits();
|
||||
if (A.Expr != B.Expr && A.Expr && B.Expr) {
|
||||
auto FragmentA = A.Expr->getFragmentInfo();
|
||||
auto FragmentB = B.Expr->getFragmentInfo();
|
||||
if (FragmentA && FragmentB)
|
||||
return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
GVEs.erase(std::unique(GVEs.begin(), GVEs.end(),
|
||||
|
|
|
@ -285,7 +285,7 @@ void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
|
|||
if (!Expr || !Expr->isFragment())
|
||||
return;
|
||||
|
||||
uint64_t FragmentOffset = Expr->getFragmentOffsetInBits();
|
||||
uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
|
||||
assert(FragmentOffset >= OffsetInBits &&
|
||||
"overlapping or duplicate fragments");
|
||||
if (FragmentOffset > OffsetInBits)
|
||||
|
|
|
@ -601,22 +601,14 @@ bool DIExpression::isValid() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DIExpression::isFragment() const {
|
||||
assert(isValid() && "Expected valid expression");
|
||||
if (unsigned N = getNumElements())
|
||||
if (N >= 3)
|
||||
return getElement(N - 3) == dwarf::DW_OP_LLVM_fragment;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t DIExpression::getFragmentOffsetInBits() const {
|
||||
assert(isFragment() && "Expected fragment");
|
||||
return getElement(getNumElements() - 2);
|
||||
}
|
||||
|
||||
uint64_t DIExpression::getFragmentSizeInBits() const {
|
||||
assert(isFragment() && "Expected fragment");
|
||||
return getElement(getNumElements() - 1);
|
||||
Optional<DIExpression::FragmentInfo>
|
||||
DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) {
|
||||
for (auto I = Start; I != End; ++I)
|
||||
if (I->getOp() == dwarf::DW_OP_LLVM_fragment) {
|
||||
DIExpression::FragmentInfo Info = {I->getArg(1), I->getArg(0)};
|
||||
return Info;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
bool DIExpression::isConstant() const {
|
||||
|
|
|
@ -4344,7 +4344,8 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
|
|||
return;
|
||||
|
||||
// Nothing to do if this isn't a bit piece expression.
|
||||
if (!E->isFragment())
|
||||
auto Fragment = E->getFragmentInfo();
|
||||
if (!Fragment)
|
||||
return;
|
||||
|
||||
// The frontend helps out GDB by emitting the members of local anonymous
|
||||
|
@ -4362,8 +4363,8 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
|
|||
if (!VarSize)
|
||||
return;
|
||||
|
||||
unsigned FragSize = E->getFragmentSizeInBits();
|
||||
unsigned FragOffset = E->getFragmentOffsetInBits();
|
||||
unsigned FragSize = Fragment->SizeInBits;
|
||||
unsigned FragOffset = Fragment->OffsetInBits;
|
||||
AssertDI(FragSize + FragOffset <= VarSize,
|
||||
"fragment is larger than or outside of variable", &I, V, E);
|
||||
AssertDI(FragSize != VarSize, "fragment covers entire variable", &I, V, E);
|
||||
|
|
|
@ -4026,13 +4026,13 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
|
|||
if (Fragment.Size < AllocaSize || Expr->isFragment()) {
|
||||
// If this alloca is already a scalar replacement of a larger aggregate,
|
||||
// Fragment.Offset describes the offset inside the scalar.
|
||||
uint64_t Offset =
|
||||
Expr->isFragment() ? Expr->getFragmentOffsetInBits() : 0;
|
||||
auto ExprFragment = Expr->getFragmentInfo();
|
||||
uint64_t Offset = ExprFragment ? ExprFragment->OffsetInBits : 0;
|
||||
uint64_t Start = Offset + Fragment.Offset;
|
||||
uint64_t Size = Fragment.Size;
|
||||
if (Expr->isFragment()) {
|
||||
if (ExprFragment) {
|
||||
uint64_t AbsEnd =
|
||||
Expr->getFragmentOffsetInBits() + Expr->getFragmentSizeInBits();
|
||||
ExprFragment->OffsetInBits + ExprFragment->SizeInBits;
|
||||
if (Start >= AbsEnd)
|
||||
// No need to describe a SROAed padding.
|
||||
continue;
|
||||
|
|
|
@ -1112,9 +1112,10 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
|
|||
unsigned FragmentOffset = 0;
|
||||
// If this already is a bit fragment, we drop the bit fragment from the
|
||||
// expression and record the offset.
|
||||
if (DIExpr->isFragment()) {
|
||||
auto Fragment = DIExpr->getFragmentInfo();
|
||||
if (Fragment) {
|
||||
Ops.append(DIExpr->elements_begin(), DIExpr->elements_end()-3);
|
||||
FragmentOffset = DIExpr->getFragmentOffsetInBits();
|
||||
FragmentOffset = Fragment->OffsetInBits;
|
||||
} else {
|
||||
Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue