Update of 94055 to track the IR level call site information via an intrinsic.
authorJim Grosbach <grosbach@apple.com>
Thu, 28 Jan 2010 01:45:32 +0000 (01:45 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 28 Jan 2010 01:45:32 +0000 (01:45 +0000)
This allows code gen and the exception table writer to cooperate to make sure
landing pads are associated with the correct invoke locations.

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

docs/ExceptionHandling.html
include/llvm/CodeGen/MachineModuleInfo.h
include/llvm/Intrinsics.td
lib/CodeGen/AsmPrinter/DwarfException.cpp
lib/CodeGen/MachineModuleInfo.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/SjLjEHPrepare.cpp

index 438edda6cd88dd40ef9579f7f318ba18ac59cbb3..9c7c615052a84aff36750414cf6ffaba84f69e70 100644 (file)
@@ -39,6 +39,7 @@
        <li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li>
        <li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li>
        <li><a href="#llvm_eh_sjlj_lsda"><tt>llvm.eh.sjlj.lsda</tt></a></li>
+       <li><a href="#llvm_eh_sjlj_callsite"><tt>llvm.eh.sjlj.callsite</tt></a></li>
   </ol></li>
   <li><a href="#asm">Asm Table Formats</a>
   <ol>
 
 </div>
 
+<!-- ======================================================================= -->
+<div class="doc_subsubsection">
+  <a name="llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>
+</div>
+
+<div class="doc_text">
+
+<pre>
+  void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32)
+</pre>
+
+<p>For SJLJ based exception handling, the <a href="#llvm_eh_sjlj_callsite">
+  <tt>llvm.eh.sjlj.callsite</tt></a> intrinsic identifies the callsite value
+  associated with the following invoke instruction. This is used to ensure
+  that landing pad entries in the LSDA are generated in the matching order.</p>
+
+</div>
+
 <!-- ======================================================================= -->
 <div class="doc_section">
   <a name="asm">Asm Table Formats</a>
index d2bd0f1a881aa72f81afe1121b44882f29338a08..556ba7f27efdfb6b013f3afc4e455791fab1d52b 100644 (file)
@@ -113,7 +113,14 @@ class MachineModuleInfo : public ImmutablePass {
   // LandingPads - List of LandingPadInfo describing the landing pad information
   // in the current function.
   std::vector<LandingPadInfo> LandingPads;
-  
+
+  // Map of invoke call site index values to associated begin EH_LABEL for
+  // the current function.
+  DenseMap<unsigned, unsigned> CallSiteMap;
+
+  // The current call site index being processed, if any. 0 if none.
+  unsigned CurCallSite;
+
   // TypeInfos - List of C++ TypeInfo used in the current function.
   //
   std::vector<GlobalVariable *> TypeInfos;
@@ -294,7 +301,26 @@ public:
   const std::vector<LandingPadInfo> &getLandingPads() const {
     return LandingPads;
   }
-  
+
+  /// setCallSiteBeginLabel - Map the begin label for a call site
+  void setCallSiteBeginLabel(unsigned BeginLabel, unsigned Site) {
+    CallSiteMap[BeginLabel] = Site;
+  }
+
+  /// getCallSiteBeginLabel - Get the call site number for a begin label
+  unsigned getCallSiteBeginLabel(unsigned BeginLabel) {
+    assert(CallSiteMap.count(BeginLabel) &&
+           "Missing call site number for EH_LABEL!");
+    return CallSiteMap[BeginLabel];
+  }
+
+  /// setCurrentCallSite - Set the call site currently being processed.
+  void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
+
+  /// getCurrentCallSite - Get the call site currently being processed, if any.
+  /// return zero if none.
+  unsigned getCurrentCallSite(void) { return CurCallSite; }
+
   /// getTypeInfos - Return a reference to the C++ typeinfo for the current
   /// function.
   const std::vector<GlobalVariable *> &getTypeInfos() const {
index 684f8724cf76344cbc405e4400ec61c503012bbb..3a0da9cabdae1f9303d45af02f07bcdfc99d4790 100644 (file)
@@ -309,6 +309,7 @@ let Properties = [IntrNoMem] in {
   def int_eh_sjlj_setjmp  : Intrinsic<[llvm_i32_ty],  [llvm_ptr_ty]>;
   def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty]>;
   def int_eh_sjlj_lsda    : Intrinsic<[llvm_ptr_ty]>;
+  def int_eh_sjlj_callsite: Intrinsic<[llvm_void_ty], [llvm_i32_ty]>;
 }
 
 //===---------------- Generic Variable Attribute Intrinsics----------------===//
index d119b3cbd3cb46da771cd1621922911fe532dacd..c762b70176799fd21c6b47d294585386db5557e4 100644 (file)
@@ -579,7 +579,16 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
         }
 
         // Otherwise, create a new call-site.
