aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-05-26 20:39:00 +0000
committerBill Wendling <isanbard@gmail.com>2010-05-26 20:39:00 +0000
commit983da3c173bb3d1cf51d93f5d6b821dbfd838425 (patch)
tree7004367bdac40f749a57e332b852ad98bff322a5
parent2e0ec26ae45a6c00f6cc726ba4d42201b1c4b20e (diff)
downloadexternal_llvm-983da3c173bb3d1cf51d93f5d6b821dbfd838425.zip
external_llvm-983da3c173bb3d1cf51d93f5d6b821dbfd838425.tar.gz
external_llvm-983da3c173bb3d1cf51d93f5d6b821dbfd838425.tar.bz2
Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of
usual suspects that could "return twice". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104737 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp45
1 files changed, 24 insertions, 21 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 3f3d4c9..d952bc0 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -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) {