From: Duncan Sands Date: Sat, 2 Jun 2007 16:53:42 +0000 (+0000) Subject: Integrate exception filter support and exception catch support. This X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=73ef58ab92d5cd23b119b7f206e5f8a8c529098d;p=oota-llvm.git Integrate exception filter support and exception catch support. This simplifies the code in DwarfWriter, allows for multiple filters and makes it trivial to specify filters accompanied by cleanups or catch-all specifications (see next patch). What a deal! Patch blessed by Anton. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37398 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index c13ba517529..790433e8b4e 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -960,16 +960,13 @@ struct LandingPadInfo { SmallVector EndLabels; // Labels after invoke. unsigned LandingPadLabel; // Label at beginning of landing pad. Function *Personality; // Personality function. - std::vector TypeIds; // List of type ids. - bool IsFilter; // Indicate if the landing pad is a - // throw filter. - + std::vector TypeIds; // List of type ids (filters negative) + LandingPadInfo(MachineBasicBlock *MBB) : LandingPadBlock(MBB) , LandingPadLabel(0) , Personality(NULL) , TypeIds() - , IsFilter(false) {} }; @@ -1021,6 +1018,10 @@ private: // std::vector TypeInfos; + // FilterIds - List of typeids encoding filters used in the current function. + // + std::vector FilterIds; + // Personalities - Vector of all personality functions ever seen. Used to emit // common EH frames. std::vector Personalities; @@ -1213,20 +1214,25 @@ public: const std::vector& getPersonalities() const { return Personalities; } - + /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// void addCatchTypeInfo(MachineBasicBlock *LandingPad, std::vector &TyInfo); - - /// setIsFilterLandingPad - Indicates that the landing pad is a throw filter. + + /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. /// - void setIsFilterLandingPad(MachineBasicBlock *LandingPad); - + void addFilterTypeInfo(MachineBasicBlock *LandingPad, + std::vector &TyInfo); + /// getTypeIDFor - Return the type id for the specified typeinfo. This is /// function wide. unsigned getTypeIDFor(GlobalVariable *TI); - + + /// getFilterIDFor - Return the id of the filter encoded by TyIds. This is + /// function wide. + int getFilterIDFor(std::vector &TyIds); + /// TidyLandingPads - Remap landing pad labels and remove any deleted landing /// pads. void TidyLandingPads(); @@ -1242,7 +1248,13 @@ public: const std::vector &getTypeInfos() const { return TypeInfos; } - + + /// getFilterIds - Return a reference to the typeids encoding filters used in + /// the current function. + const std::vector &getFilterIds() const { + return FilterIds; + } + /// getPersonality - Return a personality function if available. The presence /// of one is required to emit exception handling info. Function *getPersonality() const; diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp index 7e97788bc12..5ab399705a3 100644 --- a/lib/CodeGen/DwarfWriter.cpp +++ b/lib/CodeGen/DwarfWriter.cpp @@ -2896,13 +2896,10 @@ private: /// EquivPads - Whether two landing pads have equivalent actions. static bool EquivPads(const LandingPadInfo *L, const LandingPadInfo *R) { - const std::vector &LIds = L->TypeIds; - const std::vector &RIds = R->TypeIds; + const std::vector &LIds = L->TypeIds; + const std::vector &RIds = R->TypeIds; unsigned LSize = LIds.size(), RSize = RIds.size(); - if (L->IsFilter != R->IsFilter) - return false; - if (LSize != RSize) return false; @@ -2915,14 +2912,10 @@ private: /// PadLT - An order on landing pads, with EquivPads as order equivalence. static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { - const std::vector &LIds = L->TypeIds; - const std::vector &RIds = R->TypeIds; + const std::vector &LIds = L->TypeIds; + const std::vector &RIds = R->TypeIds; unsigned LSize = LIds.size(), RSize = RIds.size(); - if (L->IsFilter != R->IsFilter) - // Make filters come last - return L->IsFilter < R->IsFilter; - if (LSize != RSize) return LSize < RSize; @@ -2972,6 +2965,7 @@ private: MMI->TidyLandingPads(); const std::vector &TypeInfos = MMI->getTypeInfos(); + const std::vector &FilterIds = MMI->getFilterIds(); const std::vector &PadInfos = MMI->getLandingPads(); if (PadInfos.empty()) return; @@ -2985,11 +2979,6 @@ private: // Gather first action index for each landing pad site. SmallVector Actions; - // FIXME - Assume there is only one filter typeinfo list per function - // time being. I.E., Each call to eh_filter will have the same list. - // This can change if a function is inlined. - const LandingPadInfo *Filter = 0; - // Compute sizes for exception table. unsigned SizeSites = 0; unsigned SizeActions = 0; @@ -3003,24 +2992,15 @@ private: unsigned SizeSiteActions = 0; if (!i || !EquivPads(LandingPad, LandingPads[i-1])) { - const std::vector &TypeIds = LandingPad->TypeIds; + const std::vector &TypeIds = LandingPad->TypeIds; unsigned SizeAction = 0; - if (LandingPad->IsFilter) { - // FIXME - Assume there is only one filter typeinfo list per function - // time being. I.E., Each call to eh_filter will have the same list. - // This can change if a function is inlined. - Filter = LandingPad; - SizeAction = Asm->SizeSLEB128(-1) + Asm->SizeSLEB128(0); - SizeSiteActions += SizeAction; - // Record the first action of the landing pad site. - FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; - } else if (TypeIds.empty()) { + if (TypeIds.empty()) { FirstAction = 0; } else { // Gather the action sizes for (unsigned j = 0, M = TypeIds.size(); j != M; ++j) { - unsigned TypeID = TypeIds[j]; + int TypeID = TypeIds[j]; unsigned SizeTypeID = Asm->SizeSLEB128(TypeID); signed Action = j ? -(SizeAction + SizeTypeID) : 0; SizeAction = SizeTypeID + Asm->SizeSLEB128(Action); @@ -3140,25 +3120,18 @@ private: for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { if (!i || Actions[i] != Actions[i-1]) { const LandingPadInfo *LandingPad = LandingPads[i]; - const std::vector &TypeIds = LandingPad->TypeIds; + const std::vector &TypeIds = LandingPad->TypeIds; unsigned SizeAction = 0; - if (LandingPad->IsFilter) { - Asm->EmitSLEB128Bytes(-1); + for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) { + int TypeID = TypeIds[j]; + unsigned SizeTypeID = Asm->SizeSLEB128(TypeID); + Asm->EmitSLEB128Bytes(TypeID); Asm->EOL("TypeInfo index"); - Asm->EmitSLEB128Bytes(0); + signed Action = j ? -(SizeAction + SizeTypeID) : 0; + SizeAction = SizeTypeID + Asm->SizeSLEB128(Action); + Asm->EmitSLEB128Bytes(Action); Asm->EOL("Next action"); - } else { - for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) { - unsigned TypeID = TypeIds[j]; - unsigned SizeTypeID = Asm->SizeSLEB128(TypeID); - Asm->EmitSLEB128Bytes(TypeID); - Asm->EOL("TypeInfo index"); - signed Action = j ? -(SizeAction + SizeTypeID) : 0; - SizeAction = SizeTypeID + Asm->SizeSLEB128(Action); - Asm->EmitSLEB128Bytes(Action); - Asm->EOL("Next action"); - } } } } @@ -3180,16 +3153,11 @@ private: Asm->EOL("TypeInfo"); } - // Emit the filter typeinfo. - if (Filter) { - const std::vector &TypeIds = Filter->TypeIds; - for (unsigned j = 0, M = TypeIds.size(); j < M; ++j) { - unsigned TypeID = TypeIds[j]; - Asm->EmitSLEB128Bytes(TypeID); - Asm->EOL("TypeInfo index"); - } - Asm->EmitSLEB128Bytes(0); - Asm->EOL("End of filter typeinfo"); + // Emit the filter typeids. + for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) { + unsigned TypeID = FilterIds[j]; + Asm->EmitSLEB128Bytes(TypeID); + Asm->EOL("Filter TypeInfo index"); } Asm->EmitAlignment(2); diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 564c070bc34..32d8394527a 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -1521,6 +1521,7 @@ void MachineModuleInfo::EndFunction() { // Clean up exception info. LandingPads.clear(); TypeInfos.clear(); + FilterIds.clear(); } /// getDescFor - Convert a Value to a debug information descriptor. @@ -1708,12 +1709,16 @@ 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::setIsFilterLandingPad(MachineBasicBlock *LandingPad) { +void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad, + std::vector &TyInfo) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); - LP.IsFilter = true; + 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)); } /// TidyLandingPads - Remap landing pad labels and remove any deleted landing @@ -1760,6 +1765,20 @@ unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) { return TypeInfos.size(); } +/// getFilterIDFor - Return the filter id for the specified typeinfos. This is +/// function wide. +int MachineModuleInfo::getFilterIDFor(std::vector &TyIds) { + // TODO: map duplicate filters to the same filter id; a filter equal to the + // tail of an existing filter also need not be added; re-order filters and + // filter elements to maximize this kind of sharing. + 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]); + 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 diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index cfdf6d0ea57..6b6834bffc9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2611,8 +2611,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { isa(CE->getOperand(0)) && "Personality should be a function"); MMI->addPersonality(CurMBB, cast(CE->getOperand(0))); - if (Intrinsic == Intrinsic::eh_filter) - MMI->setIsFilterLandingPad(CurMBB); // Gather all the type infos for this landing pad and pass them along to // MachineModuleInfo. @@ -2624,7 +2622,10 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { "TypeInfo must be a global variable or NULL"); TyInfo.push_back(GV); } - MMI->addCatchTypeInfo(CurMBB, TyInfo); + if (Intrinsic == Intrinsic::eh_filter) + MMI->addFilterTypeInfo(CurMBB, TyInfo); + else + MMI->addCatchTypeInfo(CurMBB, TyInfo); // Mark exception selector register as live in. unsigned Reg = TLI.getExceptionSelectorRegister();