Skip to content

Commit db9a140

Browse files
Merge pull request #61887 from nate-chandler/opaque-values/1/20221102
[OpaqueValues] Handle Builtin.addressOfBorrow.
2 parents ae7466f + ae7c69b commit db9a140

File tree

8 files changed

+71
-0
lines changed

8 files changed

+71
-0
lines changed

include/swift/AST/Builtins.def

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,24 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(EndAsyncLet, "endAsyncLet", "", Special)
915915
/// until the endAsyncLet.
916916
BUILTIN_MISC_OPERATION(EndAsyncLetLifetime, "endAsyncLetLifetime", "", Special)
917917

918+
/// addressOfBorrowOpaque (__shared T) -> Builtin.RawPointer
919+
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is
920+
/// only valid within the scope of the borrow.
921+
///
922+
/// Differs from addressOfBorrow only in that it is not lowered until
923+
/// AddressLowering.
924+
BUILTIN_MISC_OPERATION(AddressOfBorrowOpaque, "addressOfBorrowOpaque", "", Special)
925+
926+
/// unprotectedAddressOfBorrowOpaque (__shared T) -> Builtin.RawPointer
927+
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is only
928+
/// valid within the scope of the borrow.
929+
/// In contrast to `addressOfBorrowOpaque`, this builtin doesn't trigger an
930+
/// insertion of stack protectors.
931+
///
932+
/// Differs from unprotectedAddressOfBorrow only in that it is not lowered until
933+
/// AddressLowering.
934+
BUILTIN_MISC_OPERATION(UnprotectedAddressOfBorrowOpaque, "unprotectedAddressOfBorrowOpaque", "", Special)
935+
918936
/// createAsyncTask(): (
919937
/// Int, // task-creation flags
920938
/// @escaping () async throws -> T // function

lib/AST/Builtins.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,7 +2701,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
27012701
return getLegacyCondFailOperation(Context, Id);
27022702

