X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineModuleInfo.cpp;h=80c4854238afe3e63fe0df3df3eb69326d633add;hb=1b3f9198ab3880be34b6252423b9e388b5cd6a5e;hp=60526643fdfc68c4cfbf8febef734ed46cf3e20e;hpb=8342cfff9a221dd69c1d9c615414ec3b8c8db776;p=oota-llvm.git diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 60526643fdf..80c4854238a 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -10,1688 +10,368 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Constants.h" -#include "llvm/Analysis/ValueTracking.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/Target/TargetOptions.h" #include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" -#include "llvm/Intrinsics.h" -#include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; using namespace llvm::dwarf; // Handle the Pass registration stuff necessary to use TargetData's. -static RegisterPass -X("machinemoduleinfo", "Module Information"); +INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo", + "Machine Module Information", false, false) char MachineModuleInfo::ID = 0; -//===----------------------------------------------------------------------===// - -/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the -/// specified value in their initializer somewhere. -static void -getGlobalVariablesUsing(Value *V, std::vector &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(*I)) { - // If the user is a GlobalVariable then add to result. - Result.push_back(GV); - } else if (Constant *C = dyn_cast(*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 -getGlobalVariablesUsing(Module &M, const std::string &RootName) { - std::vector Result; // GlobalVariables matching criteria. - - std::vector 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(V)) { - if (GV->hasInitializer() && isa(GV->getInitializer())) { - ConstantArray *Init = cast(GV->getInitializer()); - return Init->isString(); - } - } else if (Constant *C = dyn_cast(V)) { - if (GlobalValue *GV = dyn_cast(C)) - return isStringValue(GV); - else if (ConstantExpr *CE = dyn_cast(C)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - if (CE->getNumOperands() == 3 && - cast(CE->getOperand(1))->isNullValue() && - isa(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(V)) { - return GV; - } else if (ConstantExpr *CE = dyn_cast(V)) { - if (CE->getOpcode() == Instruction::BitCast) { - return dyn_cast(CE->getOperand(0)); - } else if (CE->getOpcode() == Instruction::GetElementPtr) { - for (unsigned int i=1; igetNumOperands(); i++) { - if (!CE->getOperand(i)->isNullValue()) - return NULL; - } - return dyn_cast(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(V) || isa(V)) { - return true; - } else if (ConstantExpr *CE = dyn_cast(V)) { - if (CE->getOpcode() == Instruction::BitCast) { - return isa(CE->getOperand(0)); - } else if (CE->getOpcode() == Instruction::GetElementPtr) { - for (unsigned int i=1; igetNumOperands(); i++) { - if (!CE->getOperand(i)->isNullValue()) - return false; - } - return isa(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(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(CI->getOperand(i)); -} - -//===----------------------------------------------------------------------===// - -/// ApplyToFields - Target the visitor to each field of the debug information -/// descriptor. -void DIVisitor::ApplyToFields(DebugInfoDesc *DD) { - DD->ApplyToFields(this); -} +// Out of line virtual method. +MachineModuleInfoImpl::~MachineModuleInfoImpl() {} -namespace { - -//===----------------------------------------------------------------------===// -/// 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. - +namespace llvm { +class MMIAddrLabelMapCallbackPtr : CallbackVH { + MMIAddrLabelMap *Map; 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 &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. + MMIAddrLabelMapCallbackPtr() : Map(0) {} + MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(0) {} -public: - DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV) - : DIVisitor() - , DR(D) - , I(0) - , CI(cast(GV->getInitializer())) - {} - - /// Apply - Set the value of each of the fields. - /// - virtual void Apply(int &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getSExtValue(); - } - virtual void Apply(unsigned &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getZExtValue(); - } - virtual void Apply(int64_t &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getSExtValue(); - } - virtual void Apply(uint64_t &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getZExtValue(); - } - virtual void Apply(bool &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getZExtValue(); + void setPtr(BasicBlock *BB) { + ValueHandleBase::operator=(BB); } - virtual void Apply(std::string &Field) { - Constant *C = CI->getOperand(I++); - // Fills in the string if it succeeds - if (!GetConstantStringInfo(C, Field)) - Field.clear(); - } - 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 &Field) { - Field.resize(0); - Constant *C = CI->getOperand(I++); - GlobalVariable *GV = getGlobalVariable(C); - if (GV->hasInitializer()) { - if (ConstantArray *CA = dyn_cast(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(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 &Elements; // Element accumulator. - -public: - DISerializeVisitor(DISerializer &S, std::vector &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 &Field) { - const PointerType *EmptyTy = SR.getEmptyStructPtrType(); - unsigned N = Field.size(); - ArrayType *AT = ArrayType::get(EmptyTy, N); - std::vector 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(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); - } -}; + void setMap(MMIAddrLabelMap *map) { Map = map; } -//===----------------------------------------------------------------------===// -/// DIGetTypesVisitor - This DIVisitor gathers all the field types in -/// the supplied DebugInfoDesc. -class DIGetTypesVisitor : public DIVisitor { -private: - DISerializer &SR; // Active serializer. - std::vector &Fields; // Type accumulator. - -public: - DIGetTypesVisitor(DISerializer &S, std::vector &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 &Field) { - const PointerType *EmptyTy = SR.getEmptyStructPtrType(); - Fields.push_back(EmptyTy); - } + virtual void deleted(); + virtual void allUsesReplacedWith(Value *V2); }; -//===----------------------------------------------------------------------===// -/// 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. - +class MMIAddrLabelMap { + MCContext &Context; + struct AddrLabelSymEntry { + /// Symbols - The symbols for the label. This is a pointer union that is + /// either one symbol (the common case) or a list of symbols. + PointerUnion*> Symbols; + + Function *Fn; // The containing function of the BasicBlock. + unsigned Index; // The index in BBCallbacks for the BasicBlock. + }; + + DenseMap, AddrLabelSymEntry> AddrLabelSymbols; + + /// BBCallbacks - Callbacks for the BasicBlock's that we have entries for. We + /// use this so we get notified if a block is deleted or RAUWd. + std::vector BBCallbacks; + + /// DeletedAddrLabelsNeedingEmission - This is a per-function list of symbols + /// whose corresponding BasicBlock got deleted. These symbols need to be + /// emitted at some point in the file, so AsmPrinter emits them after the + /// function body. + DenseMap, std::vector > + DeletedAddrLabelsNeedingEmission; public: - DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV) - : DIVisitor() - , VR(V) - , IsValid(true) - , I(0) - , CI(cast(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(C); - } - virtual void Apply(unsigned &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(C); - } - virtual void Apply(int64_t &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(C); - } - virtual void Apply(uint64_t &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(C); - } - virtual void Apply(bool &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(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 &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(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); - } - } -}; - -} -//===----------------------------------------------------------------------===// + MMIAddrLabelMap(MCContext &context) : Context(context) {} + ~MMIAddrLabelMap() { + assert(DeletedAddrLabelsNeedingEmission.empty() && + "Some labels for deleted blocks never got emitted"); -/// 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 *const 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; + // Deallocate any of the 'list of symbols' case. + for (DenseMap, AddrLabelSymEntry>::iterator + I = AddrLabelSymbols.begin(), E = AddrLabelSymbols.end(); I != E; ++I) + if (I->second.Symbols.is*>()) + delete I->second.Symbols.get*>(); } - 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"; -} + MCSymbol *getAddrLabelSymbol(BasicBlock *BB); + std::vector getAddrLabelSymbolToEmit(BasicBlock *BB); -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *DerivedTypeDesc::getTypeString() const { - return "llvm.dbg.derivedtype.type"; -} + void takeDeletedSymbolsForFunction(Function *F, + std::vector &Result); -#ifndef NDEBUG -void DerivedTypeDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Context(" << getContext() << "), " - << "Name(\"" << getName() << "\"), " - << "Size(" << getSize() << "), " - << "File(" << getFile() << "), " - << "Line(" << getLine() << "), " - << "FromType(" << FromType << ")\n"; + void UpdateForDeletedBlock(BasicBlock *BB); + void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); +}; } -#endif -//===----------------------------------------------------------------------===// +MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) { + assert(BB->hasAddressTaken() && + "Shouldn't get label for block without address taken"); + AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; -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; + // If we already had an entry for this block, just return it. + if (!Entry.Symbols.isNull()) { + assert(BB->getParent() == Entry.Fn && "Parent changed"); + if (Entry.Symbols.is()) + return Entry.Symbols.get(); + return (*Entry.Symbols.get*>())[0]; } - 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; + // Otherwise, this is a new entry, create a new symbol for it and add an + // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. + BBCallbacks.push_back(BB); + BBCallbacks.back().setMap(this); + Entry.Index = BBCallbacks.size()-1; + Entry.Fn = BB->getParent(); + MCSymbol *Result = Context.CreateTempSymbol(); + Entry.Symbols = Result; + return Result; } -/// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. -/// -void SubrangeDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); +std::vector +MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { + assert(BB->hasAddressTaken() && + "Shouldn't get label for block without address taken"); + AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; - Visitor->Apply(Lo); - Visitor->Apply(Hi); -} + std::vector Result; -/// 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"; + // If we already had an entry for this block, just return it. + if (Entry.Symbols.isNull()) + Result.push_back(getAddrLabelSymbol(BB)); + else if (MCSymbol *Sym = Entry.Symbols.dyn_cast()) + Result.push_back(Sym); + else + Result = *Entry.Symbols.get*>(); + return Result; } -#ifndef NDEBUG -void SubrangeDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Lo(" << Lo << "), " - << "Hi(" << Hi << ")\n"; -} -#endif -//===----------------------------------------------------------------------===// +/// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return +/// them. +void MMIAddrLabelMap:: +takeDeletedSymbolsForFunction(Function *F, std::vector &Result) { + DenseMap, std::vector >::iterator I = + DeletedAddrLabelsNeedingEmission.find(F); -EnumeratorDesc::EnumeratorDesc() -: DebugInfoDesc(DW_TAG_enumerator) -, Name("") -, Value(0) -{} + // If there are no entries for the function, just return. + if (I == DeletedAddrLabelsNeedingEmission.end()) return; -// Implement isa/cast/dyncast. -bool EnumeratorDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_enumerator; + // Otherwise, take the list. + std::swap(Result, I->second); + DeletedAddrLabelsNeedingEmission.erase(I); } -/// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. -/// -void EnumeratorDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); - Visitor->Apply(Name); - Visitor->Apply(Value); -} +void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { + // If the block got deleted, there is no need for the symbol. If the symbol + // was already emitted, we can just forget about it, otherwise we need to + // queue it up for later emission when the function is output. + AddrLabelSymEntry Entry = AddrLabelSymbols[BB]; + AddrLabelSymbols.erase(BB); + assert(!Entry.Symbols.isNull() && "Didn't have a symbol, why a callback?"); + BBCallbacks[Entry.Index] = 0; // Clear the callback. -/// 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"; -} + assert((BB->getParent() == 0 || BB->getParent() == Entry.Fn) && + "Block/parent mismatch"); -#ifndef NDEBUG -void EnumeratorDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Name(" << Name << "), " - << "Value(" << Value << ")\n"; -} -#endif + // Handle both the single and the multiple symbols cases. + if (MCSymbol *Sym = Entry.Symbols.dyn_cast()) { + if (Sym->isDefined()) + return; -//===----------------------------------------------------------------------===// + // If the block is not yet defined, we need to emit it at the end of the + // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list + // for the containing Function. Since the block is being deleted, its + // parent may already be removed, we have to get the function from 'Entry'. + DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); + } else { + std::vector *Syms = Entry.Symbols.get*>(); + + for (unsigned i = 0, e = Syms->size(); i != e; ++i) { + MCSymbol *Sym = (*Syms)[i]; + if (Sym->isDefined()) continue; // Ignore already emitted labels. + + // If the block is not yet defined, we need to emit it at the end of the + // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list + // for the containing Function. Since the block is being deleted, its + // parent may already be removed, we have to get the function from + // 'Entry'. + DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); + } -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; + // The entry is deleted, free the memory associated with the symbol list. + delete Syms; } - 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 +void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { + // Get the entry for the RAUW'd block and remove it from our map. + AddrLabelSymEntry OldEntry = AddrLabelSymbols[Old]; + AddrLabelSymbols.erase(Old); + assert(!OldEntry.Symbols.isNull() && "Didn't have a symbol, why a callback?"); -//===----------------------------------------------------------------------===// + AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; -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 *const 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 *const 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); + // If New is not address taken, just move our symbol over to it. + if (NewEntry.Symbols.isNull()) { + BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. + NewEntry = OldEntry; // Set New's entry. + return; } - - return Slot; -} -//===----------------------------------------------------------------------===// + BBCallbacks[OldEntry.Index] = 0; // Update the callback. -/// getStrPtrType - Return a "sbyte *" type. -/// -const PointerType *DISerializer::getStrPtrType() { - // If not already defined. - if (!StrPtrTy) { - // Construct the pointer to signed bytes. - StrPtrTy = PointerType::getUnqual(Type::Int8Ty); + // Otherwise, we need to add the old symbol to the new block's set. If it is + // just a single entry, upgrade it to a symbol list. + if (MCSymbol *PrevSym = NewEntry.Symbols.dyn_cast()) { + std::vector *SymList = new std::vector(); + SymList->push_back(PrevSym); + NewEntry.Symbols = SymList; } - - 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()); - // Construct the pointer to empty structure type. - EmptyStructPtrTy = PointerType::getUnqual(EmptyStructTy); - } - - return EmptyStructPtrTy; -} + std::vector *SymList = + NewEntry.Symbols.get*>(); -/// 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 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); + // If the old entry was a single symbol, add it. + if (MCSymbol *Sym = OldEntry.Symbols.dyn_cast()) { + SymList->push_back(Sym); + return; } - - 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; - + // Otherwise, concatenate the list. + std::vector *Syms =OldEntry.Symbols.get*>(); + SymList->insert(SymList->end(), Syms->begin(), Syms->end()); + delete Syms; } -/// 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 Elements; - // Add fields. - DISerializeVisitor SRAM(*this, Elements); - SRAM.ApplyToFields(DD); - - // Set the globals initializer. - GV->setInitializer(ConstantStruct::get(Ty, Elements)); - - return GV; -} -/// addDescriptor - Directly connect DD with existing GV. -void DISerializer::addDescriptor(DebugInfoDesc *DD, - GlobalVariable *GV) { - DescGlobals[DD] = GV; +void MMIAddrLabelMapCallbackPtr::deleted() { + Map->UpdateForDeletedBlock(cast(getValPtr())); } -//===----------------------------------------------------------------------===// - -/// 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(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; +void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { + Map->UpdateForRAUWBlock(cast(getValPtr()), cast(V2)); } -/// isVerified - Return true if the specified GV has already been -/// verified as a debug information descriptor. -bool DIVerifier::isVerified(GlobalVariable *GV) { - unsigned &ValiditySlot = Validity[GV]; - if (ValiditySlot) return ValiditySlot == Valid; - return false; -} //===----------------------------------------------------------------------===// -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(const MCAsmInfo &MAI, + const MCRegisterInfo &MRI, + const MCObjectFileInfo *MOFI) + : ImmutablePass(ID), Context(MAI, MRI, MOFI), + ObjFileMMI(0), CompactUnwindEncoding(0), CurCallSite(0), CallsEHReturn(0), + CallsUnwindInit(0), DbgInfoAvailable(false), + CallsExternalVAFunctionWithFloatingPointArguments(false) { + initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry()); + // Always emit some info, by default "no personality" info. + Personalities.push_back(NULL); + AddrLabelSymbols = 0; + TheModule = 0; } -//===----------------------------------------------------------------------===// - MachineModuleInfo::MachineModuleInfo() -: ImmutablePass((intptr_t)&ID) -, DR() -, VR() -, CompileUnits() -, Directories() -, SourceFiles() -, Lines() -, LabelIDList() -, ScopeMap() -, RootScope(NULL) -, FrameMoves() -, LandingPads() -, Personalities() -, CallsEHReturn(0) -, CallsUnwindInit(0) -{ - // Always emit "no personality" info - Personalities.push_back(NULL); + : ImmutablePass(ID), + Context(*(MCAsmInfo*)0, *(MCRegisterInfo*)0, (MCObjectFileInfo*)0) { + assert(0 && "This MachineModuleInfo constructor should never be called, MMI " + "should always be explicitly constructed by LLVMTargetMachine"); + abort(); } + MachineModuleInfo::~MachineModuleInfo() { + delete ObjFileMMI; + // FIXME: Why isn't doFinalization being called?? + //assert(AddrLabelSymbols == 0 && "doFinalization not called"); + delete AddrLabelSymbols; + AddrLabelSymbols = 0; } /// doInitialization - Initialize the state for a new module. /// bool MachineModuleInfo::doInitialization() { + assert(AddrLabelSymbols == 0 && "Improperly initialized"); return false; } /// doFinalization - Tear down the state after completion of a module. /// bool MachineModuleInfo::doFinalization() { + delete AddrLabelSymbols; + AddrLabelSymbols = 0; 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 line info. - Lines.clear(); - // Clean up frame info. FrameMoves.clear(); - + // Clean up exception info. LandingPads.clear(); + CallSiteMap.clear(); TypeInfos.clear(); FilterIds.clear(); FilterEnds.clear(); CallsEHReturn = 0; CallsUnwindInit = 0; -} - -/// 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); + CompactUnwindEncoding = 0; + VariableDbgInfo.clear(); } /// AnalyzeModule - Scan the module for global debug information. /// -void MachineModuleInfo::AnalyzeModule(Module &M) { - SetupCompileUnits(M); - - // Insert functions in the llvm.used array into UsedFunctions. - GlobalVariable *GV = M.getGlobalVariable("llvm.used"); +void MachineModuleInfo::AnalyzeModule(const Module &M) { + // Insert functions in the llvm.used array (but not llvm.compiler.used) into + // UsedFunctions. + const GlobalVariable *GV = M.getGlobalVariable("llvm.used"); if (!GV || !GV->hasInitializer()) return; // Should be an array of 'i8*'. - ConstantArray *InitList = dyn_cast(GV->getInitializer()); + const ConstantArray *InitList = dyn_cast(GV->getInitializer()); if (InitList == 0) return; - for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { - if (ConstantExpr *CE = dyn_cast(InitList->getOperand(i))) - if (CE->getOpcode() == Instruction::BitCast) - if (Function *F = dyn_cast(CE->getOperand(0))) - UsedFunctions.insert(F); - } + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) + if (const Function *F = + dyn_cast(InitList->getOperand(i)->stripPointerCasts())) + UsedFunctions.insert(F); } -/// SetupCompileUnits - Set up the unique vector of compile units. -/// -void MachineModuleInfo::SetupCompileUnits(Module &M) { - std::vectorCU = getAnchoredDescriptors(M); - - for (unsigned i = 0, N = CU.size(); i < N; i++) { - CompileUnits.insert(CU[i]); - } -} +//===- Address of Block Management ----------------------------------------===// -/// getCompileUnits - Return a vector of debug compile units. -/// -const UniqueVector MachineModuleInfo::getCompileUnits()const{ - return CompileUnits; -} -/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the -/// named GlobalVariable. -std::vector -MachineModuleInfo::getGlobalVariablesUsing(Module &M, - const std::string &RootName) { - return ::getGlobalVariablesUsing(M, RootName); +/// getAddrLabelSymbol - Return the symbol to be used for the specified basic +/// block when its address is taken. This cannot be its normal LBB label +/// because the block may be accessed outside its containing function. +MCSymbol *MachineModuleInfo::getAddrLabelSymbol(const BasicBlock *BB) { + // Lazily create AddrLabelSymbols. + if (AddrLabelSymbols == 0) + AddrLabelSymbols = new MMIAddrLabelMap(Context); + return AddrLabelSymbols->getAddrLabelSymbol(const_cast(BB)); } -/// RecordSourceLine - 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::RecordSourceLine(unsigned Line, unsigned Column, - unsigned Source) { - unsigned ID = NextLabelID(); - Lines.push_back(SourceLineInfo(Line, Column, Source, ID)); - return ID; +/// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified +/// basic block when its address is taken. If other blocks were RAUW'd to +/// this one, we may have to emit them as well, return the whole set. +std::vector MachineModuleInfo:: +getAddrLabelSymbolToEmit(const BasicBlock *BB) { + // Lazily create AddrLabelSymbols. + if (AddrLabelSymbols == 0) + AddrLabelSymbols = new MMIAddrLabelMap(Context); + return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast(BB)); } -/// 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(GlobalValue *GV, unsigned FrameIndex) { - VariableDesc *VD = cast(DR.Deserialize(GV)); - 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(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; +/// takeDeletedSymbolsForFunction - If the specified function has had any +/// references to address-taken blocks generated, but the block got deleted, +/// return the symbol now so we can emit it. This prevents emitting a +/// reference to a symbol that has no definition. +void MachineModuleInfo:: +takeDeletedSymbolsForFunction(const Function *F, + std::vector &Result) { + // If no blocks have had their addresses taken, we're done. + if (AddrLabelSymbols == 0) return; + return AddrLabelSymbols-> + takeDeletedSymbolsForFunction(const_cast(F), Result); } -//===-EH-------------------------------------------------------------------===// +//===- EH -----------------------------------------------------------------===// /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the /// specified MachineBasicBlock. @@ -1703,7 +383,7 @@ LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo if (LP.LandingPadBlock == LandingPad) return LP; } - + LandingPads.push_back(LandingPadInfo(LandingPad)); return LandingPads[N]; } @@ -1711,7 +391,7 @@ LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo /// addInvoke - Provide the begin and end labels of an invoke style call and /// associate it with a try landing pad block. void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad, - unsigned BeginLabel, unsigned EndLabel) { + MCSymbol *BeginLabel, MCSymbol *EndLabel) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); LP.BeginLabels.push_back(BeginLabel); LP.EndLabels.push_back(EndLabel); @@ -1719,31 +399,37 @@ void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad, /// addLandingPad - Provide the label of a try LandingPad block. /// -unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) { - unsigned LandingPadLabel = NextLabelID(); +MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) { + MCSymbol *LandingPadLabel = Context.CreateTempSymbol(); LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); - LP.LandingPadLabel = LandingPadLabel; + LP.LandingPadLabel = LandingPadLabel; return LandingPadLabel; } /// addPersonality - Provide the personality function for the exception /// information. void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad, - Function *Personality) { + const Function *Personality) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); LP.Personality = Personality; for (unsigned i = 0; i < Personalities.size(); ++i) if (Personalities[i] == Personality) return; - - Personalities.push_back(Personality); + + // If this is the first personality we're adding go + // ahead and add it at the beginning. + if (Personalities[0] == NULL) + Personalities[0] = Personality; + else + Personalities.push_back(Personality); } /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// -void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad, - std::vector &TyInfo) { +void MachineModuleInfo:: +addCatchTypeInfo(MachineBasicBlock *LandingPad, + ArrayRef TyInfo) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); for (unsigned N = TyInfo.size(); N; --N) LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1])); @@ -1751,10 +437,11 @@ void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad, /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. /// -void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad, - std::vector &TyInfo) { +void MachineModuleInfo:: +addFilterTypeInfo(MachineBasicBlock *LandingPad, + ArrayRef TyInfo) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); - std::vector IdsInFilter (TyInfo.size()); + std::vector IdsInFilter(TyInfo.size()); for (unsigned I = 0, E = TyInfo.size(); I != E; ++I) IdsInFilter[I] = getTypeIDFor(TyInfo[I]); LP.TypeIds.push_back(getFilterIDFor(IdsInFilter)); @@ -1769,10 +456,13 @@ void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) { /// TidyLandingPads - Remap landing pad labels and remove any deleted landing /// pads. -void MachineModuleInfo::TidyLandingPads() { +void MachineModuleInfo::TidyLandingPads(DenseMap *LPMap) { for (unsigned i = 0; i != LandingPads.size(); ) { LandingPadInfo &LandingPad = LandingPads[i]; - LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel); + if (LandingPad.LandingPadLabel && + !LandingPad.LandingPadLabel->isDefined() && + (!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0)) + LandingPad.LandingPadLabel = 0; // Special case: we *should* emit LPs with null LP MBB. This indicates // "nounwind" case. @@ -1781,19 +471,17 @@ void MachineModuleInfo::TidyLandingPads() { continue; } - for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) { - unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]); - unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]); - - if (!BeginLabel || !EndLabel) { - LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j); - LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j); - continue; - } - - LandingPad.BeginLabels[j] = BeginLabel; - LandingPad.EndLabels[j] = EndLabel; - ++j; + for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) { + MCSymbol *BeginLabel = LandingPad.BeginLabels[j]; + MCSymbol *EndLabel = LandingPad.EndLabels[j]; + if ((BeginLabel->isDefined() || + (LPMap && (*LPMap)[BeginLabel] != 0)) && + (EndLabel->isDefined() || + (LPMap && (*LPMap)[EndLabel] != 0))) continue; + + LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j); + LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j); + --j, --e; } // Remove landing pads with no try-ranges. @@ -1807,14 +495,21 @@ void MachineModuleInfo::TidyLandingPads() { if (!LandingPad.LandingPadBlock || (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0])) LandingPad.TypeIds.clear(); - ++i; } } -/// getTypeIDFor - Return the type id for the specified typeinfo. This is +/// setCallSiteLandingPad - Map the landing pad's EH symbol to the call site +/// indexes. +void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym, + ArrayRef Sites) { + for (unsigned I = 0, E = Sites.size(); I != E; ++I) + LPadToCallSiteMap[Sym].push_back(Sites[I]); +} + +/// getTypeIDFor - Return the type id for the specified typeinfo. This is /// function wide. -unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) { +unsigned MachineModuleInfo::getTypeIDFor(const GlobalVariable *TI) { for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i) if (TypeInfos[i] == TI) return i + 1; @@ -1854,97 +549,30 @@ try_next:; } /// getPersonality - Return the personality function for the current function. -Function *MachineModuleInfo::getPersonality() const { +const Function *MachineModuleInfo::getPersonality() const { // FIXME: Until PR1414 will be fixed, we're using 1 personality function per // function return !LandingPads.empty() ? LandingPads[0].Personality : NULL; } /// getPersonalityIndex - Return unique index for current personality -/// function. NULL personality function should always get zero index. +/// function. NULL/first personality function should always get zero index. unsigned MachineModuleInfo::getPersonalityIndex() const { const Function* Personality = NULL; - + // Scan landing pads. If there is at least one non-NULL personality - use it. for (unsigned i = 0; i != LandingPads.size(); ++i) if (LandingPads[i].Personality) { Personality = LandingPads[i].Personality; break; } - + for (unsigned i = 0; i < Personalities.size(); ++i) { if (Personalities[i] == Personality) return i; } - // This should never happen - assert(0 && "Personality function should be set!"); + // This will happen if the current personality function is + // in the zero index. return 0; } - -//===----------------------------------------------------------------------===// -/// 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 { - static char ID; - DebugLabelFolder() : MachineFunctionPass((intptr_t)&ID) {} - - virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Label Folder"; } -}; - -char DebugLabelFolder::ID = 0; - -bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) { - // Get machine module info. - MachineModuleInfo *MMI = getAnalysisToUpdate(); - if (!MMI) 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 (I->isDebugLabel()) { - // 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(); } - -} -