-        CallSites.push_back(Site);
+        if (MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
+          CallSites.push_back(Site);
+        else {
+          // SjLj EH must maintain the call sites in the order assigned
+          // to them by the SjLjPrepare pass.
+          unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel);
+          if (CallSites.size() < SiteNo)
+            CallSites.resize(SiteNo);
+          CallSites[SiteNo - 1] = Site;
+        }
         PreviousIsInvoke = true;
       } else {
         // Create a gap.
index ed5bb5e5410c3d583552974095ac79096791cbb1..dc26d9144ffae8cbccbdaed14594b0757b90fb70 100644 (file)
@@ -71,6 +71,7 @@ void MachineModuleInfo::EndFunction() {
 
   // Clean up exception info.
   LandingPads.clear();
+  CallSiteMap.clear();
   TypeInfos.clear();
   FilterIds.clear();
   FilterEnds.clear();
index 36059a5e85ba91913f124e2e66cd6b7f6b7e2108..23ebc7b17d61886cff0e2d25c432451f12389b2e 100644 (file)
@@ -4327,6 +4327,16 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
     return 0;
   }
+  case Intrinsic::eh_sjlj_callsite: {
+    MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+    ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1));
+    assert(CI && "Non-constant call site value in eh.sjlj.callsite!");
+    assert(MMI->getCurrentCallSite() == 0 && "Overlapping call sites!");
+
+    MMI->setCurrentCallSite(CI->getZExtValue());
+    return 0;
+  }
+
   case Intrinsic::convertff:
   case Intrinsic::convertfsi:
   case Intrinsic::convertfui:
@@ -4784,6 +4794,15 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
     // used to detect deletion of the invoke via the MachineModuleInfo.
     BeginLabel = MMI->NextLabelID();
 
+    // For SjLj, keep track of which landing pads go with which invokes
+    // so as to maintain the ordering of pads in the LSDA.
+    unsigned CallSiteIndex = MMI->getCurrentCallSite();
+    if (CallSiteIndex) {
+      MMI->setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
+      // Now that the call site is handled, stop tracking it.
+      MMI->setCurrentCallSite(0);
+    }
+
     // Both PendingLoads and PendingExports must be flushed here;
     // this call might not return.
     (void)getRoot();
index 95589331cf423d1c567b29fb3633b7ab42518b96..8d4d1b21dd8156deac3d5767f0007d29a4453f29 100644 (file)
@@ -51,6 +51,7 @@ namespace {
     Value *PersonalityFn;
     Constant *SelectorFn;
     Constant *ExceptionFn;
+    Constant *CallSiteFn;
 
     Value *CallSite;
   public:
@@ -116,6 +117,7 @@ bool SjLjEHPass::doInitialization(Module &M) {
   LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda);
   SelectorFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_selector);
   ExceptionFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_exception);
+  CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite);
   PersonalityFn = 0;
 
   return true;
@@ -143,15 +145,14 @@ void SjLjEHPass::markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
     }
   }
 
-  // Insert a store of the invoke num before the invoke and store zero into the
-  // location afterward.
+  // Insert a store of the invoke num before the invoke
   new StoreInst(CallSiteNoC, CallSite, true, II);  // volatile
+  CallInst::Create(CallSiteFn, CallSiteNoC, "", II);
 
   // Add a switch case to our unwind block.
   CatchSwitch->addCase(SwitchValC, II->getUnwindDest());
-  // We still want this to look like an invoke so we emit the LSDA properly
-  // FIXME: ??? Or will this cause strangeness with mis-matched IDs like
-  //  when it was in the front end?
+  // We still want this to look like an invoke so we emit the LSDA properly,
+  // so we don't transform the invoke into a call here.
 }
 
 /// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until