Index: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h +++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h @@ -2477,14 +2477,18 @@ 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. Index: llvm/trunk/include/llvm/Transforms/Utils/Local.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h @@ -316,7 +316,7 @@ /// (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 @@ -325,8 +325,8 @@ /// 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 Index: llvm/trunk/lib/CodeGen/LiveDebugValues.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LiveDebugValues.cpp +++ llvm/trunk/lib/CodeGen/LiveDebugValues.cpp @@ -462,9 +462,9 @@ // 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); Index: llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp +++ llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp @@ -1316,11 +1316,13 @@ // 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; } Index: llvm/trunk/lib/CodeGen/MachineInstr.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp @@ -2075,7 +2075,7 @@ 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; } Index: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp @@ -1187,11 +1187,13 @@ // to be direct. if (MI.isIndirectDebugValue() && DIExpr->isImplicit()) { SmallVector 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; } Index: llvm/trunk/lib/CodeGen/SafeStack.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SafeStack.cpp +++ llvm/trunk/lib/CodeGen/SafeStack.cpp @@ -576,7 +576,7 @@ // 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(NewArg)->getNextNode()); IRB.CreateMemCpy(Off, Align, Arg, Arg->getParamAlignment(), Size); @@ -591,8 +591,8 @@ 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. @@ -683,8 +683,7 @@ if (AI->hasName() && isa(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(); } Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -7946,9 +7946,8 @@ // 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()); Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1363,7 +1363,7 @@ 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()); } Index: llvm/trunk/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/trunk/lib/IR/DebugInfoMetadata.cpp +++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp @@ -979,17 +979,18 @@ 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 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); } Index: llvm/trunk/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp =================================================================== --- llvm/trunk/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp +++ llvm/trunk/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp @@ -72,8 +72,8 @@ 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; } Index: llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp +++ llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp @@ -568,11 +568,8 @@ unsigned VReg, int64_t AddrDispShift) { DIExpression *Expr = const_cast(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(); Index: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp @@ -1671,7 +1671,8 @@ 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); Index: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -3053,7 +3053,7 @@ Value *FakeStack; Value *LocalStackBase; Value *LocalStackBaseAlloca; - bool Deref; + uint8_t DIExprFlags = DIExpression::ApplyOffset; if (DoStackMalloc) { LocalStackBaseAlloca = @@ -3094,7 +3094,7 @@ 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); @@ -3102,14 +3102,13 @@ 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()); Index: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp @@ -1862,8 +1862,7 @@ // 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 VarArgsToForward; Index: llvm/trunk/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp +++ llvm/trunk/lib/Transforms/Utils/Local.cpp @@ -1552,14 +1552,14 @@ 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); @@ -1571,10 +1571,10 @@ } 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, Index: llvm/trunk/unittests/IR/MetadataTest.cpp =================================================================== --- llvm/trunk/unittests/IR/MetadataTest.cpp +++ llvm/trunk/unittests/IR/MetadataTest.cpp @@ -2335,7 +2335,11 @@ // 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, Index: llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp =================================================================== --- llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp +++ llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp @@ -153,8 +153,7 @@ 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;