From 983da3c173bb3d1cf51d93f5d6b821dbfd838425 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 26 May 2010 20:39:00 +0000 Subject: 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 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 45 ++++++++++++++------------- 1 file 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(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) { -- cgit v1.1