Skip to content

Commit 44d5f56

Browse files
authored
Merge pull request #3525 from swiftwasm/main
[pull] swiftwasm from main
2 parents 9772eb4 + a66435c commit 44d5f56

File tree

149 files changed

+595
-241
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+595
-241
lines changed

docs/SIL.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6194,7 +6194,8 @@ pointer_to_address
61946194
``````````````````
61956195
::
61966196

6197-
sil-instruction ::= 'pointer_to_address' sil-operand 'to' ('[' 'strict' ']')? sil-type
6197+
sil-instruction ::= 'pointer_to_address' sil-operand 'to' ('[' 'strict' ']')? ('[' 'invariant' ']')? ('[' 'alignment' '=' alignment ']')? sil-type
6198+
alignment ::= [0-9]+
61986199

61996200
%1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*T
62006201
// %1 will be of type $*T
@@ -6214,6 +6215,12 @@ type. A memory access from an address that is not strict cannot have
62146215
its address substituted with a strict address, even if other nearby
62156216
memory accesses at the same location are strict.
62166217

6218+
The ``invariant`` flag is set if loading from the returned address
6219+
always produces the same value.
6220+
6221+
The ``alignment`` integer value specifies the byte alignment of the
6222+
address. ``alignment=0`` is the default, indicating the natural
6223+
alignment of ``T``.
62176224

62186225
unchecked_ref_cast
62196226
``````````````````

include/swift/AST/ASTSynthesis.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,22 @@ Type synthesizeType(SynthesisContext &SC,
130130
return ExistentialMetatypeType::get(synthesizeType(SC, M.Sub));
131131
}
132132

133+
/// A synthesizer that generates a MoveOnly wrapper of a type.
134+
template <class S>
135+
struct MoveOnlyTypeSynthesizer {
136+
S Sub;
137+
};
138+
template <class S>
139+
constexpr MoveOnlyTypeSynthesizer<S> _moveOnly(S sub) {
140+
return {sub};
141+
}
142+
template <class S>
143+
Type synthesizeType(SynthesisContext &SC, const MoveOnlyTypeSynthesizer<S> &M) {
144+
// Until we get the actual move only type, we just return the synthesized
145+
// type.
146+
return synthesizeType(SC, M.Sub);
147+
}
148+
133149
/// Helper types for variadic synthesis.
134150
template <class... Ss>
135151
struct VariadicSynthesizerStorage;

include/swift/AST/Builtins.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,9 @@ BUILTIN_SIL_OPERATION(WithUnsafeThrowingContinuation, "withUnsafeThrowingContinu
515515
/// Force the current task to be rescheduled on the specified actor.
516516
BUILTIN_SIL_OPERATION(HopToActor, "hopToActor", None)
517517

518+
/// Generate a move_value instruction to convert a T to a @_moveOnly T.
519+
BUILTIN_SIL_OPERATION(Move, "move", Special)
520+
518521
#undef BUILTIN_SIL_OPERATION
519522

520523
// BUILTIN_RUNTIME_CALL - A call into a runtime function.

include/swift/SIL/SILBuilder.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,12 +1064,12 @@ class SILBuilder {
10641064
getSILDebugLocation(Loc), Op, Ty));
10651065
}
10661066

1067-
PointerToAddressInst *createPointerToAddress(SILLocation Loc, SILValue Op,
1068-
SILType Ty,
1069-
bool isStrict,
1070-
bool isInvariant = false){
1067+
PointerToAddressInst *
1068+
createPointerToAddress(SILLocation Loc, SILValue Op, SILType Ty,
1069+
bool isStrict, bool isInvariant = false,
1070+
llvm::MaybeAlign alignment = llvm::MaybeAlign()) {
10711071
return insert(new (getModule()) PointerToAddressInst(
1072-
getSILDebugLocation(Loc), Op, Ty, isStrict, isInvariant));
1072+
getSILDebugLocation(Loc), Op, Ty, isStrict, isInvariant, alignment));
10731073
}
10741074

