static const DIExpression *extractAddressClass(const DIExpression *Expr,
unsigned &AddrClass);
- /// Constants for DIExpression::prepend.
- enum { NoDeref = false, WithDeref = true, WithStackValue = true };
+ /// Used for DIExpression::prepend.
+ enum PrependOps : uint8_t {
+ ApplyOffset = 0,
+ DerefBefore = 1 << 0,
+ DerefAfter = 1 << 1,
+ StackValue = 1 << 2
+ };
/// Prepend \p DIExpr with a deref and offset operation and optionally turn it
/// into a stack value.
- static DIExpression *prepend(const DIExpression *Expr, bool DerefBefore,
- int64_t Offset = 0, bool DerefAfter = false,
- bool StackValue = false);
+ static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
+ int64_t Offset = 0);
/// Prepend \p DIExpr with the given opcodes and optionally turn it into a
/// stack value.
/// (between the optional Deref operations). Offset can be negative.
bool replaceDbgDeclare(Value *Address, Value *NewAddress,
Instruction *InsertBefore, DIBuilder &Builder,
- bool DerefBefore, int Offset, bool DerefAfter);
+ uint8_t DIExprFlags, int Offset);
/// Replaces llvm.dbg.declare instruction when the alloca it describes
/// is replaced with a new value. If Deref is true, an additional
/// optional Deref operations). Offset can be negative. The new
/// llvm.dbg.declare is inserted immediately after AI.
bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
- DIBuilder &Builder, bool DerefBefore,
- int Offset, bool DerefAfter);
+ DIBuilder &Builder, uint8_t DIExprFlags,
+ int Offset);
/// Replaces multiple llvm.dbg.value instructions when the alloca it describes
/// is replaced with a new value. If Offset is non-zero, a constant displacement
// Create a DBG_VALUE instruction to describe the Var in its spilled
// location.
VarLoc::SpillLoc SpillLocation = extractSpillBaseRegAndOffset(MI);
- auto *SpillExpr =
- DIExpression::prepend(DMI->getDebugExpression(), DIExpression::NoDeref,
- SpillLocation.SpillOffset);
+ auto *SpillExpr = DIExpression::prepend(DMI->getDebugExpression(),
+ DIExpression::ApplyOffset,
+ SpillLocation.SpillOffset);
NewDMI =
BuildMI(*MF, DMI->getDebugLoc(), DMI->getDesc(), true,
SpillLocation.SpillBase, DMI->getDebugVariable(), SpillExpr);
// that the original virtual register was a pointer. Also, add the stack slot
// offset for the spilled register to the expression.
const DIExpression *Expr = Expression;
+ uint8_t DIExprFlags = DIExpression::ApplyOffset;
bool IsIndirect = Loc.wasIndirect();
if (Spilled) {
- auto Deref = IsIndirect ? DIExpression::WithDeref : DIExpression::NoDeref;
+ if (IsIndirect)
+ DIExprFlags |= DIExpression::DerefAfter;
Expr =
- DIExpression::prepend(Expr, DIExpression::NoDeref, SpillOffset, Deref);
+ DIExpression::prepend(Expr, DIExprFlags, SpillOffset);
IsIndirect = true;
}
const DIExpression *Expr = MI.getDebugExpression();
if (MI.isIndirectDebugValue()) {
assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset");
- Expr = DIExpression::prepend(Expr, DIExpression::WithDeref);
+ Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore);
}
return Expr;
}
// to be direct.
if (MI.isIndirectDebugValue() && DIExpr->isImplicit()) {
SmallVector<uint64_t, 2> Ops = {dwarf::DW_OP_deref_size, Size};
- DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, DIExpression::WithStackValue);
+ bool WithStackValue = true;
+ DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue);
// Make the DBG_VALUE direct.
MI.getOperand(1).ChangeToRegister(0, false);
}
- DIExpr = DIExpression::prepend(DIExpr, DIExpression::NoDeref, Offset);
+ DIExpr =
+ DIExpression::prepend(DIExpr, DIExpression::ApplyOffset, Offset);
MI.getOperand(3).setMetadata(DIExpr);
continue;
}
// Replace alloc with the new location.
replaceDbgDeclare(Arg, BasePointer, BasePointer->getNextNode(), DIB,
- DIExpression::NoDeref, -Offset, DIExpression::NoDeref);
+ DIExpression::ApplyOffset, -Offset);
Arg->replaceAllUsesWith(NewArg);
IRB.SetInsertPoint(cast<Instruction>(NewArg)->getNextNode());
IRB.CreateMemCpy(Off, Align, Arg, Arg->getParamAlignment(), Size);
if (Size == 0)
Size = 1; // Don't create zero-sized stack objects.
- replaceDbgDeclareForAlloca(AI, BasePointer, DIB, DIExpression::NoDeref,
- -Offset, DIExpression::NoDeref);
+ replaceDbgDeclareForAlloca(AI, BasePointer, DIB, DIExpression::ApplyOffset,
+ -Offset);
replaceDbgValueForAlloca(AI, BasePointer, DIB, -Offset);
// Replace uses of the alloca with the new location.
if (AI->hasName() && isa<Instruction>(NewAI))
NewAI->takeName(AI);
- replaceDbgDeclareForAlloca(AI, NewAI, DIB, DIExpression::NoDeref, 0,
- DIExpression::NoDeref);
+ replaceDbgDeclareForAlloca(AI, NewAI, DIB, DIExpression::ApplyOffset, 0);
AI->replaceAllUsesWith(NewAI);
AI->eraseFromParent();
}
// DIExpression, we need to mark the expression with a
// DW_OP_stack_value.
auto *DIExpr = DV->getExpression();
- DIExpr = DIExpression::prepend(DIExpr, DIExpression::NoDeref, Offset,
- DIExpression::NoDeref,
- DIExpression::WithStackValue);
+ DIExpr =
+ DIExpression::prepend(DIExpr, DIExpression::StackValue, Offset);
SDDbgValue *Clone =
getDbgValue(DV->getVariable(), DIExpr, N0.getNode(), N0.getResNo(),
DV->isIndirect(), DV->getDebugLoc(), DV->getOrder());
DIExpression *Expr = DI->getExpression();
if (Offset.getBoolValue())
- Expr = DIExpression::prepend(Expr, DIExpression::NoDeref,
+ Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset,
Offset.getZExtValue());
MF->setVariableDbgInfo(DI->getVariable(), Expr, FI, DI->getDebugLoc());
}
return Expr;
}
-DIExpression *DIExpression::prepend(const DIExpression *Expr, bool DerefBefore,
- int64_t Offset, bool DerefAfter,
- bool StackValue) {
+DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags,
+ int64_t Offset) {
SmallVector<uint64_t, 8> Ops;
- if (DerefBefore)
+ if (Flags & DIExpression::DerefBefore)
Ops.push_back(dwarf::DW_OP_deref);
appendOffset(Ops, Offset);
- if (DerefAfter)
+ if (Flags & DIExpression::DerefAfter)
Ops.push_back(dwarf::DW_OP_deref);
+ bool StackValue = Flags & DIExpression::StackValue;
+
return prependOpcodes(Expr, Ops, StackValue);
}
TFI.getFrameIndexReference(MF, MI.getOperand(0).getIndex(), Reg);
MI.getOperand(0).ChangeToRegister(Reg, /*isDef=*/false);
MI.getOperand(0).setIsDebug();
- auto *DIExpr = DIExpression::prepend(MI.getDebugExpression(),
- DIExpression::NoDeref, Offset);
+ auto *DIExpr = DIExpression::prepend(
+ MI.getDebugExpression(), DIExpression::ApplyOffset, Offset);
MI.getOperand(3).setMetadata(DIExpr);
continue;
}
unsigned VReg,
int64_t AddrDispShift) {
DIExpression *Expr = const_cast<DIExpression *>(MI.getDebugExpression());
-
if (AddrDispShift != 0)
- Expr = DIExpression::prepend(Expr, DIExpression::NoDeref, AddrDispShift,
- DIExpression::NoDeref,
- DIExpression::WithStackValue);
+ Expr = DIExpression::prepend(Expr, DIExpression::StackValue, AddrDispShift);
// Replace DBG_VALUE instruction with modified version.
MachineBasicBlock *MBB = MI.getParent();
dwarf::DW_OP_constu, ValMinus,
dwarf::DW_OP_mul, dwarf::DW_OP_constu, ValInit,
dwarf::DW_OP_plus};
- E = DIExpression::prependOpcodes(E, Ops, DIExpression::WithStackValue);
+ bool WithStackValue = true;
+ E = DIExpression::prependOpcodes(E, Ops, WithStackValue);
DIGlobalVariableExpression *DGVE =
DIGlobalVariableExpression::get(NewGV->getContext(), DGV, E);
NewGV->addDebugInfo(DGVE);
Value *FakeStack;
Value *LocalStackBase;
Value *LocalStackBaseAlloca;
- bool Deref;
+ uint8_t DIExprFlags = DIExpression::ApplyOffset;
if (DoStackMalloc) {
LocalStackBaseAlloca =
LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack);
IRB.SetCurrentDebugLocation(EntryDebugLocation);
IRB.CreateStore(LocalStackBase, LocalStackBaseAlloca);
- Deref = true;
+ DIExprFlags |= DIExpression::DerefBefore;
} else {
// void *FakeStack = nullptr;
// void *LocalStackBase = alloca(LocalStackSize);
LocalStackBase =
DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca;
LocalStackBaseAlloca = LocalStackBase;
- Deref = false;
}
// Replace Alloca instructions with base+offset.
for (const auto &Desc : SVD) {
AllocaInst *AI = Desc.AI;
- replaceDbgDeclareForAlloca(AI, LocalStackBaseAlloca, DIB, Deref,
- Desc.Offset, DIExpression::NoDeref);
+ replaceDbgDeclareForAlloca(AI, LocalStackBaseAlloca, DIB, DIExprFlags,
+ Desc.Offset);
Value *NewAllocaPtr = IRB.CreateIntToPtr(
IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset)),
AI->getType());
// Move any dbg.declares describing the allocas into the entry basic block.
DIBuilder DIB(*Caller->getParent());
for (auto &AI : IFI.StaticAllocas)
- replaceDbgDeclareForAlloca(AI, AI, DIB, DIExpression::NoDeref, 0,
- DIExpression::NoDeref);
+ replaceDbgDeclareForAlloca(AI, AI, DIB, DIExpression::ApplyOffset, 0);
}
SmallVector<Value*,4> VarArgsToForward;
bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,
Instruction *InsertBefore, DIBuilder &Builder,
- bool DerefBefore, int Offset, bool DerefAfter) {
+ uint8_t DIExprFlags, int Offset) {
auto DbgAddrs = FindDbgAddrUses(Address);
for (DbgVariableIntrinsic *DII : DbgAddrs) {
DebugLoc Loc = DII->getDebugLoc();
auto *DIVar = DII->getVariable();
auto *DIExpr = DII->getExpression();
assert(DIVar && "Missing variable");
- DIExpr = DIExpression::prepend(DIExpr, DerefBefore, Offset, DerefAfter);
+ DIExpr = DIExpression::prepend(DIExpr, DIExprFlags, Offset);
// Insert llvm.dbg.declare immediately before InsertBefore, and remove old
// llvm.dbg.declare.
Builder.insertDeclare(NewAddress, DIVar, DIExpr, Loc, InsertBefore);
}
bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
- DIBuilder &Builder, bool DerefBefore,
- int Offset, bool DerefAfter) {
+ DIBuilder &Builder, uint8_t DIExprFlags,
+ int Offset) {
return replaceDbgDeclare(AI, NewAllocaAddress, AI->getNextNode(), Builder,
- DerefBefore, Offset, DerefAfter);
+ DIExprFlags, Offset);
}
static void replaceOneDbgValueForAlloca(DbgValueInst *DVI, Value *NewAddress,
// Test DIExpression::prepend().
uint64_t Elts0[] = {dwarf::DW_OP_LLVM_fragment, 0, 32};
auto *N0 = DIExpression::get(Context, Elts0);
- auto *N0WithPrependedOps = DIExpression::prepend(N0, true, 64, true, true);
+ uint8_t DIExprFlags = DIExpression::ApplyOffset;
+ DIExprFlags |= DIExpression::DerefBefore;
+ DIExprFlags |= DIExpression::DerefAfter;
+ DIExprFlags |= DIExpression::StackValue;
+ auto *N0WithPrependedOps = DIExpression::prepend(N0, DIExprFlags, 64);
uint64_t Elts1[] = {dwarf::DW_OP_deref,
dwarf::DW_OP_plus_uconst, 64,
dwarf::DW_OP_deref,
ASSERT_TRUE(DII);
Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C));
DIBuilder DIB(*M);
- replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::NoDeref, 0,
- DIExpression::NoDeref);
+ replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::ApplyOffset, 0);
// There should be exactly two dbg.declares.
int Declares = 0;