Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of

usual suspects that could "return twice".

llvm-svn: 104737
This commit is contained in:
Bill Wendling 2010-05-26 20:39:00 +00:00
parent b889fc987e
commit 27311269cb
1 changed files with 23 additions and 20 deletions

View File

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