diff options
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 53 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 72 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfo.cpp | 102 |
3 files changed, 91 insertions, 136 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index b4f327bab5c..bbb8462652c 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -17,7 +17,6 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" @@ -107,20 +106,6 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; } - case 'd': { - if (Name.startswith("dbg.declare") && F->arg_size() == 2) { - F->setName(Name + ".old"); - NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_declare); - return true; - } - if (Name.startswith("dbg.value") && F->arg_size() == 3) { - F->setName(Name + ".old"); - NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value); - return true; - } - break; - } - case 'o': // We only need to change the name to match the mangling including the // address space. @@ -254,22 +239,6 @@ bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { return false; } -static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) { - if (!DbgNode || Elt >= DbgNode->getNumOperands()) - return nullptr; - return dyn_cast_or_null<MDNode>(DbgNode->getOperand(Elt)); -} - -static DIExpression getExpression(Value *VarOperand, Function *F) { - // Old-style DIVariables have an optional expression as the 8th element. - DIExpression Expr(getNodeField(cast<MDNode>(VarOperand), 8)); - if (!Expr) { - DIBuilder DIB(*F->getParent()); - Expr = DIB.createExpression(); - } - return Expr; -} - // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the // upgraded intrinsic. All argument and return casting must be provided in // order to seamlessly integrate with existing context. @@ -433,32 +402,12 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { } std::string Name = CI->getName().str(); - if (!Name.empty()) - CI->setName(Name + ".old"); + CI->setName(Name + ".old"); switch (NewFn->getIntrinsicID()) { default: llvm_unreachable("Unknown function for CallInst upgrade."); - // Upgrade debug intrinsics to use an additional DIExpression argument. - case Intrinsic::dbg_declare: { - auto NewCI = - Builder.CreateCall3(NewFn, CI->getArgOperand(0), CI->getArgOperand(1), - getExpression(CI->getArgOperand(1), F), Name); - NewCI->setDebugLoc(CI->getDebugLoc()); - CI->replaceAllUsesWith(NewCI); - CI->eraseFromParent(); - return; - } - case Intrinsic::dbg_value: { - auto NewCI = Builder.CreateCall4( - NewFn, CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), - getExpression(CI->getArgOperand(2), F), Name); - NewCI->setDebugLoc(CI->getDebugLoc()); - CI->replaceAllUsesWith(NewCI); - CI->eraseFromParent(); - return; - } case Intrinsic::ctlz: case Intrinsic::cttz: assert(CI->getNumArgOperands() == 1 && diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 1ab52523d73..a5c09b60c4f 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -1042,28 +1042,50 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, return RetVar; } -/// createExpression - Create a new descriptor for the specified -/// variable which has a complex address expression for its address. -/// @param Addr An array of complex address operations. -DIExpression DIBuilder::createExpression(ArrayRef<Value *> Addr) { - SmallVector<llvm::Value *, 16> Elts; - Elts.push_back(GetTagConstant(VMContext, DW_TAG_expression)); - Elts.insert(Elts.end(), Addr.begin(), Addr.end()); - return DIExpression(MDNode::get(VMContext, Elts)); +/// createComplexVariable - Create a new descriptor for the specified variable +/// which has a complex address expression for its address. +DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, + StringRef Name, DIFile F, + unsigned LineNo, + DITypeRef Ty, + ArrayRef<Value *> Addr, + unsigned ArgNo) { + assert(Addr.size() > 0 && "complex address is empty"); + Value *Elts[] = { + GetTagConstant(VMContext, Tag), + getNonCompileUnitScope(Scope), + MDString::get(VMContext, Name), + F, + ConstantInt::get(Type::getInt32Ty(VMContext), + (LineNo | (ArgNo << 24))), + Ty, + Constant::getNullValue(Type::getInt32Ty(VMContext)), + Constant::getNullValue(Type::getInt32Ty(VMContext)), + MDNode::get(VMContext, Addr) + }; + return DIVariable(MDNode::get(VMContext, Elts)); } /// createVariablePiece - Create a descriptor to describe one part /// of aggregate variable that is fragmented across multiple Values. -DIExpression DIBuilder::createPieceExpression(unsigned OffsetInBytes, - unsigned SizeInBytes) { +DIVariable DIBuilder::createVariablePiece(DIVariable Variable, + unsigned OffsetInBytes, + unsigned SizeInBytes) { assert(SizeInBytes > 0 && "zero-size piece"); Value *Addr[] = { - GetTagConstant(VMContext, DW_TAG_expression), - ConstantInt::get(Type::getInt64Ty(VMContext), dwarf::DW_OP_piece), - ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBytes), - ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBytes)}; + ConstantInt::get(Type::getInt32Ty(VMContext), OpPiece), + ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBytes), + ConstantInt::get(Type::getInt32Ty(VMContext), SizeInBytes) + }; + + assert((Variable->getNumOperands() == 8 || Variable.isVariablePiece()) && + "variable already has a complex address"); + SmallVector<Value *, 9> Elts; + for (unsigned i = 0; i < 8; ++i) + Elts.push_back(Variable->getOperand(i)); - return DIExpression(MDNode::get(VMContext, Addr)); + Elts.push_back(MDNode::get(VMContext, Addr)); + return DIVariable(MDNode::get(VMContext, Elts)); } /// createFunction - Create a new descriptor for the specified function. @@ -1270,7 +1292,6 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, - DIExpression Expr, Instruction *InsertBefore) { assert(Storage && "no storage passed to dbg.declare"); assert(VarInfo.isVariable() && @@ -1278,13 +1299,12 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr}; + Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo }; return CallInst::Create(DeclareFn, Args, "", InsertBefore); } /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, - DIExpression Expr, BasicBlock *InsertAtEnd) { assert(Storage && "no storage passed to dbg.declare"); assert(VarInfo.isVariable() && @@ -1292,7 +1312,7 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr}; + Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo }; // If this block already has a terminator then insert this intrinsic // before the terminator. @@ -1305,7 +1325,6 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, DIVariable VarInfo, - DIExpression Expr, Instruction *InsertBefore) { assert(V && "no value passed to dbg.value"); assert(VarInfo.isVariable() && @@ -1313,16 +1332,15 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); - Value *Args[] = {MDNode::get(V->getContext(), V), - ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), - VarInfo, Expr}; + Value *Args[] = { MDNode::get(V->getContext(), V), + ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), + VarInfo }; return CallInst::Create(ValueFn, Args, "", InsertBefore); } /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, DIVariable VarInfo, - DIExpression Expr, BasicBlock *InsertAtEnd) { assert(V && "no value passed to dbg.value"); assert(VarInfo.isVariable() && @@ -1330,8 +1348,8 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); - Value *Args[] = {MDNode::get(V->getContext(), V), - ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), - VarInfo, Expr}; + Value *Args[] = { MDNode::get(V->getContext(), V), + ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), + VarInfo }; return CallInst::Create(ValueFn, Args, "", InsertAtEnd); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 4e36a8df3e1..4274d82d158 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -49,7 +49,7 @@ bool DIDescriptor::Verify() const { DIObjCProperty(DbgNode).Verify() || DITemplateTypeParameter(DbgNode).Verify() || DITemplateValueParameter(DbgNode).Verify() || - DIImportedEntity(DbgNode).Verify() || DIExpression(DbgNode).Verify()); + DIImportedEntity(DbgNode).Verify()); } static Value *getField(const MDNode *DbgNode, unsigned Elt) { @@ -138,9 +138,33 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { } } +uint64_t DIVariable::getAddrElement(unsigned Idx) const { + DIDescriptor ComplexExpr = getDescriptorField(8); + if (Idx < ComplexExpr->getNumOperands()) + if (auto *CI = dyn_cast_or_null<ConstantInt>(ComplexExpr->getOperand(Idx))) + return CI->getZExtValue(); + + assert(false && "non-existing complex address element requested"); + return 0; +} + /// getInlinedAt - If this variable is inlined then return inline location. MDNode *DIVariable::getInlinedAt() const { return getNodeField(DbgNode, 7); } +bool DIVariable::isVariablePiece() const { + return hasComplexAddress() && getAddrElement(0) == DIBuilder::OpPiece; +} + +uint64_t DIVariable::getPieceOffset() const { + assert(isVariablePiece()); + return getAddrElement(1); +} + +uint64_t DIVariable::getPieceSize() const { + assert(isVariablePiece()); + return getAddrElement(2); +} + /// Return the size reported by the variable's type. unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) { DIType Ty = getType().resolve(Map); @@ -154,29 +178,8 @@ unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) { return Ty.getSizeInBits(); } -uint64_t DIExpression::getElement(unsigned Idx) const { - unsigned I = Idx + 1; - if (I < DbgNode->getNumOperands()) - if (auto *CI = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(I))) - return CI->getZExtValue(); - - assert(false && "non-existing complex address element requested"); - return 0; -} - -bool DIExpression::isVariablePiece() const { - return getNumElements() && getElement(0) == dwarf::DW_OP_piece; -} -uint64_t DIExpression::getPieceOffset() const { - assert(isVariablePiece()); - return getElement(1); -} -uint64_t DIExpression::getPieceSize() const { - assert(isVariablePiece()); - return getElement(2); -} //===----------------------------------------------------------------------===// // Predicates @@ -354,12 +357,6 @@ bool DIDescriptor::isImportedEntity() const { getTag() == dwarf::DW_TAG_imported_declaration); } -/// \brief Return true if the specified tag is DW_TAG_imported_module or -/// DW_TAG_imported_declaration. -bool DIDescriptor::isExpression() const { - return DbgNode && (getTag() == dwarf::DW_TAG_expression); -} - //===----------------------------------------------------------------------===// // Simple Descriptor Constructors and other Methods //===----------------------------------------------------------------------===// @@ -599,16 +596,14 @@ bool DIVariable::Verify() const { if (!fieldIsTypeRef(DbgNode, 5)) return false; - // Variable without an inline location. - if (DbgNode->getNumOperands() == 7) + // Variable without a complex expression. + if (DbgNode->getNumOperands() == 8) return true; - return DbgNode->getNumOperands() == 8; + // Make sure the complex expression is an MDNode. + return (DbgNode->getNumOperands() == 9 && fieldIsMDNode(DbgNode, 8)); } -/// Verify - Verify that a variable descriptor is well formed. -bool DIExpression::Verify() const { return isExpression(); } - /// Verify - Verify that a location descriptor is well formed. bool DILocation::Verify() const { if (!DbgNode) @@ -941,6 +936,19 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { return DIVariable(MDNode::get(VMContext, Elts)); } + +/// getEntireVariable - Remove OpPiece exprs from the variable. +DIVariable llvm::getEntireVariable(DIVariable DV) { + if (!DV.isVariablePiece()) + return DV; + + SmallVector<Value *, 8> Elts; + for (unsigned i = 0; i < 8; ++i) + Elts.push_back(DV->getOperand(i)); + + return DIVariable(MDNode::get(DV->getContext(), Elts)); +} + /// getDISubprogram - Find subprogram that is enclosing this scope. DISubprogram llvm::getDISubprogram(const MDNode *Scope) { DIDescriptor D(Scope); @@ -1285,8 +1293,6 @@ void DIDescriptor::print(raw_ostream &OS) const { DINameSpace(DbgNode).printInternal(OS); } else if (this->isScope()) { DIScope(DbgNode).printInternal(OS); - } else if (this->isExpression()) { - DIExpression(DbgNode).printInternal(OS); } } @@ -1436,28 +1442,10 @@ void DIVariable::printInternal(raw_ostream &OS) const { OS << " [" << Res << ']'; OS << " [line " << getLineNumber() << ']'; -} -void DIExpression::printInternal(raw_ostream &OS) const { - for (unsigned I = 0; I < getNumElements(); ++I) { - uint64_t OpCode = getElement(I); - OS << " [" << OperationEncodingString(OpCode); - switch (OpCode) { - case DW_OP_plus: { - OS << " " << getElement(++I); - break; - } - case DW_OP_piece: { - unsigned Offset = getElement(++I); - unsigned Size = getElement(++I); - OS << " offset=" << Offset << ", size= " << Size; - break; - } - default: - break; - } - OS << "]"; - } + if (isVariablePiece()) + OS << " [piece, size " << getPieceSize() + << ", offset " << getPieceOffset() << ']'; } void DIObjCProperty::printInternal(raw_ostream &OS) const { |