Make SILInstruction no longer a subclass of ValueBase and

introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
This commit is contained in:
John McCall
2017-09-21 00:17:10 -07:00
parent 6d9294f565
commit ab3f77baf2
195 changed files with 6114 additions and 4985 deletions

View File

@@ -41,7 +41,7 @@ using namespace swift::irgen;
///
/// TODO: This should be a common utility.
static SILLocation getLocForValue(SILValue value) {
if (auto *instr = dyn_cast<SILInstruction>(value)) {
if (auto *instr = value->getDefiningInstruction()) {
return instr->getLoc();
}
if (auto *arg = dyn_cast<SILArgument>(value)) {
@@ -377,9 +377,9 @@ struct StructLoweringState {
// All args for which we did a load
llvm::DenseMap<SILValue, SILValue> argsToLoadedValueMap;
// All applies for which we did an alloc
llvm::DenseMap<SILValue, SILValue> applyRetToAllocMap;
llvm::DenseMap<SILInstruction *, SILValue> applyRetToAllocMap;
// recerse map of the one above
llvm::DenseMap<SILInstruction *, SILValue> allocToApplyRetMap;
llvm::DenseMap<SILInstruction *, SILInstruction*> allocToApplyRetMap;
// All call sites with SILArgument that needs to be re-written
// Calls are removed from the set when rewritten.
SmallVector<SILInstruction *, 16> applies;
@@ -392,7 +392,7 @@ struct StructLoweringState {
// All struct_extract instrs that should be converted to struct_element_addr
SmallVector<StructExtractInst *, 16> structExtractInstsToMod;
// All tuple instructions for which the return type is a function type
SmallVector<SILInstruction *, 8> tupleInstsToMod;
SmallVector<SingleValueInstruction *, 8> tupleInstsToMod;
// All allock stack instructions to modify
SmallVector<AllocStackInst *, 8> allocStackInstsToMod;
// All pointer to address instructions to modify
@@ -401,7 +401,7 @@ struct StructLoweringState {
SmallVector<RetainValueInst *, 16> retainInstsToMod;
SmallVector<ReleaseValueInst *, 16> releaseInstsToMod;
// All result types instrs for which we need to convert the ResultTy
llvm::SetVector<SILInstruction *> resultTyInstsToMod;
llvm::SetVector<SingleValueInstruction *> resultTyInstsToMod;
// All instructions that use the large struct that are not covered above
SmallVector<SILInstruction *, 16> instsToMod;
// All function-exiting terminators (return or throw instructions).
@@ -443,10 +443,10 @@ protected:
void visitStructExtractInst(StructExtractInst *instr);
void visitRetainInst(RetainValueInst *instr);
void visitReleaseInst(ReleaseValueInst *instr);
void visitResultTyInst(SILInstruction *instr);
void visitResultTyInst(SingleValueInstruction *instr);
void visitDebugValueInst(DebugValueInst *instr);
void visitDestroyValueInst(DestroyValueInst *instr);
void visitTupleInst(SILInstruction *instr);
void visitTupleInst(SingleValueInstruction *instr);
void visitAllocStackInst(AllocStackInst *instr);
void visitPointerToAddressInst(PointerToAddressInst *instr);
void visitReturnInst(ReturnInst *instr);
@@ -467,82 +467,82 @@ void LargeValueVisitor::mapValueStorage() {
for (auto &II : *BB) {
SILInstruction *currIns = &II;
switch (currIns->getKind()) {
case ValueKind::ApplyInst:
case ValueKind::TryApplyInst:
case ValueKind::PartialApplyInst: {
case SILInstructionKind::ApplyInst:
case SILInstructionKind::TryApplyInst:
case SILInstructionKind::PartialApplyInst: {
visitApply(ApplySite(currIns));
break;
}
case ValueKind::ClassMethodInst:
case ValueKind::SuperMethodInst:
case ValueKind::DynamicMethodInst:
case ValueKind::WitnessMethodInst: {
case SILInstructionKind::ClassMethodInst:
case SILInstructionKind::SuperMethodInst:
case SILInstructionKind::DynamicMethodInst:
case SILInstructionKind::WitnessMethodInst: {
// TODO Any more instructions to add here?
auto *MI = dyn_cast<MethodInst>(currIns);
visitMethodInst(MI);
break;
}
case ValueKind::StructExtractInst:
case ValueKind::StructElementAddrInst:
case ValueKind::RefTailAddrInst:
case ValueKind::RefElementAddrInst:
case ValueKind::BeginAccessInst:
case ValueKind::EnumInst: {
case SILInstructionKind::StructExtractInst:
case SILInstructionKind::StructElementAddrInst:
case SILInstructionKind::RefTailAddrInst:
case SILInstructionKind::RefElementAddrInst:
case SILInstructionKind::BeginAccessInst:
case SILInstructionKind::EnumInst: {
// TODO Any more instructions to add here?
visitResultTyInst(currIns);
visitResultTyInst(cast<SingleValueInstruction>(currIns));
break;
}
case ValueKind::StoreInst: {
case SILInstructionKind::StoreInst: {
auto *SI = dyn_cast<StoreInst>(currIns);
visitStoreInst(SI);
break;
}
case ValueKind::RetainValueInst: {
case SILInstructionKind::RetainValueInst: {
auto *RETI = dyn_cast<RetainValueInst>(currIns);
visitRetainInst(RETI);
break;
}
case ValueKind::ReleaseValueInst: {
case SILInstructionKind::ReleaseValueInst: {
auto *RELI = dyn_cast<ReleaseValueInst>(currIns);
visitReleaseInst(RELI);
break;
}
case ValueKind::DebugValueInst: {
case SILInstructionKind::DebugValueInst: {
auto *DI = dyn_cast<DebugValueInst>(currIns);
visitDebugValueInst(DI);
break;
}
case ValueKind::DestroyValueInst: {
case SILInstructionKind::DestroyValueInst: {
auto *DI = dyn_cast<DestroyValueInst>(currIns);
visitDestroyValueInst(DI);
break;
}
case ValueKind::SwitchEnumInst: {
case SILInstructionKind::SwitchEnumInst: {
auto *SEI = dyn_cast<SwitchEnumInst>(currIns);
visitSwitchEnumInst(SEI);
break;
}
case ValueKind::TupleElementAddrInst:
case ValueKind::TupleExtractInst: {
visitTupleInst(currIns);
case SILInstructionKind::TupleElementAddrInst:
case SILInstructionKind::TupleExtractInst: {
visitTupleInst(cast<SingleValueInstruction>(currIns));
break;
}
case ValueKind::AllocStackInst: {
case SILInstructionKind::AllocStackInst: {
auto *ASI = dyn_cast<AllocStackInst>(currIns);
visitAllocStackInst(ASI);
break;
}
case ValueKind::PointerToAddressInst: {
case SILInstructionKind::PointerToAddressInst: {
auto *PTA = dyn_cast<PointerToAddressInst>(currIns);
visitPointerToAddressInst(PTA);
break;
}
case ValueKind::ReturnInst: {
case SILInstructionKind::ReturnInst: {
auto *RI = dyn_cast<ReturnInst>(currIns);
visitReturnInst(RI);
break;
}
case ValueKind::DeallocStackInst: {
case SILInstructionKind::DeallocStackInst: {
auto *DI = dyn_cast<DeallocStackInst>(currIns);
visitDeallocInst(DI);
break;
@@ -748,7 +748,7 @@ void LargeValueVisitor::visitDestroyValueInst(DestroyValueInst *instr) {
}
}
void LargeValueVisitor::visitResultTyInst(SILInstruction *instr) {
void LargeValueVisitor::visitResultTyInst(SingleValueInstruction *instr) {
GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment();
auto loweredTy = instr->getFunction()->getLoweredFunctionType();
if (!genEnv && loweredTy->isPolymorphic()) {
@@ -767,7 +767,7 @@ void LargeValueVisitor::visitResultTyInst(SILInstruction *instr) {
}
}
void LargeValueVisitor::visitTupleInst(SILInstruction *instr) {
void LargeValueVisitor::visitTupleInst(SingleValueInstruction *instr) {
SILType currSILType = instr->getType().getObjectType();
CanType currCanType = currSILType.getSwiftRValueType();
if (auto funcType = dyn_cast<SILFunctionType>(currCanType)) {
@@ -853,7 +853,7 @@ protected:
void convertIndirectBasicBlockArgs();
void convertApplyResults();
void allocateForArg(SILValue value);
AllocStackInst *allocateForApply(SILValue value, SILType type);
AllocStackInst *allocateForApply(SILInstruction *apply, SILType type);
SILArgument *replaceArgType(SILBuilder &argBuilder, SILArgument *arg,
SILType newSILType);
};
@@ -889,49 +889,49 @@ void LoadableStorageAllocation::replaceLoadWithCopyAddr(
for (auto *user : optimizableLoad->getUses()) {
SILInstruction *userIns = user->getUser();
switch (userIns->getKind()) {
case ValueKind::CopyAddrInst:
case ValueKind::DeallocStackInst:
case SILInstructionKind::CopyAddrInst:
case SILInstructionKind::DeallocStackInst:
break;
case ValueKind::ApplyInst:
case ValueKind::TryApplyInst:
case ValueKind::PartialApplyInst: {
case SILInstructionKind::ApplyInst:
case SILInstructionKind::TryApplyInst:
case SILInstructionKind::PartialApplyInst: {
if (std::find(pass.applies.begin(), pass.applies.end(), userIns) ==
pass.applies.end()) {
pass.applies.push_back(userIns);
}
break;
}
case ValueKind::RetainValueInst: {
case SILInstructionKind::RetainValueInst: {
auto *insToInsert = dyn_cast<RetainValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.retainInstsToMod.push_back(insToInsert);
break;
}
case ValueKind::ReleaseValueInst: {
case SILInstructionKind::ReleaseValueInst: {
auto *insToInsert = dyn_cast<ReleaseValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.releaseInstsToMod.push_back(insToInsert);
break;
}
case ValueKind::StoreInst: {
case SILInstructionKind::StoreInst: {
auto *insToInsert = dyn_cast<StoreInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.storeInstsToMod.push_back(insToInsert);
break;
}
case ValueKind::DebugValueInst: {
case SILInstructionKind::DebugValueInst: {
auto *insToInsert = dyn_cast<DebugValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.debugInstsToMod.push_back(insToInsert);
break;
}
case ValueKind::DestroyValueInst: {
case SILInstructionKind::DestroyValueInst: {
auto *insToInsert = dyn_cast<DestroyValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.destroyValueInstsToMod.push_back(insToInsert);
break;
}
case ValueKind::StructExtractInst: {
case SILInstructionKind::StructExtractInst: {
auto *instToInsert = dyn_cast<StructExtractInst>(userIns);
if (std::find(pass.structExtractInstsToMod.begin(),
pass.structExtractInstsToMod.end(),
@@ -940,7 +940,7 @@ void LoadableStorageAllocation::replaceLoadWithCopyAddr(
}
break;
}
case ValueKind::SwitchEnumInst: {
case SILInstructionKind::SwitchEnumInst: {
auto *instToInsert = dyn_cast<SwitchEnumInst>(userIns);
if (std::find(pass.switchEnumInstsToMod.begin(),
pass.switchEnumInstsToMod.end(),
@@ -963,9 +963,9 @@ static bool usesContainApplies(LoadInst *unoptimizableLoad,
for (auto *user : unoptimizableLoad->getUses()) {
SILInstruction *userIns = user->getUser();
switch (userIns->getKind()) {
case ValueKind::ApplyInst:
case ValueKind::TryApplyInst:
case ValueKind::PartialApplyInst: {
case SILInstructionKind::ApplyInst:
case SILInstructionKind::TryApplyInst:
case SILInstructionKind::PartialApplyInst: {
ApplySite site(userIns);
SILValue callee = site.getCallee();
if (callee == unoptimizableLoad) {
@@ -1017,12 +1017,12 @@ void LoadableStorageAllocation::replaceLoadWithCopyAddrForModifiable(
for (auto *user : unoptimizableLoad->getUses()) {
SILInstruction *userIns = user->getUser();
switch (userIns->getKind()) {
case ValueKind::CopyAddrInst:
case ValueKind::DeallocStackInst:
case SILInstructionKind::CopyAddrInst:
case SILInstructionKind::DeallocStackInst:
break;
case ValueKind::ApplyInst:
case ValueKind::TryApplyInst:
case ValueKind::PartialApplyInst: {
case SILInstructionKind::ApplyInst:
case SILInstructionKind::TryApplyInst:
case SILInstructionKind::PartialApplyInst: {
ApplySite site(userIns);
if (!modifiableApply(site, pass.Mod)) {
break;
@@ -1049,48 +1049,48 @@ void LoadableStorageAllocation::replaceLoadWithCopyAddrForModifiable(
usersToMod.push_back(user);
break;
}
case ValueKind::RetainValueInst: {
case SILInstructionKind::RetainValueInst: {
auto *insToInsert = dyn_cast<RetainValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.retainInstsToMod.push_back(insToInsert);
usersToMod.push_back(user);
break;
}
case ValueKind::ReleaseValueInst: {
case SILInstructionKind::ReleaseValueInst: {
auto *insToInsert = dyn_cast<ReleaseValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.releaseInstsToMod.push_back(insToInsert);
usersToMod.push_back(user);
break;
}
case ValueKind::StoreInst: {
case SILInstructionKind::StoreInst: {
auto *insToInsert = dyn_cast<StoreInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.storeInstsToMod.push_back(insToInsert);
usersToMod.push_back(user);
break;
}
case ValueKind::DebugValueInst: {
case SILInstructionKind::DebugValueInst: {
auto *insToInsert = dyn_cast<DebugValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.debugInstsToMod.push_back(insToInsert);
usersToMod.push_back(user);
break;
}
case ValueKind::DestroyValueInst: {
case SILInstructionKind::DestroyValueInst: {
auto *insToInsert = dyn_cast<DestroyValueInst>(userIns);
assert(insToInsert && "Unexpected cast failure");
pass.destroyValueInstsToMod.push_back(insToInsert);
usersToMod.push_back(user);
break;
}
case ValueKind::StructExtractInst: {
case SILInstructionKind::StructExtractInst: {
auto *instToInsert = dyn_cast<StructExtractInst>(userIns);
pass.structExtractInstsToMod.push_back(instToInsert);
usersToMod.push_back(user);
break;
}
case ValueKind::SwitchEnumInst: {
case SILInstructionKind::SwitchEnumInst: {
auto *instToInsert = dyn_cast<SwitchEnumInst>(userIns);
pass.switchEnumInstsToMod.push_back(instToInsert);
usersToMod.push_back(user);
@@ -1234,7 +1234,7 @@ void LoadableStorageAllocation::convertApplyResults() {
if (!ApplySite::isa(currIns)) {
continue;
}
if (dyn_cast<PartialApplyInst>(currIns)) {
if (isa<PartialApplyInst>(currIns)) {
continue;
}
auto applySite = ApplySite(currIns);
@@ -1263,8 +1263,10 @@ void LoadableStorageAllocation::convertApplyResults() {
}
auto newSILType = getNewSILType(genEnv, resultStorageType, pass.Mod);
auto *newVal = allocateForApply(currIns, newSILType.getObjectType());
currIns->replaceAllUsesWith(newVal);
if (auto tryApplyIns = dyn_cast<TryApplyInst>(currIns)) {
if (auto apply = dyn_cast<ApplyInst>(currIns)) {
apply->replaceAllUsesWith(newVal);
} else {
auto tryApplyIns = cast<TryApplyInst>(currIns);
auto *normalBB = tryApplyIns->getNormalBB();
SILBuilder argBuilder(normalBB->begin());
assert(normalBB->getNumArguments() == 1 &&
@@ -1338,8 +1340,7 @@ void LoadableStorageAllocation::allocateForArg(SILValue value) {
assert(pass.allocToApplyRetMap.find(allocInstr) !=
pass.allocToApplyRetMap.end() &&
"Alloc is not for apply results");
auto *applyInst =
dyn_cast<SILInstruction>(pass.allocToApplyRetMap[allocInstr]);
auto *applyInst = pass.allocToApplyRetMap[allocInstr];
assert(applyInst && "Value is not an apply");
auto II = applyInst->getIterator();
SILBuilder loadBuilder(II);
@@ -1388,14 +1389,15 @@ void LoadableStorageAllocation::allocateForArg(SILValue value) {
}
}
AllocStackInst *LoadableStorageAllocation::allocateForApply(SILValue value,
SILType type) {
AllocStackInst *
LoadableStorageAllocation::allocateForApply(SILInstruction *apply,
SILType type) {
SILBuilder allocBuilder(pass.F->begin()->begin());
auto *allocInstr = allocBuilder.createAllocStack(getLocForValue(value), type);
auto *allocInstr = allocBuilder.createAllocStack(apply->getLoc(), type);
pass.largeLoadableArgs.push_back(allocInstr);
pass.allocToApplyRetMap[allocInstr] = value;
pass.applyRetToAllocMap[value] = allocInstr;
pass.allocToApplyRetMap[allocInstr] = apply;
pass.applyRetToAllocMap[apply] = allocInstr;
for (TermInst *termInst : pass.returnInsts) {
SILBuilder deallocBuilder(termInst);
@@ -1429,7 +1431,7 @@ private:
private:
llvm::SetVector<SILFunction *> modFuncs;
llvm::SetVector<SILInstruction *> conversionInstrs;
llvm::SetVector<SingleValueInstruction *> conversionInstrs;
llvm::SetVector<BuiltinInst *> builtinInstrs;
llvm::SetVector<LoadInst *> loadInstrsOfFunc;
llvm::SetVector<UncheckedEnumDataInst *> uncheckedEnumDataOfFunc;
@@ -1437,7 +1439,7 @@ private:
uncheckedTakeEnumDataAddrOfFunc;
llvm::SetVector<StoreInst *> storeToBlockStorageInstrs;
llvm::DenseSet<SILInstruction *> modApplies;
llvm::DenseMap<SILValue, SILValue> allApplyRetToAllocMap;
llvm::DenseMap<SILInstruction *, SILValue> allApplyRetToAllocMap;
};
} // end anonymous namespace
@@ -1462,14 +1464,13 @@ static void setInstrUsers(StructLoweringState &pass, AllocStackInst *allocInstr,
SILBuilder copyBuilder(storeUser);
SILValue tgt = storeUser->getDest();
createOutlinedCopyCall(copyBuilder, allocInstr, tgt, pass);
storeUser->replaceAllUsesWith(tgt);
storeUser->getParent()->erase(storeUser);
storeUser->eraseFromParent();
}
}
}
static void allocateAndSetForInstrOperand(StructLoweringState &pass,
SILInstruction *instrOperand) {
SingleValueInstruction *instrOperand){
assert(instrOperand->getType().isObject());
SILBuilder allocBuilder(pass.F->begin()->begin());
AllocStackInst *allocInstr = allocBuilder.createAllocStack(
@@ -1535,21 +1536,21 @@ static void allocateAndSetForArgumentOperand(StructLoweringState &pass,
setInstrUsers(pass, allocInstr, value, store);
}
static bool allUsesAreReplaceable(SILInstruction *instr,
static bool allUsesAreReplaceable(SingleValueInstruction *instr,
irgen::IRGenModule &Mod) {
bool allUsesAreReplaceable = true;
for (auto *user : instr->getUses()) {
SILInstruction *userIns = user->getUser();
switch (userIns->getKind()) {
case ValueKind::RetainValueInst:
case ValueKind::ReleaseValueInst:
case ValueKind::StoreInst:
case ValueKind::DebugValueInst:
case ValueKind::DestroyValueInst:
case SILInstructionKind::RetainValueInst:
case SILInstructionKind::ReleaseValueInst:
case SILInstructionKind::StoreInst:
case SILInstructionKind::DebugValueInst:
case SILInstructionKind::DestroyValueInst:
break;
case ValueKind::ApplyInst:
case ValueKind::TryApplyInst:
case ValueKind::PartialApplyInst: {
case SILInstructionKind::ApplyInst:
case SILInstructionKind::TryApplyInst:
case SILInstructionKind::PartialApplyInst: {
// Replaceable only if it is not the function pointer
ApplySite site(userIns);
if (!modifiableApply(site, Mod)) {
@@ -1573,8 +1574,8 @@ static bool allUsesAreReplaceable(SILInstruction *instr,
}
break;
}
case ValueKind::StructExtractInst:
case ValueKind::SwitchEnumInst: {
case SILInstructionKind::StructExtractInst:
case SILInstructionKind::SwitchEnumInst: {
break;
}
default:
@@ -1584,7 +1585,7 @@ static bool allUsesAreReplaceable(SILInstruction *instr,
return allUsesAreReplaceable;
}
static void castTupleInstr(SILInstruction *instr, IRGenModule &Mod) {
static void castTupleInstr(SingleValueInstruction *instr, IRGenModule &Mod) {
SILType currSILType = instr->getType().getObjectType();
CanType currCanType = currSILType.getSwiftRValueType();
SILFunctionType *funcType = dyn_cast<SILFunctionType>(currCanType);
@@ -1601,15 +1602,15 @@ static void castTupleInstr(SILInstruction *instr, IRGenModule &Mod) {
auto II = instr->getIterator();
++II;
SILBuilder castBuilder(II);
SILInstruction *castInstr = nullptr;
SingleValueInstruction *castInstr = nullptr;
switch (instr->getKind()) {
// Add cast to the new sil function type:
case ValueKind::TupleExtractInst: {
case SILInstructionKind::TupleExtractInst: {
castInstr = castBuilder.createUncheckedBitCast(instr->getLoc(), instr,
newSILType.getObjectType());
break;
}
case ValueKind::TupleElementAddrInst: {
case SILInstructionKind::TupleElementAddrInst: {
castInstr = castBuilder.createUncheckedAddrCast(
instr->getLoc(), instr, newSILType.getAddressType());
break;
@@ -1725,9 +1726,8 @@ static void rewriteFunction(StructLoweringState &pass,
}
SILBasicBlock *defaultBB =
instr->hasDefault() ? instr->getDefaultBB() : nullptr;
auto *newInstr = enumBuilder.createSwitchEnumAddr(
enumBuilder.createSwitchEnumAddr(
instr->getLoc(), copiedValue, defaultBB, caseBBs);
instr->replaceAllUsesWith(newInstr);
instr->getParent()->erase(instr);
}
@@ -1780,8 +1780,7 @@ static void rewriteFunction(StructLoweringState &pass,
SILValue currOperand = operand.get();
SILType silType = currOperand->getType();
if (isLargeLoadableType(genEnv, silType, pass.Mod)) {
SILInstruction *currOperandInstr =
dyn_cast<SILInstruction>(currOperand);
auto currOperandInstr = dyn_cast<SingleValueInstruction>(currOperand);
// Get its storage location as a new operand
if (!currOperandInstr) {
allocateAndSetForArgumentOperand(pass, currOperand, applyInst);
@@ -1826,7 +1825,7 @@ static void rewriteFunction(StructLoweringState &pass,
}
}
for (SILInstruction *instr : pass.tupleInstsToMod) {
for (SingleValueInstruction *instr : pass.tupleInstsToMod) {
castTupleInstr(instr, pass.Mod);
}
@@ -1896,71 +1895,68 @@ static void rewriteFunction(StructLoweringState &pass,
SILBuilder copyBuilder(instr);
createOutlinedCopyCall(copyBuilder, src, tgt, pass);
instr->replaceAllUsesWith(tgt);
instr->getParent()->erase(instr);
}
for (RetainValueInst *instr : pass.retainInstsToMod) {
SILBuilder retainBuilder(instr);
auto *newInstr = retainBuilder.createRetainValueAddr(
retainBuilder.createRetainValueAddr(
instr->getLoc(), instr->getOperand(), instr->getAtomicity());
instr->replaceAllUsesWith(newInstr);
instr->getParent()->erase(instr);
}
for (ReleaseValueInst *instr : pass.releaseInstsToMod) {
SILBuilder releaseBuilder(instr);
auto *newInstr = releaseBuilder.createReleaseValueAddr(
releaseBuilder.createReleaseValueAddr(
instr->getLoc(), instr->getOperand(), instr->getAtomicity());
instr->replaceAllUsesWith(newInstr);
instr->getParent()->erase(instr);
}
for (SILInstruction *instr : pass.resultTyInstsToMod) {
for (SingleValueInstruction *instr : pass.resultTyInstsToMod) {
// Update the return type of these instrs
// Note: The operand was already updated!
SILType currSILType = instr->getType().getObjectType();
SILType newSILType = getNewSILType(genEnv, currSILType, pass.Mod);
SILBuilder resultTyBuilder(instr);
SILLocation Loc = instr->getLoc();
SILInstruction *newInstr = nullptr;
SingleValueInstruction *newInstr = nullptr;
switch (instr->getKind()) {
case ValueKind::StructExtractInst: {
auto *convInstr = dyn_cast<StructExtractInst>(instr);
case SILInstructionKind::StructExtractInst: {
auto *convInstr = cast<StructExtractInst>(instr);
newInstr = resultTyBuilder.createStructExtract(
Loc, convInstr->getOperand(), convInstr->getField(),
newSILType.getObjectType());
break;
}
case ValueKind::StructElementAddrInst: {
auto *convInstr = dyn_cast<StructElementAddrInst>(instr);
case SILInstructionKind::StructElementAddrInst: {
auto *convInstr = cast<StructElementAddrInst>(instr);
newInstr = resultTyBuilder.createStructElementAddr(
Loc, convInstr->getOperand(), convInstr->getField(),
newSILType.getAddressType());
break;
}
case ValueKind::RefTailAddrInst: {
auto *convInstr = dyn_cast<RefTailAddrInst>(instr);
case SILInstructionKind::RefTailAddrInst: {
auto *convInstr = cast<RefTailAddrInst>(instr);
newInstr = resultTyBuilder.createRefTailAddr(Loc, convInstr->getOperand(),
newSILType.getAddressType());
break;
}
case ValueKind::RefElementAddrInst: {
auto *convInstr = dyn_cast<RefElementAddrInst>(instr);
case SILInstructionKind::RefElementAddrInst: {
auto *convInstr = cast<RefElementAddrInst>(instr);
newInstr = resultTyBuilder.createRefElementAddr(
Loc, convInstr->getOperand(), convInstr->getField(),
newSILType.getAddressType());
break;
}
case ValueKind::BeginAccessInst: {
auto *convInstr = dyn_cast<BeginAccessInst>(instr);
case SILInstructionKind::BeginAccessInst: {
auto *convInstr = cast<BeginAccessInst>(instr);
newInstr = resultTyBuilder.createBeginAccess(Loc, convInstr->getOperand(),
convInstr->getAccessKind(),
convInstr->getEnforcement());
break;
}
case ValueKind::EnumInst: {
auto *convInstr = dyn_cast<EnumInst>(instr);
case SILInstructionKind::EnumInst: {
auto *convInstr = cast<EnumInst>(instr);
SILValue operand =
convInstr->hasOperand() ? convInstr->getOperand() : SILValue();
newInstr = resultTyBuilder.createEnum(
@@ -1971,7 +1967,7 @@ static void rewriteFunction(StructLoweringState &pass,
llvm_unreachable("Unhandled aggrTy instr");
}
instr->replaceAllUsesWith(newInstr);
instr->getParent()->erase(instr);
instr->eraseFromParent();
}
for (MethodInst *instr : pass.methodInstsToMod) {
@@ -1993,19 +1989,19 @@ static void rewriteFunction(StructLoweringState &pass,
MethodInst *newInstr = nullptr;
switch (instr->getKind()) {
case ValueKind::ClassMethodInst: {
case SILInstructionKind::ClassMethodInst: {
SILValue selfValue = instr->getOperand(0);
newInstr = methodBuilder.createClassMethod(loc, selfValue, member,
newSILType, isVolatile);
break;
}
case ValueKind::SuperMethodInst: {
case SILInstructionKind::SuperMethodInst: {
SILValue selfValue = instr->getOperand(0);
newInstr = methodBuilder.createSuperMethod(loc, selfValue, member,
newSILType, isVolatile);
break;
}
case ValueKind::DynamicMethodInst: {
case SILInstructionKind::DynamicMethodInst: {
auto *DMI = dyn_cast<DynamicMethodInst>(instr);
assert(DMI && "ValueKind is Witness Method but dyn_cast failed");
SILValue selfValue = instr->getOperand(0);
@@ -2013,7 +2009,7 @@ static void rewriteFunction(StructLoweringState &pass,
newSILType, isVolatile);
break;
}
case ValueKind::WitnessMethodInst: {
case SILInstructionKind::WitnessMethodInst: {
auto *WMI = dyn_cast<WitnessMethodInst>(instr);
assert(WMI && "ValueKind is Witness Method but dyn_cast failed");
newInstr = methodBuilder.createWitnessMethod(
@@ -2045,7 +2041,7 @@ static void rewriteFunction(StructLoweringState &pass,
auto IIR = instr->getReverseIterator();
for (++IIR; IIR != instr->getParent()->rend(); ++IIR) {
auto *currIIInstr = &(*IIR);
if (currIIInstr->getKind() != ValueKind::DeallocStackInst) {
if (currIIInstr->getKind() != SILInstructionKind::DeallocStackInst) {
// got the right location - stop.
--IIR;
break;
@@ -2068,9 +2064,8 @@ static void rewriteFunction(StructLoweringState &pass,
auto emptyTy = retBuilder.getModule().Types.getLoweredType(
TupleType::getEmpty(retBuilder.getModule().getASTContext()));
auto newRetTuple = retBuilder.createTuple(regLoc, emptyTy, {});
auto newRet = retBuilder.createReturn(newRetTuple->getLoc(), newRetTuple);
instr->replaceAllUsesWith(newRet);
instr->getParent()->erase(instr);
retBuilder.createReturn(newRetTuple->getLoc(), newRetTuple);
instr->eraseFromParent();
}
}
@@ -2222,11 +2217,10 @@ void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
// Collect common info
ApplySite applySite = ApplySite(applyInst);
SILValue callee = applySite.getCallee();
if (ApplySite::isa(callee)) {
if (auto site = ApplySite::isa(callee)) {
// We need to re-create the callee's apply before recreating this one
// else verification will fail with wrong SubstCalleeType
auto calleInstr = dyn_cast<SILInstruction>(callee);
assert(calleInstr && "Expected ApplySite Instr");
auto calleInstr = site.getInstruction();
if (modApplies.find(calleInstr) != modApplies.end()) {
recreateSingleApply(calleInstr);
modApplies.erase(calleInstr);
@@ -2252,12 +2246,12 @@ void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
// If we turned a direct result into an indirect parameter
// Find the new alloc we created earlier.
// and pass it as first parameter:
if (applyInst->getKind() != ValueKind::PartialApplyInst &&
if (applyInst->getKind() != SILInstructionKind::PartialApplyInst &&
modResultType(genEnv, origCanType, *currIRMod) &&
modifiableApply(applySite, *getIRGenModule())) {
assert(allApplyRetToAllocMap.find(applyInst) !=
allApplyRetToAllocMap.end());
auto newAlloc = allApplyRetToAllocMap[applyInst];
auto newAlloc = allApplyRetToAllocMap.find(applyInst)->second;
callArgs.push_back(newAlloc);
}
SmallVector<Substitution, 4> newSubs =
@@ -2270,39 +2264,35 @@ void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
callArgs.push_back(currOperand);
}
// Recreate apply with new operands due to substitution-type cache
SILInstruction *newApply = nullptr;
switch (applyInst->getKind()) {
case ValueKind::ApplyInst: {
auto *castedApply = dyn_cast<ApplyInst>(applyInst);
assert(castedApply && "ValueKind is ApplyInst but cast to it failed");
newApply = applyBuilder.createApply(castedApply->getLoc(), callee, newSubs,
callArgs, castedApply->isNonThrowing());
applyInst->replaceAllUsesWith(newApply);
case SILInstructionKind::ApplyInst: {
auto *castedApply = cast<ApplyInst>(applyInst);
SILValue newApply =
applyBuilder.createApply(castedApply->getLoc(), callee, newSubs,
callArgs, castedApply->isNonThrowing());
castedApply->replaceAllUsesWith(newApply);
break;
}
case ValueKind::TryApplyInst: {
auto *castedApply = dyn_cast<TryApplyInst>(applyInst);
assert(castedApply && "ValueKind is TryApplyInst but cast to it failed");
newApply = applyBuilder.createTryApply(
case SILInstructionKind::TryApplyInst: {
auto *castedApply = cast<TryApplyInst>(applyInst);
applyBuilder.createTryApply(
castedApply->getLoc(), callee, newSubs, callArgs,
castedApply->getNormalBB(), castedApply->getErrorBB());
applyInst->replaceAllUsesWith(newApply);
break;
}
case ValueKind::PartialApplyInst: {
auto *castedApply = dyn_cast<PartialApplyInst>(applyInst);
assert(castedApply &&
"ValueKind is PartialApplyInst but cast to it failed");
case SILInstructionKind::PartialApplyInst: {
auto *castedApply = cast<PartialApplyInst>(applyInst);
// Change the type of the Closure
auto partialApplyConvention = castedApply->getType()
.getSwiftRValueType()
->getAs<SILFunctionType>()
->getCalleeConvention();
newApply = applyBuilder.createPartialApply(castedApply->getLoc(), callee,
newSubs, callArgs,
partialApplyConvention);
applyInst->replaceAllUsesWith(newApply);
auto newApply =
applyBuilder.createPartialApply(castedApply->getLoc(), callee,
newSubs, callArgs,
partialApplyConvention);
castedApply->replaceAllUsesWith(newApply);
break;
}
default:
@@ -2351,7 +2341,7 @@ void LoadableByAddress::recreateUncheckedEnumDataInstrs() {
SILType newType = getNewSILType(genEnv, origType, *currIRMod);
auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
enumInstr->getElement(), F->getModule());
SILInstruction *newInstr = nullptr;
SingleValueInstruction *newInstr = nullptr;
if (caseTy != newType) {
auto *takeEnum = enumBuilder.createUncheckedEnumData(
enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
@@ -2385,7 +2375,7 @@ void LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst() {
SILType newType = getNewSILType(genEnv, origType, *currIRMod);
auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
enumInstr->getElement(), F->getModule());
SILInstruction *newInstr = nullptr;
SingleValueInstruction *newInstr = nullptr;
if (caseTy != origType.getObjectType()) {
auto *takeEnum = enumBuilder.createUncheckedTakeEnumDataAddr(
enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
@@ -2405,9 +2395,7 @@ void LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst() {
void LoadableByAddress::fixStoreToBlockStorageInstrs() {
for (auto *instr : storeToBlockStorageInstrs) {
auto dest = instr->getDest();
ProjectBlockStorageInst *destBlock =
dyn_cast<ProjectBlockStorageInst>(dest);
assert(destBlock && "Expected Block Storage dest");
auto destBlock = cast<ProjectBlockStorageInst>(dest);
SILType destType = destBlock->getType();
auto src = instr->getSrc();
SILType srcType = src->getType();
@@ -2447,28 +2435,23 @@ void LoadableByAddress::recreateConvInstrs() {
SILType newType =
getNewSILFunctionType(genEnv, currSILFunctionType, *currIRMod);
SILBuilder convBuilder(convInstr);
SILInstruction *newInstr = nullptr;
SingleValueInstruction *newInstr = nullptr;
switch (convInstr->getKind()) {
case ValueKind::ThinToThickFunctionInst: {
ThinToThickFunctionInst *instr =
dyn_cast<ThinToThickFunctionInst>(convInstr);
assert(instr && "Unexpected conversion instruction");
case SILInstructionKind::ThinToThickFunctionInst: {
auto instr = cast<ThinToThickFunctionInst>(convInstr);
newInstr = convBuilder.createThinToThickFunction(
instr->getLoc(), instr->getOperand(), newType);
break;
}
case ValueKind::ThinFunctionToPointerInst: {
ThinFunctionToPointerInst *instr =
dyn_cast<ThinFunctionToPointerInst>(convInstr);
assert(instr && "Unexpected conversion instruction");
case SILInstructionKind::ThinFunctionToPointerInst: {
auto instr = cast<ThinFunctionToPointerInst>(convInstr);
newType = getNewSILType(genEnv, instr->getType(), *getIRGenModule());
newInstr = convBuilder.createThinFunctionToPointer(
instr->getLoc(), instr->getOperand(), newType);
break;
}
case ValueKind::ConvertFunctionInst: {
auto *instr = dyn_cast<ConvertFunctionInst>(convInstr);
assert(instr && "Unexpected conversion instruction");
case SILInstructionKind::ConvertFunctionInst: {
auto instr = cast<ConvertFunctionInst>(convInstr);
newInstr = convBuilder.createConvertFunction(
instr->getLoc(), instr->getOperand(), newType);
break;
@@ -2549,26 +2532,27 @@ void LoadableByAddress::run() {
for (auto *user : FRI->getUses()) {
SILInstruction *currInstr = user->getUser();
switch (currInstr->getKind()) {
case ValueKind::ApplyInst:
case ValueKind::TryApplyInst:
case ValueKind::PartialApplyInst: {
case SILInstructionKind::ApplyInst:
case SILInstructionKind::TryApplyInst:
case SILInstructionKind::PartialApplyInst: {
if (modApplies.count(currInstr) == 0) {
modApplies.insert(currInstr);
}
break;
}
case ValueKind::ThinFunctionToPointerInst:
case ValueKind::ThinToThickFunctionInst: {
conversionInstrs.insert(currInstr);
case SILInstructionKind::ThinFunctionToPointerInst:
case SILInstructionKind::ThinToThickFunctionInst: {
conversionInstrs.insert(
cast<SingleValueInstruction>(currInstr));
break;
}
case ValueKind::BuiltinInst: {
auto *instr = dyn_cast<BuiltinInst>(currInstr);
case SILInstructionKind::BuiltinInst: {
auto *instr = cast<BuiltinInst>(currInstr);
builtinInstrs.insert(instr);
break;
}
case ValueKind::DebugValueAddrInst:
case ValueKind::DebugValueInst: {
case SILInstructionKind::DebugValueAddrInst:
case SILInstructionKind::DebugValueInst: {
break;
}
default: