Fix AllocBoxToStack cloning problem described in rdar://problem/19287131.

Recent name mangling changes resulted in AllocBoxToStack cloning the
referenced function of a partial apply once for every reference (i.e. we
would end up with N copies within the cloned function if there were N
references).

Fix this by checking for an already existing function *outside* of the
cloner rather than inside of it.

Swift SVN r24005
This commit is contained in:
Mark Lacey
2014-12-18 10:25:47 +00:00
parent 7530f406fd
commit 465db2121a
2 changed files with 142 additions and 17 deletions

View File

@@ -465,7 +465,8 @@ class DeadParamCloner : public SILClonerWithScopes<DeadParamCloner> {
friend class SILVisitor<DeadParamCloner>;
friend class SILCloner<DeadParamCloner>;
DeadParamCloner(SILFunction *Orig, ParamIndexList &DeadParamIndices);
DeadParamCloner(SILFunction *Orig, ParamIndexList &DeadParamIndices,
llvm::StringRef ClonedName);
void populateCloned();
@@ -473,7 +474,8 @@ class DeadParamCloner : public SILClonerWithScopes<DeadParamCloner> {
private:
static SILFunction *initCloned(SILFunction *Orig,
ParamIndexList &DeadParamIndices);
ParamIndexList &DeadParamIndices,
llvm::StringRef ClonedName);
void visitStrongReleaseInst(StrongReleaseInst *Inst);
void visitStrongRetainInst(StrongRetainInst *Inst);
@@ -488,8 +490,10 @@ class DeadParamCloner : public SILClonerWithScopes<DeadParamCloner> {
} // end anonymous namespace.
DeadParamCloner::DeadParamCloner(SILFunction *Orig,
ParamIndexList &DeadParamIndices)
: SILClonerWithScopes<DeadParamCloner>(*initCloned(Orig, DeadParamIndices)),
ParamIndexList &DeadParamIndices,
llvm::StringRef ClonedName)
: SILClonerWithScopes<DeadParamCloner>(*initCloned(Orig, DeadParamIndices,
ClonedName)),
Orig(Orig), DeadParamIndices(DeadParamIndices) {
}
@@ -510,15 +514,10 @@ static void getClonedName(SILFunction *F,
/// parameters (which are specified by DeadParamIndices).
SILFunction*
DeadParamCloner::initCloned(SILFunction *Orig,
ParamIndexList &DeadParamIndices) {
ParamIndexList &DeadParamIndices,
llvm::StringRef ClonedName) {
SILModule &M = Orig->getModule();
llvm::SmallString<64> ClonedName;
getClonedName(Orig, DeadParamIndices, ClonedName);
if (auto *PrevFn = M.lookUpFunction(ClonedName))
return PrevFn;
SmallVector<SILParameterInfo, 4> ClonedInterfaceArgTys;
// Generate a new parameter list with deleted parameters removed.
@@ -628,9 +627,20 @@ specializePartialApply(PartialApplyInst *PartialApply,
auto *F = FRI->getReferencedFunction();
assert(F && "Expected a referenced function!");
// Clone the function the existing partial_apply references.
DeadParamCloner Cloner(F, DeadParamIndices);
Cloner.populateCloned();
llvm::SmallString<64> ClonedName;
getClonedName(F, DeadParamIndices, ClonedName);
auto &M = PartialApply->getModule();
SILFunction *ClonedFn;
if (auto *PrevFn = M.lookUpFunction(ClonedName)) {
ClonedFn = PrevFn;
} else {
// Clone the function the existing partial_apply references.
DeadParamCloner Cloner(F, DeadParamIndices, ClonedName);
Cloner.populateCloned();
ClonedFn = Cloner.getCloned();
}
// Now create the new partial_apply using the cloned function.
llvm::SmallVector<SILValue, 16> Args;
@@ -660,9 +670,8 @@ specializePartialApply(PartialApplyInst *PartialApply,
// Build the function_ref and partial_apply.
SILValue FunctionRef = Builder.createFunctionRef(PartialApply->getLoc(),
Cloner.getCloned());
CanSILFunctionType CanFnTy = Cloner.getCloned()->getLoweredFunctionType();
auto &M = PartialApply->getModule();
ClonedFn);
CanSILFunctionType CanFnTy = ClonedFn->getLoweredFunctionType();
auto const &Subs = PartialApply->getSubstitutions();
CanSILFunctionType SubstCalleeTy = CanFnTy->substGenericArgs(M,
M.getSwiftModule(),