Skip to content

SIL: Remove is_nonnull instruction #12433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4557,24 +4557,6 @@ objc_existential_metatype_to_object

TODO

is_nonnull
``````````
::

sil-instruction ::= 'is_nonnull' sil-operand

%1 = is_nonnull %0 : $C
// %0 must be of reference or function type $C
// %1 will be of type Builtin.Int1

Checks whether a reference type value is null, returning 1 if
the value is not null, or 0 if it is null. If the value is a function
type, it checks the function pointer (not the data pointer) for null.

This is not a sensical thing for SIL to represent given that reference
types are non-nullable, but makes sense at the machine level. This is
a horrible hack that should go away someday.

Checked Conversions
~~~~~~~~~~~~~~~~~~~

Expand Down
1 change: 0 additions & 1 deletion include/swift/SIL/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,6 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(ThickToObjCMetatypeInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCToThickMetatypeInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCMetatypeToObjectInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCExistentialMetatypeToObjectInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(IsNonnullInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(RetainValueInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(RetainValueAddrInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(ReleaseValueInst)
Expand Down
6 changes: 0 additions & 6 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -889,12 +889,6 @@ class SILBuilder {
RefToUnmanagedInst(getSILDebugLocation(Loc), op, ty));
}

IsNonnullInst *createIsNonnull(SILLocation Loc, SILValue operand) {
return insert(new (getModule()) IsNonnullInst(
getSILDebugLocation(Loc), operand,
SILType::getBuiltinIntegerType(1, getASTContext())));
}

UnconditionalCheckedCastInst *
createUnconditionalCheckedCast(SILLocation Loc, SILValue op, SILType destTy) {
return insert(UnconditionalCheckedCastInst::create(
Expand Down
9 changes: 0 additions & 9 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1184,15 +1184,6 @@ visitObjCToThickMetatypeInst(ObjCToThickMetatypeInst *Inst) {
getOpType(Inst->getType())));
}

template<typename ImplClass>
void
SILCloner<ImplClass>::visitIsNonnullInst(IsNonnullInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createIsNonnull(getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand())));
}

template<typename ImplClass>
void
SILCloner<ImplClass>::visitUnconditionalCheckedCastInst(
Expand Down
10 changes: 0 additions & 10 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3831,16 +3831,6 @@ class ObjCProtocolInst
MutableArrayRef<Operand> getAllOperands() { return {}; }
};

/// Test that an address or reference type is not null.
class IsNonnullInst
: public UnaryInstructionBase<SILInstructionKind::IsNonnullInst,
SingleValueInstruction> {
friend SILBuilder;

IsNonnullInst(SILDebugLocation DebugLoc, SILValue Operand, SILType BoolTy)
: UnaryInstructionBase(DebugLoc, Operand, BoolTy) {}
};


/// Perform an unconditional checked cast that aborts if the cast fails.
class UnconditionalCheckedCastInst final
Expand Down
7 changes: 2 additions & 5 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -462,12 +462,9 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
SINGLE_VALUE_INST(KeyPathInst, keypath,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)

SINGLE_VALUE_INST(IsNonnullInst, is_nonnull,
SingleValueInstruction, None, DoesNotRelease)

SINGLE_VALUE_INST_RANGE(SingleValueInstruction, AllocStackInst, IsNonnullInst)
SINGLE_VALUE_INST_RANGE(SingleValueInstruction, AllocStackInst, KeyPathInst)

NODE_RANGE(ValueBase, SILPHIArgument, IsNonnullInst)
NODE_RANGE(ValueBase, SILPHIArgument, KeyPathInst)

// Terminators
ABSTRACT_INST(TermInst, SILInstruction)
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
/// in source control, you should also update the comment to briefly
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
const uint16_t VERSION_MINOR = 369; // Last change: associated type overrides
const uint16_t VERSION_MINOR = 370; // Last change: remove is_nonnull

using DeclID = PointerEmbeddedInt<unsigned, 31>;
using DeclIDField = BCFixed<31>;
Expand Down
31 changes: 0 additions & 31 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,8 +1009,6 @@ class IRGenSILFunction :
void visitBridgeObjectToRefInst(BridgeObjectToRefInst *i);
void visitBridgeObjectToWordInst(BridgeObjectToWordInst *i);

void visitIsNonnullInst(IsNonnullInst *i);

void visitIndexAddrInst(IndexAddrInst *i);
void visitTailAddrInst(TailAddrInst *i);
void visitIndexRawPointerInst(IndexRawPointerInst *i);
Expand Down Expand Up @@ -4695,35 +4693,6 @@ void IRGenSILFunction::visitKeyPathInst(swift::KeyPathInst *I) {
setLoweredExplosion(I, e);
}

void IRGenSILFunction::visitIsNonnullInst(swift::IsNonnullInst *i) {
// Get the value we're testing, which may be a function, an address or an
// instance pointer.
llvm::Value *val;

SILValue operand = i->getOperand();
auto type = operand->getType();
if (type.isAddress()) {
val = getLoweredAddress(operand).getAddress();
} else if (auto fnType = type.getAs<SILFunctionType>()) {
Explosion values = getLoweredExplosion(operand);
val = values.claimNext(); // Function pointer.
if (fnType->getRepresentation() == SILFunctionTypeRepresentation::Thick)
(void) values.claimNext(); // Ignore the data pointer.
} else {
Explosion values = getLoweredExplosion(operand);
val = values.claimNext();
}

// Check that the result isn't null.
auto *valTy = cast<llvm::PointerType>(val->getType());
llvm::Value *result = Builder.CreateICmp(llvm::CmpInst::ICMP_NE,
val, llvm::ConstantPointerNull::get(valTy));

Explosion out;
out.add(result);
setLoweredExplosion(i, out);
}

void IRGenSILFunction::visitUpcastInst(swift::UpcastInst *i) {
auto toTy = getTypeInfo(i->getType()).getSchema()[0].getScalarType();

Expand Down
8 changes: 0 additions & 8 deletions lib/ParseSIL/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4005,14 +4005,6 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
ResultVal = B.createRefTailAddr(InstLoc, Val, ResultTy);
break;
}
case SILInstructionKind::IsNonnullInst: {
SourceLoc Loc;
if (parseTypedValueRef(Val, Loc, B) ||
parseSILDebugLocation(InstLoc, B))
return true;
ResultVal = B.createIsNonnull(InstLoc, Val);
break;
}
case SILInstructionKind::IndexAddrInst: {
SILValue IndexVal;
if (parseTypedValueRef(Val, B) ||
Expand Down
4 changes: 0 additions & 4 deletions lib/SIL/SILInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,10 +721,6 @@ namespace {
return true;
}

bool visitIsNonnullInst(IsNonnullInst *RHS) {
return true;
}

bool visitBridgeObjectToRefInst(BridgeObjectToRefInst *X) {
return true;
}
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/SILOwnershipVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,6 @@ ACCEPTS_ANY_OWNERSHIP_INST(UncheckedTrivialBitCast)
ACCEPTS_ANY_OWNERSHIP_INST(ExistentialMetatype)
ACCEPTS_ANY_OWNERSHIP_INST(ValueMetatype)
ACCEPTS_ANY_OWNERSHIP_INST(UncheckedOwnershipConversion)
ACCEPTS_ANY_OWNERSHIP_INST(IsNonnull)
#undef ACCEPTS_ANY_OWNERSHIP_INST

// Trivial if trivial typed, otherwise must accept owned?
Expand Down
4 changes: 0 additions & 4 deletions lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1467,10 +1467,6 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
printUncheckedConversionInst(I, I->getOperand());
}

void visitIsNonnullInst(IsNonnullInst *I) {
*this << getIDAndType(I->getOperand());
}

void visitCopyValueInst(CopyValueInst *I) {
*this << getIDAndType(I->getOperand());
}
Expand Down
7 changes: 0 additions & 7 deletions lib/SIL/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3107,13 +3107,6 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
}
}

void checkIsNonnullInst(IsNonnullInst *II) {
// The operand must be a function type or a class type.
auto OpTy = II->getOperand()->getType().getSwiftRValueType();
require(OpTy->mayHaveSuperclass() || OpTy->is<SILFunctionType>(),
"is_nonnull operand must be a class or function type");
}

void checkAddressToPointerInst(AddressToPointerInst *AI) {
require(AI->getOperand()->getType().isAddress(),
"address-to-pointer operand must be an address");
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/ValueOwnershipKindClassifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ CONSTANT_OWNERSHIP_INST(Trivial, InitEnumDataAddr)
CONSTANT_OWNERSHIP_INST(Trivial, InitExistentialAddr)
CONSTANT_OWNERSHIP_INST(Trivial, InitExistentialMetatype)
CONSTANT_OWNERSHIP_INST(Trivial, IntegerLiteral)
CONSTANT_OWNERSHIP_INST(Trivial, IsNonnull)
CONSTANT_OWNERSHIP_INST(Trivial, IsUnique)
CONSTANT_OWNERSHIP_INST(Trivial, IsUniqueOrPinned)
CONSTANT_OWNERSHIP_INST(Trivial, MarkUninitializedBehavior)
Expand Down
43 changes: 0 additions & 43 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4138,49 +4138,6 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
SGF.SelfInitDelegationState = SILGenFunction::NormalSelf;
SGF.InitDelegationSelf = ManagedValue();

// If we are using Objective-C allocation, the caller can return
// nil. When this happens with an explicitly-written super.init or
// self.init invocation, return early if we did get nil.
//
// TODO: Remove this when failable initializers are fully implemented.
auto classDecl = selfTy->getClassOrBoundGenericClass();

// Dig out the constructor reference to check if it is an explicit
// 'self.init' or 'super.init' call.
bool isChainToSuper = false;
auto *calledCtor = E->getCalledConstructor(isChainToSuper);

if (classDecl &&
!calledCtor->isImplicit() &&
usesObjCAllocator(classDecl)) {

// Check whether the new self is null. *NOTE* At this point, we can not
// access the actual new value using newSelf anymore. We need to grab self
// via the normal manner of doing so.
SILValue isNonnullSelf;
{
Scope S(SGF, E);
RValue selfRValue =
SGF.emitRValueForDecl(E, selfDecl, selfTy->getCanonicalType(),
AccessSemantics::DirectToStorage,
SGFContext::AllowGuaranteedPlusZero);
ManagedValue reloadedSelf =
std::move(selfRValue).getAsSingleValue(SGF, E);
isNonnullSelf = SGF.B.createIsNonnull(E, reloadedSelf.getValue());
}
Condition cond = SGF.emitCondition(isNonnullSelf, E,
/*hasFalseCode=*/false,
/*invertValue=*/true,
{ });

// If self is null, branch to the epilog.
cond.enterTrue(SGF);
SGF.Cleanups.emitBranchAndCleanups(SGF.ReturnDest, E, { });
cond.exitTrue(SGF);

cond.complete(SGF);
}

return SGF.emitEmptyTupleRValue(E, C);
}

Expand Down
5 changes: 0 additions & 5 deletions lib/SILOptimizer/Transforms/CSE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,6 @@ class HashVisitor : public SILInstructionVisitor<HashVisitor, llvm::hash_code> {
return hash;
}

hash_code visitIsNonnullInst(IsNonnullInst *X) {
return llvm::hash_combine(X->getKind(), X->getOperand(), X->getType());
}

hash_code visitThinFunctionToPointerInst(ThinFunctionToPointerInst *X) {
return llvm::hash_combine(X->getKind(), X->getOperand(), X->getType());
}
Expand Down Expand Up @@ -901,7 +897,6 @@ bool CSE::canHandle(SILInstruction *Inst) {
case SILInstructionKind::CondFailInst:
case SILInstructionKind::EnumInst:
case SILInstructionKind::UncheckedEnumDataInst:
case SILInstructionKind::IsNonnullInst:
case SILInstructionKind::UncheckedTrivialBitCastInst:
case SILInstructionKind::UncheckedBitwiseCastInst:
case SILInstructionKind::RefToRawPointerInst:
Expand Down
1 change: 0 additions & 1 deletion lib/SILOptimizer/Utils/SILInliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,6 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
case SILInstructionKind::InitExistentialMetatypeInst:
case SILInstructionKind::InitExistentialRefInst:
case SILInstructionKind::InjectEnumAddrInst:
case SILInstructionKind::IsNonnullInst:
case SILInstructionKind::LoadInst:
case SILInstructionKind::LoadBorrowInst:
case SILInstructionKind::LoadUnownedInst:
Expand Down
1 change: 0 additions & 1 deletion lib/Serialization/DeserializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
UNARY_INSTRUCTION(DeinitExistentialValue)
UNARY_INSTRUCTION(EndBorrowArgument)
UNARY_INSTRUCTION(DestroyAddr)
UNARY_INSTRUCTION(IsNonnull)
UNARY_INSTRUCTION(Return)
UNARY_INSTRUCTION(Throw)
UNARY_INSTRUCTION(FixLifetime)
Expand Down
1 change: 0 additions & 1 deletion lib/Serialization/SerializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,6 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
case SILInstructionKind::DeinitExistentialAddrInst:
case SILInstructionKind::DeinitExistentialValueInst:
case SILInstructionKind::DestroyAddrInst:
case SILInstructionKind::IsNonnullInst:
case SILInstructionKind::LoadInst:
case SILInstructionKind::LoadBorrowInst:
case SILInstructionKind::BeginBorrowInst:
Expand Down
12 changes: 0 additions & 12 deletions test/IRGen/function_types.sil
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,6 @@ entry(%x : $*X):
return %z : $()
}

// CHECK-LABEL: define{{( protected)?}} swiftcc i1 @test_is_nonnull_function(i8*, %swift.refcounted*) {{.*}} {
// CHECK-NEXT: entry:
// CHECK-NEXT: %2 = icmp ne i8* %0, null
// CHECK-NEXT: ret i1 %2
// CHECK-NEXT: }

sil @test_is_nonnull_function : $@convention(thin) (() -> ()) -> Builtin.Int1 {
bb0(%0 : $() -> ()):
%3 = is_nonnull %0 : $() -> ()
return %3 : $Builtin.Int1 // id: %5
}

// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @test_function_to_pointer(i8*)
// CHECK-NEXT: entry:
// CHECK-NEXT: ret i8* %0
Expand Down
2 changes: 0 additions & 2 deletions test/SIL/Parser/undef.sil
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,6 @@ bb0:
bridge_object_to_word undef : $Builtin.BridgeObject to $Builtin.Word
// CHECK: thin_to_thick_function undef : $@convention(thin) () -> () to $() -> ()
thin_to_thick_function undef : $@convention(thin) () -> () to $() -> ()
// CHECK: is_nonnull undef : $C
is_nonnull undef : $C

// Checked Conversions

Expand Down
9 changes: 1 addition & 8 deletions test/SIL/ownership-verifier/use_verifier.sil
Original file line number Diff line number Diff line change
Expand Up @@ -387,13 +387,6 @@ bb0(%0 : @owned $SuperKlass):
return %9999 : $()
}

