mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[DebugInfo] Support DIArgList in DbgVariableIntrinsic
This patch updates DbgVariableIntrinsics to support use of a DIArgList for the location operand, resulting in a significant change to its interface. This patch does not update all IR passes to support multiple location operands in a dbg.value; the only change is to update the DbgVariableIntrinsic interface and its uses. All code outside of the intrinsic classes assumes that an intrinsic will always have exactly one location operand; they will still support DIArgLists, but only if they contain exactly one Value. Among other changes, the setOperand and setArgOperand functions in DbgVariableIntrinsic have been made private. This is to prevent code from setting the operands of these intrinsics directly, which could easily result in incorrect/invalid operands being set. This does not prevent these functions from being called on a debug intrinsic at all, as they can still be called on any CallInst pointer; it is assumed that any code directly setting the operands on a generic call instruction is doing so safely. The intention for making these functions private is to prevent DIArgLists from being overwritten by code that's naively trying to replace one of the Values it points to, and also to fail fast if a DbgVariableIntrinsic is updated to use a DIArgList without a valid corresponding DIExpression.
This commit is contained in:
parent
3d630d42cc
commit
bfb6dad2ae
@ -24,6 +24,7 @@
|
||||
#define LLVM_IR_INTRINSICINST_H
|
||||
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/FPEnv.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
@ -146,10 +147,78 @@ public:
|
||||
/// This is the common base class for debug info intrinsics for variables.
|
||||
class DbgVariableIntrinsic : public DbgInfoIntrinsic {
|
||||
public:
|
||||
/// Get the location corresponding to the variable referenced by the debug
|
||||
// Iterator for ValueAsMetadata that internally uses direct pointer iteration
|
||||
// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
|
||||
// ValueAsMetadata .
|
||||
class location_op_iterator
|
||||
: public iterator_facade_base<location_op_iterator,
|
||||
std::bidirectional_iterator_tag, Value *> {
|
||||
PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
|
||||
|
||||
public:
|
||||
location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
|
||||
location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
|
||||
|
||||
location_op_iterator(const location_op_iterator &R) : I(R.I) {}
|
||||
location_op_iterator &operator=(const location_op_iterator &R) {
|
||||
I = R.I;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const location_op_iterator &RHS) const {
|
||||
return I == RHS.I;
|
||||
}
|
||||
const Value *operator*() const {
|
||||
ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
|
||||
? I.get<ValueAsMetadata *>()
|
||||
: *I.get<ValueAsMetadata **>();
|
||||
return VAM->getValue();
|
||||
};
|
||||
Value *operator*() {
|
||||
ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
|
||||
? I.get<ValueAsMetadata *>()
|
||||
: *I.get<ValueAsMetadata **>();
|
||||
return VAM->getValue();
|
||||
}
|
||||
location_op_iterator &operator++() {
|
||||
if (I.is<ValueAsMetadata *>())
|
||||
I = I.get<ValueAsMetadata *>() + 1;
|
||||
else
|
||||
I = I.get<ValueAsMetadata **>() + 1;
|
||||
return *this;
|
||||
}
|
||||
location_op_iterator &operator--() {
|
||||
if (I.is<ValueAsMetadata *>())
|
||||
I = I.get<ValueAsMetadata *>() - 1;
|
||||
else
|
||||
I = I.get<ValueAsMetadata **>() - 1;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// Get the locations corresponding to the variable referenced by the debug
|
||||
/// info intrinsic. Depending on the intrinsic, this could be the
|
||||
/// variable's value or its address.
|
||||
Value *getVariableLocation(bool AllowNullOp = true) const;
|
||||
iterator_range<location_op_iterator> location_ops() const;
|
||||
|
||||
Value *getVariableLocationOp(unsigned OpIdx) const;
|
||||
|
||||
void replaceVariableLocationOp(Value *OldValue, Value *NewValue);
|
||||
|
||||
void setVariable(DILocalVariable *NewVar) {
|
||||
setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar));
|
||||
}
|
||||
|
||||
void setExpression(DIExpression *NewExpr) {
|
||||
setArgOperand(2, MetadataAsValue::get(NewExpr->getContext(), NewExpr));
|
||||
}
|
||||
|
||||
unsigned getNumVariableLocationOps() const {
|
||||
if (hasArgList())
|
||||
return cast<DIArgList>(getRawLocation())->getArgs().size();
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
|
||||
|
||||
/// Does this describe the address of a local variable. True for dbg.addr
|
||||
/// and dbg.declare, but not dbg.value, which describes its value.
|
||||
@ -157,6 +226,24 @@ public:
|
||||
return getIntrinsicID() != Intrinsic::dbg_value;
|
||||
}
|
||||
|
||||
void setUndef() {
|
||||
// TODO: When/if we remove duplicate values from DIArgLists, we don't need
|
||||
// this set anymore.
|
||||
SmallPtrSet<Value *, 4> RemovedValues;
|
||||
for (Value *OldValue : location_ops()) {
|
||||
if (!RemovedValues.insert(OldValue).second)
|
||||
continue;
|
||||
Value *Undef = UndefValue::get(OldValue->getType());
|
||||
replaceVariableLocationOp(OldValue, Undef);
|
||||
}
|
||||
}
|
||||
|
||||
bool isUndef() const {
|
||||
return (getNumVariableLocationOps() == 0 &&
|
||||
!getExpression()->isComplex()) ||
|
||||
any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
|
||||
}
|
||||
|
||||
DILocalVariable *getVariable() const {
|
||||
return cast<DILocalVariable>(getRawVariable());
|
||||
}
|
||||
@ -165,6 +252,10 @@ public:
|
||||
return cast<DIExpression>(getRawExpression());
|
||||
}
|
||||
|
||||
Metadata *getRawLocation() const {
|
||||
return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
|
||||
}
|
||||
|
||||
Metadata *getRawVariable() const {
|
||||
return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
|
||||
}
|
||||
@ -193,12 +284,21 @@ public:
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
/// @}
|
||||
private:
|
||||
void setArgOperand(unsigned i, Value *v) {
|
||||
DbgInfoIntrinsic::setArgOperand(i, v);
|
||||
}
|
||||
void setOperand(unsigned i, Value *v) { DbgInfoIntrinsic::setOperand(i, v); }
|
||||
};
|
||||
|
||||
/// This represents the llvm.dbg.declare instruction.
|
||||
class DbgDeclareInst : public DbgVariableIntrinsic {
|
||||
public:
|
||||
Value *getAddress() const { return getVariableLocation(); }
|
||||
Value *getAddress() const {
|
||||
assert(getNumVariableLocationOps() == 1 &&
|
||||
"dbg.declare must have exactly 1 location operand.");
|
||||
return getVariableLocationOp(0);
|
||||
}
|
||||
|
||||
/// \name Casting methods
|
||||
/// @{
|
||||
@ -214,7 +314,11 @@ public:
|
||||
/// This represents the llvm.dbg.addr instruction.
|
||||
class DbgAddrIntrinsic : public DbgVariableIntrinsic {
|
||||
public:
|
||||
Value *getAddress() const { return getVariableLocation(); }
|
||||
Value *getAddress() const {
|
||||
assert(getNumVariableLocationOps() == 1 &&
|
||||
"dbg.addr must have exactly 1 location operand.");
|
||||
return getVariableLocationOp(0);
|
||||
}
|
||||
|
||||
/// \name Casting methods
|
||||
/// @{
|
||||
@ -229,8 +333,13 @@ public:
|
||||
/// This represents the llvm.dbg.value instruction.
|
||||
class DbgValueInst : public DbgVariableIntrinsic {
|
||||
public:
|
||||
Value *getValue() const {
|
||||
return getVariableLocation(/* AllowNullOp = */ false);
|
||||
// The default argument should only be used in ISel, and the default option
|
||||
// should be removed once ISel support for multiple location ops is complete.
|
||||
Value *getValue(unsigned OpIdx = 0) const {
|
||||
return getVariableLocationOp(OpIdx);
|
||||
}
|
||||
iterator_range<location_op_iterator> getValues() const {
|
||||
return location_ops();
|
||||
}
|
||||
|
||||
/// \name Casting methods
|
||||
|
@ -550,8 +550,7 @@ class MetadataLoader::MetadataLoaderImpl {
|
||||
SmallVector<uint64_t, 8> Ops;
|
||||
Ops.append(std::next(DIExpr->elements_begin()),
|
||||
DIExpr->elements_end());
|
||||
auto *E = DIExpression::get(Context, Ops);
|
||||
DDI->setOperand(2, MetadataAsValue::get(Context, E));
|
||||
DDI->setExpression(DIExpression::get(Context, Ops));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2883,11 +2883,8 @@ class TypePromotionTransaction {
|
||||
// including the debug uses. Since we are undoing the replacements,
|
||||
// the original debug uses must also be reinstated to maintain the
|
||||
// correctness and utility of debug value instructions.
|
||||
for (auto *DVI: DbgValues) {
|
||||
LLVMContext &Ctx = Inst->getType()->getContext();
|
||||
auto *MV = MetadataAsValue::get(Ctx, ValueAsMetadata::get(Inst));
|
||||
DVI->setOperand(0, MV);
|
||||
}
|
||||
for (auto *DVI : DbgValues)
|
||||
DVI->replaceVariableLocationOp(DVI->getVariableLocationOp(0), Inst);
|
||||
}
|
||||
};
|
||||
|
||||
@ -7878,7 +7875,7 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) {
|
||||
DbgValueInst &DVI = *cast<DbgValueInst>(I);
|
||||
|
||||
// Does this dbg.value refer to a sunk address calculation?
|
||||
Value *Location = DVI.getVariableLocation();
|
||||
Value *Location = DVI.getVariableLocationOp(0);
|
||||
WeakTrackingVH SunkAddrVH = SunkAddrs[Location];
|
||||
Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr;
|
||||
if (SunkAddr) {
|
||||
@ -7886,8 +7883,7 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) {
|
||||
// opportunity to be accurately lowered. This update may change the type of
|
||||
// pointer being referred to; however this makes no difference to debugging
|
||||
// information, and we can't generate bitcasts that may affect codegen.
|
||||
DVI.setOperand(0, MetadataAsValue::get(DVI.getContext(),
|
||||
ValueAsMetadata::get(SunkAddr)));
|
||||
DVI.replaceVariableLocationOp(Location, SunkAddr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1191,8 +1191,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
|
||||
<< "in EmitFuncArgumentDbgValue\n");
|
||||
} else {
|
||||
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
|
||||
auto Undef =
|
||||
UndefValue::get(DDI.getDI()->getVariableLocation()->getType());
|
||||
auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType());
|
||||
auto SDV =
|
||||
DAG.getConstantDbgValue(Variable, Expr, Undef, dl, DbgSDNodeOrder);
|
||||
DAG.AddDbgValue(SDV, nullptr, false);
|
||||
@ -1246,7 +1245,7 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
|
||||
// This was the final opportunity to salvage this debug information, and it
|
||||
// couldn't be done. Place an undef DBG_VALUE at this location to terminate
|
||||
// any earlier variable location.
|
||||
auto Undef = UndefValue::get(DDI.getDI()->getVariableLocation()->getType());
|
||||
auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType());
|
||||
auto SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder);
|
||||
DAG.AddDbgValue(SDV, nullptr, false);
|
||||
|
||||
@ -5885,7 +5884,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
|
||||
LLVM_DEBUG(dbgs() << "SelectionDAG visiting debug intrinsic: " << DI
|
||||
<< "\n");
|
||||
// Check if address has undef value.
|
||||
const Value *Address = DI.getVariableLocation();
|
||||
const Value *Address = DI.getVariableLocationOp(0);
|
||||
if (!Address || isa<UndefValue>(Address) ||
|
||||
(Address->use_empty() && !isa<Argument>(Address))) {
|
||||
LLVM_DEBUG(dbgs() << "Dropping debug info for " << DI
|
||||
|
@ -721,6 +721,12 @@ static bool removeDeadUsersOfConstant(const Constant *C) {
|
||||
return false; // Constant wasn't dead
|
||||
}
|
||||
|
||||
// If C is only used by metadata, it should not be preserved but should have
|
||||
// its uses replaced.
|
||||
if (C->isUsedByMetadata()) {
|
||||
const_cast<Constant *>(C)->replaceAllUsesWith(
|
||||
UndefValue::get(C->getType()));
|
||||
}
|
||||
const_cast<Constant*>(C)->destroyConstant();
|
||||
return true;
|
||||
}
|
||||
|
@ -38,18 +38,65 @@ using namespace llvm;
|
||||
/// intrinsics for variables.
|
||||
///
|
||||
|
||||
Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const {
|
||||
Value *Op = getArgOperand(0);
|
||||
if (AllowNullOp && !Op)
|
||||
iterator_range<DbgVariableIntrinsic::location_op_iterator>
|
||||
DbgVariableIntrinsic::location_ops() const {
|
||||
auto *MD = getRawLocation();
|
||||
assert(MD && "First operand of DbgVariableIntrinsic should be non-null.");
|
||||
|
||||
// If operand is ValueAsMetadata, return a range over just that operand.
|
||||
if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) {
|
||||
return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
|
||||
}
|
||||
// If operand is DIArgList, return a range over its args.
|
||||
if (auto *AL = dyn_cast<DIArgList>(MD))
|
||||
return {location_op_iterator(AL->args_begin()),
|
||||
location_op_iterator(AL->args_end())};
|
||||
// Operand must be an empty metadata tuple, so return empty iterator.
|
||||
return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
|
||||
location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
|
||||
}
|
||||
|
||||
Value *DbgVariableIntrinsic::getVariableLocationOp(unsigned OpIdx) const {
|
||||
auto *MD = getRawLocation();
|
||||
assert(MD && "First operand of DbgVariableIntrinsic should be non-null.");
|
||||
if (auto *AL = dyn_cast<DIArgList>(MD))
|
||||
return AL->getArgs()[OpIdx]->getValue();
|
||||
if (isa<MDNode>(MD))
|
||||
return nullptr;
|
||||
assert(
|
||||
isa<ValueAsMetadata>(MD) &&
|
||||
"Attempted to get location operand from DbgVariableIntrinsic with none.");
|
||||
auto *V = cast<ValueAsMetadata>(MD);
|
||||
assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
|
||||
"single location operand.");
|
||||
return V->getValue();
|
||||
}
|
||||
|
||||
auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
|
||||
if (auto *V = dyn_cast<ValueAsMetadata>(MD))
|
||||
return V->getValue();
|
||||
static ValueAsMetadata *getAsMetadata(Value *V) {
|
||||
return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
|
||||
cast<MetadataAsValue>(V)->getMetadata())
|
||||
: ValueAsMetadata::get(V);
|
||||
}
|
||||
|
||||
// When the value goes to null, it gets replaced by an empty MDNode.
|
||||
assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
|
||||
return nullptr;
|
||||
void DbgVariableIntrinsic::replaceVariableLocationOp(Value *OldValue,
|
||||
Value *NewValue) {
|
||||
assert(NewValue && "Values must be non-null");
|
||||
auto Locations = location_ops();
|
||||
auto OldIt = find(Locations, OldValue);
|
||||
assert(OldIt != Locations.end() && "OldValue must be a current location");
|
||||
if (!hasArgList()) {
|
||||
Value *NewOperand = isa<MetadataAsValue>(NewValue)
|
||||
? NewValue
|
||||
: MetadataAsValue::get(
|
||||
getContext(), ValueAsMetadata::get(NewValue));
|
||||
return setArgOperand(0, NewOperand);
|
||||
}
|
||||
SmallVector<ValueAsMetadata *, 4> MDs;
|
||||
ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
|
||||
for (auto *VMD : Locations)
|
||||
MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
|
||||
setArgOperand(
|
||||
0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs)));
|
||||
}
|
||||
|
||||
Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const {
|
||||
|
@ -5371,7 +5371,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
|
||||
}
|
||||
|
||||
void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic &DII) {
|
||||
auto *MD = cast<MetadataAsValue>(DII.getArgOperand(0))->getMetadata();
|
||||
auto *MD = DII.getRawLocation();
|
||||
AssertDI(isa<ValueAsMetadata>(MD) || isa<DIArgList>(MD) ||
|
||||
(isa<MDNode>(MD) && !cast<MDNode>(MD)->getNumOperands()),
|
||||
"invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD);
|
||||
|
@ -284,6 +284,7 @@ public:
|
||||
class AArch64StackTagging : public FunctionPass {
|
||||
struct AllocaInfo {
|
||||
AllocaInst *AI;
|
||||
TrackingVH<Instruction> OldAI; // Track through RAUW to replace debug uses.
|
||||
SmallVector<IntrinsicInst *, 2> LifetimeStart;
|
||||
SmallVector<IntrinsicInst *, 2> LifetimeEnd;
|
||||
SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics;
|
||||
@ -557,12 +558,13 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
|
||||
Instruction *I = &*IT;
|
||||
if (auto *AI = dyn_cast<AllocaInst>(I)) {
|
||||
Allocas[AI].AI = AI;
|
||||
Allocas[AI].OldAI = AI;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(I)) {
|
||||
if (auto *AI =
|
||||
dyn_cast_or_null<AllocaInst>(DVI->getVariableLocation())) {
|
||||
dyn_cast_or_null<AllocaInst>(DVI->getVariableLocationOp(0))) {
|
||||
Allocas[AI].DbgVariableIntrinsics.push_back(DVI);
|
||||
}
|
||||
continue;
|
||||
@ -705,9 +707,7 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
|
||||
|
||||
// Fixup debug intrinsics to point to the new alloca.
|
||||
for (auto DVI : Info.DbgVariableIntrinsics)
|
||||
DVI->setArgOperand(
|
||||
0,
|
||||
MetadataAsValue::get(F->getContext(), LocalAsMetadata::get(Info.AI)));
|
||||
DVI->replaceVariableLocationOp(Info.OldAI, Info.AI);
|
||||
}
|
||||
|
||||
// If we have instrumented at least one alloca, all unrecognized lifetime
|
||||
|
@ -2156,6 +2156,7 @@ void coro::salvageDebugInfo(
|
||||
// function argument and convert into a DIExpression.
|
||||
bool OutermostLoad = true;
|
||||
Value *Storage = DDI->getAddress();
|
||||
Value *OriginalStorage = Storage;
|
||||
while (Storage) {
|
||||
if (auto *LdInst = dyn_cast<LoadInst>(Storage)) {
|
||||
Storage = LdInst->getOperand(0);
|
||||
@ -2206,10 +2207,8 @@ void coro::salvageDebugInfo(
|
||||
if (Expr && Expr->isComplex())
|
||||
Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore);
|
||||
}
|
||||
auto &VMContext = DDI->getFunction()->getContext();
|
||||
DDI->setOperand(
|
||||
0, MetadataAsValue::get(VMContext, ValueAsMetadata::get(Storage)));
|
||||
DDI->setOperand(2, MetadataAsValue::get(VMContext, Expr));
|
||||
DDI->replaceVariableLocationOp(OriginalStorage, Storage);
|
||||
DDI->setExpression(Expr);
|
||||
if (auto *InsertPt = dyn_cast_or_null<Instruction>(Storage))
|
||||
DDI->moveAfter(InsertPt);
|
||||
}
|
||||
|
@ -3582,10 +3582,6 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
|
||||
if (!isa<DbgDeclareInst>(DII))
|
||||
return false;
|
||||
|
||||
if (isa<CastInst>(I))
|
||||
DII->setOperand(
|
||||
0, MetadataAsValue::get(I->getContext(),
|
||||
ValueAsMetadata::get(I->getOperand(0))));
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -1153,9 +1153,10 @@ bool HWAddressSanitizer::instrumentStack(
|
||||
// to put it at the beginning of the expression.
|
||||
SmallVector<uint64_t, 8> NewOps = {dwarf::DW_OP_LLVM_tag_offset,
|
||||
RetagMask(N)};
|
||||
DDI->setArgOperand(
|
||||
2, MetadataAsValue::get(*C, DIExpression::prependOpcodes(
|
||||
DDI->getExpression(), NewOps)));
|
||||
auto Locations = DDI->location_ops();
|
||||
unsigned LocNo = std::distance(Locations.begin(), find(Locations, AI));
|
||||
DDI->setExpression(
|
||||
DIExpression::appendOpsToArg(DDI->getExpression(), NewOps, LocNo));
|
||||
}
|
||||
|
||||
size_t Size = getAllocaSizeInBytes(*AI);
|
||||
@ -1219,7 +1220,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
|
||||
|
||||
if (auto *DDI = dyn_cast<DbgVariableIntrinsic>(&Inst))
|
||||
if (auto *Alloca =
|
||||
dyn_cast_or_null<AllocaInst>(DDI->getVariableLocation()))
|
||||
dyn_cast_or_null<AllocaInst>(DDI->getVariableLocationOp(0)))
|
||||
AllocaDbgMap[Alloca].push_back(DDI);
|
||||
|
||||
if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
|
||||
@ -1300,10 +1301,9 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
|
||||
for (auto &Inst : BB)
|
||||
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&Inst))
|
||||
if (auto *AI =
|
||||
dyn_cast_or_null<AllocaInst>(DVI->getVariableLocation()))
|
||||
dyn_cast_or_null<AllocaInst>(DVI->getVariableLocationOp(0)))
|
||||
if (auto *NewAI = AllocaToPaddedAllocaMap.lookup(AI))
|
||||
DVI->setArgOperand(
|
||||
0, MetadataAsValue::get(*C, LocalAsMetadata::get(NewAI)));
|
||||
DVI->replaceVariableLocationOp(AI, NewAI);
|
||||
for (auto &P : AllocaToPaddedAllocaMap)
|
||||
P.first->eraseFromParent();
|
||||
}
|
||||
|
@ -521,7 +521,7 @@ bool AggressiveDeadCodeElimination::removeDeadInstructions() {
|
||||
// If intrinsic is pointing at a live SSA value, there may be an
|
||||
// earlier optimization bug: if we know the location of the variable,
|
||||
// why isn't the scope of the location alive?
|
||||
if (Value *V = DII->getVariableLocation())
|
||||
if (Value *V = DII->getVariableLocationOp(0))
|
||||
if (Instruction *II = dyn_cast<Instruction>(V))
|
||||
if (isLive(II))
|
||||
dbgs() << "Dropping debug info for " << *DII << "\n";
|
||||
|
@ -5836,7 +5836,7 @@ static void DbgGatherEqualValues(Loop *L, ScalarEvolution &SE,
|
||||
auto DVI = dyn_cast<DbgValueInst>(&I);
|
||||
if (!DVI)
|
||||
continue;
|
||||
auto V = DVI->getVariableLocation();
|
||||
auto V = DVI->getVariableLocationOp(0);
|
||||
if (!V || !SE.isSCEVable(V->getType()))
|
||||
continue;
|
||||
auto DbgValueSCEV = SE.getSCEV(V);
|
||||
@ -5862,7 +5862,7 @@ static void DbgApplyEqualValues(EqualValuesMap &DbgValueToEqualSet) {
|
||||
for (auto A : DbgValueToEqualSet) {
|
||||
auto DVI = A.first;
|
||||
// Only update those that are now undef.
|
||||
if (!isa_and_nonnull<UndefValue>(DVI->getVariableLocation()))
|
||||
if (!isa_and_nonnull<UndefValue>(DVI->getVariableLocationOp(0)))
|
||||
continue;
|
||||
for (auto EV : A.second) {
|
||||
auto V = std::get<WeakVH>(EV);
|
||||
@ -5870,14 +5870,13 @@ static void DbgApplyEqualValues(EqualValuesMap &DbgValueToEqualSet) {
|
||||
continue;
|
||||
auto DbgDIExpr = std::get<DIExpression *>(EV);
|
||||
auto Offset = std::get<int64_t>(EV);
|
||||
auto &Ctx = DVI->getContext();
|
||||
DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V)));
|
||||
DVI->replaceVariableLocationOp(DVI->getVariableLocationOp(0), V);
|
||||
if (Offset) {
|
||||
SmallVector<uint64_t, 8> Ops;
|
||||
DIExpression::appendOffset(Ops, Offset);
|
||||
DbgDIExpr = DIExpression::prependOpcodes(DbgDIExpr, Ops, true);
|
||||
}
|
||||
DVI->setOperand(2, MetadataAsValue::get(Ctx, DbgDIExpr));
|
||||
DVI->setExpression(DbgDIExpr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
|
||||
// Debug variable has special operand to check it's not hoisted.
|
||||
if (const auto *DVI = dyn_cast<DbgVariableIntrinsic>(U)) {
|
||||
if (const auto *I =
|
||||
dyn_cast_or_null<Instruction>(DVI->getVariableLocation()))
|
||||
dyn_cast_or_null<Instruction>(DVI->getVariableLocationOp(0)))
|
||||
if (NotHoisted.count(I) == 0)
|
||||
return true;
|
||||
return false;
|
||||
|
@ -1514,7 +1514,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
|
||||
// If the location isn't a constant or an instruction, delete the
|
||||
// intrinsic.
|
||||
auto *DVI = cast<DbgVariableIntrinsic>(DII);
|
||||
Value *Location = DVI->getVariableLocation();
|
||||
Value *Location = DVI->getVariableLocationOp(0);
|
||||
if (!Location ||
|
||||
(!isa<Constant>(Location) && !isa<Instruction>(Location))) {
|
||||
DebugIntrinsicsToDelete.push_back(DVI);
|
||||
@ -1537,7 +1537,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
|
||||
NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
|
||||
OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero,
|
||||
OldVar->getAlignInBits());
|
||||
DVI->setArgOperand(1, MetadataAsValue::get(Ctx, NewVar));
|
||||
DVI->setVariable(cast<DILocalVariable>(NewVar));
|
||||
}
|
||||
for (auto *DII : DebugIntrinsicsToDelete)
|
||||
DII->eraseFromParent();
|
||||
|
@ -236,7 +236,6 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
||||
llvm::findDbgValues(DbgValues, I);
|
||||
|
||||
// Update pre-existing debug value uses that reside outside the loop.
|
||||
auto &Ctx = I->getContext();
|
||||
for (auto DVI : DbgValues) {
|
||||
BasicBlock *UserBB = DVI->getParent();
|
||||
if (InstBB == UserBB || L->contains(UserBB))
|
||||
@ -247,7 +246,7 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
||||
Value *V = AddedPHIs.size() == 1 ? AddedPHIs[0]
|
||||
: SSAUpdate.FindValueForBlock(UserBB);
|
||||
if (V)
|
||||
DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V)));
|
||||
DVI->replaceVariableLocationOp(I, V);
|
||||
}
|
||||
|
||||
// SSAUpdater might have inserted phi-nodes inside other loops. We'll need
|
||||
|
@ -566,8 +566,7 @@ bool llvm::replaceDbgUsesWithUndef(Instruction *I) {
|
||||
findDbgUsers(DbgUsers, I);
|
||||
for (auto *DII : DbgUsers) {
|
||||
Value *Undef = UndefValue::get(I->getType());
|
||||
DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
|
||||
ValueAsMetadata::get(Undef)));
|
||||
DII->replaceVariableLocationOp(I, Undef);
|
||||
}
|
||||
return !DbgUsers.empty();
|
||||
}
|
||||
@ -1389,7 +1388,7 @@ static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) {
|
||||
// VLA). Try to use the size of the alloca that the dbg intrinsic describes
|
||||
// intead.
|
||||
if (DII->isAddressOfVariable())
|
||||
if (auto *AI = dyn_cast_or_null<AllocaInst>(DII->getVariableLocation()))
|
||||
if (auto *AI = dyn_cast_or_null<AllocaInst>(DII->getVariableLocationOp(0)))
|
||||
if (Optional<TypeSize> FragmentSize = AI->getAllocationSizeInBits(DL)) {
|
||||
assert(ValueSize.isScalable() == FragmentSize->isScalable() &&
|
||||
"Both sizes should agree on the scalable flag.");
|
||||
@ -1597,7 +1596,8 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
|
||||
ValueToValueMapTy DbgValueMap;
|
||||
for (auto &I : *BB) {
|
||||
if (auto DbgII = dyn_cast<DbgVariableIntrinsic>(&I)) {
|
||||
if (auto *Loc = dyn_cast_or_null<PHINode>(DbgII->getVariableLocation()))
|
||||
if (auto *Loc =
|
||||
dyn_cast_or_null<PHINode>(DbgII->getVariableLocationOp(0)))
|
||||
DbgValueMap.insert({Loc, DbgII});
|
||||
}
|
||||
}
|
||||
@ -1607,19 +1607,18 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
|
||||
// Then iterate through the new PHIs and look to see if they use one of the
|
||||
// previously mapped PHIs. If so, insert a new dbg.value intrinsic that will
|
||||
// propagate the info through the new PHI.
|
||||
LLVMContext &C = BB->getContext();
|
||||
for (auto PHI : InsertedPHIs) {
|
||||
BasicBlock *Parent = PHI->getParent();
|
||||
// Avoid inserting an intrinsic into an EH block.
|
||||
if (Parent->getFirstNonPHI()->isEHPad())
|
||||
continue;
|
||||
auto PhiMAV = MetadataAsValue::get(C, ValueAsMetadata::get(PHI));
|
||||
for (auto VI : PHI->operand_values()) {
|
||||
auto V = DbgValueMap.find(VI);
|
||||
if (V != DbgValueMap.end()) {
|
||||
auto *DbgII = cast<DbgVariableIntrinsic>(V->second);
|
||||
Instruction *NewDbgII = DbgII->clone();
|
||||
NewDbgII->setOperand(0, PhiMAV);
|
||||
DbgVariableIntrinsic *NewDbgII =
|
||||
cast<DbgVariableIntrinsic>(DbgII->clone());
|
||||
NewDbgII->replaceVariableLocationOp(VI, PHI);
|
||||
auto InsertionPt = Parent->getFirstInsertionPt();
|
||||
assert(InsertionPt != Parent->end() && "Ill-formed basic block");
|
||||
NewDbgII->insertBefore(&*InsertionPt);
|
||||
@ -1736,11 +1735,6 @@ void llvm::replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
|
||||
replaceOneDbgValueForAlloca(DVI, NewAllocaAddress, Builder, Offset);
|
||||
}
|
||||
|
||||
/// Wrap \p V in a ValueAsMetadata instance.
|
||||
static MetadataAsValue *wrapValueInMetadata(LLVMContext &C, Value *V) {
|
||||
return MetadataAsValue::get(C, ValueAsMetadata::get(V));
|
||||
}
|
||||
|
||||
/// Where possible to salvage debug information for \p I do so
|
||||
/// and return True. If not possible mark undef and return False.
|
||||
void llvm::salvageDebugInfo(Instruction &I) {
|
||||
@ -1751,9 +1745,7 @@ void llvm::salvageDebugInfo(Instruction &I) {
|
||||
|
||||
void llvm::salvageDebugInfoForDbgValues(
|
||||
Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) {
|
||||
auto &Ctx = I.getContext();
|
||||
bool Salvaged = false;
|
||||
auto wrapMD = [&](Value *V) { return wrapValueInMetadata(Ctx, V); };
|
||||
|
||||
for (auto *DII : DbgUsers) {
|
||||
// Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they
|
||||
@ -1769,8 +1761,8 @@ void llvm::salvageDebugInfoForDbgValues(
|
||||
if (!DIExpr)
|
||||
break;
|
||||
|
||||
DII->setOperand(0, wrapMD(I.getOperand(0)));
|
||||
DII->setOperand(2, MetadataAsValue::get(Ctx, DIExpr));
|
||||
DII->replaceVariableLocationOp(&I, I.getOperand(0));
|
||||
DII->setExpression(DIExpr);
|
||||
LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n');
|
||||
Salvaged = true;
|
||||
}
|
||||
@ -1780,8 +1772,7 @@ void llvm::salvageDebugInfoForDbgValues(
|
||||
|
||||
for (auto *DII : DbgUsers) {
|
||||
Value *Undef = UndefValue::get(I.getType());
|
||||
DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
|
||||
ValueAsMetadata::get(Undef)));
|
||||
DII->replaceVariableLocationOp(&I, Undef);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1925,13 +1916,12 @@ static bool rewriteDebugUsers(
|
||||
if (UndefOrSalvage.count(DII))
|
||||
continue;
|
||||
|
||||
LLVMContext &Ctx = DII->getContext();
|
||||
DbgValReplacement DVR = RewriteExpr(*DII);
|
||||
if (!DVR)
|
||||
continue;
|
||||
|
||||
DII->setOperand(0, wrapValueInMetadata(Ctx, &To));
|
||||
DII->setOperand(2, MetadataAsValue::get(Ctx, *DVR));
|
||||
DII->replaceVariableLocationOp(&From, &To);
|
||||
DII->setExpression(*DVR);
|
||||
LLVM_DEBUG(dbgs() << "REWRITE: " << *DII << '\n');
|
||||
Changed = true;
|
||||
}
|
||||
|
@ -179,9 +179,7 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader,
|
||||
NewVal = SSA.GetValueInMiddleOfBlock(UserBB);
|
||||
else
|
||||
NewVal = UndefValue::get(OrigHeaderVal->getType());
|
||||
DbgValue->setOperand(0,
|
||||
MetadataAsValue::get(OrigHeaderVal->getContext(),
|
||||
ValueAsMetadata::get(NewVal)));
|
||||
DbgValue->replaceVariableLocationOp(OrigHeaderVal, NewVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -390,7 +388,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
||||
using DbgIntrinsicHash =
|
||||
std::pair<std::pair<Value *, DILocalVariable *>, DIExpression *>;
|
||||
auto makeHash = [](DbgVariableIntrinsic *D) -> DbgIntrinsicHash {
|
||||
return {{D->getVariableLocation(), D->getVariable()}, D->getExpression()};
|
||||
return {{D->getVariableLocationOp(0), D->getVariable()},
|
||||
D->getExpression()};
|
||||
};
|
||||
SmallDenseSet<DbgIntrinsicHash, 8> DbgIntrinsics;
|
||||
for (auto I = std::next(OrigPreheader->rbegin()), E = OrigPreheader->rend();
|
||||
|
@ -524,7 +524,9 @@ struct SalvageDebugInfoTest : ::testing::Test {
|
||||
}
|
||||
|
||||
bool doesDebugValueDescribeX(const DbgValueInst &DI) {
|
||||
const auto &CI = *cast<ConstantInt>(DI.getValue());
|
||||
if (DI.getNumVariableLocationOps() != 1)
|
||||
return false;
|
||||
const auto &CI = *cast<ConstantInt>(DI.getValue(0));
|
||||
if (CI.isZero())
|
||||
return DI.getExpression()->getElements().equals(
|
||||
{dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value});
|
||||
@ -534,7 +536,9 @@ struct SalvageDebugInfoTest : ::testing::Test {
|
||||
}
|
||||
|
||||
bool doesDebugValueDescribeY(const DbgValueInst &DI) {
|
||||
const auto &CI = *cast<ConstantInt>(DI.getValue());
|
||||
if (DI.getNumVariableLocationOps() != 1)
|
||||
return false;
|
||||
const auto &CI = *cast<ConstantInt>(DI.getVariableLocationOp(0));
|
||||
if (CI.isZero())
|
||||
return DI.getExpression()->getElements().equals(
|
||||
{dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_plus_uconst, 2,
|
||||
@ -758,13 +762,15 @@ TEST(Local, ReplaceAllDbgUsesWith) {
|
||||
EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT));
|
||||
|
||||
auto *ADbgVal = cast<DbgValueInst>(A.getNextNode());
|
||||
EXPECT_EQ(ConstantInt::get(A.getType(), 0), ADbgVal->getVariableLocation());
|
||||
EXPECT_EQ(ADbgVal->getNumVariableLocationOps(), 1);
|
||||
EXPECT_EQ(ConstantInt::get(A.getType(), 0), ADbgVal->getVariableLocationOp(0));
|
||||
|
||||
// Introduce a use-before-def. Check that the dbg.values for %f become undef.
|
||||
EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT));
|
||||
|
||||
auto *FDbgVal = cast<DbgValueInst>(F_.getNextNode());
|
||||
EXPECT_TRUE(isa<UndefValue>(FDbgVal->getVariableLocation()));
|
||||
EXPECT_EQ(FDbgVal->getNumVariableLocationOps(), 1);
|
||||
EXPECT_TRUE(FDbgVal->isUndef());
|
||||
|
||||
SmallVector<DbgValueInst *, 1> FDbgVals;
|
||||
findDbgValues(FDbgVals, &F_);
|
||||
|
Loading…
x
Reference in New Issue
Block a user