Integrate exception filter support and exception catch support. This
authorDuncan Sands <baldrick@free.fr>
Sat, 2 Jun 2007 16:53:42 +0000 (16:53 +0000)
committerDuncan Sands <baldrick@free.fr>
Sat, 2 Jun 2007 16:53:42 +0000 (16:53 +0000)
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
lib/CodeGen/DwarfWriter.cpp
lib/CodeGen/MachineModuleInfo.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index c13ba517529ca5f39f11474c822828e6bf62364c..790433e8b4e3f34865218d2cfe885f9aa173312f 100644 (file)
@@ -960,16 +960,13 @@ struct LandingPadInfo {
   SmallVector<unsigned, 1> EndLabels;   // Labels after invoke.
   unsigned LandingPadLabel;             // Label at beginning of landing pad.
   Function *Personality;                // Personality function.
-  std::vector<unsigned> TypeIds;        // List of type ids.
-  bool IsFilter;                        // Indicate if the landing pad is a
-                                        // throw filter.
-  
+  std::vector<int> 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<GlobalVariable *> TypeInfos;
 
+  // FilterIds - List of typeids encoding filters used in the current function.
+  //
+  std::vector<unsigned> FilterIds;
+
   // Personalities - Vector of all personality functions ever seen. Used to emit
   // common EH frames.
   std::vector<Function *> Personalities;
@@ -1213,20 +1214,25 @@ public:
   const std::vector<Function *>& getPersonalities() const {
     return Personalities;
   }
-    
+
   /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
   ///
   void addCatchTypeInfo(MachineBasicBlock *LandingPad,
                         std::vector<GlobalVariable *> &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<GlobalVariable *> &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<unsigned> &TyIds);
+
   /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
   /// pads.
   void TidyLandingPads();
@@ -1242,7 +1248,13 @@ public:
   const std::vector<GlobalVariable *> &getTypeInfos() const {
     return TypeInfos;
   }
-  
+
+  /// getFilterIds - Return a reference to the typeids encoding filters used in
+  /// the current function.
+  const std::vector<unsigned> &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;
index 7e97788bc12e2147f77402893f8a807e2735e32f..5ab399705a3c335116e241c5eeccc42b36c13920 100644 (file)
@@ -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<unsigned> &LIds = L->TypeIds;
-    const std::vector<unsigned> &RIds = R->TypeIds;
+    const std::vector<int> &LIds = L->TypeIds;
+    const std::vector<int> &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<unsigned> &LIds = L->TypeIds;
-    const std::vector<unsigned> &RIds = R->TypeIds;
+    const std::vector<int> &LIds = L->TypeIds;
+    const std::vector<int> &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<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
+    const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
     const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
     if (PadInfos.empty()) return;
 
@@ -2985,11 +2979,6 @@ private:
     // Gather first action index for each landing pad site.
     SmallVector<unsigned, 32> 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<unsigned> &TypeIds = LandingPad->TypeIds;
+        const std::vector<int> &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<unsigned> &TypeIds = LandingPad->TypeIds;
+        const std::vector<int> &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<unsigned> &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);
index 564c070bc34cd4d11bf45f256b7ef55d083a6940..32d8394527a1ae7d3447e03181108ee0c1248d7f 100644 (file)
@@ -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<GlobalVariable *> &TyInfo) {
   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
-  LP.IsFilter = true;
+  std::vector<unsigned> 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<unsigned> &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
index cfdf6d0ea571bd9ecc602ae72fb5f5a6268d816a..6b6834bffc9f42e00a1bf98d7299f4546388fd09 100644 (file)
@@ -2611,8 +2611,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
              isa<Function>(CE->getOperand(0)) &&
              "Personality should be a function");
       MMI->addPersonality(CurMBB, cast<Function>(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();