Skip to content

Commit 7ae56aa

Browse files
committed
[sil] Add a new instruction ignored_use.
This is used for synthetic uses like _ = x that do not act as a true use but instead only suppress unused variable warnings. This patch just adds the instruction. Eventually, we can use it to move the unused variable warning from Sema to SIL slimmming the type checker down a little bit... but for now I am using it so that other diagnostic passes can have a SIL instruction (with SIL location) so that we can emit diagnostics on code like _ = x. Today we just do not emit anything at all for that case so a diagnostic SIL pass would not see any instruction that it could emit a diagnostic upon. In the next patch of this series, I am going to add SILGen support to do that.
1 parent bdfb609 commit 7ae56aa

File tree

20 files changed

+114
-3
lines changed

20 files changed

+114
-3
lines changed

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,3 +1736,6 @@ final public class ThunkInst : Instruction {
17361736

17371737
final public class MergeIsolationRegionInst : Instruction {
17381738
}
1739+
1740+
final public class IgnoredUseInst : Instruction {
1741+
}

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,5 @@ public func registerSILClasses() {
258258
register(CheckedCastAddrBranchInst.self)
259259
register(ThunkInst.self)
260260
register(MergeIsolationRegionInst.self)
261+
register(IgnoredUseInst.self)
261262
}

docs/SIL/Instructions.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5551,3 +5551,21 @@ sil-instruction ::= 'has_symbol' sil-decl-ref
55515551
Returns true if each of the underlying symbol addresses associated with
55525552
the given declaration are non-null. This can be used to determine
55535553
whether a weakly-imported declaration is available at runtime.
5554+
5555+
## Miscellaneous instructions
5556+
5557+
### ignored_use
5558+
5559+
```none
5560+
sil-instruction ::= 'ignored_use'
5561+
```
5562+
5563+
This instruction acts as a synthetic use instruction that suppresses unused
5564+
variable warnings. In Swift the equivalent operation is '_ = x'. This
5565+
importantly also provides a way to find the source location for '_ = x' when
5566+
emitting SIL diagnostics. It is only legal in Raw SIL and is removed as dead
5567+
code when we convert to Canonical SIL.
5568+
5569+
DISCUSSION: Before the introduction of this instruction, in certain cases,
5570+
SILGen would just not emit anything for '_ = x'... so one could not emit
5571+
diagnostics upon this case.

include/swift/SIL/SILBuilder.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,6 +3089,15 @@ class SILBuilder {
30893089
getModule(), getSILDebugLocation(Loc), Decl));
30903090
}
30913091

3092+
//===--------------------------------------------------------------------===//
3093+
// Misc Uses
3094+
//===--------------------------------------------------------------------===//
3095+
3096+
IgnoredUseInst *createIgnoredUse(SILLocation loc, SILValue value) {
3097+
return insert(new (getModule())
3098+
IgnoredUseInst(getSILDebugLocation(loc), value));
3099+
}
3100+
30923101
//===--------------------------------------------------------------------===//
30933102
// Private Helper Methods
30943103
//===--------------------------------------------------------------------===//

include/swift/SIL/SILCloner.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3796,6 +3796,14 @@ void SILCloner<ImplClass>::visitHasSymbolInst(HasSymbolInst *Inst) {
37963796
Inst->getDecl()));
37973797
}
37983798

3799+
template <typename ImplClass>
3800+
void SILCloner<ImplClass>::visitIgnoredUseInst(IgnoredUseInst *Inst) {
3801+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
3802+
recordClonedInstruction(
3803+
Inst, getBuilder().createIgnoredUse(getOpLocation(Inst->getLoc()),
3804+
getOpValue(Inst->getOperand())));
3805+
}
3806+
37993807
} // end namespace swift
38003808

38013809
#endif

include/swift/SIL/SILInstruction.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11725,6 +11725,17 @@ class MergeIsolationRegionInst final
1172511725
}
1172611726
};
1172711727

