diff options
author | Bill Wendling <isanbard@gmail.com> | 2010-05-26 20:39:00 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2010-05-26 20:39:00 +0000 |
commit | 8d717c7d999231c8c54601720b08cd3eecf6d518 (patch) | |
tree | 7004367bdac40f749a57e332b852ad98bff322a5 | |
parent | 83194de76a34e240927cf45c0debf12efe845c9b (diff) |
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.cpp | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 3f3d4c9eaf..d952bc0377 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) { |