Remove check for any program instances running before function calls.

Given the change in 0c20483853, this is no longer necessary, since
we know that one instance will always be running if we're executing a
given block of code.
This commit is contained in:
Matt Pharr
2011-09-13 06:26:16 -07:00
parent 0c20483853
commit 9ca7541d52

102
expr.cpp
View File

@@ -2222,55 +2222,6 @@ FunctionCallExpr::FunctionCallExpr(Expr *f, ExprList *a, SourcePos p, bool il)
}
/** Starting from the function initialFunction, we're calling into
calledFunc. The question is: is this a recursive call back to
initialFunc? If it definitely is or if it may be, then return true.
Return false if it definitely is not.
*/
static bool
lMayBeRecursiveCall(llvm::Function *calledFunc,
llvm::Function *initialFunc,
std::set<llvm::Function *> &seenFuncs) {
// Easy case: intrinsics aren't going to call functions themselves
if (calledFunc->isIntrinsic())
return false;
std::string name = calledFunc->getName();
if (name.size() > 2 && name[0] == '_' && name[1] == '_')
// builtin stdlib function; none of these are recursive...
return false;
if (calledFunc->isDeclaration())
// There's visibility into what the called function does without a
// definition, so we have to be conservative
return true;
if (calledFunc == initialFunc)
// hello recursive call
return true;
// Otherwise iterate over all of the instructions in the function. If
// any of them is a function call then check recursively..
llvm::inst_iterator iter;
for (iter = llvm::inst_begin(calledFunc);
iter != llvm::inst_end(calledFunc); ++iter) {
llvm::Instruction *inst = &*iter;
llvm::CallInst *ci = llvm::dyn_cast<llvm::CallInst>(inst);
if (ci != NULL) {
llvm::Function *nextCalledFunc = ci->getCalledFunction();
// Don't repeatedly test functions we've seen before
if (seenFuncs.find(nextCalledFunc) == seenFuncs.end()) {
seenFuncs.insert(nextCalledFunc);
if (lMayBeRecursiveCall(nextCalledFunc, initialFunc,
seenFuncs))
return true;
}
}
}
return false;
}
llvm::Value *
FunctionCallExpr::GetValue(FunctionEmitContext *ctx) const {
if (!func || !args)
@@ -2391,47 +2342,14 @@ FunctionCallExpr::GetValue(FunctionEmitContext *ctx) const {
}
}
// We sometimes need to check to see if the mask is all off here;
// specifically, if the mask is all off and we call a recursive
// function, then we will probably have an unsesirable infinite loop.
ctx->SetDebugPos(pos);
llvm::BasicBlock *bDoCall = ctx->CreateBasicBlock("funcall_mask_ok");
llvm::BasicBlock *bSkip = ctx->CreateBasicBlock("funcall_mask_off");
llvm::BasicBlock *bAfter = ctx->CreateBasicBlock("after_funcall");
llvm::Function *currentFunc = ctx->GetCurrentBasicBlock()->getParent();
// If we need to check the mask (it may be a recursive call, possibly
// transitively), or we're launching a task, which is expensive and
// thus probably always worth checking, then use the mask to choose
// whether to go to the bDoCallBlock or the bSkip block
std::set<llvm::Function *> seenFuncs;
seenFuncs.insert(currentFunc);
if (ft->isTask || lMayBeRecursiveCall(callee, currentFunc, seenFuncs)) {
Debug(pos, "Checking mask before function call \"%s\".", funSym->name.c_str());
ctx->BranchIfMaskAny(bDoCall, bSkip);
}
else
// If we don't need to check the mask, then always to the call;
// just jump to bDoCall
ctx->BranchInst(bDoCall);
// And the bSkip block just jumps immediately to bAfter. So why do we
// need it? So the phi node below can easily tell what paths are
// going into it
ctx->SetCurrentBasicBlock(bSkip);
ctx->BranchInst(bAfter);
// Emit the code to do the function call
ctx->SetCurrentBasicBlock(bDoCall);
llvm::Value *retVal = NULL;
ctx->SetDebugPos(pos);
if (ft->isTask)
ctx->LaunchInst(callee, argVals);
else {
// Most of the time, the mask is passed as the last argument. this
// isn't the case for things like SSE intrinsics and extern "C"
// functions from the application.
// isn't the case for things like intrinsics, builtins, and extern
// "C" functions from the application.
assert(callargs.size() + 1 == callee->arg_size() ||
callargs.size() == callee->arg_size());
@@ -2458,22 +2376,10 @@ FunctionCallExpr::GetValue(FunctionEmitContext *ctx) const {
}
}
// And jump out to the 'after funciton call' basic block
ctx->BranchInst(bAfter);
ctx->SetCurrentBasicBlock(bAfter);
if (isVoidFunc)
return NULL;
// The return value for the non-void case is either undefined or the
// function return value, depending on whether we actually ran the code
// path that called the function or not.
LLVM_TYPE_CONST llvm::Type *lrType = ft->GetReturnType()->LLVMType(g->ctx);
llvm::PHINode *ret = ctx->PhiNode(lrType, 2, "fun_ret");
assert(retVal != NULL);
ret->addIncoming(llvm::UndefValue::get(lrType), bSkip);
ret->addIncoming(retVal, bDoCall);
return ret;
else
return retVal;
}