X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineModuleInfo.cpp;h=6d285bde049ba7b5ac547fe87fcfba96899c447f;hb=63e3cd4e0f3731d6801ac24199652e4d7b4b3729;hp=d62eb962a3e3f091abd7b0a46569ecef9e379d1b;hpb=c718288f4939258a51ec5ae0c5be7b1a05eb6898;p=oota-llvm.git diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index d62eb962a3e..6d285bde049 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -2,8 +2,8 @@ // // 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. // //===----------------------------------------------------------------------===// @@ -30,7 +30,7 @@ using namespace llvm::dwarf; namespace { RegisterPass X("machinemoduleinfo", "Module Information"); } -const int MachineModuleInfo::ID = 0; +char MachineModuleInfo::ID = 0; //===----------------------------------------------------------------------===// @@ -104,6 +104,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 +123,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; @@ -1262,7 +1274,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; @@ -1277,7 +1289,7 @@ const PointerType *DISerializer::getEmptyStructPtrType() { const StructType *EmptyStructTy = StructType::get(std::vector()); // Construct the pointer to empty structure type. - EmptyStructPtrTy = PointerType::get(EmptyStructTy); + EmptyStructPtrTy = PointerType::getUnqual(EmptyStructTy); } return EmptyStructPtrTy; @@ -1323,7 +1335,7 @@ Constant *DISerializer::getString(const std::string &String) { // Otherwise create and return a new string global. GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true, GlobalVariable::InternalLinkage, - ConstStr, "str", M); + ConstStr, ".str", M); StrGV->setSection("llvm.metadata"); // Convert to generic string pointer. Slot = ConstantExpr::getBitCast(StrGV, getStrPtrType()); @@ -1364,6 +1376,12 @@ GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) { 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 @@ -1453,6 +1471,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() { @@ -1475,7 +1501,13 @@ MachineModuleInfo::MachineModuleInfo() , RootScope(NULL) , FrameMoves() , LandingPads() -{} +, Personalities() +, CallsEHReturn(0) +, CallsUnwindInit(0) +{ + // Always emit "no personality" info + Personalities.push_back(NULL); +} MachineModuleInfo::~MachineModuleInfo() { } @@ -1517,6 +1549,10 @@ void MachineModuleInfo::EndFunction() { // Clean up exception info. LandingPads.clear(); TypeInfos.clear(); + FilterIds.clear(); + FilterEnds.clear(); + CallsEHReturn = 0; + CallsUnwindInit = 0; } /// getDescFor - Convert a Value to a debug information descriptor. @@ -1526,16 +1562,25 @@ 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); + + // 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); + } } /// needsFrameInfo - Returns true if we need to gather callee-saved register @@ -1568,11 +1613,11 @@ MachineModuleInfo::getGlobalVariablesUsing(Module &M, return ::getGlobalVariablesUsing(M, RootName); } -/// 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; @@ -1614,8 +1659,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); @@ -1669,8 +1714,8 @@ LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad, unsigned BeginLabel, unsigned EndLabel) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); - if (!LP.BeginLabel) LP.BeginLabel = BeginLabel; - LP.EndLabel = EndLabel; + LP.BeginLabels.push_back(BeginLabel); + LP.EndLabels.push_back(EndLabel); } /// addLandingPad - Provide the label of a try LandingPad block. @@ -1688,6 +1733,12 @@ void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad, 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); } /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. @@ -1698,12 +1749,23 @@ void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad, for (unsigned N = TyInfo.size(); N; --N) LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1])); } - -/// setIsFilterLandingPad - Indicates that the landing pad is a throw filter. + +/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. +/// +void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad, + std::vector &TyInfo) { + LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); + 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)); +} + +/// addCleanup - Add a cleanup action for a landing pad. /// -void MachineModuleInfo::setIsFilterLandingPad(MachineBasicBlock *LandingPad) { +void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); - LP.IsFilter = true; + LP.TypeIds.push_back(0); } /// TidyLandingPads - Remap landing pad labels and remove any deleted landing @@ -1711,17 +1773,42 @@ void MachineModuleInfo::setIsFilterLandingPad(MachineBasicBlock *LandingPad) { void MachineModuleInfo::TidyLandingPads() { for (unsigned i = 0; i != LandingPads.size(); ) { LandingPadInfo &LandingPad = LandingPads[i]; - LandingPad.BeginLabel = MappedLabel(LandingPad.BeginLabel); - LandingPad.EndLabel = MappedLabel(LandingPad.EndLabel); LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel); - - if (!LandingPad.BeginLabel || - !LandingPad.EndLabel || - !LandingPad.LandingPadLabel) { + + // Special case: we *should* emit LPs with null LP MBB. This indicates + // "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); + continue; + } + + LandingPad.BeginLabels[j] = BeginLabel; + 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; } } @@ -1736,12 +1823,65 @@ unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) { return TypeInfos.size(); } -/// getLandingPadInfos - Return a reference to the landing pad info for the -/// current function. +/// getFilterIDFor - Return the filter id for the specified typeinfos. This is +/// function wide. +int MachineModuleInfo::getFilterIDFor(std::vector &TyIds) { + // If the new filter coincides with the tail of an existing filter, then + // re-use the existing filter. Folding filters more than this requires + // re-ordering filters and/or their elements - probably not worth it. + for (std::vector::iterator I = FilterEnds.begin(), + E = FilterEnds.end(); I != E; ++I) { + unsigned i = *I, j = TyIds.size(); + + while (i && j) + if (FilterIds[--i] != TyIds[--j]) + goto try_next; + + if (!j) + // The new filter coincides with range [i, end) of the existing filter. + return -(1 + i); + +try_next:; + } + + // Add the new filter. + int FilterID = -(1 + FilterIds.size()); + FilterIds.reserve(FilterIds.size() + TyIds.size() + 1); + for (unsigned I = 0, N = TyIds.size(); I != N; ++I) + FilterIds.push_back(TyIds[I]); + FilterEnds.push_back(FilterIds.size()); + FilterIds.push_back(0); // terminator + return FilterID; +} + +/// getPersonality - Return the personality function for the current function. 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. +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!"); + return 0; +} //===----------------------------------------------------------------------===// /// DebugLabelFolding pass - This pass prunes out redundant labels. This allows @@ -1751,22 +1891,19 @@ Function *MachineModuleInfo::getPersonality() const { namespace llvm { struct DebugLabelFolder : public MachineFunctionPass { - static const int ID; + static char ID; DebugLabelFolder() : MachineFunctionPass((intptr_t)&ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); virtual const char *getPassName() const { return "Label Folder"; } }; -const int DebugLabelFolder::ID = 0; +char DebugLabelFolder::ID = 0; 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; @@ -1779,7 +1916,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();