mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[func-sig-opts] If we already made a specialized version of a function, do not respecialize, just bail.
This patch ensures that if we already have a version of a function with an optimized function signature, we do not turn the original function into a thunk or change the original function to call the already created specialized version of it. The reason for doing this is: 1. It enables us to avoid the question of whether or not the callee and caller properly mesh. To do this safely, we would really need to analyze the specialized version of the function to make sure that it meshes. This could be fragile. 2. This situation should not occur often since we only run function signature specialization once in the pipeline and we do not specialize external functions (* see below) implying linking will not affect this optimization. * We do not specialize functions with external linkage since: 1. Linking in a function to the current module does not provide any more information about the internals or the signature of the function that was available in the original module. 2. For function signature optimization to work, we need to be able to optimize both the caller and the callee. External functions are not emitted into the final object file implying that any changes we make to the caller or callee will not be apparent in the final object file. So we will not get any optimization benefit and could potentially introduce miscompiles. Swift SVN r22609
This commit is contained in:
@@ -470,32 +470,21 @@ optimizeFunctionSignature(SILFunction *F,
|
||||
createNewName(*F, Arguments, NewFName);
|
||||
|
||||
// If we already have a specialized version of this function, do not
|
||||
// respecialize. Just rewrite the body of this function as the appropriate
|
||||
// thunk.
|
||||
// respecialize. For now just bail.
|
||||
//
|
||||
// TODO: Can we find out when we don't need to remake the thunk? Doing this
|
||||
// ensures that we do not need to identify if this function was converted into
|
||||
// a thunk or not. This is simpler yet wasteful. The thing is I don't expect
|
||||
// this to happen very often. If it becomes an issue, it should be
|
||||
// refactored. The thing I am worried about are false negatives due to the
|
||||
// compiler "shifting" or bugs where we remove the release from a thunk when
|
||||
// we process it a second time.
|
||||
SILFunction *NewF;
|
||||
if ((NewF = F->getModule().lookUpFunction(NewFName))) {
|
||||
// Otherwise, create the new function and transfer the current function over
|
||||
// to that function.
|
||||
convertFunctionToThunk(F, NewF, Arguments);
|
||||
} else {
|
||||
// Otherwise, move F over to NewF.
|
||||
NewF = moveFunctionBodyToNewFunctionWithName(F, NewFName, Arguments);
|
||||
}
|
||||
// TODO: Improve this. I do not expect this to occur often so I am fine for
|
||||
// now avoiding this issue. The main things I am worried about are assumptions
|
||||
// that we make about the callee and caller being violated. That said, this is
|
||||
// just a fear.
|
||||
if (F->getModule().lookUpFunction(NewFName))
|
||||
return false;
|
||||
|
||||
// Rewrite all apply insts calling F to call NewF. Update each call site as
|
||||
// appropriate given the form of function signature optimization performed.
|
||||
rewriteApplyInstToCallNewFunction(F, NewF, Arguments, CallSites);
|
||||
// Otherwise, move F over to NewF.
|
||||
SILFunction *NewF = moveFunctionBodyToNewFunctionWithName(F, NewFName,
|
||||
Arguments);
|
||||
|
||||
// Remove all Callee releases that we found and made redundent via owned to
|
||||
// guaranteed conversion.
|
||||
// And remove all Callee releases that we found and made redundent via owned
|
||||
// to guaranteed conversion.
|
||||
//
|
||||
// TODO: If more stuff needs to be placed here, refactor into its own method.
|
||||
for (auto &A : Arguments) {
|
||||
@@ -504,6 +493,10 @@ optimizeFunctionSignature(SILFunction *F,
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite all apply insts calling F to call NewF. Update each call site as
|
||||
// appropriate given the form of function signature optimization performed.
|
||||
rewriteApplyInstToCallNewFunction(F, NewF, Arguments, CallSites);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user