From 73ef58ab92d5cd23b119b7f206e5f8a8c529098d Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Sat, 2 Jun 2007 16:53:42 +0000 Subject: [PATCH] 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 --- include/llvm/CodeGen/MachineModuleInfo.h | 36 ++++++--- lib/CodeGen/DwarfWriter.cpp | 74 ++++++------------- lib/CodeGen/MachineModuleInfo.cpp | 27 ++++++- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 7 +- 4 files changed, 72 insertions(+), 72 deletions(-) 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(); -- 2.34.1