11728+
/// An instruction that represents a semantic-less use that is used to
11729+
/// suppresses unused value variable warnings. E.x.: _ = x.
11730+
class IgnoredUseInst final
11731+
: public UnaryInstructionBase<SILInstructionKind::IgnoredUseInst,
11732+
NonValueInstruction> {
11733+
friend SILBuilder;
11734+
11735+
IgnoredUseInst(SILDebugLocation loc, SILValue operand)
11736+
: UnaryInstructionBase(loc, operand) {}
11737+
};
11738+
1172811739
inline SILType *AllocRefInstBase::getTypeStorage() {
1172911740
// If the size of the subclasses are equal, then all of this compiles away.
1173011741
if (auto I = dyn_cast<AllocRefInst>(this))

include/swift/SIL/SILNodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,9 @@ NON_VALUE_INST(MarkUnresolvedMoveAddrInst, mark_unresolved_move_addr,
897897
NON_VALUE_INST(MergeIsolationRegionInst, merge_isolation_region,
898898
SILInstruction, None, DoesNotRelease)
899899

900+
NON_VALUE_INST(IgnoredUseInst, ignored_use,
901+
SILInstruction, None, DoesNotRelease)
902+
900903
NON_VALUE_INST(IncrementProfilerCounterInst, increment_profiler_counter,
901904
SILInstruction, MayReadWrite, DoesNotRelease)
902905

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,9 @@ class IRGenSILFunction :
12731273
visitMoveOnlyWrapperToCopyableBoxInst(MoveOnlyWrapperToCopyableBoxInst *i) {
12741274
llvm_unreachable("OSSA instruction");
12751275
}
1276+
1277+
void visitIgnoredUseInst(IgnoredUseInst *i) {}
1278+
12761279
void
12771280
visitMoveOnlyWrapperToCopyableAddrInst(MoveOnlyWrapperToCopyableAddrInst *i) {
12781281
auto e = getLoweredExplosion(i->getOperand());

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ OPERAND_OWNERSHIP(TrivialUse, GlobalAddr)
214214
// The dealloc_stack_ref operand needs to have NonUse ownership because
215215
// this use comes after the last consuming use (which is usually a dealloc_ref).
216216
OPERAND_OWNERSHIP(NonUse, DeallocStackRef)
217+
OPERAND_OWNERSHIP(InstantaneousUse, IgnoredUse)
217218

218219
// Use an owned or guaranteed value only for the duration of the operation.
219220
OPERAND_OWNERSHIP(InstantaneousUse, ExistentialMetatype)

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2873,6 +2873,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
28732873
*this << GI->getFormalResumeType();
28742874
}
28752875

2876+
void visitIgnoredUseInst(IgnoredUseInst *i) {
2877+
*this << getIDAndType(i->getOperand());
2878+
}
2879+
28762880
void visitGetAsyncContinuationAddrInst(GetAsyncContinuationAddrInst *GI) {
28772881
if (GI->throws())
28782882
*this << "[throws] ";

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5077,6 +5077,11 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
50775077
}
50785078
break;
50795079
}
5080+
case SILInstructionKind::IgnoredUseInst:
5081+
if (parseTypedValueRef(Val, B) || parseSILDebugLocation(InstLoc, B))
5082+
return true;
5083+
ResultVal = B.createIgnoredUse(InstLoc, Val);
5084+
break;
50805085

50815086
case SILInstructionKind::DeallocStackInst:
50825087
if (parseTypedValueRef(Val, B) || parseSILDebugLocation(InstLoc, B))

lib/SIL/Utils/InstructionUtils.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ bool swift::isEndOfScopeMarker(SILInstruction *user) {
335335

336336
bool swift::isIncidentalUse(SILInstruction *user) {
337337
return isEndOfScopeMarker(user) || user->isDebugInstruction() ||
338-
isa<FixLifetimeInst>(user) || isa<EndLifetimeInst>(user);
338+
isa<FixLifetimeInst>(user) || isa<EndLifetimeInst>(user) ||
339+
isa<IgnoredUseInst>(user);
339340
}
340341

341342
bool swift::onlyAffectsRefCount(SILInstruction *user) {
@@ -623,6 +624,7 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
623624
case SILInstructionKind::DebugStepInst:
624625
case SILInstructionKind::FunctionExtractIsolationInst:
625626
case SILInstructionKind::TypeValueInst:
627+
case SILInstructionKind::IgnoredUseInst:
626628
return RuntimeEffect::NoEffect;
627629

628630
case SILInstructionKind::OpenExistentialMetatypeInst:

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,6 +3103,7 @@ CONSTANT_TRANSLATION(DebugStepInst, Ignored)
31033103
CONSTANT_TRANSLATION(IncrementProfilerCounterInst, Ignored)
31043104
CONSTANT_TRANSLATION(SpecifyTestInst, Ignored)
31053105
CONSTANT_TRANSLATION(TypeValueInst, Ignored)
3106+
CONSTANT_TRANSLATION(IgnoredUseInst, Ignored)
31063107

31073108
//===---
31083109
// Require

lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ static bool hasOpaqueArchetype(TypeExpansionContext context,
333333
case SILInstructionKind::PackElementSetInst:
334334
case SILInstructionKind::TuplePackElementAddrInst:
335335
case SILInstructionKind::TypeValueInst:
336+
case SILInstructionKind::IgnoredUseInst:
336337
// Handle by operand and result check.
337338
break;
338339

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
900900
case SILInstructionKind::MoveOnlyWrapperToCopyableAddrInst:
901901
case SILInstructionKind::CopyableToMoveOnlyWrapperAddrInst:
902902
case SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst:
903+
case SILInstructionKind::IgnoredUseInst:
903904
return InlineCost::Free;
904905

905906
// Typed GEPs are free.

lib/Serialization/DeserializeSIL.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,6 +2241,14 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
22412241
getSILType(Ty, (SILValueCategory)TyCategory, Fn)));
22422242
break;
22432243
}
2244+
case SILInstructionKind::IgnoredUseInst: {
2245+
assert(RecordKind == SIL_ONE_OPERAND && "Should be one operand");
2246+
auto Ty = MF->getType(TyID);
2247+
ResultInst = Builder.createIgnoredUse(
2248+
Loc, getLocalValue(Builder.maybeGetFunction(), ValID,
2249+
getSILType(Ty, (SILValueCategory)TyCategory, Fn)));
2250+
break;
2251+
}
22442252
case SILInstructionKind::DeallocPackInst: {
22452253
auto Ty = MF->getType(TyID);
22462254
ResultInst = Builder.createDeallocPack(

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 914; // @execution attribute
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 915; // ignored_use
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

lib/Serialization/SerializeSIL.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,17 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
16921692

16931693
break;
16941694
}
1695+
case SILInstructionKind::IgnoredUseInst: {
1696+
// Use SILOneOperandLayout to specify our operand.
1697+
auto *iui = cast<IgnoredUseInst>(&SI);
1698+
unsigned abbrCode = SILAbbrCodes[SILOneOperandLayout::Code];
1699+
SILOneOperandLayout::emitRecord(
1700+
Out, ScratchRecord, abbrCode, (unsigned)iui->getKind(), 0,
1701+
S.addTypeRef(iui->getOperand()->getType().getRawASTType()),
1702+
(unsigned)iui->getOperand()->getType().getCategory(),
1703+
addValueRef(iui->getOperand()));
1704+
break;
1705+
}
16951706
case SILInstructionKind::DynamicFunctionRefInst: {
16961707
// Use SILOneOperandLayout to specify the function type and the function
16971708
// name (IdentifierID).

test/SIL/Parser/basic2.sil

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,4 +469,14 @@ bb0(%0 : @guaranteed $Klass):
469469
dealloc_stack %1 : $*MoveOnlyPair
470470
%9999 = tuple ()
471471
return %9999 : $()
472-
}
472+
}
473+
474+
// CHECK-LABEL: sil [ossa] @ignored_use_test : $@convention(thin) (@guaranteed Klass) -> () {
475+
// CHECK: ignored_use %0 : $Klass
476+
// CHECK: } // end sil function 'ignored_use_test'
477+
sil [ossa] @ignored_use_test : $@convention(thin) (@guaranteed Klass) -> () {
478+
bb0(%0 : @guaranteed $Klass):
479+
ignored_use %0 : $Klass
480+
%9999 = tuple ()
481+
return %9999 : $()
482+
}

test/SIL/Serialization/basic2.sil

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ class Klass {}
1515
sil @getC : $@convention(thin) () -> (@owned C)
1616
sil @getKlass : $@convention(thin) () -> (@owned Klass)
1717

18+
// CHECK-LABEL: sil [ossa] @ignored_use_test : $@convention(thin) (@guaranteed Klass) -> () {
19+
// CHECK: ignored_use %0 : $Klass
20+
// CHECK: } // end sil function 'ignored_use_test'
21+
sil [ossa] @ignored_use_test : $@convention(thin) (@guaranteed Klass) -> () {
22+
bb0(%0 : @guaranteed $Klass):
23+
ignored_use %0 : $Klass
24+
%9999 = tuple ()
25+
return %9999 : $()
26+
}
27+
1828
// CHECK-LABEL: sil [ossa] @merge_isolation_region : $@convention(thin) (@guaranteed Klass) -> () {
1929
// CHECK: merge_isolation_region %0 : $Klass, %1 : $*C
2030
// CHECK: merge_isolation_region %1 : $*C, %0 : $Klass, %0 : $Klass
@@ -365,3 +375,4 @@ bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
365375
%9999 = tuple ()
366376
return %9999 : $()
367377
}
378+

0 commit comments

Comments
 (0)