X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FDebugInfo.cpp;h=12bb2921f51ee5dc04869149c788a5599f6eced2;hb=ef4cfc749a61d0d0252196c957697436ba7ec068;hp=29175a6a2d4e8bbf7f22182d2fde04a47636f83d;hpb=b07fbd9bdde37ebd404e8b8dc167795728f162e1;p=oota-llvm.git diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 29175a6a2d4..12bb2921f51 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -16,10 +16,11 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Intrinsics.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Analysis/ValueTracking.h" -#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Streams.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -101,8 +102,8 @@ DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV) DIBlock::DIBlock(GlobalVariable *GV) : DIDescriptor(GV, dwarf::DW_TAG_lexical_block) {} // needed by DIVariable::getType() -DIType::DIType(GlobalVariable *GV) : DIDescriptor(GV) { - if (!GV) return; +DIType::DIType(GlobalVariable *gv) : DIDescriptor(gv) { + if (!gv) return; unsigned tag = getTag(); if (tag != dwarf::DW_TAG_base_type && !DIDerivedType::isDerivedType(tag) && !DICompositeType::isCompositeType(tag)) @@ -111,7 +112,7 @@ DIType::DIType(GlobalVariable *GV) : DIDescriptor(GV) { /// isDerivedType - Return true if the specified tag is legal for /// DIDerivedType. -bool DIDerivedType::isDerivedType(unsigned Tag) { +bool DIType::isDerivedType(unsigned Tag) { switch (Tag) { case dwarf::DW_TAG_typedef: case dwarf::DW_TAG_pointer_type: @@ -136,7 +137,7 @@ DIDerivedType::DIDerivedType(GlobalVariable *GV) : DIType(GV, true, true) { /// isCompositeType - Return true if the specified tag is legal for /// DICompositeType. -bool DICompositeType::isCompositeType(unsigned TAG) { +bool DIType::isCompositeType(unsigned TAG) { switch (TAG) { case dwarf::DW_TAG_array_type: case dwarf::DW_TAG_structure_type: @@ -168,12 +169,120 @@ bool DIVariable::isVariable(unsigned Tag) { } } -DIVariable::DIVariable(GlobalVariable *GV) : DIDescriptor(GV) { - if (GV && !isVariable(getTag())) +DIVariable::DIVariable(GlobalVariable *gv) : DIDescriptor(gv) { + if (gv && !isVariable(getTag())) GV = 0; } +unsigned DIArray::getNumElements() const { + assert (GV && "Invalid DIArray"); + Constant *C = GV->getInitializer(); + assert (C && "Invalid DIArray initializer"); + return C->getNumOperands(); +} + +/// Verify - Verify that a compile unit is well formed. +bool DICompileUnit::Verify() const { + if (isNull()) + return false; + if (getFilename().empty()) + return false; + // It is possible that directory and produce string is empty. + return true; +} + +/// Verify - Verify that a type descriptor is well formed. +bool DIType::Verify() const { + if (isNull()) + return false; + if (getContext().isNull()) + return false; + + DICompileUnit CU = getCompileUnit(); + if (!CU.isNull() && !CU.Verify()) + return false; + return true; +} + +/// Verify - Verify that a composite type descriptor is well formed. +bool DICompositeType::Verify() const { + if (isNull()) + return false; + if (getContext().isNull()) + return false; + DICompileUnit CU = getCompileUnit(); + if (!CU.isNull() && !CU.Verify()) + return false; + return true; +} + +/// Verify - Verify that a subprogram descriptor is well formed. +bool DISubprogram::Verify() const { + if (isNull()) + return false; + + if (getContext().isNull()) + return false; + + DICompileUnit CU = getCompileUnit(); + if (!CU.Verify()) + return false; + + DICompositeType Ty = getType(); + if (!Ty.isNull() && !Ty.Verify()) + return false; + return true; +} + +/// Verify - Verify that a global variable descriptor is well formed. +bool DIGlobalVariable::Verify() const { + if (isNull()) + return false; + + if (getContext().isNull()) + return false; + + DICompileUnit CU = getCompileUnit(); + if (!CU.Verify()) + return false; + + DIType Ty = getType(); + if (!Ty.Verify()) + return false; + + if (!getGlobal()) + return false; + + return true; +} + +/// Verify - Verify that a variable descriptor is well formed. +bool DIVariable::Verify() const { + if (isNull()) + return false; + + if (getContext().isNull()) + return false; + + DIType Ty = getType(); + if (!Ty.Verify()) + return false; + + + return true; +} + +/// getOriginalTypeSize - If this type is derived from a base type then +/// return base type size. +uint64_t DIDerivedType::getOriginalTypeSize() const { + if (getTag() != dwarf::DW_TAG_member) + return getSizeInBits(); + DIType BT = getTypeDerivedFrom(); + if (BT.getTag() != dwarf::DW_TAG_base_type) + return getSizeInBits(); + return BT.getSizeInBits(); +} //===----------------------------------------------------------------------===// // DIFactory: Basic Helpers @@ -192,9 +301,9 @@ Constant *DIFactory::getCastToEmpty(DIDescriptor D) { } Constant *DIFactory::GetTagConstant(unsigned TAG) { - assert((TAG & DIDescriptor::VersionMask) == 0 && + assert((TAG & LLVMDebugVersionMask) == 0 && "Tag too large for debug encoding!"); - return ConstantInt::get(Type::Int32Ty, TAG | DIDescriptor::Version6); + return ConstantInt::get(Type::Int32Ty, TAG | LLVMDebugVersion); } Constant *DIFactory::GetStringConstant(const std::string &String) { @@ -341,14 +450,22 @@ DISubrange DIFactory::GetOrCreateSubrange(int64_t Lo, int64_t Hi) { DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID, const std::string &Filename, const std::string &Directory, - const std::string &Producer) { + const std::string &Producer, + bool isMain, + bool isOptimized, + const char *Flags, + unsigned RunTimeVer) { Constant *Elts[] = { GetTagConstant(dwarf::DW_TAG_compile_unit), getCastToEmpty(GetOrCreateCompileUnitAnchor()), ConstantInt::get(Type::Int32Ty, LangID), GetStringConstant(Filename), GetStringConstant(Directory), - GetStringConstant(Producer) + GetStringConstant(Producer), + ConstantInt::get(Type::Int1Ty, isMain), + ConstantInt::get(Type::Int1Ty, isOptimized), + GetStringConstant(Flags), + ConstantInt::get(Type::Int32Ty, RunTimeVer) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -458,7 +575,9 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, - DIArray Elements) { + DIArray Elements, + unsigned RuntimeLang) { + Constant *Elts[] = { GetTagConstant(Tag), getCastToEmpty(Context), @@ -470,7 +589,8 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag, ConstantInt::get(Type::Int64Ty, OffsetInBits), ConstantInt::get(Type::Int32Ty, Flags), getCastToEmpty(DerivedFrom), - getCastToEmpty(Elements) + getCastToEmpty(Elements), + ConstantInt::get(Type::Int32Ty, RuntimeLang) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -495,6 +615,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context, unsigned LineNo, DIType Type, bool isLocalToUnit, bool isDefinition) { + Constant *Elts[] = { GetTagConstant(dwarf::DW_TAG_subprogram), getCastToEmpty(GetOrCreateSubprogramAnchor()), @@ -527,7 +648,6 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name, DICompileUnit CompileUnit, unsigned LineNo, DIType Type,bool isLocalToUnit, bool isDefinition, llvm::GlobalVariable *Val) { - Constant *Elts[] = { GetTagConstant(dwarf::DW_TAG_variable), getCastToEmpty(GetOrCreateGlobalVariableAnchor()), @@ -559,14 +679,13 @@ DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context, const std::string &Name, DICompileUnit CompileUnit, unsigned LineNo, DIType Type) { - Constant *Elts[] = { GetTagConstant(Tag), getCastToEmpty(Context), GetStringConstant(Name), getCastToEmpty(CompileUnit), ConstantInt::get(Type::Int32Ty, LineNo), - getCastToEmpty(Type), + getCastToEmpty(Type) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -669,3 +788,175 @@ void DIFactory::InsertDeclare(llvm::Value *Storage, DIVariable D, Value *Args[] = { Storage, getCastToEmpty(D) }; CallInst::Create(DeclareFn, Args, Args+2, "", BB); } + +namespace llvm { + /// Finds the stoppoint coressponding to this instruction, that is the + /// stoppoint that dominates this instruction + const DbgStopPointInst *findStopPoint(const Instruction *Inst) + { + if (const DbgStopPointInst *DSI = dyn_cast(Inst)) + return DSI; + + const BasicBlock *BB = Inst->getParent(); + BasicBlock::const_iterator I = Inst, B; + do { + B = BB->begin(); + // A BB consisting only of a terminator can't have a stoppoint. + if (I != B) { + do { + --I; + if (const DbgStopPointInst *DSI = dyn_cast(I)) + return DSI; + } while (I != B); + } + // This BB didn't have a stoppoint: if there is only one + // predecessor, look for a stoppoint there. + // We could use getIDom(), but that would require dominator info. + BB = I->getParent()->getUniquePredecessor(); + if (BB) + I = BB->getTerminator(); + } while (BB != 0); + return 0; + } + + /// Finds the stoppoint corresponding to first real (non-debug intrinsic) + /// instruction in this Basic Block, and returns the stoppoint for it. + const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB) + { + for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { + if (const DbgStopPointInst *DSI = dyn_cast(I)) + return DSI; + } + // Fallback to looking for stoppoint of unique predecessor. + // Useful if this BB contains no stoppoints, but unique predecessor does. + BB = BB->getUniquePredecessor(); + if (BB) + return findStopPoint(BB->getTerminator()); + return 0; + } + + /// Finds the dbg.declare intrinsic corresponding to this value if any. + /// It looks through pointer casts too. + const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts) + { + if (stripCasts) { + V = V->stripPointerCasts(); + // Look for the bitcast. + for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); + I != E; ++I) { + if (isa(I)) + return findDbgDeclare(*I, false); + } + return 0; + } + + // Find dbg.declare among uses of the instruction. + for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); + I != E; ++I) { + if (const DbgDeclareInst *DDI = dyn_cast(I)) + return DDI; + } + return 0; + } +} + +/// dump - print compile unit. +void DICompileUnit::dump() const { + cerr << " [" << dwarf::LanguageString(getLanguage()) << "] "; + cerr << " [" << getDirectory() << "/" << getFilename() << " ]"; +} + +/// dump - print type. +void DIType::dump() const { + if (isNull()) return; + if (!getName().empty()) + cerr << " [" << getName() << "] "; + unsigned Tag = getTag(); + cerr << " [" << dwarf::TagString(Tag) << "] "; + // TODO : Print context + getCompileUnit().dump(); + cerr << " [" + << getLineNumber() << ", " + << getSizeInBits() << ", " + << getAlignInBits() << ", " + << getOffsetInBits() + << "] "; + if (isPrivate()) + cerr << " [private] "; + else if (isProtected()) + cerr << " [protected] "; + if (isForwardDecl()) + cerr << " [fwd] "; + + if (isBasicType(Tag)) + DIBasicType(GV).dump(); + else if (isDerivedType(Tag)) + DIDerivedType(GV).dump(); + else if (isCompositeType(Tag)) + DICompositeType(GV).dump(); + else { + cerr << "Invalid DIType\n"; + return; + } + cerr << "\n"; +} + +/// dump - print basic type. +void DIBasicType::dump() const { + cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] "; + +} + +/// dump - print derived type. +void DIDerivedType::dump() const { + cerr << "\n\t Derived From: "; getTypeDerivedFrom().dump(); +} + +/// dump - print composite type. +void DICompositeType::dump() const { + DIArray A = getTypeArray(); + if (A.isNull()) + return; + cerr << " [" << A.getNumElements() << " elements]"; +} + +/// dump - print global. +void DIGlobal::dump() const { + + if (!getName().empty()) + cerr << " [" << getName() << "] "; + unsigned Tag = getTag(); + cerr << " [" << dwarf::TagString(Tag) << "] "; + // TODO : Print context + getCompileUnit().dump(); + cerr << " [" << getLineNumber() << "] "; + if (isLocalToUnit()) + cerr << " [local] "; + if (isDefinition()) + cerr << " [def] "; + + if (isGlobalVariable(Tag)) + DIGlobalVariable(GV).dump(); + + cerr << "\n"; +} + +/// dump - print subprogram. +void DISubprogram::dump() const { + DIGlobal::dump(); +} + +/// dump - print global variable. +void DIGlobalVariable::dump() const { + cerr << " ["; getGlobal()->dump(); cerr << "] "; +} + +/// dump - print variable. +void DIVariable::dump() const { + if (!getName().empty()) + cerr << " [" << getName() << "] "; + getCompileUnit().dump(); + cerr << " [" << getLineNumber() << "] "; + getType().dump(); + cerr << "\n"; +}