Skip to content

Commit 295bb62

Browse files
committed
Add support for open_existential_box_value in Address Lowering
1 parent 16c277f commit 295bb62

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
///
3838
/// 1. Reused-storage: Some operations are guaranteed to reuse their operand's
3939
/// storage. This includes extracting an enum payload and opening an existential
40-
/// value. This is required avoid introducing new copies or moves.
40+
/// value. This is required to avoid introducing new copies or moves.
4141
///
4242
/// // %data's storage must reuse storage allocated for %enum
4343
/// %data = unchecked_enum_data %enum : $Optional<T>, #Optional.some!enumelt
@@ -2503,12 +2503,6 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
25032503
// types.
25042504
void visitOpenExistentialValueInst(OpenExistentialValueInst *openExistential);
25052505

2506-
void visitOpenExistentialBoxValueInst(
2507-
OpenExistentialBoxValueInst *openExistentialBox) {
2508-
// FIXME: Unimplemented
2509-
llvm::report_fatal_error("Unimplemented OpenExistentialBox use.");
2510-
}
2511-
25122506
void visitReturnInst(ReturnInst *returnInst) {
25132507
// Returns are rewritten for any function with indirect results after
25142508
// opaque value rewriting.
@@ -2931,11 +2925,18 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
29312925
addrMat.initializeComposingUse(&initExistentialValue->getOperandRef());
29322926
}
29332927

2934-
// Project an opaque value out of a box-type existential.
29352928
void visitOpenExistentialBoxValueInst(
2936-
OpenExistentialBoxValueInst *openExistentialBox) {
2937-
// FIXME: Unimplemented
2938-
llvm::report_fatal_error("Unimplemented OpenExistentialBoxValue def.");
2929+
OpenExistentialBoxValueInst *openExistentialBoxValue) {
2930+
// Replace the module's openedArchetypesDef
2931+
pass.getModule()->willDeleteInstruction(openExistentialBoxValue);
2932+
2933+
auto *openAddr = builder.createOpenExistentialBox(
2934+
openExistentialBoxValue->getLoc(),
2935+
openExistentialBoxValue->getOperand(),
2936+
openExistentialBoxValue->getType().getAddressType());
2937+
2938+
openExistentialBoxValue->replaceAllTypeDependentUsesWith(openAddr);
2939+
markRewritten(openExistentialBoxValue, openAddr);
29392940
}
29402941

29412942
// Load an opaque value.
@@ -2970,6 +2971,14 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
29702971
for (Operand &operand : tupleInst->getAllOperands())
29712972
addrMat.initializeComposingUse(&operand);
29722973
}
2974+
2975+
void markRewritten(SILValue oldValue, SILValue addr) {
2976+
auto &storage = pass.valueStorageMap.getStorage(oldValue);
2977+
// getReusedStorageOperand() ensures that oldValue does not already have
2978+
// separate storage. So there's no need to delete its alloc_stack.
2979+
assert(!storage.storageAddress || storage.storageAddress == addr);
2980+
storage.storageAddress = addr;
2981+
}
29732982
};
29742983
} // end anonymous namespace
29752984

@@ -3124,7 +3133,8 @@ static void deleteRewrittenInstructions(AddressLoweringState &pass) {
31243133
}
31253134
}
31263135
LLVM_DEBUG(llvm::dbgs() << "DEAD "; deadInst->dump());
3127-
if (!isa<OpenExistentialValueInst>(deadInst)) {
3136+
if (!isa<OpenExistentialValueInst>(deadInst) &&
3137+
!isa<OpenExistentialBoxValueInst>(deadInst)) {
31283138
pass.deleter.forceDeleteWithUsers(deadInst);
31293139
continue;
31303140
}

0 commit comments

Comments
 (0)