X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineModuleInfo.cpp;h=4b64901bd4e2d18b481a310fc93e6a5c36cd40f8;hb=f9410141f703f4e8a6aba717617ef958249f6d13;hp=62224fdca8487f427ad8be1ac832ec511595bc16;hpb=6590b0457c5e28a7336ae31de194953d8127217a;p=oota-llvm.git diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 62224fdca84..4b64901bd4e 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -2,17 +2,18 @@ // // 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. +// This file 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/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -27,9 +28,8 @@ using namespace llvm; using namespace llvm::dwarf; // Handle the Pass registration stuff necessary to use TargetData's. -namespace { - RegisterPass X("machinemoduleinfo", "Module Information"); -} +static RegisterPass +X("machinemoduleinfo", "Module Information"); char MachineModuleInfo::ID = 0; //===----------------------------------------------------------------------===// @@ -52,10 +52,9 @@ getGlobalVariablesUsing(Value *V, std::vector &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. - +static void +getGlobalVariablesUsing(Module &M, const std::string &RootName, + std::vector &Result) { std::vector FieldTypes; FieldTypes.push_back(Type::Int32Ty); FieldTypes.push_back(Type::Int32Ty); @@ -65,11 +64,8 @@ getGlobalVariablesUsing(Module &M, const std::string &RootName) { StructType::get(FieldTypes)); // If present and linkonce then scan for users. - if (UseRoot && UseRoot->hasLinkOnceLinkage()) { + if (UseRoot && UseRoot->hasLinkOnceLinkage()) getGlobalVariablesUsing(UseRoot, Result); - } - - return Result; } /// isStringValue - Return true if the given value can be coerced to a string. @@ -104,6 +100,12 @@ static GlobalVariable *getGlobalVariable(Value *V) { } 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; @@ -117,6 +119,12 @@ static bool isGlobalVariable(Value *V) { } 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; @@ -142,39 +150,164 @@ static ConstantInt *getUIntOperand(GlobalVariable *GV, unsigned i) { //===----------------------------------------------------------------------===// +static unsigned CountFields(DebugInfoDesc *DD) { + unsigned Count = 0; + + switch (DD->getTag()) { + case DW_TAG_anchor: // AnchorDesc + // Tag + // AnchorTag + Count = 2; + break; + case DW_TAG_compile_unit: // CompileUnitDesc + // [DW_TAG_anchor] + // if (Version == 0) DebugVersion + // Language + // FileName + // Directory + // Producer + Count = 6; + + // Handle cases out of sync with compiler. + if (DD->getVersion() == 0) + ++Count; + + break; + case DW_TAG_variable: // GlobalVariableDesc + // [DW_TAG_anchor] + // Context + // Name + // FullName + // LinkageName + // File + // Line + // TyDesc + // IsStatic + // IsDefinition + // Global + Count = 12; + break; + case DW_TAG_subprogram: // SubprogramDesc + // [DW_TAG_anchor] + // Context + // Name + // FullName + // LinkageName + // File + // Line + // TyDesc + // IsStatic + // IsDefinition + Count = 11; + break; + case DW_TAG_lexical_block: // BlockDesc + // Tag + // Context + Count = 2; + break; + case DW_TAG_base_type: // BasicTypeDesc + // Tag + // Context + // Name + // File + // Line + // Size + // Align + // Offset + // if (Version > LLVMDebugVersion4) Flags + // Encoding + Count = 9; + + if (DD->getVersion() > LLVMDebugVersion4) + ++Count; + + break; + 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: // DerivedTypeDesc + // Tag + // Context + // Name + // File + // Line + // Size + // Align + // Offset + // if (Version > LLVMDebugVersion4) Flags + // FromType + Count = 9; + + if (DD->getVersion() > LLVMDebugVersion4) + ++Count; + + break; + 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: // CompositeTypeDesc + // Tag + // Context + // Name + // File + // Line + // Size + // Align + // Offset + // if (Version > LLVMDebugVersion4) Flags + // FromType + // Elements + Count = 10; + + if (DD->getVersion() > LLVMDebugVersion4) + ++Count; + + break; + case DW_TAG_subrange_type: // SubrangeDesc + // Tag + // Lo + // Hi + Count = 3; + break; + case DW_TAG_enumerator: // EnumeratorDesc + // Tag + // Name + // Value + Count = 3; + break; + case DW_TAG_return_variable: + case DW_TAG_arg_variable: + case DW_TAG_auto_variable: // VariableDesc + // Tag + // Context + // Name + // File + // Line + // TyDesc + Count = 6; + break; + default: + break; + } + + return Count; +} + +//===----------------------------------------------------------------------===// + /// 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 &Field) { - ++Count; - } -}; +namespace { //===----------------------------------------------------------------------===// /// DIDeserializeVisitor - This DIVisitor deserializes all the fields in the @@ -187,10 +320,7 @@ private: public: DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV) - : DIVisitor() - , DR(D) - , I(0) - , CI(cast(GV->getInitializer())) + : DIVisitor(), DR(D), I(0), CI(cast(GV->getInitializer())) {} /// Apply - Set the value of each of the fields. @@ -217,7 +347,9 @@ public: } virtual void Apply(std::string &Field) { Constant *C = CI->getOperand(I++); - Field = C->getStringValue(); + // Fills in the string if it succeeds + if (!GetConstantStringInfo(C, Field)) + Field.clear(); } virtual void Apply(DebugInfoDesc *&Field) { Constant *C = CI->getOperand(I++); @@ -281,7 +413,7 @@ public: Elements.push_back(ConstantInt::get(Type::Int1Ty, Field)); } virtual void Apply(std::string &Field) { - Elements.push_back(SR.getString(Field)); + Elements.push_back(SR.getString(Field)); } virtual void Apply(DebugInfoDesc *&Field) { GlobalVariable *GV = NULL; @@ -467,6 +599,7 @@ public: } }; +} //===----------------------------------------------------------------------===// @@ -658,7 +791,7 @@ const char *CompileUnitDesc::getTypeString() const { /// getAnchorString - Return a string used to label this descriptor's anchor. /// -const char *CompileUnitDesc::AnchorString = "llvm.dbg.compile_units"; +const char *const CompileUnitDesc::AnchorString = "llvm.dbg.compile_units"; const char *CompileUnitDesc::getAnchorString() const { return AnchorString; } @@ -1108,7 +1241,7 @@ const char *GlobalVariableDesc::getTypeString() const { /// getAnchorString - Return a string used to label this descriptor's anchor. /// -const char *GlobalVariableDesc::AnchorString = "llvm.dbg.global_variables"; +const char *const GlobalVariableDesc::AnchorString = "llvm.dbg.global_variables"; const char *GlobalVariableDesc::getAnchorString() const { return AnchorString; } @@ -1162,7 +1295,7 @@ const char *SubprogramDesc::getTypeString() const { /// getAnchorString - Return a string used to label this descriptor's anchor. /// -const char *SubprogramDesc::AnchorString = "llvm.dbg.subprograms"; +const char *const SubprogramDesc::AnchorString = "llvm.dbg.subprograms"; const char *SubprogramDesc::getAnchorString() const { return AnchorString; } @@ -1262,7 +1395,7 @@ const PointerType *DISerializer::getStrPtrType() { // If not already defined. if (!StrPtrTy) { // Construct the pointer to signed bytes. - StrPtrTy = PointerType::get(Type::Int8Ty); + StrPtrTy = PointerType::getUnqual(Type::Int8Ty); } return StrPtrTy; @@ -1272,14 +1405,13 @@ const PointerType *DISerializer::getStrPtrType() { /// 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::get(EmptyStructTy); - } - + if (EmptyStructPtrTy) return EmptyStructPtrTy; + + // Construct the pointer to empty structure type. + const StructType *EmptyStructTy = StructType::get(NULL, NULL); + + // Construct the pointer to empty structure type. + EmptyStructPtrTy = PointerType::getUnqual(EmptyStructTy); return EmptyStructPtrTy; } @@ -1312,22 +1444,27 @@ const StructType *DISerializer::getTagType(DebugInfoDesc *DD) { 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; } @@ -1357,13 +1494,19 @@ GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) { // 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; +} + //===----------------------------------------------------------------------===// /// Verify - Return true if the GlobalVariable appears to be a valid @@ -1423,12 +1566,10 @@ bool DIVerifier::Verify(GlobalVariable *GV) { // Get the field count. unsigned &CountSlot = Counts[Tag]; - if (!CountSlot) { + + if (!CountSlot) // Check the operand count to the field count - DICountVisitor CTAM; - CTAM.ApplyToFields(DD); - CountSlot = CTAM.getCount(); - } + CountSlot = CountFields(DD); // Field count must be at most equal operand count. if (CountSlot > N) { @@ -1453,6 +1594,14 @@ bool DIVerifier::Verify(GlobalVariable *GV) { return true; } +/// 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() { @@ -1463,7 +1612,7 @@ DebugScope::~DebugScope() { //===----------------------------------------------------------------------===// MachineModuleInfo::MachineModuleInfo() -: ImmutablePass((intptr_t)&ID) +: ImmutablePass(&ID) , DR() , VR() , CompileUnits() @@ -1536,28 +1685,32 @@ 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); -} -/// needsFrameInfo - Returns true if we need to gather callee-saved register -/// move info for the frame. -bool MachineModuleInfo::needsFrameInfo() const { - return hasDebugInfo() || ExceptionHandling; + // Insert functions in the llvm.used array into UsedFunctions. + GlobalVariable *GV = M.getGlobalVariable("llvm.used"); + if (!GV || !GV->hasInitializer()) return; + + // Should be an array of 'i8*'. + 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); + } } /// SetupCompileUnits - Set up the unique vector of compile units. /// void MachineModuleInfo::SetupCompileUnits(Module &M) { - std::vectorCU = getAnchoredDescriptors(M); + std::vector CU; + getAnchoredDescriptors(M, CU); for (unsigned i = 0, N = CU.size(); i < N; i++) { CompileUnits.insert(CU[i]); @@ -1572,17 +1725,18 @@ const UniqueVector MachineModuleInfo::getCompileUnits()const{ /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the /// named GlobalVariable. -std::vector +void MachineModuleInfo::getGlobalVariablesUsing(Module &M, - const std::string &RootName) { - return ::getGlobalVariablesUsing(M, RootName); + const std::string &RootName, + std::vector&Result){ + return ::getGlobalVariablesUsing(M, RootName, Result); } -/// RecordLabel - Records location information and associates it with a +/// 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::RecordLabel(unsigned Line, unsigned Column, - unsigned Source) { +unsigned MachineModuleInfo::RecordSourceLine(unsigned Line, unsigned Column, + unsigned Source) { unsigned ID = NextLabelID(); Lines.push_back(SourceLineInfo(Line, Column, Source, ID)); return ID; @@ -1624,8 +1778,8 @@ unsigned MachineModuleInfo::RecordRegionEnd(Value *V) { /// RecordVariable - Indicate the declaration of a local variable. /// -void MachineModuleInfo::RecordVariable(Value *V, unsigned FrameIndex) { - VariableDesc *VD = cast(DR.Deserialize(V)); +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); @@ -1720,7 +1874,7 @@ void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad, void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad, std::vector &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)); @@ -1740,22 +1894,17 @@ void MachineModuleInfo::TidyLandingPads() { LandingPadInfo &LandingPad = LandingPads[i]; LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel); - if (!LandingPad.LandingPadBlock) - // Must not have cleanups if no landing pad. - LandingPad.TypeIds.clear(); - // Special case: we *should* emit LPs with null LP MBB. This indicates - // "rethrow" case. + // "nounwind" case. if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) { LandingPads.erase(LandingPads.begin() + i); 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); @@ -1766,7 +1915,19 @@ void MachineModuleInfo::TidyLandingPads() { LandingPad.EndLabels[j] = EndLabel; ++j; } - + + // Remove landing pads with no try-ranges. + if (LandingPads[i].BeginLabels.empty()) { + LandingPads.erase(LandingPads.begin() + i); + continue; + } + + // If there is no landing pad, ensure that the list of typeids is empty. + // If the only typeid is a cleanup, this is the same as having no typeids. + if (!LandingPad.LandingPadBlock || + (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0])) + LandingPad.TypeIds.clear(); + ++i; } } @@ -1850,7 +2011,13 @@ namespace llvm { struct DebugLabelFolder : public MachineFunctionPass { static char ID; - DebugLabelFolder() : MachineFunctionPass((intptr_t)&ID) {} + DebugLabelFolder() : MachineFunctionPass(&ID) {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + MachineFunctionPass::getAnalysisUsage(AU); + } virtual bool runOnMachineFunction(MachineFunction &MF); virtual const char *getPassName() const { return "Label Folder"; } @@ -1862,9 +2029,6 @@ bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) { // Get machine module info. MachineModuleInfo *MMI = getAnalysisToUpdate(); 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; @@ -1877,7 +2041,7 @@ bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) { // Iterate through instructions. for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { // Is it a label. - if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) { + if (I->isDebugLabel()) { // The label ID # is always operand #0, an immediate. unsigned NextLabel = I->getOperand(0).getImm();