From: Bill Wendling Date: Wed, 26 May 2010 20:39:00 +0000 (+0000) Subject: Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8d717c7d999231c8c54601720b08cd3eecf6d518;p=oota-llvm.git 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 --- diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 3f3d4c9eaf1..d952bc0377f 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(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(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(I)) + if (CI->getParent()->getParent() == F) + return true; + } return false; +#undef NUM_RETURNS_TWICE_FNS } bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {