From d480d308b0d3e9d5b7657de69cd3ac24d2acd4cf Mon Sep 17 00:00:00 2001
From: David Majnemer <david.majnemer@gmail.com>
Date: Fri, 10 Apr 2015 04:56:17 +0000
Subject: [PATCH] [WinEHPrepare] Don't rely on the order of IR

The IPToState table must be emitted after we have generated labels for
all functions in the table.  Don't rely on the order of the list of
globals.  Instead, utilize WinEHFuncInfo to tell us how many catch
handlers we expect to outline.  Once we know we've visited all the catch
handlers, emit the cppxdata.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234566 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/llvm/CodeGen/WinEHFuncInfo.h              |  6 +++++-
 lib/CodeGen/AsmPrinter/Win64Exception.cpp         |  6 +++++-
 lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 14 +++++++++-----
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h
index 9b826754015..5fc2b126db8 100644
--- a/include/llvm/CodeGen/WinEHFuncInfo.h
+++ b/include/llvm/CodeGen/WinEHFuncInfo.h
@@ -142,7 +142,11 @@ struct WinEHFuncInfo {
   int UnwindHelpFrameIdx;
   int UnwindHelpFrameOffset;
 
-  WinEHFuncInfo() : UnwindHelpFrameIdx(INT_MAX), UnwindHelpFrameOffset(-1) {}
+  unsigned NumIPToStateFuncsVisited;
+
+  WinEHFuncInfo()
+      : UnwindHelpFrameIdx(INT_MAX), UnwindHelpFrameOffset(-1),
+        NumIPToStateFuncsVisited(0) {}
 };
 
 }
diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
index a685d2e23d5..39f7875cb3f 100644
--- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp
+++ b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
@@ -343,7 +343,11 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) {
     }
   }
 
-  if (ParentF != F)
+  // Defer emission until we've visited the parent function and all the catch
+  // handlers.
+  if (ParentF == F || FuncInfo.CatchHandlerMaxState.count(F))
+    ++FuncInfo.NumIPToStateFuncsVisited;
+  if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
     return;
 
   MCSymbol *UnwindMapXData = nullptr;
diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index 8eac8eb4f1b..65a67265d79 100644
--- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -275,11 +275,15 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
       MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
 
   // Calculate EH numbers for WinEH.
-  if (fn.getFnAttribute("wineh-parent").getValueAsString() == fn.getName()) {
-    WinEHNumbering Num(MMI.getWinEHFuncInfo(&fn));
-    Num.calculateStateNumbers(fn);
-    // Pop everything on the handler stack.
-    Num.processCallSite(None, ImmutableCallSite());
+  if (fn.hasFnAttribute("wineh-parent")) {
+    const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
+    WinEHFuncInfo &FI = MMI.getWinEHFuncInfo(WinEHParentFn);
+    if (FI.LandingPadStateMap.empty()) {
+      WinEHNumbering Num(FI);
+      Num.calculateStateNumbers(*WinEHParentFn);
+      // Pop everything on the handler stack.
+      Num.processCallSite(None, ImmutableCallSite());
+    }
   }
 }
 
-- 
2.34.1