Skip to content

Commit 102b6f0

Browse files
author
Joe Shajrawi
authored
Merge pull request swiftlang#14587 from shajrawi/newinstr
Optimizer peephole for tagged BridgeObjects
2 parents 1d27a04 + 3675019 commit 102b6f0

26 files changed

+205
-16
lines changed

include/swift/AST/Builtins.def

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,18 @@ BUILTIN_SIL_OPERATION(CastFromNativeObject, "castFromNativeObject", Special)
225225
/// or else undefined behavior will ensue.
226226
BUILTIN_SIL_OPERATION(CastToBridgeObject, "castToBridgeObject", Special)
227227

228+
/// ValueToBridgeObject has type (T) -> Builtin.BridgeObject.
229+
/// It sets the BridgeObject to a tagged pointer representation holding its
230+
// operands by tagging and shifting the operand if needed.
231+
///
232+
/// valueToBridgeObject(x) === (x << _swift_abi_ObjCReservedLowBits) |
233+
/// _swift_BridgeObject_TaggedPointerBits
234+
///
235+
/// x thus must not be using any high bits shifted away (via _swift_abi_ObjCReservedLowBits)
236+
/// or the tag bits post-shift.
237+
/// ARC operations on such tagged values are NOPs.
238+
BUILTIN_SIL_OPERATION(ValueToBridgeObject, "valueToBridgeObject", Special)
239+
228240
/// CastReferenceFromBridgeObject has type (Builtin.BridgeObject) -> T.
229241
/// It recovers the heap object reference by masking spare bits from the
230242
/// BridgeObject.
@@ -436,6 +448,8 @@ BUILTIN_MISC_OPERATION(StaticReport, "staticReport", "", Special)
436448
/// Returns the selected assertion configuration.
437449
BUILTIN_MISC_OPERATION(AssertConf, "assert_configuration", "n", Special)
438450

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

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

include/swift/SIL/PatternMatch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(StrongRetainUnownedInst)
384384
UNARY_OP_MATCH_WITH_ARG_MATCHER(UnownedRetainInst)
385385
UNARY_OP_MATCH_WITH_ARG_MATCHER(UnownedReleaseInst)
386386
UNARY_OP_MATCH_WITH_ARG_MATCHER(ClassifyBridgeObjectInst)
387+
UNARY_OP_MATCH_WITH_ARG_MATCHER(ValueToBridgeObjectInst)
387388
UNARY_OP_MATCH_WITH_ARG_MATCHER(FixLifetimeInst)
388389
UNARY_OP_MATCH_WITH_ARG_MATCHER(CopyBlockInst)
389390
UNARY_OP_MATCH_WITH_ARG_MATCHER(DeallocStackInst)

include/swift/SIL/SILBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,13 @@ class SILBuilder {
870870
getSILDebugLocation(Loc), Op, Ty));
871871
}
872872

873+
ValueToBridgeObjectInst *createValueToBridgeObject(SILLocation Loc,
874+
SILValue value) {
875+
auto Ty = SILType::getBridgeObjectType(getASTContext());
876+
return insert(new (getModule()) ValueToBridgeObjectInst(
877+
getSILDebugLocation(Loc), value, Ty));
878+
}
879+
873880
BridgeObjectToWordInst *createBridgeObjectToWord(SILLocation Loc,
874881
SILValue Op) {
875882
auto Ty = SILType::getBuiltinWordType(getASTContext());

include/swift/SIL/SILCloner.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,15 @@ SILCloner<ImplClass>::visitRefToRawPointerInst(RefToRawPointerInst *Inst) {
11441144
getOpType(Inst->getType())));
11451145
}
11461146