sil @test_isnonnull : $@convention(thin) (@owned SuperKlass) -> Builtin.Int1 {
bb0(%0 : @owned $SuperKlass):
%1 = is_nonnull %0 : $SuperKlass
destroy_value %0 : $SuperKlass
return %1 : $Builtin.Int1
}

//////////////////////
// Terminator Tests //
//////////////////////
Expand Down Expand Up @@ -980,4 +973,4 @@ bb2(%2 : @owned $Builtin.NativeObject):
bb3:
%9999 = tuple()
return %9999 : $()
}
}
16 changes: 0 additions & 16 deletions test/SILGen/objc_thunks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -427,22 +427,6 @@ extension Hoozit {
// CHECK: [[CTOR:%[0-9]+]] = objc_method [[SELF:%[0-9]+]] : $Hoozit, #Hoozit.init!initializer.1.foreign : (Hoozit.Type) -> (Int) -> Hoozit, $@convention(objc_method) (Int, @owned Hoozit) -> @owned Hoozit
// CHECK: [[NEW_SELF:%[0-9]+]] = apply [[CTOR]]
// CHECK: store [[NEW_SELF]] to [init] [[PB_BOX]] : $*Hoozit
// CHECK: [[RELOADED_SELF:%.*]] = load_borrow [[PB_BOX]]
// CHECK: [[NONNULL:%[0-9]+]] = is_nonnull [[RELOADED_SELF]] : $Hoozit
// CHECK: end_borrow [[RELOADED_SELF]] from [[PB_BOX]]
// CHECK-NEXT: cond_br [[NONNULL]], [[NONNULL_BB:bb[0-9]+]], [[NULL_BB:bb[0-9]+]]
// CHECK: [[NULL_BB]]:
// CHECK-NEXT: destroy_value [[X_BOX]] : ${ var X }
// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]

// CHECK: [[NONNULL_BB]]:
// CHECK: [[OTHER_REF:%[0-9]+]] = function_ref @_T011objc_thunks5otheryyF : $@convention(thin) () -> ()
// CHECK-NEXT: apply [[OTHER_REF]]() : $@convention(thin) () -> ()
// CHECK-NEXT: destroy_value [[X_BOX]] : ${ var X }
// CHECK-NEXT: br [[EPILOG_BB]]

// CHECK: [[EPILOG_BB]]:
// CHECK-NOT: super_method
// CHECK: return
self.init(int:Int(d))
other()
Expand Down
13 changes: 0 additions & 13 deletions test/SILOptimizer/cse.sil
Original file line number Diff line number Diff line change
Expand Up @@ -806,19 +806,6 @@ bb0(%0 : $@sil_unmanaged C):
return %3: $(C, C)
}

// CHECK-LABEL: sil @cse_is_nonnull
// CHECK: is_nonnull
// CHECK-NOT: is_nonnull
// CHECK: tuple
// CHECK: return
sil @cse_is_nonnull : $@convention(thin) (C) -> (Builtin.Int1, Builtin.Int1) {
bb0(%0 : $C):
%1 = is_nonnull %0 : $C
%2 = is_nonnull %0 : $C
%3 = tuple (%1: $Builtin.Int1, %2: $Builtin.Int1)
return %3: $(Builtin.Int1, Builtin.Int1)
}

enum Enum1 {
case Case1
case Case2
Expand Down
Loading