mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[semantic-sil] Add ValueOwnershipKind field to SILPHIArgument and split Argument creation methods into one for SILPHIArgument and another for SILFunctionArgument.
We preserve the current behavior of assuming Any ownership always and use
default arguments to hide this change most of the time. There are asserts now in
the SILBasicBlock::{create,replace,insert}{PHI,Function}Argument to ensure that
the people can only create SILFunctionArguments in entry blocks and
SILPHIArguments in non-entry blocks. This will ensure that the code in tree
maintains the API distinction even if we are not using the full distinction in
between the two.
Once the verifier is finished being upstreamed, I am going to audit the
createPHIArgument cases for the proper ownership. This is b/c I will be able to
use the verifier to properly debug the code. At that point, I will also start
serializing/printing/parsing the ownershipkind of SILPHIArguments, but lets take
things one step at a time and move incrementally.
In the process, I also discovered a CSE bug. I am not sure how it ever worked.
Basically we replace an argument with a new argument type but return the uses of
the old argument to refer to the old argument instead of a new argument.
rdar://29671437
This commit is contained in:
@@ -103,25 +103,36 @@ void SILBasicBlock::eraseFromParent() {
|
||||
getParent()->getBlocks().erase(this);
|
||||
}
|
||||
|
||||
void SILBasicBlock::cloneArgumentList(SILBasicBlock *Other) {
|
||||
assert(Other->isEntry() == isEntry() &&
|
||||
"Expected to both blocks to be entries or not");
|
||||
if (isEntry()) {
|
||||
for (auto *FuncArg : Other->getFunctionArguments()) {
|
||||
createFunctionArgument(FuncArg->getType(), FuncArg->getDecl());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto *PHIArg : Other->getPHIArguments()) {
|
||||
createPHIArgument(PHIArg->getType(), PHIArg->getOwnershipKind(),
|
||||
PHIArg->getDecl());
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the ith BB argument with a new one with type Ty (and optional
|
||||
/// ValueDecl D).
|
||||
SILArgument *SILBasicBlock::replaceArgument(unsigned i, SILType Ty,
|
||||
const ValueDecl *D) {
|
||||
SILFunctionArgument *
|
||||
SILBasicBlock::replaceFunctionArgument(unsigned i, SILType Ty,
|
||||
const ValueDecl *D) {
|
||||
assert(isEntry() && "Function Arguments can only be in the entry block");
|
||||
SILModule &M = getParent()->getModule();
|
||||
|
||||
assert(ArgumentList[i]->use_empty() && "Expected no uses of the old BB arg!");
|
||||
bool IsFunctionArg =
|
||||
ArgumentList[i]->getKind() == ValueKind::SILFunctionArgument;
|
||||
|
||||
// Notify the delete handlers that this argument is being deleted.
|
||||
M.notifyDeleteHandlers(ArgumentList[i]);
|
||||
|
||||
SILArgument *NewArg;
|
||||
if (IsFunctionArg) {
|
||||
NewArg = new (M) SILFunctionArgument(Ty, D);
|
||||
} else {
|
||||
NewArg = new (M) SILPHIArgument(Ty, D);
|
||||
}
|
||||
SILFunctionArgument *NewArg = new (M) SILFunctionArgument(Ty, D);
|
||||
NewArg->setParent(this);
|
||||
|
||||
// TODO: When we switch to malloc/free allocation we'll be leaking memory
|
||||
@@ -131,17 +142,54 @@ SILArgument *SILBasicBlock::replaceArgument(unsigned i, SILType Ty,
|
||||
return NewArg;
|
||||
}
|
||||
|
||||
SILArgument *SILBasicBlock::createArgument(SILType Ty, const ValueDecl *D) {
|
||||
if (isEntry())
|
||||
return new (getModule()) SILFunctionArgument(this, Ty, D);
|
||||
return new (getModule()) SILPHIArgument(this, Ty, D);
|
||||
SILFunctionArgument *SILBasicBlock::createFunctionArgument(SILType Ty,
|
||||
const ValueDecl *D) {
|
||||
assert(isEntry() && "Function Arguments can only be in the entry block");
|
||||
return new (getModule()) SILFunctionArgument(this, Ty, D);
|
||||
}
|
||||
|
||||
SILArgument *SILBasicBlock::insertArgument(arg_iterator Iter, SILType Ty,
|
||||
const ValueDecl *D) {
|
||||
if (isEntry())
|
||||
return new (getModule()) SILFunctionArgument(this, Iter, Ty, D);
|
||||
return new (getModule()) SILPHIArgument(this, Iter, Ty, D);
|
||||
SILFunctionArgument *SILBasicBlock::insertFunctionArgument(arg_iterator Iter,
|
||||
SILType Ty,
|
||||
const ValueDecl *D) {
|
||||
assert(isEntry() && "Function Arguments can only be in the entry block");
|
||||
return new (getModule()) SILFunctionArgument(this, Iter, Ty, D);
|
||||
}
|
||||
|
||||
/// Replace the ith BB argument with a new one with type Ty (and optional
|
||||
/// ValueDecl D).
|
||||
SILPHIArgument *SILBasicBlock::replacePHIArgument(unsigned i, SILType Ty,
|
||||
ValueOwnershipKind Kind,
|
||||
const ValueDecl *D) {
|
||||
assert(!isEntry() && "PHI Arguments can not be in the entry block");
|
||||
SILModule &M = getParent()->getModule();
|
||||
|
||||
assert(ArgumentList[i]->use_empty() && "Expected no uses of the old BB arg!");
|
||||
|
||||
// Notify the delete handlers that this argument is being deleted.
|
||||
M.notifyDeleteHandlers(ArgumentList[i]);
|
||||
|
||||
SILPHIArgument *NewArg = new (M) SILPHIArgument(Ty, Kind, D);
|
||||
NewArg->setParent(this);
|
||||
|
||||
// TODO: When we switch to malloc/free allocation we'll be leaking memory
|
||||
// here.
|
||||
ArgumentList[i] = NewArg;
|
||||
|
||||
return NewArg;
|
||||
}
|
||||
|
||||
SILPHIArgument *SILBasicBlock::createPHIArgument(SILType Ty,
|
||||
ValueOwnershipKind Kind,
|
||||
const ValueDecl *D) {
|
||||
assert(!isEntry() && "PHI Arguments can not be in the entry block");
|
||||
return new (getModule()) SILPHIArgument(this, Ty, Kind, D);
|
||||
}
|
||||
|
||||
SILPHIArgument *SILBasicBlock::insertPHIArgument(arg_iterator Iter, SILType Ty,
|
||||
ValueOwnershipKind Kind,
|
||||
const ValueDecl *D) {
|
||||
assert(!isEntry() && "PHI Arguments can not be in the entry block");
|
||||
return new (getModule()) SILPHIArgument(this, Iter, Ty, Kind, D);
|
||||
}
|
||||
|
||||
void SILBasicBlock::eraseArgument(int Index) {
|
||||
|
||||
Reference in New Issue
Block a user