1147+
template <typename ImplClass>
1148+
void SILCloner<ImplClass>::visitValueToBridgeObjectInst(
1149+
ValueToBridgeObjectInst *Inst) {
1150+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1151+
doPostProcess(
1152+
Inst, getBuilder().createValueToBridgeObject(
1153+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
1154+
}
1155+
11471156
template<typename ImplClass>
11481157
void
11491158
SILCloner<ImplClass>::visitRawPointerToRefInst(RawPointerToRefInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4106,6 +4106,18 @@ class BridgeObjectToRefInst
41064106
: UnaryInstructionBase(DebugLoc, Operand, Ty) {}
41074107
};
41084108

4109+
/// Sets the BridgeObject to a tagged pointer representation holding its
4110+
/// operands
4111+
class ValueToBridgeObjectInst
4112+
: public UnaryInstructionBase<SILInstructionKind::ValueToBridgeObjectInst,
4113+
ConversionInst> {
4114+
friend SILBuilder;
4115+
4116+
ValueToBridgeObjectInst(SILDebugLocation DebugLoc, SILValue Operand,
4117+
SILType BridgeObjectTy)
4118+
: UnaryInstructionBase(DebugLoc, Operand, BridgeObjectTy) {}
4119+
};
4120+
41094121
/// Retrieve the bit pattern of a BridgeObject.
41104122
class BridgeObjectToWordInst
41114123
: public UnaryInstructionBase<SILInstructionKind::BridgeObjectToWordInst,

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
355355

356356
SINGLE_VALUE_INST(ClassifyBridgeObjectInst, classify_bridge_object,
357357
SingleValueInstruction, None, DoesNotRelease)
358+
SINGLE_VALUE_INST(ValueToBridgeObjectInst, value_to_bridge_object,
359+
SingleValueInstruction, None, DoesNotRelease)
358360
SINGLE_VALUE_INST(MarkDependenceInst, mark_dependence,
359361
SingleValueInstruction, None, DoesNotRelease)
360362
SINGLE_VALUE_INST(CopyBlockInst, copy_block,

lib/AST/Builtins.cpp

Lines changed: 20 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);
@@ -882,6 +886,13 @@ static ValueDecl *getClassifyBridgeObject(ASTContext &C, Identifier Id) {
882886
return getBuiltinFunction(Id, { C.TheBridgeObjectType }, resultTy);
883887
}
884888

889+
static ValueDecl *getValueToBridgeObject(ASTContext &C, Identifier Id) {
890+
BuiltinGenericSignatureBuilder builder(C);
891+
builder.addParameter(makeGenericParam(0));
892+
builder.setResult(makeConcrete(C.TheBridgeObjectType));
893+
return builder.build(Id);
894+
}
895+
885896
static ValueDecl *getUnsafeGuaranteed(ASTContext &C, Identifier Id) {
886897
// <T : AnyObject> T -> (T, Int8Ty)
887898
//
@@ -1621,6 +1632,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
16211632
if (Types.size() != 1) return nullptr;
16221633
return getGepRawOperation(Id, Types[0]);
16231634

1635+
case BuiltinValueKind::StringObjectOr:
1636+
if (Types.size() != 1)
1637+
return nullptr;
1638+
return getStringObjectOrOperation(Id, Types[0]);
1639+
16241640
case BuiltinValueKind::Gep:
16251641
if (Types.size() != 1) return nullptr;
16261642
return getGepOperation(Context, Id, Types[0]);
@@ -1820,6 +1836,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
18201836
case BuiltinValueKind::ClassifyBridgeObject:
18211837
if (!Types.empty()) return nullptr;
18221838
return getClassifyBridgeObject(Context, Id);
1839+
case BuiltinValueKind::ValueToBridgeObject:
1840+
if (!Types.empty())
1841+
return nullptr;
1842+
return getValueToBridgeObject(Context, Id);
18231843
case BuiltinValueKind::UnsafeGuaranteed:
18241844
return getUnsafeGuaranteed(Context, Id);
18251845

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/IRGen/IRGenSIL.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,7 @@ class IRGenSILFunction :
10561056
void visitClassifyBridgeObjectInst(ClassifyBridgeObjectInst *i);
10571057
void visitBridgeObjectToRefInst(BridgeObjectToRefInst *i);
10581058
void visitBridgeObjectToWordInst(BridgeObjectToWordInst *i);
1059+
void visitValueToBridgeObjectInst(ValueToBridgeObjectInst *i);
10591060

10601061
void visitIndexAddrInst(IndexAddrInst *i);
10611062
void visitTailAddrInst(TailAddrInst *i);
@@ -4705,6 +4706,18 @@ visitClassifyBridgeObjectInst(ClassifyBridgeObjectInst *i) {
47054706
setLoweredExplosion(i, wordEx);
47064707
}
47074708

4709+
void IRGenSILFunction::visitValueToBridgeObjectInst(
4710+
ValueToBridgeObjectInst *i) {
4711+
Explosion in = getLoweredExplosion(i->getOperand());
4712+
Explosion out;
4713+
4714+
emitValueBitwiseCast(
4715+
*this, i->getLoc().getSourceLoc(), in,
4716+
cast<LoadableTypeInfo>(getTypeInfo(i->getOperand()->getType())), out,
4717+
cast<LoadableTypeInfo>(getTypeInfo(i->getType())));
4718+
4719+
setLoweredExplosion(i, out);
4720+
}
47084721

47094722
void IRGenSILFunction::visitBridgeObjectToRefInst(
47104723
swift::BridgeObjectToRefInst *i) {

lib/ParseSIL/ParseSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,6 +2340,7 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
23402340
} break;
23412341

23422342
UNARY_INSTRUCTION(ClassifyBridgeObject)
2343+
UNARY_INSTRUCTION(ValueToBridgeObject)
23432344
UNARY_INSTRUCTION(FixLifetime)
23442345
UNARY_INSTRUCTION(EndLifetime)
23452346
UNARY_INSTRUCTION(CopyBlock)

0 commit comments

Comments
 (0)