Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of
authorBill Wendling <isanbard@gmail.com>
Wed, 26 May 2010 20:39:00 +0000 (20:39 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 26 May 2010 20:39:00 +0000 (20:39 +0000)
usual suspects that could "return twice".

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

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 3f3d4c9eaf14f2efb26c031a6ba062d3e28b11d6..d952bc0377fc1a33e3a4a23206425b50ae0d3c88 100644 (file)
@@ -193,31 +193,34 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
 }
 
 /// FunctionCallsSetJmp - Return true if the function has a call to setjmp or
-/// sigsetjmp. This is used to limit code-gen optimizations on the machine
-/// function.
+/// other function that gcc recognizes as "returning twice". This is used to
+/// limit code-gen optimizations on the machine function.
 static bool FunctionCallsSetJmp(const Function *F) {
   const Module *M = F->getParent();
-  const Function *SetJmp = M->getFunction("setjmp");
-  const Function *SigSetJmp = M->getFunction("sigsetjmp");
-
-  if (!SetJmp && !SigSetJmp)
-    return false;
-
-  if (SetJmp && !SetJmp->use_empty())
-    for (Value::const_use_iterator
-           I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I)
-      if (const CallInst *CI = dyn_cast<CallInst>(I))
-        if (CI->getParent()->getParent() == F)
-          return true;
-
-  if (SigSetJmp && !SigSetJmp->use_empty())
-    for (Value::const_use_iterator
-           I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I)
-      if (const CallInst *CI = dyn_cast<CallInst>(I))
-        if (CI->getParent()->getParent() == F)
-          return true;
+  static const char *ReturnsTwiceFns[] = {
+    "setjmp",
+    "sigsetjmp",
+    "setjmp_syscall",
+    "savectx",
+    "qsetjmp",
+    "vfork",
+    "getcontext"
+  };
+#define NUM_RETURNS_TWICE_FNS sizeof(ReturnsTwiceFns) / sizeof(const char *)
+
+  for (unsigned I = 0; I < NUM_RETURNS_TWICE_FNS; ++I)
+    if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) {
+      if (!Callee->use_empty())
+        for (Value::const_use_iterator
+               I = Callee->use_begin(), E = Callee->use_end();
+             I != E; ++I)
+          if (const CallInst *CI = dyn_cast<CallInst>(I))
+            if (CI->getParent()->getParent() == F)
+              return true;
+    }
 
   return false;
+#undef NUM_RETURNS_TWICE_FNS
 }
 
 bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {