mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-29 10:25:12 +00:00
Make adding nocapture a bit stronger. FreeInst is nocapture. Also,
functions that don't write can't leak a pointer except through the return value, so a void readonly function is implicitly nocapture. Test these, and add a test that verifies that f1 calling f2 with an otherwise dead pointer gets both of them marked nocapture. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61552 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -208,10 +208,20 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isa<FreeInst>(I)) {
|
||||
// Freeing a pointer does not cause it to escape.
|
||||
continue;
|
||||
}
|
||||
|
||||
CallSite CS = CallSite::get(I);
|
||||
if (CS.getInstruction()) {
|
||||
// Does not escape if only passed via 'nocapture' arguments. Note
|
||||
// that calling a function pointer does not in itself cause that
|
||||
// Does not escape if the callee is readonly and doesn't return a
|
||||
// copy through its own return value.
|
||||
if (CS.onlyReadsMemory() && I->getType() == Type::VoidTy)
|
||||
continue;
|
||||
|
||||
// Does not escape if passed via 'nocapture' arguments. Note that
|
||||
// calling a function pointer does not in itself cause that
|
||||
// function pointer to escape. This is a subtle point considering
|
||||
// that (for example) the callee might return its own address. It
|
||||
// is analogous to saying that loading a value from a pointer does
|
||||
@@ -264,6 +274,20 @@ bool FunctionAttrs::AddNoCaptureAttrs(const std::vector<CallGraphNode *> &SCC) {
|
||||
// External node - skip it;
|
||||
continue;
|
||||
|
||||
// If the function is readonly and doesn't return any value, we
|
||||
// know that the pointer value can't escape. Mark all of its pointer
|
||||
// arguments nocapture.
|
||||
if (F->onlyReadsMemory() && F->getReturnType() == Type::VoidTy) {
|
||||
for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end();
|
||||
A != E; ++A)
|
||||
if (isa<PointerType>(A->getType()) && !A->hasNoCaptureAttr()) {
|
||||
A->addAttr(Attribute::NoCapture);
|
||||
++NumNoCapture;
|
||||
Changed = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Definitions with weak linkage may be overridden at linktime with
|
||||
// something that writes memory, so treat them like declarations.
|
||||
if (F->isDeclaration() || F->mayBeOverridden())
|
||||
@@ -273,7 +297,7 @@ bool FunctionAttrs::AddNoCaptureAttrs(const std::vector<CallGraphNode *> &SCC) {
|
||||
if (isa<PointerType>(A->getType()) && !A->hasNoCaptureAttr() &&
|
||||
!isCaptured(*F, A)) {
|
||||
A->addAttr(Attribute::NoCapture);
|
||||
NumNoCapture++;
|
||||
++NumNoCapture;
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user