From ce72b1755f5993a42c2e04e32a93fa5228a285d4 Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Sat, 11 Feb 2006 01:01:30 +0000 Subject: [PATCH] Reorg for integration with gcc4. Old style debug info will not be passed though to SelIDAG. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26115 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineDebugInfo.h | 228 ++++++++--- lib/CodeGen/MachineDebugInfo.cpp | 356 ++++++++++++------ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 43 +-- 3 files changed, 435 insertions(+), 192 deletions(-) diff --git a/include/llvm/CodeGen/MachineDebugInfo.h b/include/llvm/CodeGen/MachineDebugInfo.h index c7fe55a267a..0d80f93eadd 100644 --- a/include/llvm/CodeGen/MachineDebugInfo.h +++ b/include/llvm/CodeGen/MachineDebugInfo.h @@ -32,6 +32,7 @@ #include "llvm/Support/Dwarf.h" #include "llvm/ADT/UniqueVector.h" +#include "llvm/GlobalValue.h" #include "llvm/Pass.h" #include "llvm/User.h" @@ -42,6 +43,7 @@ namespace llvm { //===----------------------------------------------------------------------===// // Forward declarations. +class Constant; class DebugInfoDesc; class GlobalVariable; class Module; @@ -57,12 +59,13 @@ enum { // DebugInfoDesc type identifying tags. // FIXME - Change over with gcc4. + DI_TAG_anchor = 0, #if 1 DI_TAG_compile_unit = DW_TAG_compile_unit, DI_TAG_global_variable = DW_TAG_variable, DI_TAG_subprogram = DW_TAG_subprogram #else - DI_TAG_compile_unit = 1, + DI_TAG_compile_unit, DI_TAG_global_variable, DI_TAG_subprogram #endif @@ -117,6 +120,10 @@ public: /// Return NULL if not a recognized Tag. static DebugInfoDesc *DescFactory(unsigned Tag); + /// getLinkage - get linkage appropriate for this type of descriptor. + /// + virtual GlobalValue::LinkageTypes getLinkage() const; + //===--------------------------------------------------------------------===// // Subclasses should supply the following static methods. @@ -128,11 +135,15 @@ public: /// ApplyToFields - Target the vistor to the fields of the descriptor. /// - virtual void ApplyToFields(DIVisitor *Visitor) = 0; + virtual void ApplyToFields(DIVisitor *Visitor); - /// TypeString - Return a string used to compose globalnames and labels. + /// getDescString - Return a string used to compose global names and labels. /// - virtual const char *TypeString() const = 0; + virtual const char *getDescString() const = 0; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const = 0; #ifndef NDEBUG virtual void dump() = 0; @@ -140,28 +151,91 @@ public: }; +//===----------------------------------------------------------------------===// +/// AnchorDesc - Descriptors of this class act as markers for identifying +/// descriptors of certain groups. +class AnchorDesc : public DebugInfoDesc { +private: + std::string Name; // Anchor type string. + +public: + AnchorDesc() + : DebugInfoDesc(DI_TAG_anchor) + , Name("") + {} + AnchorDesc(const std::string &N) + : DebugInfoDesc(DI_TAG_anchor) + , Name(N) + {} + + // Accessors + const std::string &getName() const { return Name; } + + // Implement isa/cast/dyncast. + static bool classof(const AnchorDesc *) { return true; } + static bool classof(const DebugInfoDesc *D) { + return D->getTag() == DI_TAG_anchor; + } + + /// getLinkage - get linkage appropriate for this type of descriptor. + /// + virtual GlobalValue::LinkageTypes getLinkage() const; + + /// ApplyToFields - Target the visitor to the fields of the AnchorDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// AnchoredDesc - This class manages anchors for a variety of top level +/// descriptors. +class AnchoredDesc : public DebugInfoDesc { +private: + AnchorDesc *Anchor; // Anchor for all descriptors of the + // same type. + +protected: + + AnchoredDesc(unsigned T); + +public: + // Accessors. + AnchorDesc *getAnchor() const { return Anchor; } + void setAnchor(AnchorDesc *A) { Anchor = A; } + + //===--------------------------------------------------------------------===// + // Subclasses should supply the following virtual methods. + + /// ApplyToFields - Target the visitor to the fields of the AnchoredDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); +}; + //===----------------------------------------------------------------------===// /// CompileUnitDesc - This class packages debug information associated with a /// source/header file. -class CompileUnitDesc : public DebugInfoDesc { +class CompileUnitDesc : public AnchoredDesc { private: unsigned DebugVersion; // LLVM debug version when produced. unsigned Language; // Language number (ex. DW_LANG_C89.) std::string FileName; // Source file name. std::string Directory; // Source file directory. std::string Producer; // Compiler string. - GlobalVariable *TransUnit; // Translation unit - ignored. public: - CompileUnitDesc() - : DebugInfoDesc(DI_TAG_compile_unit) - , DebugVersion(LLVMDebugVersion) - , Language(0) - , FileName("") - , Directory("") - , Producer("") - , TransUnit(NULL) - {} + CompileUnitDesc(); // Accessors unsigned getDebugVersion() const { return DebugVersion; } @@ -173,6 +247,7 @@ public: void setFileName(const std::string &FN) { FileName = FN; } void setDirectory(const std::string &D) { Directory = D; } void setProducer(const std::string &P) { Producer = P; } + // FIXME - Need translation unit getter/setter. // Implement isa/cast/dyncast. @@ -189,9 +264,17 @@ public: /// virtual void ApplyToFields(DIVisitor *Visitor); - /// TypeString - Return a string used to compose globalnames and labels. + /// getDescString - Return a string used to compose global names and labels. /// - virtual const char *TypeString() const; + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + + /// getAnchorString - Return a string used to label this descriptor's anchor. + /// + virtual const char *getAnchorString() const; #ifndef NDEBUG virtual void dump(); @@ -199,42 +282,49 @@ public: }; //===----------------------------------------------------------------------===// -/// GlobalVariableDesc - This class packages debug information associated with a -/// GlobalVariable. -class GlobalVariableDesc : public DebugInfoDesc { +/// GlobalDesc - This class is the base descriptor for global functions and +/// variables. +class GlobalDesc : public AnchoredDesc { private: DebugInfoDesc *Context; // Context debug descriptor. std::string Name; // Global name. - GlobalVariable *TransUnit; // Translation unit - ignored. // FIXME - Use a descriptor. GlobalVariable *TyDesc; // Type debug descriptor. bool IsStatic; // Is the global a static. bool IsDefinition; // Is the global defined in context. - GlobalVariable *Global; // llvm global. +protected: + GlobalDesc(unsigned T); + public: - GlobalVariableDesc() - : DebugInfoDesc(DI_TAG_global_variable) - , Context(0) - , Name("") - , TransUnit(NULL) - , TyDesc(NULL) - , IsStatic(false) - , IsDefinition(false) - , Global(NULL) - {} - // Accessors DebugInfoDesc *getContext() const { return Context; } const std::string &getName() const { return Name; } bool isStatic() const { return IsStatic; } bool isDefinition() const { return IsDefinition; } - GlobalVariable *getGlobalVariable() const { return Global; } + void setContext(DebugInfoDesc *C) { Context = C; } void setName(const std::string &N) { Name = N; } void setIsStatic(bool IS) { IsStatic = IS; } void setIsDefinition(bool ID) { IsDefinition = ID; } + + /// ApplyToFields - Target the visitor to the fields of the GlobalDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); +}; + +//===----------------------------------------------------------------------===// +/// GlobalVariableDesc - This class packages debug information associated with a +/// GlobalVariable. +class GlobalVariableDesc : public GlobalDesc { +private: + GlobalVariable *Global; // llvm global. + +public: + GlobalVariableDesc(); + + // Accessors. + GlobalVariable *getGlobalVariable() const { return Global; } void setGlobalVariable(GlobalVariable *GV) { Global = GV; } - // FIXME - Other getters/setters. // Implement isa/cast/dyncast. static bool classof(const GlobalVariableDesc *) { return true; } @@ -246,10 +336,18 @@ public: /// GlobalVariableDesc. virtual void ApplyToFields(DIVisitor *Visitor); - /// TypeString - Return a string used to compose globalnames and labels. + /// getDescString - Return a string used to compose global names and labels. /// - virtual const char *TypeString() const; + virtual const char *getDescString() const; + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + + /// getAnchorString - Return a string used to label this descriptor's anchor. + /// + virtual const char *getAnchorString() const; + #ifndef NDEBUG virtual void dump(); #endif @@ -258,32 +356,24 @@ public: //===----------------------------------------------------------------------===// /// SubprogramDesc - This class packages debug information associated with a /// subprogram/function. -class SubprogramDesc : public DebugInfoDesc { +class SubprogramDesc : public GlobalDesc { private: DebugInfoDesc *Context; // Context debug descriptor. std::string Name; // Subprogram name. - GlobalVariable *TransUnit; // Translation unit - ignored. // FIXME - Use a descriptor. GlobalVariable *TyDesc; // Type debug descriptor. bool IsStatic; // Is the subprogram a static. bool IsDefinition; // Is the subprogram defined in context. public: - SubprogramDesc() - : DebugInfoDesc(DI_TAG_subprogram) - , Context(0) - , Name("") - , TransUnit(NULL) - , TyDesc(NULL) - , IsStatic(false) - , IsDefinition(false) - {} + SubprogramDesc(); // Accessors DebugInfoDesc *getContext() const { return Context; } const std::string &getName() const { return Name; } bool isStatic() const { return IsStatic; } bool isDefinition() const { return IsDefinition; } + void setContext(DebugInfoDesc *C) { Context = C; } void setName(const std::string &N) { Name = N; } void setIsStatic(bool IS) { IsStatic = IS; } void setIsDefinition(bool ID) { IsDefinition = ID; } @@ -299,10 +389,18 @@ public: /// virtual void ApplyToFields(DIVisitor *Visitor); - /// TypeString - Return a string used to compose globalnames and labels. + /// getDescString - Return a string used to compose global names and labels. /// - virtual const char *TypeString() const; + virtual const char *getDescString() const; + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + + /// getAnchorString - Return a string used to label this descriptor's anchor. + /// + virtual const char *getAnchorString() const; + #ifndef NDEBUG virtual void dump(); #endif @@ -313,18 +411,15 @@ public: /// into DebugInfoDesc objects. class DIDeserializer { private: - Module *M; // Definition space module. unsigned DebugVersion; // Version of debug information in use. std::map GlobalDescs; // Previously defined gloabls. public: - DIDeserializer() : M(NULL), DebugVersion(LLVMDebugVersion) {} + DIDeserializer() : DebugVersion(LLVMDebugVersion) {} ~DIDeserializer() {} // Accessors - Module *getModule() const { return M; }; - void setModule(Module *module) { M = module; } unsigned getDebugVersion() const { return DebugVersion; } /// Deserialize - Reconstitute a GlobalVariable into it's component @@ -345,10 +440,18 @@ private: // Types per Tag. Created lazily. std::map DescGlobals; // Previously defined descriptors. - std::map StringCache; + std::map StringCache; // Previously defined strings. + public: - DISerializer() : M(NULL) {} + DISerializer() + : M(NULL) + , StrPtrTy(NULL) + , EmptyStructPtrTy(NULL) + , TagTypes() + , DescGlobals() + , StringCache() + {} ~DISerializer() {} // Accessors @@ -369,7 +472,7 @@ public: /// getString - Construct the string as constant string global. /// - GlobalVariable *getString(const std::string &String); + Constant *getString(const std::string &String); /// Serialize - Recursively cast the specified descriptor into a /// GlobalVariable so that it can be serialized to a .bc or .ll file. @@ -395,6 +498,7 @@ public: /// Verify - Return true if the GlobalVariable appears to be a valid /// serialization of a DebugInfoDesc. + bool Verify(Value *V); bool Verify(GlobalVariable *GV); }; @@ -454,9 +558,7 @@ public: class MachineDebugInfo : public ImmutablePass { private: // Use the same serializer/deserializer/verifier for the module. - DISerializer SR; DIDeserializer DR; - DIVerifier VR; // CompileUnits - Uniquing vector for compile units. UniqueVector CompileUnits; @@ -482,6 +584,14 @@ public: /// bool doFinalization(); + /// Deserialize - Convert a Value to a debug information descriptor. + /// + DebugInfoDesc *Deserialize(Value *V); + + /// Verify - Verify that a Value is debug information descriptor. + /// + bool Verify(Value *V); + /// AnalyzeModule - Scan the module for global debug information. /// void AnalyzeModule(Module &M); diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp index 28fc9c306f8..460ed5c1b19 100644 --- a/lib/CodeGen/MachineDebugInfo.cpp +++ b/lib/CodeGen/MachineDebugInfo.cpp @@ -49,10 +49,14 @@ getGlobalVariablesUsing(Value *V, std::vector &Result) { static std::vector getGlobalVariablesUsing(Module &M, const std::string &RootName) { std::vector Result; // GlobalVariables matching criteria. + + std::vector FieldTypes; + FieldTypes.push_back(Type::UIntTy); + FieldTypes.push_back(PointerType::get(Type::SByteTy)); // Get the GlobalVariable root. GlobalVariable *UseRoot = M.getGlobalVariable(RootName, - StructType::get(std::vector())); + StructType::get(FieldTypes)); // If present and linkonce then scan for users. if (UseRoot && UseRoot->hasLinkOnceLinkage()) { @@ -168,28 +172,6 @@ static ConstantUInt *getUIntOperand(GlobalVariable *GV, unsigned i) { // Check constant. return dyn_cast(CI->getOperand(i)); } - -//===----------------------------------------------------------------------===// - -/// TagFromGlobal - Returns the Tag number from a debug info descriptor -/// GlobalVariable. -unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) { - ConstantUInt *C = getUIntOperand(GV, 0); - return C ? (unsigned)C->getValue() : (unsigned)DIInvalid; -} - -/// DescFactory - Create an instance of debug info descriptor based on Tag. -/// Return NULL if not a recognized Tag. -DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) { - switch (Tag) { - case DI_TAG_compile_unit: return new CompileUnitDesc(); - case DI_TAG_global_variable: return new GlobalVariableDesc(); - case DI_TAG_subprogram: return new SubprogramDesc(); - default: break; - } - return NULL; -} - //===----------------------------------------------------------------------===// /// ApplyToFields - Target the visitor to each field of the debug information @@ -206,7 +188,7 @@ private: unsigned Count; // Running count of fields. public: - DICountVisitor() : DIVisitor(), Count(1) {} + DICountVisitor() : DIVisitor(), Count(0) {} // Accessors. unsigned getCount() const { return Count; } @@ -234,7 +216,7 @@ public: DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV) : DIVisitor() , DR(D) - , I(1) + , I(0) , CI(cast(GV->getInitializer())) {} @@ -284,7 +266,7 @@ public: /// Apply - Set the value of each of the fields. /// virtual void Apply(int &Field) { - Elements.push_back(ConstantUInt::get(Type::IntTy, Field)); + Elements.push_back(ConstantSInt::get(Type::IntTy, Field)); } virtual void Apply(unsigned &Field) { Elements.push_back(ConstantUInt::get(Type::UIntTy, Field)); @@ -314,7 +296,11 @@ public: } virtual void Apply(GlobalVariable *&Field) { const PointerType *EmptyTy = SR.getEmptyStructPtrType(); - Elements.push_back(ConstantExpr::getCast(Field, EmptyTy)); + if (Field) { + Elements.push_back(ConstantExpr::getCast(Field, EmptyTy)); + } else { + Elements.push_back(ConstantPointerNull::get(EmptyTy)); + } } }; @@ -373,7 +359,7 @@ public: : DIVisitor() , VR(V) , IsValid(true) - , I(1) + , I(0) , CI(cast(GV->getInitializer())) { } @@ -410,36 +396,146 @@ public: } }; + //===----------------------------------------------------------------------===// +/// TagFromGlobal - Returns the Tag number from a debug info descriptor +/// GlobalVariable. +unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) { + ConstantUInt *C = getUIntOperand(GV, 0); + return C ? (unsigned)C->getValue() : (unsigned)DIInvalid; +} + +/// DescFactory - Create an instance of debug info descriptor based on Tag. +/// Return NULL if not a recognized Tag. +DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) { + switch (Tag) { + case DI_TAG_anchor: return new AnchorDesc(); + case DI_TAG_compile_unit: return new CompileUnitDesc(); + case DI_TAG_global_variable: return new GlobalVariableDesc(); + case DI_TAG_subprogram: return new SubprogramDesc(); + default: break; + } + return NULL; +} + +/// getLinkage - get linkage appropriate for this type of descriptor. +/// +GlobalValue::LinkageTypes DebugInfoDesc::getLinkage() const { + return GlobalValue::InternalLinkage; +} + +/// ApplyToFields - Target the vistor to the fields of the descriptor. +/// +void DebugInfoDesc::ApplyToFields(DIVisitor *Visitor) { + Visitor->Apply(Tag); +} + +//===----------------------------------------------------------------------===// + +/// getLinkage - get linkage appropriate for this type of descriptor. +/// +GlobalValue::LinkageTypes AnchorDesc::getLinkage() const { + return GlobalValue::LinkOnceLinkage; +} + +/// ApplyToFields - Target the visitor to the fields of the TransUnitDesc. +/// +void AnchorDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Name); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *AnchorDesc::getDescString() const { + return Name.c_str(); +} + +/// getTypeString - Return a string used to label this descriptors type. +/// +const char *AnchorDesc::getTypeString() const { + return "llvm.dbg.anchor.type"; +} + +#ifndef NDEBUG +void AnchorDesc::dump() { + std::cerr << getDescString() << " " + << "Tag(" << getTag() << "), " + << "Name(" << Name << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +AnchoredDesc::AnchoredDesc(unsigned T) +: DebugInfoDesc(T) +, Anchor(NULL) +{} + +/// ApplyToFields - Target the visitor to the fields of the AnchoredDesc. +/// +void AnchoredDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply((DebugInfoDesc *&)Anchor); +} + +//===----------------------------------------------------------------------===// + +CompileUnitDesc::CompileUnitDesc() +: AnchoredDesc(DI_TAG_compile_unit) +, DebugVersion(LLVMDebugVersion) +, Language(0) +, FileName("") +, Directory("") +, Producer("") +{} + /// DebugVersionFromGlobal - Returns the version number from a compile unit /// GlobalVariable. unsigned CompileUnitDesc::DebugVersionFromGlobal(GlobalVariable *GV) { - ConstantUInt *C = getUIntOperand(GV, 1); + ConstantUInt *C = getUIntOperand(GV, 2); return C ? (unsigned)C->getValue() : (unsigned)DIInvalid; } /// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc. /// void CompileUnitDesc::ApplyToFields(DIVisitor *Visitor) { + AnchoredDesc::ApplyToFields(Visitor); + Visitor->Apply(DebugVersion); Visitor->Apply(Language); Visitor->Apply(FileName); Visitor->Apply(Directory); Visitor->Apply(Producer); - Visitor->Apply(TransUnit); } -/// TypeString - Return a string used to compose globalnames and labels. +/// getDescString - Return a string used to compose global names and labels. /// -const char *CompileUnitDesc::TypeString() const { - return "compile_unit"; +const char *CompileUnitDesc::getDescString() const { + return "llvm.dbg.compile_unit"; +} + +/// getTypeString - Return a string used to label this descriptors type. +/// +const char *CompileUnitDesc::getTypeString() const { + return "llvm.dbg.compile_unit.type"; +} + +/// getAnchorString - Return a string used to label this descriptor's anchor. +/// +const char *CompileUnitDesc::getAnchorString() const { + return "llvm.dbg.compile_units"; } #ifndef NDEBUG void CompileUnitDesc::dump() { - std::cerr << TypeString() << " " + std::cerr << getDescString() << " " << "Tag(" << getTag() << "), " + << "Anchor(" << getAnchor() << "), " + << "DebugVersion(" << DebugVersion << "), " << "Language(" << Language << "), " << "FileName(\"" << FileName << "\"), " << "Directory(\"" << Directory << "\"), " @@ -449,76 +545,122 @@ void CompileUnitDesc::dump() { //===----------------------------------------------------------------------===// -/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc. +GlobalDesc::GlobalDesc(unsigned T) +: AnchoredDesc(T) +, Context(0) +, Name("") +, TyDesc(NULL) +, IsStatic(false) +, IsDefinition(false) +{} + +/// ApplyToFields - Target the visitor to the fields of the global. /// -void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) { +void GlobalDesc::ApplyToFields(DIVisitor *Visitor) { + AnchoredDesc::ApplyToFields(Visitor); + Visitor->Apply(Context); Visitor->Apply(Name); - Visitor->Apply(TransUnit); Visitor->Apply(TyDesc); Visitor->Apply(IsStatic); Visitor->Apply(IsDefinition); +} + +//===----------------------------------------------------------------------===// + +GlobalVariableDesc::GlobalVariableDesc() +: GlobalDesc(DI_TAG_global_variable) +, Global(NULL) +{} + +/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc. +/// +void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) { + GlobalDesc::ApplyToFields(Visitor); + Visitor->Apply(Global); } -/// TypeString - Return a string used to compose globalnames and labels. +/// getDescString - Return a string used to compose global names and labels. /// -const char *GlobalVariableDesc::TypeString() const { - return "global_variable"; +const char *GlobalVariableDesc::getDescString() const { + return "llvm.dbg.global_variable"; +} + +/// getTypeString - Return a string used to label this descriptors type. +/// +const char *GlobalVariableDesc::getTypeString() const { + return "llvm.dbg.global_variable.type"; +} + +/// getAnchorString - Return a string used to label this descriptor's anchor. +/// +const char *GlobalVariableDesc::getAnchorString() const { + return "llvm.dbg.global_variables"; } #ifndef NDEBUG void GlobalVariableDesc::dump() { - std::cerr << TypeString() << " " + std::cerr << getDescString() << " " << "Tag(" << getTag() << "), " - << "Name(\"" << Name << "\"), " - << "Type(" << TyDesc << "), " - << "IsStatic(" << (IsStatic ? "true" : "false") << "), " - << "IsDefinition(" << (IsDefinition ? "true" : "false") << "), " + << "Anchor(" << getAnchor() << "), " + << "Name(\"" << getName() << "\"), " + << "IsStatic(" << (isStatic() ? "true" : "false") << "), " + << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), " << "Global(" << Global << ")\n"; } #endif //===----------------------------------------------------------------------===// +SubprogramDesc::SubprogramDesc() +: GlobalDesc(DI_TAG_subprogram) +{} + /// ApplyToFields - Target the visitor to the fields of the /// SubprogramDesc. void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) { - Visitor->Apply(Context); - Visitor->Apply(Name); - Visitor->Apply(TransUnit); - Visitor->Apply(TyDesc); - Visitor->Apply(IsStatic); - Visitor->Apply(IsDefinition); - - // FIXME - Temp variable until restructured. - GlobalVariable *Tmp; - Visitor->Apply(Tmp); + GlobalDesc::ApplyToFields(Visitor); } -/// TypeString - Return a string used to compose globalnames and labels. +/// getDescString - Return a string used to compose global names and labels. /// -const char *SubprogramDesc::TypeString() const { - return "subprogram"; +const char *SubprogramDesc::getDescString() const { + return "llvm.dbg.subprogram"; +} + +/// getTypeString - Return a string used to label this descriptors type. +/// +const char *SubprogramDesc::getTypeString() const { + return "llvm.dbg.subprogram.type"; +} + +/// getAnchorString - Return a string used to label this descriptor's anchor. +/// +const char *SubprogramDesc::getAnchorString() const { + return "llvm.dbg.subprograms"; } #ifndef NDEBUG void SubprogramDesc::dump() { - std::cerr << TypeString() << " " + std::cerr << getDescString() << " " << "Tag(" << getTag() << "), " - << "Name(\"" << Name << "\"), " - << "Type(" << TyDesc << "), " - << "IsStatic(" << (IsStatic ? "true" : "false") << "), " - << "IsDefinition(" << (IsDefinition ? "true" : "false") << ")\n"; + << "Anchor(" << getAnchor() << "), " + << "Name(\"" << getName() << "\"), " + << "IsStatic(" << (isStatic() ? "true" : "false") << "), " + << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n"; } #endif //===----------------------------------------------------------------------===// DebugInfoDesc *DIDeserializer::Deserialize(Value *V) { - return Deserialize(cast(V)); + return Deserialize(getGlobalVariable(V)); } DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) { + // Handle NULL. + if (!GV) return NULL; + // Check to see if it has been already deserialized. DebugInfoDesc *&Slot = GlobalDescs[GV]; if (Slot) return Slot; @@ -579,25 +721,17 @@ const StructType *DISerializer::getTagType(DebugInfoDesc *DD) { // If not already defined. if (!Ty) { - // Get descriptor type name. - const char *TS = DD->TypeString(); - // Set up fields vector. std::vector Fields; - // Add tag field. - Fields.push_back(Type::UIntTy); - // Get types of remaining fields. + // Get types of fields. DIGetTypesVisitor GTAM(*this, Fields); GTAM.ApplyToFields(DD); // Construct structured type. Ty = StructType::get(Fields); - // Construct a name for the type. - const std::string Name = std::string("lldb.") + DD->TypeString() + ".type"; - // Register type name with module. - M->addTypeName(Name, Ty); + M->addTypeName(DD->getTypeString(), Ty); } return Ty; @@ -605,17 +739,21 @@ const StructType *DISerializer::getTagType(DebugInfoDesc *DD) { /// getString - Construct the string as constant string global. /// -GlobalVariable *DISerializer::getString(const std::string &String) { +Constant *DISerializer::getString(const std::string &String) { // Check string cache for previous edition. - GlobalVariable *&Slot = StringCache[String]; - // return GlobalVariable if previously defined. + Constant *&Slot = StringCache[String]; + // return Constant if previously defined. if (Slot) return Slot; - // Construct strings as an llvm constant. + // Construct string as an llvm constant. Constant *ConstStr = ConstantArray::get(String); // Otherwise create and return a new string global. - return Slot = new GlobalVariable(ConstStr->getType(), true, - GlobalVariable::InternalLinkage, - ConstStr, "str", M); + GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true, + GlobalVariable::InternalLinkage, + ConstStr, "str", M); + // Convert to generic string pointer. + Slot = ConstantExpr::getCast(StrGV, getStrPtrType()); + return Slot; + } /// Serialize - Recursively cast the specified descriptor into a GlobalVariable @@ -627,29 +765,19 @@ GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) { // See if DebugInfoDesc exists, if so return prior GlobalVariable. if (Slot) return Slot; - // Get DebugInfoDesc type Tag. - unsigned Tag = DD->getTag(); - - // Construct name. - const std::string Name = std::string("lldb.") + - DD->TypeString(); - // Get the type associated with the Tag. const StructType *Ty = getTagType(DD); // Create the GlobalVariable early to prevent infinite recursion. - GlobalVariable *GV = new GlobalVariable(Ty, true, - GlobalValue::InternalLinkage, - NULL, Name, M); + GlobalVariable *GV = new GlobalVariable(Ty, true, DD->getLinkage(), + NULL, DD->getDescString(), M); // Insert new GlobalVariable in DescGlobals map. Slot = GV; // Set up elements vector std::vector Elements; - // Add Tag value. - Elements.push_back(ConstantUInt::get(Type::UIntTy, Tag)); - // Add remaining fields. + // Add fields. DISerializeVisitor SRAM(*this, Elements); SRAM.ApplyToFields(DD); @@ -678,6 +806,9 @@ bool DIVerifier::markVisited(GlobalVariable *GV) { /// Verify - Return true if the GlobalVariable appears to be a valid /// serialization of a DebugInfoDesc. +bool DIVerifier::Verify(Value *V) { + return Verify(getGlobalVariable(V)); +} bool DIVerifier::Verify(GlobalVariable *GV) { // Check if seen before. if (markVisited(GV)) return true; @@ -732,9 +863,7 @@ bool DIVerifier::Verify(GlobalVariable *GV) { MachineDebugInfo::MachineDebugInfo() -: SR() -, DR() -, VR() +: DR() , CompileUnits() , Directories() , SourceFiles() @@ -758,22 +887,32 @@ bool MachineDebugInfo::doFinalization() { return false; } +/// Deserialize - Convert a Value to a debug information descriptor. +/// +DebugInfoDesc *MachineDebugInfo::Deserialize(Value *V) { + return DR.Deserialize(V); +} + +/// Verify - Verify that a Value is debug information descriptor. +/// +bool MachineDebugInfo::Verify(Value *V) { + DIVerifier VR; + return VR.Verify(V); +} + /// AnalyzeModule - Scan the module for global debug information. /// void MachineDebugInfo::AnalyzeModule(Module &M) { - SR.setModule(&M); - DR.setModule(&M); SetupCompileUnits(M); } /// SetupCompileUnits - Set up the unique vector of compile units. /// void MachineDebugInfo::SetupCompileUnits(Module &M) { - SR.setModule(&M); - DR.setModule(&M); // Get vector of all debug compile units. + CompileUnitDesc CompileUnit; std::vector Globals = - getGlobalVariablesUsing(M, "llvm.dbg.translation_units"); + getGlobalVariablesUsing(M, CompileUnit.getAnchorString()); // Scan all compile unit globals. for (unsigned i = 0, N = Globals.size(); i < N; ++i) { @@ -793,11 +932,10 @@ const UniqueVector MachineDebugInfo::getCompileUnits()const{ /// std::vector MachineDebugInfo::getGlobalVariables(Module &M) { - SR.setModule(&M); - DR.setModule(&M); // Get vector of all debug global objects. + GlobalVariableDesc Global; std::vector Globals = - getGlobalVariablesUsing(M, "llvm.dbg.globals"); + getGlobalVariablesUsing(M, Global.getAnchorString()); // Accumulation of GlobalVariables. std::vector GlobalVariables; @@ -805,11 +943,9 @@ MachineDebugInfo::getGlobalVariables(Module &M) { // Scan all globals. for (unsigned i = 0, N = Globals.size(); i < N; ++i) { GlobalVariable *GV = Globals[i]; - if (DebugInfoDesc::TagFromGlobal(GV) == DI_TAG_global_variable) { - GlobalVariableDesc *GVD = - static_cast(DR.Deserialize(GV)); - GlobalVariables.push_back(GVD); - } + GlobalVariableDesc *GVD = + static_cast(DR.Deserialize(GV)); + GlobalVariables.push_back(GVD); } return GlobalVariables; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e2049f1cb8c..5d43f035a19 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -941,33 +941,30 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) return "llvm_debugger_stop"; - std::string fname = ""; - std::vector Ops; + MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo(); + if (DebugInfo && DebugInfo->Verify(I.getOperand(4))) { + std::vector Ops; - // Input Chain - Ops.push_back(getRoot()); - - // line number - Ops.push_back(getValue(I.getOperand(2))); - - // column - Ops.push_back(getValue(I.getOperand(3))); + // Input Chain + Ops.push_back(getRoot()); + + // line number + Ops.push_back(getValue(I.getOperand(2))); + + // column + Ops.push_back(getValue(I.getOperand(3))); - // filename/working dir - // Pull the filename out of the the compilation unit. - const GlobalVariable *cunit = dyn_cast(I.getOperand(4)); - if (cunit && cunit->hasInitializer()) { - if (ConstantStruct *CS = - dyn_cast(cunit->getInitializer())) { - if (CS->getNumOperands() > 0) { - Ops.push_back(DAG.getString(getStringValue(CS->getOperand(3)))); - Ops.push_back(DAG.getString(getStringValue(CS->getOperand(4)))); - } - } + DebugInfoDesc *DD = DebugInfo->Deserialize(I.getOperand(4)); + assert(DD && "Not a debug information descriptor"); + CompileUnitDesc *CompileUnit = dyn_cast(DD); + assert(CompileUnit && "Not a compile unit"); + Ops.push_back(DAG.getString(CompileUnit->getFileName())); + Ops.push_back(DAG.getString(CompileUnit->getDirectory())); + + if (Ops.size() == 5) // Found filename/workingdir. + DAG.setRoot(DAG.getNode(ISD::LOCATION, MVT::Other, Ops)); } - if (Ops.size() == 5) // Found filename/workingdir. - DAG.setRoot(DAG.getNode(ISD::LOCATION, MVT::Other, Ops)); setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); return 0; }