summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2018-06-15 13:48:55 +0000
committerBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2018-06-15 13:48:55 +0000
commit428caf988be17a1d3d420318f9018a8f4b11a436 (patch)
tree32397bf954b4f9f5f619510e550b9c9fd2a1c9ac /llvm/lib/Transforms
parent65d1cf8b165b739fb54326c40ec292cd9338a11c (diff)
downloadbcm5719-llvm-428caf988be17a1d3d420318f9018a8f4b11a436.tar.gz
bcm5719-llvm-428caf988be17a1d3d420318f9018a8f4b11a436.zip
Re-apply "[DebugInfo] Check size of variable in ConvertDebugDeclareToDebugValue"
This is r334704 (which was reverted in r334732) with a fix for types like x86_fp80. We need to use getTypeAllocSizeInBits and not getTypeStoreSizeInBits to avoid dropping debug info for such types. Original commit msg: > Summary: > Do not convert a DbgDeclare to DbgValue if the store > instruction only refer to a fragment of the variable > described by the DbgDeclare. > > Problem was seen when for example having an alloca for an > array or struct, and there were stores to individual elements. > In the past we inserted a DbgValue intrinsics for each store, > just as if the store wrote the whole variable. > > When handling store instructions we insert a DbgValue that > indicates that the variable is "undefined", as we do not know > which part of the variable that is updated by the store. > > When ConvertDebugDeclareToDebugValue is used with a load/phi > instruction we assert that the referenced value is large enough > to cover the whole variable. Afaict this should be true for all > scenarios where those methods are used on trunk. If the assert > blows in the future I guess we could simply skip to insert a > dbg.value instruction. > > In the future I think we should examine which part of the variable > that is accessed, and add a DbgValue instrinsic with an appropriate > DW_OP_LLVM_fragment expression. > > Reviewers: dblaikie, aprantl, rnk > > Reviewed By: aprantl > > Subscribers: JDevlieghere, llvm-commits > > Tags: #debug-info > > Differential Revision: https://reviews.llvm.org/D48024 llvm-svn: 334830
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 406b52607f0..3d976005cba 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1228,6 +1228,23 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar,
return false;
}
+/// Check if the alloc size of \p ValTy is large enough to cover the variable
+/// (or fragment of the variable) described by \p DII.
+///
+/// This is primarily intended as a helper for the different
+/// ConvertDebugDeclareToDebugValue functions. The dbg.declare/dbg.addr that is
+/// converted describes an alloca'd variable, so we need to use the
+/// alloc size of the value when doing the comparison. E.g. an i1 value will be
+/// identified as covering an n-bit fragment, if the store size of i1 is at
+/// least n bits.
+static bool valueCoversEntireFragment(Type *ValTy, DbgInfoIntrinsic *DII) {
+ const DataLayout &DL = DII->getModule()->getDataLayout();
+ uint64_t ValueSize = DL.getTypeAllocSizeInBits(ValTy);
+ if (auto FragmentSize = DII->getFragmentSizeInBits())
+ return ValueSize >= *FragmentSize;
+ return false;
+}
+
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
@@ -1238,6 +1255,21 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
auto *DIExpr = DII->getExpression();
Value *DV = SI->getOperand(0);
+ if (!valueCoversEntireFragment(SI->getValueOperand()->getType(), DII)) {
+ // FIXME: If storing to a part of the variable described by the dbg.declare,
+ // then we want to insert a dbg.value for the corresponding fragment.
+ LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: "
+ << *DII << '\n');
+ // For now, when there is a store to parts of the variable (but we do not
+ // know which part) we insert an dbg.value instrinsic to indicate that we
+ // know nothing about the variable's content.
+ DV = UndefValue::get(DV->getType());
+ if (!LdStHasDebugValue(DIVar, DIExpr, SI))
+ Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, DII->getDebugLoc(),
+ SI);
+ return;
+ }
+
// If an argument is zero extended then use argument directly. The ZExt
// may be zapped by an optimization pass in future.
Argument *ExtendedArg = nullptr;
@@ -1281,6 +1313,9 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
if (LdStHasDebugValue(DIVar, DIExpr, LI))
return;
+ assert(valueCoversEntireFragment(LI->getType(), DII) &&
+ "Load is not loading the full variable fragment.");
+
// We are now tracking the loaded value instead of the address. In the
// future if multi-location support is added to the IR, it might be
// preferable to keep tracking both the loaded value and the original
@@ -1301,6 +1336,9 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
if (PhiHasDebugValue(DIVar, DIExpr, APN))
return;
+ assert(valueCoversEntireFragment(APN->getType(), DII) &&
+ "PHI node is not describing the full variable.");
+
BasicBlock *BB = APN->getParent();
auto InsertionPt = BB->getFirstInsertionPt();
OpenPOWER on IntegriCloud