[llvm-commits] [llvm] r45197 - in /llvm/trunk/lib/CodeGen: DwarfWriter.cpp MachineModuleInfo.cpp SelectionDAG/SelectionDAGISel.cpp

Duncan Sands baldrick at free.fr
Tue Dec 18 23:36:31 PST 2007


Author: baldrick
Date: Wed Dec 19 01:36:31 2007
New Revision: 45197

URL: http://llvm.org/viewvc/llvm-project?rev=45197&view=rev
Log:
The C++ exception handling personality function wants
to know about calls that cannot throw ('nounwind'):
if such a call does throw for some reason then the
personality will terminate the program.  The distinction
between an ordinary call and a nounwind call is that
an ordinary call gets an entry in the exception table
but a nounwind call does not.  This patch sets up the
exception table appropriately.  One oddity is that
I've chosen to bracket nounwind calls with labels (like
invokes) - the other choice would have been to bracket
ordinary calls with labels.  While bracketing
ordinary calls is more natural (because bracketing
by labels would then correspond exactly to getting an
entry in the exception table), I didn't do it because
introducing labels impedes some optimizations and I'm
guessing that ordinary calls occur more often than
nounwind calls.  This fixes the gcc filter2 eh test,
at least at -O0 (the inliner needs some tweaking at
higher optimization levels).

Modified:
    llvm/trunk/lib/CodeGen/DwarfWriter.cpp
    llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=45197&r1=45196&r2=45197&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Wed Dec 19 01:36:31 2007
@@ -3013,8 +3013,10 @@
 
   /// CallSiteEntry - Structure describing an entry in the call-site table.
   struct CallSiteEntry {
+    // The 'try-range' is BeginLabel .. EndLabel.
     unsigned BeginLabel; // zero indicates the start of the function.
     unsigned EndLabel;   // zero indicates the end of the function.
+    // The landing pad starts at PadLabel.
     unsigned PadLabel;   // zero indicates that there is no landing pad.
     unsigned Action;
   };
@@ -3113,13 +3115,21 @@
       SizeActions += SizeSiteActions;
     }
 
-    // Compute the call-site table.  Entries must be ordered by address.
+    // Compute the call-site table.  The entry for an invoke has a try-range
+    // containing the call, a non-zero landing pad and an appropriate action.
+    // The entry for an ordinary call has a try-range containing the call and
+    // zero for the landing pad and the action.  Calls marked 'nounwind' have
+    // no entry and must not be contained in the try-range of any entry - they
+    // form gaps in the table.  Entries must be ordered by try-range address.
     SmallVector<CallSiteEntry, 64> CallSites;
 
     RangeMapType PadMap;
+    // Invokes and nounwind calls have entries in PadMap (due to being bracketed
+    // by try-range labels when lowered).  Ordinary calls do not, so appropriate
+    // try-ranges for them need be deduced.
     for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
       const LandingPadInfo *LandingPad = LandingPads[i];
-      for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
+      for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
         unsigned BeginLabel = LandingPad->BeginLabels[j];
         assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
         PadRange P = { i, j };
@@ -3127,27 +3137,39 @@
       }
     }
 
-    bool MayThrow = false;
+    // The end label of the previous invoke or nounwind try-range.
     unsigned LastLabel = 0;
+
+    // Whether there is a potentially throwing instruction (currently this means
+    // an ordinary call) between the end of the previous try-range and now.
+    bool SawPotentiallyThrowing = false;
+
+    // Whether the last callsite entry was for an invoke.
+    bool PreviousIsInvoke = false;
+
     const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+
