From: Adrian Prantl Date: Wed, 30 Aug 2017 20:04:17 +0000 (+0000) Subject: Refactor DIBuilder::createFragmentExpression into a static DIExpression member X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c6206ffb780c385296687eb4ed36dfe72d5bbdd;p=llvm Refactor DIBuilder::createFragmentExpression into a static DIExpression member NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312165 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index fbb0e20d6f1..6d8677ad354 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -551,18 +551,6 @@ namespace llvm { DIExpression *createExpression(ArrayRef Addr = None); DIExpression *createExpression(ArrayRef Addr); - /// Create a descriptor to describe one part of an aggregate variable that - /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation - /// will be appended to the elements of \c Expr. If \c Expr already contains - /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset - /// into the existing fragment. - /// - /// \param OffsetInBits Offset of the piece in bits. - /// \param SizeInBits Size of the piece in bits. - DIExpression *createFragmentExpression(unsigned OffsetInBits, - unsigned SizeInBits, - const DIExpression *Expr = nullptr); - /// Create an expression for a variable that does not have an address, but /// does have a constant value. DIExpression *createConstantValueExpression(uint64_t Val) { diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 131e22f5aa1..890e08107a4 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -2293,6 +2293,18 @@ public: /// into a stack value. static DIExpression *prepend(const DIExpression *DIExpr, bool Deref, int64_t Offset = 0, bool StackValue = false); + + /// Create a DIExpression to describe one part of an aggregate variable that + /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation + /// will be appended to the elements of \c Expr. If \c Expr already contains + /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset + /// into the existing fragment. + /// + /// \param OffsetInBits Offset of the piece in bits. + /// \param SizeInBits Size of the piece in bits. + static DIExpression *createFragmentExpression(const DIExpression *Exp, + unsigned OffsetInBits, + unsigned SizeInBits); }; /// Global variables. diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 4e6e90fc4bb..f76363adb99 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -19,8 +19,8 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/IR/CallingConv.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -826,10 +826,10 @@ void DAGTypeLegalizer::GetExpandedInteger(SDValue Op, SDValue &Lo, Hi = Entry.second; } -/// Transfer debug valies by generating fragment expressions for split-up +/// Transfer debug values by generating fragment expressions for split-up /// values. -static void transferDbgValues(SelectionDAG &DAG, DIBuilder &DIB, SDValue From, - SDValue To, unsigned OffsetInBits) { +static void transferDbgValues(SelectionDAG &DAG, SDValue From, SDValue To, + unsigned OffsetInBits) { SDNode *FromNode = From.getNode(); SDNode *ToNode = To.getNode(); assert(FromNode != ToNode); @@ -840,9 +840,8 @@ static void transferDbgValues(SelectionDAG &DAG, DIBuilder &DIB, SDValue From, break; DIVariable *Var = Dbg->getVariable(); - DIExpression *Fragment = DIB.createFragmentExpression( - OffsetInBits, To.getValueSizeInBits(), - cast_or_null(Dbg->getExpression())); + auto *Fragment = DIExpression::createFragmentExpression( + Dbg->getExpression(), OffsetInBits, To.getValueSizeInBits()); SDDbgValue *Clone = DAG.getDbgValue(Var, Fragment, ToNode, To.getResNo(), Dbg->isIndirect(), Dbg->getDebugLoc(), Dbg->getOrder()); @@ -865,10 +864,8 @@ void DAGTypeLegalizer::SetExpandedInteger(SDValue Op, SDValue Lo, AnalyzeNewValue(Hi); // Transfer debug values. - const Module *M = DAG.getMachineFunction().getMMI().getModule(); - DIBuilder DIB(*const_cast(M)); - transferDbgValues(DAG, DIB, Op, Lo, 0); - transferDbgValues(DAG, DIB, Op, Hi, Lo.getValueSizeInBits()); + transferDbgValues(DAG, Op, Lo, 0); + transferDbgValues(DAG, Op, Hi, Lo.getValueSizeInBits()); // Remember that this is the result of the node. std::pair &Entry = ExpandedIntegers[Op]; diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 1bd9d557b8f..87edc563eba 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -670,33 +670,6 @@ DIExpression *DIBuilder::createExpression(ArrayRef Signed) { return createExpression(Addr); } -DIExpression *DIBuilder::createFragmentExpression(unsigned OffsetInBits, - unsigned SizeInBits, - const DIExpression *Expr) { - SmallVector Ops; - // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment. - if (Expr) { - for (auto Op : Expr->expr_ops()) { - if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) { - // Make the new offset point into the existing fragment. - uint64_t FragmentOffsetInBits = Op.getArg(0); - // Op.getArg(1) is FragmentSizeInBits. - assert((OffsetInBits + SizeInBits <= Op.getArg(1)) && - "new fragment outside of original fragment"); - OffsetInBits += FragmentOffsetInBits; - break; - } - Ops.push_back(Op.getOp()); - for (unsigned I = 0; I < Op.getNumArgs(); ++I) - Ops.push_back(Op.getArg(I)); - } - } - Ops.push_back(dwarf::DW_OP_LLVM_fragment); - Ops.push_back(OffsetInBits); - Ops.push_back(SizeInBits); - return DIExpression::get(VMContext, Ops); -} - template static DISubprogram *getSubprogram(bool IsDistinct, Ts &&... Args) { if (IsDistinct) diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index c14940bad45..005aac821f9 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -724,6 +724,34 @@ DIExpression *DIExpression::prepend(const DIExpression *Expr, bool Deref, return DIExpression::get(Expr->getContext(), Ops); } +DIExpression *DIExpression::createFragmentExpression(const DIExpression *Expr, + unsigned OffsetInBits, + unsigned SizeInBits) { + SmallVector Ops; + // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment. + if (Expr) { + for (auto Op : Expr->expr_ops()) { + if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) { + // Make the new offset point into the existing fragment. + uint64_t FragmentOffsetInBits = Op.getArg(0); + // Op.getArg(0) is FragmentOffsetInBits. + // Op.getArg(1) is FragmentSizeInBits. + assert((OffsetInBits + SizeInBits <= Op.getArg(0) + Op.getArg(1)) && + "new fragment outside of original fragment"); + OffsetInBits += FragmentOffsetInBits; + break; + } + Ops.push_back(Op.getOp()); + for (unsigned I = 0; I < Op.getNumArgs(); ++I) + Ops.push_back(Op.getArg(I)); + } + } + Ops.push_back(dwarf::DW_OP_LLVM_fragment); + Ops.push_back(OffsetInBits); + Ops.push_back(SizeInBits); + return DIExpression::get(Expr->getContext(), Ops); +} + bool DIExpression::isConstant() const { // Recognize DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment Len Ofs)?. if (getNumElements() != 3 && getNumElements() != 6) diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 2ccae575597..68d745f7ed3 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -29,7 +29,6 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Instructions.h" @@ -422,14 +421,13 @@ static bool GlobalUsersSafeToSRA(GlobalValue *GV) { static void transferSRADebugInfo(GlobalVariable *GV, GlobalVariable *NGV, uint64_t FragmentOffsetInBits, uint64_t FragmentSizeInBits) { - DIBuilder DIB(*GV->getParent(), /*AllowUnresolved*/ false); SmallVector GVs; GV->getDebugInfo(GVs); for (auto *GVE : GVs) { DIVariable *Var = GVE->getVariable(); DIExpression *Expr = GVE->getExpression(); - DIExpression *NExpr = DIB.createFragmentExpression( - FragmentOffsetInBits, FragmentSizeInBits, Expr); + auto *NExpr = DIExpression::createFragmentExpression( + Expr, FragmentOffsetInBits, FragmentSizeInBits); auto *NGVE = DIGlobalVariableExpression::get(GVE->getContext(), Var, NExpr); NGV->addDebugInfo(NGVE); } diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 83e5d38a0ad..458596b4c76 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -4068,7 +4068,14 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { continue; Size = std::min(Size, AbsEnd - Start); } - FragmentExpr = DIB.createFragmentExpression(Start, Size); + // The new, smaller fragment is stenciled out from the old fragment. + if (auto OrigFragment = FragmentExpr->getFragmentInfo()) { + assert(Start >= OrigFragment->OffsetInBits && + "new fragment is outside of original fragment"); + Start -= OrigFragment->OffsetInBits; + } + FragmentExpr = + DIExpression::createFragmentExpression(Expr, Start, Size); } // Remove any existing dbg.declare intrinsic describing the same alloca.