Emit multiple common EH frames for multiple (including blank) personality
authorAnton Korobeynikov <asl@math.spbu.ru>
Sun, 13 May 2007 15:42:26 +0000 (15:42 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sun, 13 May 2007 15:42:26 +0000 (15:42 +0000)
functions. This partly fixes PR1414: now we're restricted only to one
personality function per eh frame, not per module. Further work on
"multiple personalities" topic needs representative example.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37018 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineModuleInfo.h
lib/CodeGen/DwarfWriter.cpp
lib/CodeGen/MachineModuleInfo.cpp

index 3c04c8c4898ea44a92c8b297c11beda9e7cd8864..4e7ce5b8f125f74139357b6a5d3c5331c066cf2e 100644 (file)
@@ -1020,7 +1020,9 @@ private:
   //
   std::vector<GlobalVariable *> TypeInfos;
 
-  Function *Personality;
+  // Personalities - Vector of all personality functions ever seen. Used to emit
+  // common EH frames.
+  std::vector<Function *> Personalities;
 public:
   static char ID; // Pass identification, replacement for typeid
 
@@ -1201,7 +1203,16 @@ public:
   /// addPersonality - Provide the personality function for the exception
   /// information.
   void addPersonality(MachineBasicBlock *LandingPad, Function *Personality);
-  
+
+  /// getPersonalityIndex - Get index of the current personality function inside
+  /// Personalitites array
+  unsigned getPersonalityIndex() const;
+
+  /// getPersonalities - Return array of personality functions ever seen.
+  const std::vector<Function *>& getPersonalities() const {
+    return Personalities;
+  }
+    
   /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
   ///
   void addCatchTypeInfo(MachineBasicBlock *LandingPad,
@@ -1219,7 +1230,7 @@ public:
   /// pads.
   void TidyLandingPads();
                         
-  /// getLandingPadInfos - Return a reference to the landing pad info for the
+  /// getLandingPads - Return a reference to the landing pad info for the
   /// current function.
   const std::vector<LandingPadInfo> &getLandingPads() const {
     return LandingPads;
index 9defab9da3104713dc3379f8368f014ed2674fb4..6214e1b3b835f408e2cf0180a4b77fee5e73f471 100644 (file)
@@ -2720,13 +2720,16 @@ private:
   struct FunctionEHFrameInfo {
     std::string FnName;
     unsigned Number;
+    unsigned PersonalityIndex;
     bool hasCalls;
     bool hasLandingPads;
     std::vector<MachineMove> Moves;
 
-    FunctionEHFrameInfo(const std::string &FN, unsigned Num, bool hC, bool hL,
+    FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P,
+                        bool hC, bool hL,
                         const std::vector<MachineMove> &M):
-      FnName(FN), Number(Num), hasCalls(hC), hasLandingPads(hL), Moves(M) { };
+      FnName(FN), Number(Num), PersonalityIndex(P),
+      hasCalls(hC), hasLandingPads(hL), Moves(M) { };
   };
 
   std::vector<FunctionEHFrameInfo> EHFrames;
@@ -2737,11 +2740,7 @@ private:
   
   /// EmitCommonEHFrame - Emit the common eh unwind frame.
   ///
-  void EmitCommonEHFrame() {
-    // If there is a personality present then we need to indicate that
-    // in the common eh frame.
-    Function *Personality = MMI->getPersonality();
-
+  void EmitCommonEHFrame(const Function *Personality, unsigned Index) {
     // Size and sign of stack growth.
     int stackGrowth =
         Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
@@ -2750,19 +2749,19 @@ private:
 
     // Begin eh frame section.
     Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
-    O << "EH_frame:\n";
-    EmitLabel("section_eh_frame", 0);
+    O << "EH_frame" << Index << ":\n";
+    EmitLabel("section_eh_frame", Index);
 
     // Define base labels.
-    EmitLabel("eh_frame_common", 0);
+    EmitLabel("eh_frame_common", Index);
     
     // Define the eh frame length.
-    EmitDifference("eh_frame_common_end", 0,
-                   "eh_frame_common_begin", 0, true);
+    EmitDifference("eh_frame_common_end", Index,
+                   "eh_frame_common_begin", Index, true);
     Asm->EOL("Length of Common Information Entry");
 
     // EH frame header.
-    EmitLabel("eh_frame_common_begin", 0);
+    EmitLabel("eh_frame_common_begin", Index);
     Asm->EmitInt32((int)0);
     Asm->EOL("CIE Identifier Tag");
     Asm->EmitInt8(DW_CIE_VERSION);
@@ -2810,7 +2809,7 @@ private:
     EmitFrameMoves(NULL, 0, Moves);
 
     Asm->EmitAlignment(2);
-    EmitLabel("eh_frame_common_end", 0);
+    EmitLabel("eh_frame_common_end", Index);
     
     Asm->EOL();
   }
@@ -2818,10 +2817,6 @@ private:
   /// EmitEHFrame - Emit function exception frame information.
   ///
   void EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) {
-    // If there is a personality present then we need to indicate that
-    // in the common eh frame.
-    Function *Personality = MMI->getPersonality();
-
     Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
 
     // Externally visible entry into the functions eh frame info.
@@ -2842,7 +2837,8 @@ private:
       EmitLabel("eh_frame_begin", EHFrameInfo.Number);
 
       EmitSectionOffset("eh_frame_begin", "section_eh_frame",
-                        EHFrameInfo.Number, 0, true, true);
+                        EHFrameInfo.Number, EHFrameInfo.PersonalityIndex,
+                        true, true);
       Asm->EOL("FDE CIE offset");
 
       EmitReference("eh_func_begin", EHFrameInfo.Number, true);
@@ -2853,7 +2849,7 @@ private:
       
       // If there is a personality and landing pads then point to the language
       // specific data area in the exception table.
-      if (Personality) {
+      if (EHFrameInfo.PersonalityIndex) {
         Asm->EmitULEB128Bytes(4);
         Asm->EOL("Augmentation size");
         
@@ -3117,8 +3113,11 @@ public:
   /// content.
   void EndModule() {
     if (!shouldEmit) return;
+
+    const std::vector<Function *> Personalities = MMI->getPersonalities();
+    for (unsigned i =0; i < Personalities.size(); ++i)
+      EmitCommonEHFrame(Personalities[i], i);
     
-    EmitCommonEHFrame();
     for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(),
            E = EHFrames.end(); I != E; ++I)
       EmitEHFrame(*I);
@@ -3149,6 +3148,7 @@ public:
     // Save EH frame information
     EHFrames.push_back(FunctionEHFrameInfo(getAsm()->CurrentFnName,
                                            SubprogramCount,
+                                           MMI->getPersonalityIndex(),
                                            MF->getFrameInfo()->hasCalls(),
                                            !MMI->getLandingPads().empty(),
                                            MMI->getFrameMoves()));
index 22172811dc88997d3fa131982501fb0506b3fcf2..d4d132989ec73470a9767f7688265ee9759677e9 100644 (file)
@@ -1475,8 +1475,11 @@ MachineModuleInfo::MachineModuleInfo()
 , RootScope(NULL)
 , FrameMoves()
 , LandingPads()
-, Personality(NULL)
-{}
+, Personalities()
+{
+  // Always emit "no personality" info
+  Personalities.push_back(NULL);
+}
 MachineModuleInfo::~MachineModuleInfo() {
 
 }
@@ -1686,13 +1689,15 @@ unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
 /// addPersonality - Provide the personality function for the exception
 /// information.
 void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
-                                       Function *PersFn) {
+                                       Function *Personality) {
   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
-  LP.Personality = PersFn;
+  LP.Personality = Personality;
 
-  // FIXME: Until PR1414 will be fixed, we're using 1 personality function per
-  // module
-  Personality = PersFn;
+  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.
@@ -1753,16 +1758,28 @@ unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
   return TypeInfos.size();
 }
 
-/// getLandingPadInfos - Return a reference to the landing pad info for the
-/// current function.
+/// 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
-  // module
-
-  //return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
-  return Personality;
+  // 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 = (!LandingPads.empty() ?
+                                 LandingPads[0].Personality : NULL);
+
+  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