+    // Visit all instructions in order of address.
     for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
          I != E; ++I) {
       for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
            MI != E; ++MI) {
         if (MI->getOpcode() != TargetInstrInfo::LABEL) {
-          MayThrow |= TII->isCall(MI->getOpcode());
+          SawPotentiallyThrowing |= TII->isCall(MI->getOpcode());
           continue;
         }
 
         unsigned BeginLabel = MI->getOperand(0).getImmedValue();
         assert(BeginLabel && "Invalid label!");
 
+        // End of the previous try-range?
         if (BeginLabel == LastLabel)
-          MayThrow = false;
+          SawPotentiallyThrowing = false;
 
+        // Beginning of a new try-range?
         RangeMapType::iterator L = PadMap.find(BeginLabel);
-
         if (L == PadMap.end())
+          // Nope, it was just some random label.
           continue;
 
         PadRange P = L->second;
@@ -3159,36 +3181,43 @@
         // If some instruction between the previous try-range and this one may
         // throw, create a call-site entry with no landing pad for the region
         // between the try-ranges.
-        if (MayThrow) {
+        if (SawPotentiallyThrowing) {
           CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
           CallSites.push_back(Site);
+          PreviousIsInvoke = false;
         }
 
         LastLabel = LandingPad->EndLabels[P.RangeIndex];
-        CallSiteEntry Site = {BeginLabel, LastLabel,
-          LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
+        assert(BeginLabel && LastLabel && "Invalid landing pad!");
 
-        assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
-               "Invalid landing pad!");
-
-        // Try to merge with the previous call-site.
-        if (CallSites.size()) {
-          CallSiteEntry &Prev = CallSites[CallSites.size()-1];
-          if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
-            // Extend the range of the previous entry.
-            Prev.EndLabel = Site.EndLabel;
-            continue;
+        if (LandingPad->LandingPadLabel) {
+          // This try-range is for an invoke.
+          CallSiteEntry Site = {BeginLabel, LastLabel,
+            LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
+
+          // Try to merge with the previous call-site.
+          if (PreviousIsInvoke) {
+            CallSiteEntry &Prev = CallSites[CallSites.size()-1];
+            if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
+              // Extend the range of the previous entry.
+              Prev.EndLabel = Site.EndLabel;
+              continue;
+            }
           }
-        }
 
-        // Otherwise, create a new call-site.
-        CallSites.push_back(Site);
+          // Otherwise, create a new call-site.
+          CallSites.push_back(Site);
+          PreviousIsInvoke = true;
+        } else {
+          // Create a gap.
+          PreviousIsInvoke = false;
+        }
       }
     }
     // If some instruction between the previous try-range and the end of the
     // function may throw, create a call-site entry with no landing pad for the
     // region following the try-range.
-    if (MayThrow) {
+    if (SawPotentiallyThrowing) {
       CallSiteEntry Site = {LastLabel, 0, 0, 0};
       CallSites.push_back(Site);
     }

Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=45197&r1=45196&r2=45197&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Wed Dec 19 01:36:31 2007
@@ -1747,7 +1747,7 @@
     LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
 
     // Special case: we *should* emit LPs with null LP MBB. This indicates
-    // "rethrow" case.
+    // "nounwind" case.
     if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
       LandingPads.erase(LandingPads.begin() + i);
       continue;
@@ -1757,7 +1757,6 @@
       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);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=45197&r1=45196&r2=45197&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Dec 19 01:36:31 2007
@@ -2952,7 +2952,11 @@
     Args.push_back(Entry);
   }
 
-  if (ExceptionHandling && MMI && LandingPad) {
+  bool MarkTryRange = LandingPad ||
+    // C++ requires special handling of 'nounwind' calls.
+    (Attrs && Attrs->paramHasAttr(0, ParamAttr::NoUnwind));
+
+  if (MarkTryRange && ExceptionHandling && MMI) {
     // Insert a label before the invoke call to mark the try range.  This can be
     // used to detect deletion of the invoke via the MachineModuleInfo.
     BeginLabel = MMI->NextLabelID();
@@ -2969,7 +2973,7 @@
     setValue(&I, Result.first);
   DAG.setRoot(Result.second);
 
-  if (ExceptionHandling && MMI && LandingPad) {
+  if (MarkTryRange && ExceptionHandling && MMI) {
     // Insert a label at the end of the invoke call to mark the try range.  This
     // can be used to detect deletion of the invoke via the MachineModuleInfo.
     EndLabel = MMI->NextLabelID();





More information about the llvm-commits mailing list