mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #61887 from nate-chandler/opaque-values/1/20221102
[OpaqueValues] Handle Builtin.addressOfBorrow.
This commit is contained in:
@@ -915,6 +915,24 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(EndAsyncLet, "endAsyncLet", "", Special)
|
||||
/// until the endAsyncLet.
|
||||
BUILTIN_MISC_OPERATION(EndAsyncLetLifetime, "endAsyncLetLifetime", "", Special)
|
||||
|
||||
/// addressOfBorrowOpaque (__shared T) -> Builtin.RawPointer
|
||||
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is
|
||||
/// only valid within the scope of the borrow.
|
||||
///
|
||||
/// Differs from addressOfBorrow only in that it is not lowered until
|
||||
/// AddressLowering.
|
||||
BUILTIN_MISC_OPERATION(AddressOfBorrowOpaque, "addressOfBorrowOpaque", "", Special)
|
||||
|
||||
/// unprotectedAddressOfBorrowOpaque (__shared T) -> Builtin.RawPointer
|
||||
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is only
|
||||
/// valid within the scope of the borrow.
|
||||
/// In contrast to `addressOfBorrowOpaque`, this builtin doesn't trigger an
|
||||
/// insertion of stack protectors.
|
||||
///
|
||||
/// Differs from unprotectedAddressOfBorrow only in that it is not lowered until
|
||||
/// AddressLowering.
|
||||
BUILTIN_MISC_OPERATION(UnprotectedAddressOfBorrowOpaque, "unprotectedAddressOfBorrowOpaque", "", Special)
|
||||
|
||||
/// createAsyncTask(): (
|
||||
/// Int, // task-creation flags
|
||||
/// @escaping () async throws -> T // function
|
||||
|
||||
@@ -2701,7 +2701,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
|
||||
return getLegacyCondFailOperation(Context, Id);
|
||||
|
||||
case BuiltinValueKind::AddressOfBorrow:
|
||||
case BuiltinValueKind::AddressOfBorrowOpaque:
|
||||
case BuiltinValueKind::UnprotectedAddressOfBorrow:
|
||||
case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque:
|
||||
if (!Types.empty()) return nullptr;
|
||||
return getAddressOfBorrowOperation(Context, Id);
|
||||
|
||||
|
||||
@@ -678,6 +678,8 @@ struct OperandOwnershipBuiltinClassifier
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, ErrorInMain)
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, UnexpectedError)
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, WillThrow)
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AddressOfBorrowOpaque)
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, UnprotectedAddressOfBorrowOpaque)
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AShr)
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, GenericAShr)
|
||||
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, Add)
|
||||
|
||||
@@ -382,6 +382,8 @@ struct ValueOwnershipKindBuiltinVisitor
|
||||
// This returns a value at +1 that is destroyed strictly /after/ the
|
||||
// UnsafeGuaranteedEnd. This provides the guarantee that we want.
|
||||
CONSTANT_OWNERSHIP_BUILTIN(Owned, COWBufferForReading)
|
||||
CONSTANT_OWNERSHIP_BUILTIN(None, AddressOfBorrowOpaque)
|
||||
CONSTANT_OWNERSHIP_BUILTIN(None, UnprotectedAddressOfBorrowOpaque)
|
||||
CONSTANT_OWNERSHIP_BUILTIN(None, AShr)
|
||||
CONSTANT_OWNERSHIP_BUILTIN(None, GenericAShr)
|
||||
CONSTANT_OWNERSHIP_BUILTIN(None, Add)
|
||||
|
||||
@@ -478,6 +478,17 @@ static ManagedValue emitBuiltinAddressOfBorrowBuiltins(SILGenFunction &SGF,
|
||||
// naturally emitted borrowed in memory.
|
||||
auto borrow = SGF.emitRValue(argument, SGFContext::AllowGuaranteedPlusZero)
|
||||
.getAsSingleValue(SGF, argument);
|
||||
if (!SGF.F.getConventions().useLoweredAddresses()) {
|
||||
auto &context = SGF.getASTContext();
|
||||
auto identifier =
|
||||
stackProtected
|
||||
? context.getIdentifier("addressOfBorrowOpaque")
|
||||
: context.getIdentifier("unprotectedAddressOfBorrowOpaque");
|
||||
auto builtin = SGF.B.createBuiltin(loc, identifier, rawPointerType,
|
||||
substitutions, {borrow.getValue()});
|
||||
return ManagedValue::forUnmanaged(builtin);
|
||||
}
|
||||
|
||||
if (!borrow.isPlusZero() || !borrow.getType().isAddress()) {
|
||||
SGF.SGM.diagnose(argument->getLoc(), diag::non_borrowed_indirect_addressof);
|
||||
return SGF.emitUndef(rawPointerType);
|
||||
|
||||
@@ -2617,6 +2617,16 @@ protected:
|
||||
vmi->setOperand(opAddr);
|
||||
}
|
||||
|
||||
void visitAddressOfBorrowBuiltinInst(BuiltinInst *bi, bool stackProtected) {
|
||||
SILValue value = bi->getOperand(0);
|
||||
SILValue addr = pass.valueStorageMap.getStorage(value).storageAddress;
|
||||
auto &astCtx = pass.getModule()->getASTContext();
|
||||
SILType rawPointerType = SILType::getRawPointerType(astCtx);
|
||||
SILValue result = builder.createAddressToPointer(
|
||||
bi->getLoc(), addr, rawPointerType, stackProtected);
|
||||
bi->replaceAllUsesWith(result);
|
||||
}
|
||||
|
||||
void visitBuiltinInst(BuiltinInst *bi) {
|
||||
switch (bi->getBuiltinKind().getValueOr(BuiltinValueKind::None)) {
|
||||
case BuiltinValueKind::Copy: {
|
||||
@@ -2624,6 +2634,12 @@ protected:
|
||||
bi->setOperand(0, opAddr);
|
||||
break;
|
||||
}
|
||||
case BuiltinValueKind::AddressOfBorrowOpaque:
|
||||
visitAddressOfBorrowBuiltinInst(bi, /*stackProtected=*/true);
|
||||
break;
|
||||
case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque:
|
||||
visitAddressOfBorrowBuiltinInst(bi, /*stackProtected=*/false);
|
||||
break;
|
||||
default:
|
||||
bi->dump();
|
||||
llvm::report_fatal_error("^^^ Unimplemented builtin opaque value use.");
|
||||
|
||||
@@ -193,6 +193,8 @@ static bool isBarrier(SILInstruction *inst) {
|
||||
case BuiltinValueKind::ResumeThrowingContinuationThrowing:
|
||||
case BuiltinValueKind::AutoDiffProjectTopLevelSubcontext:
|
||||
case BuiltinValueKind::AutoDiffAllocateSubcontext:
|
||||
case BuiltinValueKind::AddressOfBorrowOpaque:
|
||||
case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,22 @@ public func _copy<T>(_ value: T) -> T {
|
||||
#endif
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @getRawPointer : {{.*}} {
|
||||
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
|
||||
// CHECK: [[PTR:%[^,]+]] = address_to_pointer [stack_protection] [[ADDR]]
|
||||
// CHECK: return [[PTR]]
|
||||
// CHECK-LABEL: } // end sil function 'getRawPointer'
|
||||
@_silgen_name("getRawPointer")
|
||||
func getRawPointer<T>(to value: T) -> Builtin.RawPointer {
|
||||
return Builtin.addressOfBorrow(value)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden @getUnprotectedRawPointer : {{.*}} {
|
||||
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
|
||||
// CHECK: [[PTR:%[^,]+]] = address_to_pointer [[ADDR]]
|
||||
// CHECK: return [[PTR]]
|
||||
// CHECK-LABEL: } // end sil function 'getUnprotectedRawPointer'
|
||||
@_silgen_name("getUnprotectedRawPointer")
|
||||
func getUnprotectedRawPointer<T>(to value: T) -> Builtin.RawPointer {
|
||||
return Builtin.unprotectedAddressOfBorrow(value)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user