10751075
UncheckedRefCastInst *createUncheckedRefCast(SILLocation Loc, SILValue Op,

include/swift/SIL/SILInstruction.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5127,10 +5127,15 @@ class PointerToAddressInst
51275127
friend SILBuilder;
51285128

51295129
PointerToAddressInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
5130-
bool IsStrict, bool IsInvariant)
5131-
: UnaryInstructionBase(DebugLoc, Operand, Ty) {
5130+
bool IsStrict, bool IsInvariant,
5131+
llvm::MaybeAlign Alignment)
5132+
: UnaryInstructionBase(DebugLoc, Operand, Ty) {
51325133
SILNode::Bits.PointerToAddressInst.IsStrict = IsStrict;
51335134
SILNode::Bits.PointerToAddressInst.IsInvariant = IsInvariant;
5135+
unsigned encodedAlignment = llvm::encode(Alignment);
5136+
SILNode::Bits.PointerToAddressInst.Alignment = encodedAlignment;
5137+
assert(SILNode::Bits.PointerToAddressInst.Alignment == encodedAlignment
5138+
&& "pointer_to_address alignment overflow");
51345139
}
51355140

51365141
public:
@@ -5146,6 +5151,13 @@ class PointerToAddressInst
51465151
bool isInvariant() const {
51475152
return SILNode::Bits.PointerToAddressInst.IsInvariant;
51485153
}
5154+
5155+
/// The byte alignment of the address. Since the alignment of types isn't
5156+
/// known until IRGen (TypeInfo::getBestKnownAlignment), in SIL an unknown
5157+
/// alignment indicates the natural in-memory alignment of the element type.
5158+
llvm::MaybeAlign alignment() const {
5159+
return llvm::decodeMaybeAlign(SILNode::Bits.PointerToAddressInst.Alignment);
5160+
}
51495161
};
51505162

51515163
/// Convert a heap object reference to a different type without any runtime

include/swift/SIL/SILNode.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -368,10 +368,8 @@ class alignas(8) SILNode :
368368
UIWTDOB_BITFIELD_EMPTY(ObjCMethodInst, MethodInst);
369369

370370
SWIFT_INLINE_BITFIELD_EMPTY(ConversionInst, SingleValueInstruction);
371-
SWIFT_INLINE_BITFIELD(PointerToAddressInst, ConversionInst, 1+1,
372-
IsStrict : 1,
373-
IsInvariant : 1
374-
);
371+
SWIFT_INLINE_BITFIELD(PointerToAddressInst, ConversionInst, 8 + 1 + 1,
372+
Alignment : 8, IsStrict : 1, IsInvariant : 1);
375373

376374
UIWTDOB_BITFIELD(ConvertFunctionInst, ConversionInst, 1,
377375
WithoutActuallyEscaping : 1);

lib/AST/Builtins.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,12 @@ static ValueDecl *getDestroyArrayOperation(ASTContext &ctx, Identifier id) {
854854
_void);
855855
}
856856

857+
static ValueDecl *getMoveOperation(ASTContext &ctx, Identifier id) {
858+
return getBuiltinFunction(ctx, id, _thin, _generics(_unrestricted),
859+
_parameters(_owned(_typeparam(0))),
860+
_moveOnly(_typeparam(0)));
861+
}
862+
857863
static ValueDecl *getTransferArrayOperation(ASTContext &ctx, Identifier id) {
858864
return getBuiltinFunction(ctx, id, _thin,
859865
_generics(_unrestricted),
@@ -2500,6 +2506,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
25002506
if (!Types.empty()) return nullptr;
25012507
return getEndUnpairedAccessOperation(Context, Id);
25022508

2509+
case BuiltinValueKind::Move:
2510+
if (!Types.empty())
2511+
return nullptr;
2512+
return getMoveOperation(Context, Id);
2513+
25032514
#define BUILTIN(id, name, Attrs)
25042515
#define BUILTIN_BINARY_OPERATION(id, name, attrs)
25052516
#define BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(id, name, attrs, overload) \

lib/IRGen/IRGenSIL.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5633,9 +5633,11 @@ void IRGenSILFunction::visitPointerToAddressInst(swift::PointerToAddressInst *i)
56335633

56345634
llvm::Type *destType = ti.getStorageType()->getPointerTo();
56355635
ptrValue = Builder.CreateBitCast(ptrValue, destType);
5636-
5637-
setLoweredAddress(i,
5638-
ti.getAddressForPointer(ptrValue));
5636+
5637+
if (i->alignment())
5638+
setLoweredAddress(i, Address(ptrValue, Alignment(i->alignment()->value())));
5639+
else
5640+
setLoweredAddress(i, ti.getAddressForPointer(ptrValue));
56395641
}
56405642

56415643
static void emitPointerCastInst(IRGenSILFunction &IGF,

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
17511751
*this << "[strict] ";
17521752
if (CI->isInvariant())
17531753
*this << "[invariant] ";
1754+
if (CI->alignment())
1755+
*this << "[align=" << CI->alignment()->value() << "] ";
17541756
*this << CI->getType();
17551757
}
17561758
void visitUncheckedRefCastInst(UncheckedRefCastInst *CI) {

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -802,15 +802,35 @@ static SILLinkage resolveSILLinkage(Optional<SILLinkage> linkage,
802802
}
803803
}
804804

805-
static bool parseSILOptional(StringRef &Result, SourceLoc &Loc, SILParser &SP) {
806-
if (SP.P.consumeIf(tok::l_square)) {
807-
Identifier Id;
808-
SP.parseSILIdentifier(Id, Loc, diag::expected_in_attribute_list);
809-
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
810-
Result = Id.str();
805+
// Returns false if no optional exists. Returns true on both success and
806+
// failure. On success, the Result string is nonempty. If the optional is
807+
// assigned to an integer value, \p value contains the parsed value. Otherwise,
808+
// value is set to the maximum uint64_t.
809+
static bool parseSILOptional(StringRef &Result, uint64_t &value, SourceLoc &Loc,
810+
SILParser &SP) {
811+
if (!SP.P.consumeIf(tok::l_square))
812+
return false;
813+
814+
value = ~uint64_t(0);
815+
816+
Identifier Id;
817+
if (SP.parseSILIdentifier(Id, Loc, diag::expected_in_attribute_list))
811818
return true;
819+
820+
if (SP.P.consumeIf(tok::equal)) {
821+
if (SP.parseInteger(value, diag::expected_in_attribute_list))
822+
return true;
812823
}
813-
return false;
824+
if (SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list))
825+
return true;
826+
827+
Result = Id.str();
828+
return true;
829+
}
830+
831+
static bool parseSILOptional(StringRef &Result, SourceLoc &Loc, SILParser &SP) {
832+
uint64_t value;
833+
return parseSILOptional(Result, value, Loc, SP);
814834
}
815835

816836
static bool parseSILOptional(StringRef &Result, SILParser &SP) {
@@ -3603,21 +3623,35 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
36033623
parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
36043624
"to"))
36053625
return true;
3606-
if (parseSILOptional(attr, *this) && attr.empty())
3607-
return true;
3626+
3627+
bool isStrict = false;
3628+
bool isInvariant = false;
3629+
llvm::MaybeAlign alignment;
3630+
uint64_t parsedValue = 0;
3631+
while (parseSILOptional(attr, parsedValue, ToLoc, *this)) {
3632+
if (attr.empty())
3633+
return true;
3634+
3635+
if (attr.equals("strict"))
3636+
isStrict = true;
3637+
3638+
if (attr.equals("invariant"))
3639+
isInvariant = true;
3640+
3641+
if (attr.equals("align"))
3642+
alignment = llvm::Align(parsedValue);
3643+
}
3644+
36083645
if (parseSILType(Ty) || parseSILDebugLocation(InstLoc, B))
36093646
return true;
36103647

3611-
bool isStrict = attr.equals("strict");
3612-
bool isInvariant = attr.equals("invariant");
3613-
36143648
if (ToToken.str() != "to") {
36153649
P.diagnose(ToLoc, diag::expected_tok_in_sil_instr, "to");
36163650
return true;
36173651
}
36183652

3619-
ResultVal =
3620-
B.createPointerToAddress(InstLoc, Val, Ty, isStrict, isInvariant);
3653+
ResultVal = B.createPointerToAddress(InstLoc, Val, Ty, isStrict,
3654+
isInvariant, alignment);
36213655
break;
36223656
}
36233657
case SILInstructionKind::RefToBridgeObjectInst: {

0 commit comments

Comments
 (0)