27032703
case BuiltinValueKind::AddressOfBorrow:
2704+
case BuiltinValueKind::AddressOfBorrowOpaque:
27042705
case BuiltinValueKind::UnprotectedAddressOfBorrow:
2706+
case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque:
27052707
if (!Types.empty()) return nullptr;
27062708
return getAddressOfBorrowOperation(Context, Id);
27072709

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,8 @@ struct OperandOwnershipBuiltinClassifier
678678
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, ErrorInMain)
679679
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, UnexpectedError)
680680
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, WillThrow)
681+
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AddressOfBorrowOpaque)
682+
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, UnprotectedAddressOfBorrowOpaque)
681683
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AShr)
682684
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, GenericAShr)
683685
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, Add)

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ struct ValueOwnershipKindBuiltinVisitor
382382
// This returns a value at +1 that is destroyed strictly /after/ the
383383
// UnsafeGuaranteedEnd. This provides the guarantee that we want.
384384
CONSTANT_OWNERSHIP_BUILTIN(Owned, COWBufferForReading)
385+
CONSTANT_OWNERSHIP_BUILTIN(None, AddressOfBorrowOpaque)
386+
CONSTANT_OWNERSHIP_BUILTIN(None, UnprotectedAddressOfBorrowOpaque)
385387
CONSTANT_OWNERSHIP_BUILTIN(None, AShr)
386388
CONSTANT_OWNERSHIP_BUILTIN(None, GenericAShr)
387389
CONSTANT_OWNERSHIP_BUILTIN(None, Add)

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,17 @@ static ManagedValue emitBuiltinAddressOfBorrowBuiltins(SILGenFunction &SGF,
478478
// naturally emitted borrowed in memory.
479479
auto borrow = SGF.emitRValue(argument, SGFContext::AllowGuaranteedPlusZero)
480480
.getAsSingleValue(SGF, argument);
481+
if (!SGF.F.getConventions().useLoweredAddresses()) {
482+
auto &context = SGF.getASTContext();
483+
auto identifier =
484+
stackProtected
485+
? context.getIdentifier("addressOfBorrowOpaque")
486+
: context.getIdentifier("unprotectedAddressOfBorrowOpaque");
487+
auto builtin = SGF.B.createBuiltin(loc, identifier, rawPointerType,
488+
substitutions, {borrow.getValue()});
489+
return ManagedValue::forUnmanaged(builtin);
490+
}
491+
481492
if (!borrow.isPlusZero() || !borrow.getType().isAddress()) {
482493
SGF.SGM.diagnose(argument->getLoc(), diag::non_borrowed_indirect_addressof);
483494
return SGF.emitUndef(rawPointerType);

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2617,13 +2617,29 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
26172617
vmi->setOperand(opAddr);
26182618
}
26192619

2620+
void visitAddressOfBorrowBuiltinInst(BuiltinInst *bi, bool stackProtected) {
2621+
SILValue value = bi->getOperand(0);
2622+
SILValue addr = pass.valueStorageMap.getStorage(value).storageAddress;
2623+
auto &astCtx = pass.getModule()->getASTContext();
2624+
SILType rawPointerType = SILType::getRawPointerType(astCtx);
2625+
SILValue result = builder.createAddressToPointer(
2626+
bi->getLoc(), addr, rawPointerType, stackProtected);
2627+
bi->replaceAllUsesWith(result);
2628+
}
2629+
26202630
void visitBuiltinInst(BuiltinInst *bi) {
26212631
switch (bi->getBuiltinKind().getValueOr(BuiltinValueKind::None)) {
26222632
case BuiltinValueKind::Copy: {
26232633
SILValue opAddr = addrMat.materializeAddress(use->get());
26242634
bi->setOperand(0, opAddr);
26252635
break;
26262636
}
2637+
case BuiltinValueKind::AddressOfBorrowOpaque:
2638+
visitAddressOfBorrowBuiltinInst(bi, /*stackProtected=*/true);
2639+
break;
2640+
case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque:
2641+
visitAddressOfBorrowBuiltinInst(bi, /*stackProtected=*/false);
2642+
break;
26272643
default:
26282644
bi->dump();
26292645
llvm::report_fatal_error("^^^ Unimplemented builtin opaque value use.");

lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ static bool isBarrier(SILInstruction *inst) {
193193
case BuiltinValueKind::ResumeThrowingContinuationThrowing:
194194
case BuiltinValueKind::AutoDiffProjectTopLevelSubcontext:
195195
case BuiltinValueKind::AutoDiffAllocateSubcontext:
196+
case BuiltinValueKind::AddressOfBorrowOpaque:
197+
case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque:
196198
return true;
197199
}
198200
}

test/SILOptimizer/opaque_values_Onone_stdlib.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,22 @@ public func _copy<T>(_ value: T) -> T {
3131
#endif
3232
}
3333

34+
// CHECK-LABEL: sil hidden @getRawPointer : {{.*}} {
35+
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
36+
// CHECK: [[PTR:%[^,]+]] = address_to_pointer [stack_protection] [[ADDR]]
37+
// CHECK: return [[PTR]]
38+
// CHECK-LABEL: } // end sil function 'getRawPointer'
39+
@_silgen_name("getRawPointer")
40+
func getRawPointer<T>(to value: T) -> Builtin.RawPointer {
41+
return Builtin.addressOfBorrow(value)
42+
}
3443

44+
// CHECK-LABEL: sil hidden @getUnprotectedRawPointer : {{.*}} {
45+
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
46+
// CHECK: [[PTR:%[^,]+]] = address_to_pointer [[ADDR]]
47+
// CHECK: return [[PTR]]
48+
// CHECK-LABEL: } // end sil function 'getUnprotectedRawPointer'
49+
@_silgen_name("getUnprotectedRawPointer")
50+
func getUnprotectedRawPointer<T>(to value: T) -> Builtin.RawPointer {
51+
return Builtin.unprotectedAddressOfBorrow(value)
52+
}

0 commit comments

Comments
 (0)