Skip to content

Commit 6538d54

Browse files
author
Joe Shajrawi
committed
Builtins: add StringObjectOr and use it in the standard library
1 parent f732ea6 commit 6538d54

File tree

7 files changed

+58
-15
lines changed

7 files changed

+58
-15
lines changed

include/swift/AST/Builtins.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,8 @@ BUILTIN_MISC_OPERATION(StaticReport, "staticReport", "", Special)
448448
/// Returns the selected assertion configuration.
449449
BUILTIN_MISC_OPERATION(AssertConf, "assert_configuration", "n", Special)
450450

451+
/// StringObjectOr has type (T,T) -> T.
452+
BUILTIN_MISC_OPERATION(StringObjectOr, "stringObjectOr", "n", Integer)
451453

452454
/// Special truncation builtins that check for sign and overflow errors. These
453455
/// take an integer as an input and return a tuple of the truncated result and

lib/AST/Builtins.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ static ValueDecl *getGepRawOperation(Identifier Id, Type ArgType) {
265265
return getBuiltinFunction(Id, ArgElts, ResultTy);
266266
}
267267

268+
static ValueDecl *getStringObjectOrOperation(Identifier Id, Type ArgType) {
269+
return getBuiltinFunction(Id, {ArgType, ArgType}, ArgType);
270+
}
271+
268272
/// Build a binary operation declaration.
269273
static ValueDecl *getBinaryOperation(Identifier Id, Type ArgType) {
270274
return getBuiltinFunction(Id, { ArgType, ArgType }, ArgType);
@@ -1628,6 +1632,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
16281632
if (Types.size() != 1) return nullptr;
16291633
return getGepRawOperation(Id, Types[0]);
16301634

1635+
case BuiltinValueKind::StringObjectOr:
1636+
if (Types.size() != 1)
1637+
return nullptr;
1638+
return getStringObjectOrOperation(Id, Types[0]);
1639+
16311640
case BuiltinValueKind::Gep:
16321641
if (Types.size() != 1) return nullptr;
16331642
return getGepOperation(Context, Id, Types[0]);

lib/IRGen/GenBuiltin.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,14 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
252252
return;
253253
}
254254

255-
// TODO: A linear series of ifs is suboptimal.
255+
if (Builtin.ID == BuiltinValueKind::StringObjectOr) {
256+
llvm::Value *lhs = args.claimNext();
257+
llvm::Value *rhs = args.claimNext();
258+
llvm::Value *v = IGF.Builder.CreateOr(lhs, rhs);
259+
return out.add(v);
260+
}
261+
262+
// TODO: A linear series of ifs is suboptimal.
256263
#define BUILTIN_SIL_OPERATION(id, name, overload) \
257264
if (Builtin.ID == BuiltinValueKind::id) \
258265
llvm_unreachable(name " builtin should be lowered away by SILGen!");

lib/SIL/SILOwnershipVerifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,7 @@ CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, Shl)
13541354
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, Sizeof)
13551355
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, StaticReport)
13561356
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, Strideof)
1357+
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, StringObjectOr)
13571358
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, Sub)
13581359
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, TakeArrayNoAlias)
13591360
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, TakeArrayBackToFront)

lib/SIL/ValueOwnershipKindClassifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ CONSTANT_OWNERSHIP_BUILTIN(Trivial, ProjectTailElems)
467467
CONSTANT_OWNERSHIP_BUILTIN(Trivial, IsOptionalType)
468468
CONSTANT_OWNERSHIP_BUILTIN(Trivial, Sizeof)
469469
CONSTANT_OWNERSHIP_BUILTIN(Trivial, Strideof)
470+
CONSTANT_OWNERSHIP_BUILTIN(Trivial, StringObjectOr)
470471
CONSTANT_OWNERSHIP_BUILTIN(Trivial, IsPOD)
471472
CONSTANT_OWNERSHIP_BUILTIN(Trivial, IsSameMetatype)
472473
CONSTANT_OWNERSHIP_BUILTIN(Trivial, Alignof)

stdlib/public/core/StringObject.swift

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ extension _StringObject {
261261
internal
262262
static var _variantMask: UInt {
263263
@inline(__always)
264-
get { return _isValueBit | _subVariantBit }
264+
get { return UInt(Builtin.stringObjectOr_Int64(
265+
_isValueBit._value, _subVariantBit._value)) }
265266
}
266267

267268
@_versioned
@@ -364,7 +365,8 @@ extension _StringObject {
364365
internal
365366
static var _emptyStringBitPattern: UInt {
366367
@inline(__always)
367-
get { return _isValueBit | _emptyStringAddressBits }
368+
get { return UInt(Builtin.stringObjectOr_Int64(
369+
_isValueBit._value, _emptyStringAddressBits._value)) }
368370
}
369371

370372
@_versioned
@@ -784,20 +786,32 @@ extension _StringObject {
784786
_sanityCheck(_payloadBits & ~_StringObject._payloadMask == 0)
785787
var rawBits = _payloadBits & _StringObject._payloadMask
786788
if isValue {
787-
rawBits |= _StringObject._isValueBit
788-
}
789-
if isSmallOrObjC {
790-
rawBits |= _StringObject._subVariantBit
791-
}
792-
if isOpaque {
793-
rawBits |= _StringObject._isOpaqueBit
794-
}
795-
if isTwoByte {
796-
rawBits |= _StringObject._twoByteBit
797-
}
798-
if isValue {
789+
var rawBitsBuiltin = Builtin.stringObjectOr_Int64(
790+
rawBits._value, _StringObject._isValueBit._value)
791+
if isSmallOrObjC {
792+
rawBitsBuiltin = Builtin.stringObjectOr_Int64(
793+
rawBitsBuiltin, _StringObject._subVariantBit._value)
794+
}
795+
if isOpaque {
796+
rawBitsBuiltin = Builtin.stringObjectOr_Int64(
797+
rawBitsBuiltin, _StringObject._isOpaqueBit._value)
798+
}
799+
if isTwoByte {
800+
rawBitsBuiltin = Builtin.stringObjectOr_Int64(
801+
rawBitsBuiltin, _StringObject._twoByteBit._value)
802+
}
803+
rawBits = UInt(rawBitsBuiltin)
799804
self.init(taggedRawBits: rawBits)
800805
} else {
806+
if isSmallOrObjC {
807+
rawBits |= _StringObject._subVariantBit
808+
}
809+
if isOpaque {
810+
rawBits |= _StringObject._isOpaqueBit
811+
}
812+
if isTwoByte {
813+
rawBits |= _StringObject._twoByteBit
814+
}
801815
self.init(nonTaggedRawBits: rawBits)
802816
}
803817
#endif

test/IRGen/builtins.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,15 @@ func atomicload(_ p: Builtin.RawPointer) {
840840
Builtin.atomicstore_seqcst_volatile_FPIEEE32(p, d)
841841
}
842842

843+
// CHECK-LABEL: define {{.*}} @"$S8builtins14stringObjectOryS2u_SutF"(i64, i64)
844+
// CHECK-NEXT: {{.*}}:
845+
// CHECK-NEXT: %2 = or i64 %0, %1
846+
// CHECK-NEXT: ret i64 %2
847+
func stringObjectOr(_ x: UInt, _ y: UInt) -> UInt {
848+
return UInt(Builtin.stringObjectOr_Int64(
849+
x._value, y._value))
850+
}
851+
843852
func createInt(_ fn: () -> ()) throws {}
844853
// CHECK-LABEL: define {{.*}}testForceTry
845854
// CHECK: call swiftcc void @swift_unexpectedError(%swift.error*

0 commit comments

Comments
 (0)