Changes in directory llvm/lib/CodeGen:
MachineModuleInfo.cpp added (r1.1) MachineDebugInfo.cpp (r1.71) removed --- Log message: rename files --- Diffs of the changes: (+1696 -0) MachineModuleInfo.cpp | 1696 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1696 insertions(+) Index: llvm/lib/CodeGen/MachineModuleInfo.cpp diff -c /dev/null llvm/lib/CodeGen/MachineModuleInfo.cpp:1.1 *** /dev/null Fri Jan 26 15:38:36 2007 --- llvm/lib/CodeGen/MachineModuleInfo.cpp Fri Jan 26 15:38:26 2007 *************** *** 0 **** --- 1,1696 ---- + //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by James M. Laskey and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + + #include "llvm/CodeGen/MachineModuleInfo.h" + + #include "llvm/Constants.h" + #include "llvm/CodeGen/MachineFunctionPass.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineLocation.h" + #include "llvm/Target/TargetInstrInfo.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/DerivedTypes.h" + #include "llvm/GlobalVariable.h" + #include "llvm/Intrinsics.h" + #include "llvm/Instructions.h" + #include "llvm/Module.h" + #include "llvm/Support/Dwarf.h" + #include "llvm/Support/Streams.h" + using namespace llvm; + using namespace llvm::dwarf; + + // Handle the Pass registration stuff necessary to use TargetData's. + namespace { + RegisterPass<MachineModuleInfo> X("machinemoduleinfo", "Module Information"); + } + + //===----------------------------------------------------------------------===// + + /// getGlobalVariablesUsing - Return all of the GlobalVariables which have the + /// specified value in their initializer somewhere. + static void + getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) { + // Scan though value users. + for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) { + // If the user is a GlobalVariable then add to result. + Result.push_back(GV); + } else if (Constant *C = dyn_cast<Constant>(*I)) { + // If the user is a constant variable then scan its users + getGlobalVariablesUsing(C, Result); + } + } + } + + /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the + /// named GlobalVariable. + static std::vector<GlobalVariable*> + getGlobalVariablesUsing(Module &M, const std::string &RootName) { + std::vector<GlobalVariable*> Result; // GlobalVariables matching criteria. + + std::vector<const Type*> FieldTypes; + FieldTypes.push_back(Type::Int32Ty); + FieldTypes.push_back(Type::Int32Ty); + + // Get the GlobalVariable root. + GlobalVariable *UseRoot = M.getGlobalVariable(RootName, + StructType::get(FieldTypes)); + + // If present and linkonce then scan for users. + if (UseRoot && UseRoot->hasLinkOnceLinkage()) { + getGlobalVariablesUsing(UseRoot, Result); + } + + return Result; + } + + /// isStringValue - Return true if the given value can be coerced to a string. + /// + static bool isStringValue(Value *V) { + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { + if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) { + ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); + return Init->isString(); + } + } else if (Constant *C = dyn_cast<Constant>(V)) { + if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) + return isStringValue(GV); + else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { + if (CE->getOpcode() == Instruction::GetElementPtr) { + if (CE->getNumOperands() == 3 && + cast<Constant>(CE->getOperand(1))->isNullValue() && + isa<ConstantInt>(CE->getOperand(2))) { + return isStringValue(CE->getOperand(0)); + } + } + } + } + return false; + } + + /// getGlobalVariable - Return either a direct or cast Global value. + /// + static GlobalVariable *getGlobalVariable(Value *V) { + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { + return GV; + } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { + if (CE->getOpcode() == Instruction::BitCast) { + return dyn_cast<GlobalVariable>(CE->getOperand(0)); + } + } + return NULL; + } + + /// isGlobalVariable - Return true if the given value can be coerced to a + /// GlobalVariable. + static bool isGlobalVariable(Value *V) { + if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) { + return true; + } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { + if (CE->getOpcode() == Instruction::BitCast) { + return isa<GlobalVariable>(CE->getOperand(0)); + } + } + return false; + } + + /// getUIntOperand - Return ith operand if it is an unsigned integer. + /// + static ConstantInt *getUIntOperand(GlobalVariable *GV, unsigned i) { + // Make sure the GlobalVariable has an initializer. + if (!GV->hasInitializer()) return NULL; + + // Get the initializer constant. + ConstantStruct *CI = dyn_cast<ConstantStruct>(GV->getInitializer()); + if (!CI) return NULL; + + // Check if there is at least i + 1 operands. + unsigned N = CI->getNumOperands(); + if (i >= N) return NULL; + + // Check constant. + return dyn_cast<ConstantInt>(CI->getOperand(i)); + } + + //===----------------------------------------------------------------------===// + + /// ApplyToFields - Target the visitor to each field of the debug information + /// descriptor. + void DIVisitor::ApplyToFields(DebugInfoDesc *DD) { + DD->ApplyToFields(this); + } + + //===----------------------------------------------------------------------===// + /// DICountVisitor - This DIVisitor counts all the fields in the supplied debug + /// the supplied DebugInfoDesc. + class DICountVisitor : public DIVisitor { + private: + unsigned Count; // Running count of fields. + + public: + DICountVisitor() : DIVisitor(), Count(0) {} + + // Accessors. + unsigned getCount() const { return Count; } + + /// Apply - Count each of the fields. + /// + virtual void Apply(int &Field) { ++Count; } + virtual void Apply(unsigned &Field) { ++Count; } + virtual void Apply(int64_t &Field) { ++Count; } + virtual void Apply(uint64_t &Field) { ++Count; } + virtual void Apply(bool &Field) { ++Count; } + virtual void Apply(std::string &Field) { ++Count; } + virtual void Apply(DebugInfoDesc *&Field) { ++Count; } + virtual void Apply(GlobalVariable *&Field) { ++Count; } + virtual void Apply(std::vector<DebugInfoDesc *> &Field) { + ++Count; + } + }; + + //===----------------------------------------------------------------------===// + /// DIDeserializeVisitor - This DIVisitor deserializes all the fields in the + /// supplied DebugInfoDesc. + class DIDeserializeVisitor : public DIVisitor { + private: + DIDeserializer &DR; // Active deserializer. + unsigned I; // Current operand index. + ConstantStruct *CI; // GlobalVariable constant initializer. + + public: + DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV) + : DIVisitor() + , DR(D) + , I(0) + , CI(cast<ConstantStruct>(GV->getInitializer())) + {} + + /// Apply - Set the value of each of the fields. + /// + virtual void Apply(int &Field) { + Constant *C = CI->getOperand(I++); + Field = cast<ConstantInt>(C)->getSExtValue(); + } + virtual void Apply(unsigned &Field) { + Constant *C = CI->getOperand(I++); + Field = cast<ConstantInt>(C)->getZExtValue(); + } + virtual void Apply(int64_t &Field) { + Constant *C = CI->getOperand(I++); + Field = cast<ConstantInt>(C)->getSExtValue(); + } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + Field = cast<ConstantInt>(C)->getZExtValue(); + } + virtual void Apply(bool &Field) { + Constant *C = CI->getOperand(I++); + Field = cast<ConstantInt>(C)->getZExtValue(); + } + virtual void Apply(std::string &Field) { + Constant *C = CI->getOperand(I++); + Field = C->getStringValue(); + } + virtual void Apply(DebugInfoDesc *&Field) { + Constant *C = CI->getOperand(I++); + Field = DR.Deserialize(C); + } + virtual void Apply(GlobalVariable *&Field) { + Constant *C = CI->getOperand(I++); + Field = getGlobalVariable(C); + } + virtual void Apply(std::vector<DebugInfoDesc *> &Field) { + Field.resize(0); + Constant *C = CI->getOperand(I++); + GlobalVariable *GV = getGlobalVariable(C); + if (GV->hasInitializer()) { + if (ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer())) { + for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) { + GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); + DebugInfoDesc *DE = DR.Deserialize(GVE); + Field.push_back(DE); + } + } else if (GV->getInitializer()->isNullValue()) { + if (const ArrayType *T = + dyn_cast<ArrayType>(GV->getType()->getElementType())) { + Field.resize(T->getNumElements()); + } + } + } + } + }; + + //===----------------------------------------------------------------------===// + /// DISerializeVisitor - This DIVisitor serializes all the fields in + /// the supplied DebugInfoDesc. + class DISerializeVisitor : public DIVisitor { + private: + DISerializer &SR; // Active serializer. + std::vector<Constant*> &Elements; // Element accumulator. + + public: + DISerializeVisitor(DISerializer &S, std::vector<Constant*> &E) + : DIVisitor() + , SR(S) + , Elements(E) + {} + + /// Apply - Set the value of each of the fields. + /// + virtual void Apply(int &Field) { + Elements.push_back(ConstantInt::get(Type::Int32Ty, int32_t(Field))); + } + virtual void Apply(unsigned &Field) { + Elements.push_back(ConstantInt::get(Type::Int32Ty, uint32_t(Field))); + } + virtual void Apply(int64_t &Field) { + Elements.push_back(ConstantInt::get(Type::Int64Ty, int64_t(Field))); + } + virtual void Apply(uint64_t &Field) { + Elements.push_back(ConstantInt::get(Type::Int64Ty, uint64_t(Field))); + } + virtual void Apply(bool &Field) { + Elements.push_back(ConstantInt::get(Type::Int1Ty, Field)); + } + virtual void Apply(std::string &Field) { + Elements.push_back(SR.getString(Field)); + } + virtual void Apply(DebugInfoDesc *&Field) { + GlobalVariable *GV = NULL; + + // If non-NULL then convert to global. + if (Field) GV = SR.Serialize(Field); + + // FIXME - At some point should use specific type. + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + + if (GV) { + // Set to pointer to global. + Elements.push_back(ConstantExpr::getBitCast(GV, EmptyTy)); + } else { + // Use NULL. + Elements.push_back(ConstantPointerNull::get(EmptyTy)); + } + } + virtual void Apply(GlobalVariable *&Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + if (Field) { + Elements.push_back(ConstantExpr::getBitCast(Field, EmptyTy)); + } else { + Elements.push_back(ConstantPointerNull::get(EmptyTy)); + } + } + virtual void Apply(std::vector<DebugInfoDesc *> &Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + unsigned N = Field.size(); + ArrayType *AT = ArrayType::get(EmptyTy, N); + std::vector<Constant *> ArrayElements; + + for (unsigned i = 0, N = Field.size(); i < N; ++i) { + if (DebugInfoDesc *Element = Field[i]) { + GlobalVariable *GVE = SR.Serialize(Element); + Constant *CE = ConstantExpr::getBitCast(GVE, EmptyTy); + ArrayElements.push_back(cast<Constant>(CE)); + } else { + ArrayElements.push_back(ConstantPointerNull::get(EmptyTy)); + } + } + + Constant *CA = ConstantArray::get(AT, ArrayElements); + GlobalVariable *CAGV = new GlobalVariable(AT, true, + GlobalValue::InternalLinkage, + CA, "llvm.dbg.array", + SR.getModule()); + CAGV->setSection("llvm.metadata"); + Constant *CAE = ConstantExpr::getBitCast(CAGV, EmptyTy); + Elements.push_back(CAE); + } + }; + + //===----------------------------------------------------------------------===// + /// DIGetTypesVisitor - This DIVisitor gathers all the field types in + /// the supplied DebugInfoDesc. + class DIGetTypesVisitor : public DIVisitor { + private: + DISerializer &SR; // Active serializer. + std::vector<const Type*> &Fields; // Type accumulator. + + public: + DIGetTypesVisitor(DISerializer &S, std::vector<const Type*> &F) + : DIVisitor() + , SR(S) + , Fields(F) + {} + + /// Apply - Set the value of each of the fields. + /// + virtual void Apply(int &Field) { + Fields.push_back(Type::Int32Ty); + } + virtual void Apply(unsigned &Field) { + Fields.push_back(Type::Int32Ty); + } + virtual void Apply(int64_t &Field) { + Fields.push_back(Type::Int64Ty); + } + virtual void Apply(uint64_t &Field) { + Fields.push_back(Type::Int64Ty); + } + virtual void Apply(bool &Field) { + Fields.push_back(Type::Int1Ty); + } + virtual void Apply(std::string &Field) { + Fields.push_back(SR.getStrPtrType()); + } + virtual void Apply(DebugInfoDesc *&Field) { + // FIXME - At some point should use specific type. + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + Fields.push_back(EmptyTy); + } + virtual void Apply(GlobalVariable *&Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + Fields.push_back(EmptyTy); + } + virtual void Apply(std::vector<DebugInfoDesc *> &Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + Fields.push_back(EmptyTy); + } + }; + + //===----------------------------------------------------------------------===// + /// DIVerifyVisitor - This DIVisitor verifies all the field types against + /// a constant initializer. + class DIVerifyVisitor : public DIVisitor { + private: + DIVerifier &VR; // Active verifier. + bool IsValid; // Validity status. + unsigned I; // Current operand index. + ConstantStruct *CI; // GlobalVariable constant initializer. + + public: + DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV) + : DIVisitor() + , VR(V) + , IsValid(true) + , I(0) + , CI(cast<ConstantStruct>(GV->getInitializer())) + { + } + + // Accessors. + bool isValid() const { return IsValid; } + + /// Apply - Set the value of each of the fields. + /// + virtual void Apply(int &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa<ConstantInt>(C); + } + virtual void Apply(unsigned &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa<ConstantInt>(C); + } + virtual void Apply(int64_t &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa<ConstantInt>(C); + } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa<ConstantInt>(C); + } + virtual void Apply(bool &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa<ConstantInt>(C) && C->getType() == Type::Int1Ty; + } + virtual void Apply(std::string &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && + (!C || isStringValue(C) || C->isNullValue()); + } + virtual void Apply(DebugInfoDesc *&Field) { + // FIXME - Prepare the correct descriptor. + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isGlobalVariable(C); + } + virtual void Apply(GlobalVariable *&Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isGlobalVariable(C); + } + virtual void Apply(std::vector<DebugInfoDesc *> &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isGlobalVariable(C); + if (!IsValid) return; + + GlobalVariable *GV = getGlobalVariable(C); + IsValid = IsValid && GV && GV->hasInitializer(); + if (!IsValid) return; + + ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer()); + IsValid = IsValid && CA; + if (!IsValid) return; + + for (unsigned i = 0, N = CA->getNumOperands(); IsValid && i < N; ++i) { + IsValid = IsValid && isGlobalVariable(CA->getOperand(i)); + if (!IsValid) return; + + GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); + VR.Verify(GVE); + } + } + }; + + + //===----------------------------------------------------------------------===// + + /// TagFromGlobal - Returns the tag number from a debug info descriptor + /// GlobalVariable. Return DIIValid if operand is not an unsigned int. + unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) { + ConstantInt *C = getUIntOperand(GV, 0); + return C ? ((unsigned)C->getZExtValue() & ~LLVMDebugVersionMask) : + (unsigned)DW_TAG_invalid; + } + + /// VersionFromGlobal - Returns the version number from a debug info + /// descriptor GlobalVariable. Return DIIValid if operand is not an unsigned + /// int. + unsigned DebugInfoDesc::VersionFromGlobal(GlobalVariable *GV) { + ConstantInt *C = getUIntOperand(GV, 0); + return C ? ((unsigned)C->getZExtValue() & LLVMDebugVersionMask) : + (unsigned)DW_TAG_invalid; + } + + /// 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 DW_TAG_anchor: return new AnchorDesc(); + case DW_TAG_compile_unit: return new CompileUnitDesc(); + case DW_TAG_variable: return new GlobalVariableDesc(); + case DW_TAG_subprogram: return new SubprogramDesc(); + case DW_TAG_lexical_block: return new BlockDesc(); + case DW_TAG_base_type: return new BasicTypeDesc(); + case DW_TAG_typedef: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + case DW_TAG_member: + case DW_TAG_inheritance: return new DerivedTypeDesc(Tag); + case DW_TAG_array_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_vector_type: + case DW_TAG_subroutine_type: return new CompositeTypeDesc(Tag); + case DW_TAG_subrange_type: return new SubrangeDesc(); + case DW_TAG_enumerator: return new EnumeratorDesc(); + case DW_TAG_return_variable: + case DW_TAG_arg_variable: + case DW_TAG_auto_variable: return new VariableDesc(Tag); + 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); + } + + //===----------------------------------------------------------------------===// + + AnchorDesc::AnchorDesc() + : DebugInfoDesc(DW_TAG_anchor) + , AnchorTag(0) + {} + AnchorDesc::AnchorDesc(AnchoredDesc *D) + : DebugInfoDesc(DW_TAG_anchor) + , AnchorTag(D->getTag()) + {} + + // Implement isa/cast/dyncast. + bool AnchorDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_anchor; + } + + /// 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(AnchorTag); + } + + /// getDescString - Return a string used to compose global names and labels. A + /// A global variable name needs to be defined for each debug descriptor that is + /// anchored. NOTE: that each global variable named here also needs to be added + /// to the list of names left external in the internalizer. + /// ExternalNames.insert("llvm.dbg.compile_units"); + /// ExternalNames.insert("llvm.dbg.global_variables"); + /// ExternalNames.insert("llvm.dbg.subprograms"); + const char *AnchorDesc::getDescString() const { + switch (AnchorTag) { + case DW_TAG_compile_unit: return CompileUnitDesc::AnchorString; + case DW_TAG_variable: return GlobalVariableDesc::AnchorString; + case DW_TAG_subprogram: return SubprogramDesc::AnchorString; + default: break; + } + + assert(0 && "Tag does not have a case for anchor string"); + return ""; + } + + /// 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() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "AnchorTag(" << AnchorTag << ")\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(Anchor); + } + + //===----------------------------------------------------------------------===// + + CompileUnitDesc::CompileUnitDesc() + : AnchoredDesc(DW_TAG_compile_unit) + , Language(0) + , FileName("") + , Directory("") + , Producer("") + {} + + // Implement isa/cast/dyncast. + bool CompileUnitDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_compile_unit; + } + + /// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc. + /// + void CompileUnitDesc::ApplyToFields(DIVisitor *Visitor) { + AnchoredDesc::ApplyToFields(Visitor); + + // Handle cases out of sync with compiler. + if (getVersion() == 0) { + unsigned DebugVersion; + Visitor->Apply(DebugVersion); + } + + Visitor->Apply(Language); + Visitor->Apply(FileName); + Visitor->Apply(Directory); + Visitor->Apply(Producer); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + 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::AnchorString = "llvm.dbg.compile_units"; + const char *CompileUnitDesc::getAnchorString() const { + return AnchorString; + } + + #ifndef NDEBUG + void CompileUnitDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Anchor(" << getAnchor() << "), " + << "Language(" << Language << "), " + << "FileName(\"" << FileName << "\"), " + << "Directory(\"" << Directory << "\"), " + << "Producer(\"" << Producer << "\")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + TypeDesc::TypeDesc(unsigned T) + : DebugInfoDesc(T) + , Context(NULL) + , Name("") + , File(NULL) + , Line(0) + , Size(0) + , Align(0) + , Offset(0) + , Flags(0) + {} + + /// ApplyToFields - Target the visitor to the fields of the TypeDesc. + /// + void TypeDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + Visitor->Apply(Name); + Visitor->Apply(File); + Visitor->Apply(Line); + Visitor->Apply(Size); + Visitor->Apply(Align); + Visitor->Apply(Offset); + if (getVersion() > LLVMDebugVersion4) Visitor->Apply(Flags); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *TypeDesc::getDescString() const { + return "llvm.dbg.type"; + } + + /// getTypeString - Return a string used to label this descriptor's type. + /// + const char *TypeDesc::getTypeString() const { + return "llvm.dbg.type.type"; + } + + #ifndef NDEBUG + void TypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << Context << "), " + << "Name(\"" << Name << "\"), " + << "File(" << File << "), " + << "Line(" << Line << "), " + << "Size(" << Size << "), " + << "Align(" << Align << "), " + << "Offset(" << Offset << "), " + << "Flags(" << Flags << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + BasicTypeDesc::BasicTypeDesc() + : TypeDesc(DW_TAG_base_type) + , Encoding(0) + {} + + // Implement isa/cast/dyncast. + bool BasicTypeDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_base_type; + } + + /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. + /// + void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) { + TypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(Encoding); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *BasicTypeDesc::getDescString() const { + return "llvm.dbg.basictype"; + } + + /// getTypeString - Return a string used to label this descriptor's type. + /// + const char *BasicTypeDesc::getTypeString() const { + return "llvm.dbg.basictype.type"; + } + + #ifndef NDEBUG + void BasicTypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "Encoding(" << Encoding << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + DerivedTypeDesc::DerivedTypeDesc(unsigned T) + : TypeDesc(T) + , FromType(NULL) + {} + + // Implement isa/cast/dyncast. + bool DerivedTypeDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_typedef: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + case DW_TAG_member: + case DW_TAG_inheritance: + return true; + default: break; + } + return false; + } + + /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. + /// + void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) { + TypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(FromType); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *DerivedTypeDesc::getDescString() const { + return "llvm.dbg.derivedtype"; + } + + /// getTypeString - Return a string used to label this descriptor's type. + /// + const char *DerivedTypeDesc::getTypeString() const { + return "llvm.dbg.derivedtype.type"; + } + + #ifndef NDEBUG + void DerivedTypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "File(" << getFile() << "), " + << "Line(" << getLine() << "), " + << "FromType(" << FromType << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + CompositeTypeDesc::CompositeTypeDesc(unsigned T) + : DerivedTypeDesc(T) + , Elements() + {} + + // Implement isa/cast/dyncast. + bool CompositeTypeDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_array_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_vector_type: + case DW_TAG_subroutine_type: + return true; + default: break; + } + return false; + } + + /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. + /// + void CompositeTypeDesc::ApplyToFields(DIVisitor *Visitor) { + DerivedTypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(Elements); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *CompositeTypeDesc::getDescString() const { + return "llvm.dbg.compositetype"; + } + + /// getTypeString - Return a string used to label this descriptor's type. + /// + const char *CompositeTypeDesc::getTypeString() const { + return "llvm.dbg.compositetype.type"; + } + + #ifndef NDEBUG + void CompositeTypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "File(" << getFile() << "), " + << "Line(" << getLine() << "), " + << "FromType(" << getFromType() << "), " + << "Elements.size(" << Elements.size() << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + SubrangeDesc::SubrangeDesc() + : DebugInfoDesc(DW_TAG_subrange_type) + , Lo(0) + , Hi(0) + {} + + // Implement isa/cast/dyncast. + bool SubrangeDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_subrange_type; + } + + /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. + /// + void SubrangeDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Lo); + Visitor->Apply(Hi); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *SubrangeDesc::getDescString() const { + return "llvm.dbg.subrange"; + } + + /// getTypeString - Return a string used to label this descriptor's type. + /// + const char *SubrangeDesc::getTypeString() const { + return "llvm.dbg.subrange.type"; + } + + #ifndef NDEBUG + void SubrangeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Lo(" << Lo << "), " + << "Hi(" << Hi << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + EnumeratorDesc::EnumeratorDesc() + : DebugInfoDesc(DW_TAG_enumerator) + , Name("") + , Value(0) + {} + + // Implement isa/cast/dyncast. + bool EnumeratorDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_enumerator; + } + + /// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. + /// + void EnumeratorDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Name); + Visitor->Apply(Value); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *EnumeratorDesc::getDescString() const { + return "llvm.dbg.enumerator"; + } + + /// getTypeString - Return a string used to label this descriptor's type. + /// + const char *EnumeratorDesc::getTypeString() const { + return "llvm.dbg.enumerator.type"; + } + + #ifndef NDEBUG + void EnumeratorDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Name(" << Name << "), " + << "Value(" << Value << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + VariableDesc::VariableDesc(unsigned T) + : DebugInfoDesc(T) + , Context(NULL) + , Name("") + , File(NULL) + , Line(0) + , TyDesc(0) + {} + + // Implement isa/cast/dyncast. + bool VariableDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_auto_variable: + case DW_TAG_arg_variable: + case DW_TAG_return_variable: + return true; + default: break; + } + return false; + } + + /// ApplyToFields - Target the visitor to the fields of the VariableDesc. + /// + void VariableDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + Visitor->Apply(Name); + Visitor->Apply(File); + Visitor->Apply(Line); + Visitor->Apply(TyDesc); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *VariableDesc::getDescString() const { + return "llvm.dbg.variable"; + } + + /// getTypeString - Return a string used to label this descriptor's type. + /// + const char *VariableDesc::getTypeString() const { + return "llvm.dbg.variable.type"; + } + + #ifndef NDEBUG + void VariableDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << Context << "), " + << "Name(\"" << Name << "\"), " + << "File(" << File << "), " + << "Line(" << Line << "), " + << "TyDesc(" << TyDesc << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + GlobalDesc::GlobalDesc(unsigned T) + : AnchoredDesc(T) + , Context(0) + , Name("") + , FullName("") + , LinkageName("") + , File(NULL) + , Line(0) + , TyDesc(NULL) + , IsStatic(false) + , IsDefinition(false) + {} + + /// ApplyToFields - Target the visitor to the fields of the global. + /// + void GlobalDesc::ApplyToFields(DIVisitor *Visitor) { + AnchoredDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + Visitor->Apply(Name); + Visitor->Apply(FullName); + Visitor->Apply(LinkageName); + Visitor->Apply(File); + Visitor->Apply(Line); + Visitor->Apply(TyDesc); + Visitor->Apply(IsStatic); + Visitor->Apply(IsDefinition); + } + + //===----------------------------------------------------------------------===// + + GlobalVariableDesc::GlobalVariableDesc() + : GlobalDesc(DW_TAG_variable) + , Global(NULL) + {} + + // Implement isa/cast/dyncast. + bool GlobalVariableDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_variable; + } + + /// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc. + /// + void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) { + GlobalDesc::ApplyToFields(Visitor); + + Visitor->Apply(Global); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + 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::AnchorString = "llvm.dbg.global_variables"; + const char *GlobalVariableDesc::getAnchorString() const { + return AnchorString; + } + + #ifndef NDEBUG + void GlobalVariableDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Anchor(" << getAnchor() << "), " + << "Name(\"" << getName() << "\"), " + << "FullName(\"" << getFullName() << "\"), " + << "LinkageName(\"" << getLinkageName() << "\"), " + << "File(" << getFile() << ")," + << "Line(" << getLine() << ")," + << "Type(" << getType() << "), " + << "IsStatic(" << (isStatic() ? "true" : "false") << "), " + << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), " + << "Global(" << Global << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + SubprogramDesc::SubprogramDesc() + : GlobalDesc(DW_TAG_subprogram) + {} + + // Implement isa/cast/dyncast. + bool SubprogramDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_subprogram; + } + + /// ApplyToFields - Target the visitor to the fields of the + /// SubprogramDesc. + void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) { + GlobalDesc::ApplyToFields(Visitor); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + 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::AnchorString = "llvm.dbg.subprograms"; + const char *SubprogramDesc::getAnchorString() const { + return AnchorString; + } + + #ifndef NDEBUG + void SubprogramDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Anchor(" << getAnchor() << "), " + << "Name(\"" << getName() << "\"), " + << "FullName(\"" << getFullName() << "\"), " + << "LinkageName(\"" << getLinkageName() << "\"), " + << "File(" << getFile() << ")," + << "Line(" << getLine() << ")," + << "Type(" << getType() << "), " + << "IsStatic(" << (isStatic() ? "true" : "false") << "), " + << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + BlockDesc::BlockDesc() + : DebugInfoDesc(DW_TAG_lexical_block) + , Context(NULL) + {} + + // Implement isa/cast/dyncast. + bool BlockDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_lexical_block; + } + + /// ApplyToFields - Target the visitor to the fields of the BlockDesc. + /// + void BlockDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + } + + /// getDescString - Return a string used to compose global names and labels. + /// + const char *BlockDesc::getDescString() const { + return "llvm.dbg.block"; + } + + /// getTypeString - Return a string used to label this descriptors type. + /// + const char *BlockDesc::getTypeString() const { + return "llvm.dbg.block.type"; + } + + #ifndef NDEBUG + void BlockDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << ")," + << "Context(" << Context << ")\n"; + } + #endif + + //===----------------------------------------------------------------------===// + + DebugInfoDesc *DIDeserializer::Deserialize(Value *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; + + // Get the Tag from the global. + unsigned Tag = DebugInfoDesc::TagFromGlobal(GV); + + // Create an empty instance of the correct sort. + Slot = DebugInfoDesc::DescFactory(Tag); + + // If not a user defined descriptor. + if (Slot) { + // Deserialize the fields. + DIDeserializeVisitor DRAM(*this, GV); + DRAM.ApplyToFields(Slot); + } + + return Slot; + } + + //===----------------------------------------------------------------------===// + + /// getStrPtrType - Return a "sbyte *" type. + /// + const PointerType *DISerializer::getStrPtrType() { + // If not already defined. + if (!StrPtrTy) { + // Construct the pointer to signed bytes. + StrPtrTy = PointerType::get(Type::Int8Ty); + } + + return StrPtrTy; + } + + /// getEmptyStructPtrType - Return a "{ }*" type. + /// + const PointerType *DISerializer::getEmptyStructPtrType() { + // If not already defined. + if (!EmptyStructPtrTy) { + // Construct the empty structure type. + const StructType *EmptyStructTy = + StructType::get(std::vector<const Type*>()); + // Construct the pointer to empty structure type. + EmptyStructPtrTy = PointerType::get(EmptyStructTy); + } + + return EmptyStructPtrTy; + } + + /// getTagType - Return the type describing the specified descriptor (via tag.) + /// + const StructType *DISerializer::getTagType(DebugInfoDesc *DD) { + // Attempt to get the previously defined type. + StructType *&Ty = TagTypes[DD->getTag()]; + + // If not already defined. + if (!Ty) { + // Set up fields vector. + std::vector<const Type*> Fields; + // Get types of fields. + DIGetTypesVisitor GTAM(*this, Fields); + GTAM.ApplyToFields(DD); + + // Construct structured type. + Ty = StructType::get(Fields); + + // Register type name with module. + M->addTypeName(DD->getTypeString(), Ty); + } + + return Ty; + } + + /// getString - Construct the string as constant string global. + /// + Constant *DISerializer::getString(const std::string &String) { + // Check string cache for previous edition. + Constant *&Slot = StringCache[String]; + // Return Constant if previously defined. + if (Slot) return Slot; + // If empty string then use a sbyte* null instead. + if (String.empty()) { + Slot = ConstantPointerNull::get(getStrPtrType()); + } else { + // Construct string as an llvm constant. + Constant *ConstStr = ConstantArray::get(String); + // Otherwise create and return a new string global. + GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true, + GlobalVariable::InternalLinkage, + ConstStr, "str", M); + StrGV->setSection("llvm.metadata"); + // Convert to generic string pointer. + Slot = ConstantExpr::getBitCast(StrGV, getStrPtrType()); + } + return Slot; + + } + + /// Serialize - Recursively cast the specified descriptor into a GlobalVariable + /// so that it can be serialized to a .bc or .ll file. + GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) { + // Check if the DebugInfoDesc is already in the map. + GlobalVariable *&Slot = DescGlobals[DD]; + + // See if DebugInfoDesc exists, if so return prior GlobalVariable. + if (Slot) return Slot; + + // 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, DD->getLinkage(), + NULL, DD->getDescString(), M); + GV->setSection("llvm.metadata"); + + // Insert new GlobalVariable in DescGlobals map. + Slot = GV; + + // Set up elements vector + std::vector<Constant*> Elements; + // Add fields. + DISerializeVisitor SRAM(*this, Elements); + SRAM.ApplyToFields(DD); + + // Set the globals initializer. + GV->setInitializer(ConstantStruct::get(Ty, Elements)); + + return GV; + } + + //===----------------------------------------------------------------------===// + + /// Verify - Return true if the GlobalVariable appears to be a valid + /// serialization of a DebugInfoDesc. + bool DIVerifier::Verify(Value *V) { + return !V || Verify(getGlobalVariable(V)); + } + bool DIVerifier::Verify(GlobalVariable *GV) { + // NULLs are valid. + if (!GV) return true; + + // Check prior validity. + unsigned &ValiditySlot = Validity[GV]; + + // If visited before then use old state. + if (ValiditySlot) return ValiditySlot == Valid; + + // Assume validity for the time being (recursion.) + ValiditySlot = Valid; + + // Make sure the global is internal or link once (anchor.) + if (GV->getLinkage() != GlobalValue::InternalLinkage && + GV->getLinkage() != GlobalValue::LinkOnceLinkage) { + ValiditySlot = Invalid; + return false; + } + + // Get the Tag. + unsigned Tag = DebugInfoDesc::TagFromGlobal(GV); + + // Check for user defined descriptors. + if (Tag == DW_TAG_invalid) { + ValiditySlot = Valid; + return true; + } + + // Get the Version. + unsigned Version = DebugInfoDesc::VersionFromGlobal(GV); + + // Check for version mismatch. + if (Version != LLVMDebugVersion) { + ValiditySlot = Invalid; + return false; + } + + // Construct an empty DebugInfoDesc. + DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag); + + // Allow for user defined descriptors. + if (!DD) return true; + + // Get the initializer constant. + ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer()); + + // Get the operand count. + unsigned N = CI->getNumOperands(); + + // Get the field count. + unsigned &CountSlot = Counts[Tag]; + if (!CountSlot) { + // Check the operand count to the field count + DICountVisitor CTAM; + CTAM.ApplyToFields(DD); + CountSlot = CTAM.getCount(); + } + + // Field count must be at most equal operand count. + if (CountSlot > N) { + delete DD; + ValiditySlot = Invalid; + return false; + } + + // Check each field for valid type. + DIVerifyVisitor VRAM(*this, GV); + VRAM.ApplyToFields(DD); + + // Release empty DebugInfoDesc. + delete DD; + + // If fields are not valid. + if (!VRAM.isValid()) { + ValiditySlot = Invalid; + return false; + } + + return true; + } + + //===----------------------------------------------------------------------===// + + DebugScope::~DebugScope() { + for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i]; + for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; + } + + //===----------------------------------------------------------------------===// + + MachineModuleInfo::MachineModuleInfo() + : DR() + , VR() + , CompileUnits() + , Directories() + , SourceFiles() + , Lines() + , LabelIDList() + , ScopeMap() + , RootScope(NULL) + , FrameMoves() + {} + MachineModuleInfo::~MachineModuleInfo() { + + } + + /// doInitialization - Initialize the state for a new module. + /// + bool MachineModuleInfo::doInitialization() { + return false; + } + + /// doFinalization - Tear down the state after completion of a module. + /// + bool MachineModuleInfo::doFinalization() { + return false; + } + + /// BeginFunction - Begin gathering function meta information. + /// + void MachineModuleInfo::BeginFunction(MachineFunction *MF) { + // Coming soon. + } + + /// EndFunction - Discard function meta information. + /// + void MachineModuleInfo::EndFunction() { + // Clean up scope information. + if (RootScope) { + delete RootScope; + ScopeMap.clear(); + RootScope = NULL; + } + + // Clean up frame info. + FrameMoves.clear(); + } + + /// getDescFor - Convert a Value to a debug information descriptor. + /// + // FIXME - use new Value type when available. + DebugInfoDesc *MachineModuleInfo::getDescFor(Value *V) { + return DR.Deserialize(V); + } + + /// Verify - Verify that a Value is debug information descriptor. + /// + bool MachineModuleInfo::Verify(Value *V) { + return VR.Verify(V); + } + + /// AnalyzeModule - Scan the module for global debug information. + /// + void MachineModuleInfo::AnalyzeModule(Module &M) { + SetupCompileUnits(M); + } + + /// SetupCompileUnits - Set up the unique vector of compile units. + /// + void MachineModuleInfo::SetupCompileUnits(Module &M) { + std::vector<CompileUnitDesc *>CU = getAnchoredDescriptors<CompileUnitDesc>(M); + + for (unsigned i = 0, N = CU.size(); i < N; i++) { + CompileUnits.insert(CU[i]); + } + } + + /// getCompileUnits - Return a vector of debug compile units. + /// + const UniqueVector<CompileUnitDesc *> MachineModuleInfo::getCompileUnits()const{ + return CompileUnits; + } + + /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the + /// named GlobalVariable. + std::vector<GlobalVariable*> + MachineModuleInfo::getGlobalVariablesUsing(Module &M, + const std::string &RootName) { + return ::getGlobalVariablesUsing(M, RootName); + } + + /// RecordLabel - Records location information and associates it with a + /// debug label. Returns a unique label ID used to generate a label and + /// provide correspondence to the source line list. + unsigned MachineModuleInfo::RecordLabel(unsigned Line, unsigned Column, + unsigned Source) { + unsigned ID = NextLabelID(); + Lines.push_back(SourceLineInfo(Line, Column, Source, ID)); + return ID; + } + + /// RecordSource - Register a source file with debug info. Returns an source + /// ID. + unsigned MachineModuleInfo::RecordSource(const std::string &Directory, + const std::string &Source) { + unsigned DirectoryID = Directories.insert(Directory); + return SourceFiles.insert(SourceFileInfo(DirectoryID, Source)); + } + unsigned MachineModuleInfo::RecordSource(const CompileUnitDesc *CompileUnit) { + return RecordSource(CompileUnit->getDirectory(), + CompileUnit->getFileName()); + } + + /// RecordRegionStart - Indicate the start of a region. + /// + unsigned MachineModuleInfo::RecordRegionStart(Value *V) { + // FIXME - need to be able to handle split scopes because of bb cloning. + DebugInfoDesc *ScopeDesc = DR.Deserialize(V); + DebugScope *Scope = getOrCreateScope(ScopeDesc); + unsigned ID = NextLabelID(); + if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); + return ID; + } + + /// RecordRegionEnd - Indicate the end of a region. + /// + unsigned MachineModuleInfo::RecordRegionEnd(Value *V) { + // FIXME - need to be able to handle split scopes because of bb cloning. + DebugInfoDesc *ScopeDesc = DR.Deserialize(V); + DebugScope *Scope = getOrCreateScope(ScopeDesc); + unsigned ID = NextLabelID(); + Scope->setEndLabelID(ID); + return ID; + } + + /// RecordVariable - Indicate the declaration of a local variable. + /// + void MachineModuleInfo::RecordVariable(Value *V, unsigned FrameIndex) { + VariableDesc *VD = cast<VariableDesc>(DR.Deserialize(V)); + DebugScope *Scope = getOrCreateScope(VD->getContext()); + DebugVariable *DV = new DebugVariable(VD, FrameIndex); + Scope->AddVariable(DV); + } + + /// getOrCreateScope - Returns the scope associated with the given descriptor. + /// + DebugScope *MachineModuleInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) { + DebugScope *&Slot = ScopeMap[ScopeDesc]; + if (!Slot) { + // FIXME - breaks down when the context is an inlined function. + DebugInfoDesc *ParentDesc = NULL; + if (BlockDesc *Block = dyn_cast<BlockDesc>(ScopeDesc)) { + ParentDesc = Block->getContext(); + } + DebugScope *Parent = ParentDesc ? getOrCreateScope(ParentDesc) : NULL; + Slot = new DebugScope(Parent, ScopeDesc); + if (Parent) { + Parent->AddScope(Slot); + } else if (RootScope) { + // FIXME - Add inlined function scopes to the root so we can delete + // them later. Long term, handle inlined functions properly. + RootScope->AddScope(Slot); + } else { + // First function is top level function. + RootScope = Slot; + } + } + return Slot; + } + + //===----------------------------------------------------------------------===// + /// DebugLabelFolding pass - This pass prunes out redundant labels. This allows + /// a info consumer to determine if the range of two labels is empty, by seeing + /// if the labels map to the same reduced label. + + namespace llvm { + + struct DebugLabelFolder : public MachineFunctionPass { + virtual bool runOnMachineFunction(MachineFunction &MF); + virtual const char *getPassName() const { return "Label Folder"; } + }; + + bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) { + // Get machine module info. + MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>(); + if (!MMI) return false; + // Get target instruction info. + const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); + if (!TII) return false; + + // Track if change is made. + bool MadeChange = false; + // No prior label to begin. + unsigned PriorLabel = 0; + + // Iterate through basic blocks. + for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); + BB != E; ++BB) { + // Iterate through instructions. + for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { + // Is it a label. + if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) { + // The label ID # is always operand #0, an immediate. + unsigned NextLabel = I->getOperand(0).getImm(); + + // If there was an immediate prior label. + if (PriorLabel) { + // Remap the current label to prior label. + MMI->RemapLabel(NextLabel, PriorLabel); + // Delete the current label. + I = BB->erase(I); + // Indicate a change has been made. + MadeChange = true; + continue; + } else { + // Start a new round. + PriorLabel = NextLabel; + } + } else { + // No consecutive labels. + PriorLabel = 0; + } + + ++I; + } + } + + return MadeChange; + } + + FunctionPass *createDebugLabelFoldingPass() { return new DebugLabelFolder(); } + + } + _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits