Skip to content

SIL: don't print operand types in textual SIL #77763

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 3 commits into from
Nov 22, 2024
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,8 @@ ERROR(sil_value_def_type_mismatch,none,
"value '%0' used with mismatching type %1 (expected %2)", (StringRef, Type, Type))
ERROR(sil_use_of_undefined_value,none,
"use of undefined value '%0'", (StringRef))
ERROR(sil_forward_ref_value_needs_type,none,
"forward-referenced value '%0' needs a type annotation", (StringRef))
NOTE(sil_prior_reference,none,
"prior reference was here", ())

Expand Down
113 changes: 85 additions & 28 deletions lib/SIL/IR/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ llvm::cl::opt<bool>
SILPrintSourceInfo("sil-print-sourceinfo", llvm::cl::init(false),
llvm::cl::desc("Include source annotation in SIL output"));

llvm::cl::opt<bool>
SILPrintTypes("sil-print-types", llvm::cl::init(false),
llvm::cl::desc("always print type annotations for instruction operands in SIL output"));

llvm::cl::opt<bool>
SILPrintNoUses("sil-print-no-uses", llvm::cl::init(false),
llvm::cl::desc("omit use comments in SIL output"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we have a bunch of this already, but we really need to kick the habit of using global llvm::cl::opts instead of breaking down the command line into a context and threading that context into passes. This stuff all turns into global constructors that have to run in every process that even links this code in. The Carbon folks are finding that the uses in the LLVM passes alone are a significant contributor to their compile times; admittedly, they have a much faster compiler overall, but still.

Anyway, just feedback for a later PR.

Copy link
Contributor Author

@eeckstein eeckstein Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we should clean up our command line options


llvm::cl::opt<bool> SILPrintGenericSpecializationInfo(
"sil-print-generic-specialization-info", llvm::cl::init(false),
llvm::cl::desc("Include generic specialization"
Expand Down Expand Up @@ -165,31 +173,34 @@ struct SILValuePrinterInfo {
bool IsCapture = false;
bool IsReborrow = false;
bool IsEscaping = false;
bool needPrintType = false;

SILValuePrinterInfo(ID ValueID) : ValueID(ValueID), Type(), OwnershipKind() {}
SILValuePrinterInfo(ID ValueID, SILType Type)
: ValueID(ValueID), Type(Type), OwnershipKind() {}
SILValuePrinterInfo(ID ValueID, SILType Type, bool needPrintType)
: ValueID(ValueID), Type(Type), OwnershipKind(), needPrintType(needPrintType) {}
SILValuePrinterInfo(ID ValueID, SILType Type,
ValueOwnershipKind OwnershipKind)
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind) {}
SILValuePrinterInfo(ID ValueID, SILType Type,
ValueOwnershipKind OwnershipKind, bool IsNoImplicitCopy,
LifetimeAnnotation Lifetime, bool IsCapture,
bool IsReborrow, bool IsEscaping)
bool IsReborrow, bool IsEscaping, bool needPrintType)
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
IsNoImplicitCopy(IsNoImplicitCopy), Lifetime(Lifetime),
IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
needPrintType(needPrintType){}
SILValuePrinterInfo(ID ValueID, SILType Type, bool IsNoImplicitCopy,
LifetimeAnnotation Lifetime, bool IsCapture,
bool IsReborrow, bool IsEscaping)
bool IsReborrow, bool IsEscaping, bool needPrintType)
: ValueID(ValueID), Type(Type), OwnershipKind(),
IsNoImplicitCopy(IsNoImplicitCopy), Lifetime(Lifetime),
IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
IsCapture(IsCapture), IsReborrow(IsReborrow), IsEscaping(IsEscaping),
needPrintType(needPrintType) {}
SILValuePrinterInfo(ID ValueID, SILType Type,
ValueOwnershipKind OwnershipKind, bool IsReborrow,
bool IsEscaping)
bool IsEscaping, bool needPrintType)
: ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind),
IsReborrow(IsReborrow), IsEscaping(IsEscaping) {}
IsReborrow(IsReborrow), IsEscaping(IsEscaping), needPrintType(needPrintType) {}
};

/// Return the fully qualified dotted path for DeclContext.
Expand Down Expand Up @@ -656,6 +667,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
} PrintState;
LineComments lineComments;
unsigned LastBufferID;
llvm::DenseSet<const SILBasicBlock *> printedBlocks;

// Printers for the underlying stream.
#define SIMPLE_PRINTER(TYPE) \
Expand Down Expand Up @@ -684,29 +696,57 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
*this << i.ValueID;
if (!i.Type)
return *this;
*this << " : ";
if (i.IsNoImplicitCopy)
*this << "@noImplicitCopy ";
const char *separator = " : ";
if (i.IsNoImplicitCopy) {
*this << separator << "@noImplicitCopy";
separator = " ";
}
switch (i.Lifetime) {
case LifetimeAnnotation::EagerMove:
*this << "@_eagerMove ";
*this << separator << "@_eagerMove";
separator = " ";
break;
case LifetimeAnnotation::None:
break;
case LifetimeAnnotation::Lexical:
*this << "@_lexical ";
*this << separator << "@_lexical";
separator = " ";
break;
}
if (i.IsCapture)
*this << "@closureCapture ";
if (i.IsReborrow)
*this << "@reborrow ";
if (i.IsEscaping)
*this << "@pointer_escape ";
if (i.IsCapture) {
*this << separator << "@closureCapture";
separator = " ";
}
if (i.IsReborrow) {
*this << separator << "@reborrow";
separator = " ";
}
if (i.IsEscaping) {
*this << separator << "@pointer_escape";
separator = " ";
}
if (!i.IsReborrow && i.OwnershipKind && *i.OwnershipKind != OwnershipKind::None) {
*this << "@" << i.OwnershipKind.value() << " ";
*this << separator << "@" << i.OwnershipKind.value() << " ";
separator = " ";
}
if (i.needPrintType) {
*this << separator << i.Type;
}
return *this << i.Type;
return *this;
}

bool needPrintTypeFor(SILValue V) {
if (SILPrintTypes)
return true;

if (!V)
return false;

if (isa<SILUndef>(V))
return true;

// Make sure to print the type if the operand's definition was not printed so far
return printedBlocks.count(V->getParentBlock()) == 0;
}

SILPrinter &operator<<(Type t) {
Expand All @@ -733,13 +773,20 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
}

SILValuePrinterInfo getIDAndType(SILValue V) {
return {Ctx.getID(V), V ? V->getType() : SILType()};
return {Ctx.getID(V), V ? V->getType() : SILType(), needPrintTypeFor(V)};
}
SILValuePrinterInfo getIDAndForcedPrintedType(SILValue V) {
return {Ctx.getID(V), V ? V->getType() : SILType(), /*needPrintType=*/true};
}

SILValuePrinterInfo getIDAndType(SILFunctionArgument *arg) {
return {Ctx.getID(arg), arg->getType(),
arg->isNoImplicitCopy(), arg->getLifetimeAnnotation(),
arg->isClosureCapture(), arg->isReborrow(),
arg->hasPointerEscape()};
arg->hasPointerEscape(), /*needPrintType=*/true};
}
SILValuePrinterInfo getIDAndType(SILArgument *arg) {
return {Ctx.getID(arg), arg->getType(), /*needPrintType=*/true};
}

SILValuePrinterInfo getIDAndTypeAndOwnership(SILValue V) {
Expand All @@ -753,11 +800,13 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
arg->getLifetimeAnnotation(),
arg->isClosureCapture(),
arg->isReborrow(),
arg->hasPointerEscape()};
arg->hasPointerEscape(),
/*needPrintType=*/true};
}
SILValuePrinterInfo getIDAndTypeAndOwnership(SILArgument *arg) {
return {Ctx.getID(arg), arg->getType(), arg->getOwnershipKind(),
arg->isReborrow(), arg->hasPointerEscape()};
arg->isReborrow(), arg->hasPointerEscape(),
/*needPrintType=*/true};
}

//===--------------------------------------------------------------------===//
Expand All @@ -783,6 +832,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
}

void printBlockArgumentUses(const SILBasicBlock *BB) {
if (SILPrintNoUses)
return;

if (BB->args_empty())
return;

Expand Down Expand Up @@ -880,6 +932,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
#endif

void print(const SILBasicBlock *BB) {
printedBlocks.insert(BB);

// Output uses for BB arguments. These are put into place as comments before
// the block header.
printBlockArgumentUses(BB);
Expand All @@ -895,7 +949,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
printBlockArguments(BB);
*this << ":";

if (!BB->pred_empty()) {
if (!BB->pred_empty() && !SILPrintNoUses) {
PrintState.OS.PadToColumn(50);

*this << "// Preds:";
Expand Down Expand Up @@ -985,6 +1039,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
}

void printUserList(ArrayRef<SILValue> values, SILNodePointer node) {
if (SILPrintNoUses)
return;

// If the set of values is empty, we need to print the ID of
// the instruction. Otherwise, if none of the values has a use,
// we don't need to do anything.
Expand Down Expand Up @@ -2464,7 +2521,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
PrintState.OS, QualifiedSILTypeOptions);
if (!WMI->getTypeDependentOperands().empty()) {
*this << ", ";
*this << getIDAndType(WMI->getTypeDependentOperands()[0].get());
*this << getIDAndForcedPrintedType(WMI->getTypeDependentOperands()[0].get());
}
*this << " : " << WMI->getType();
printConformances({WMI->getConformance()});
Expand Down Expand Up @@ -2505,7 +2562,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
printConformances(AEI->getConformances());
}
void visitInitExistentialRefInst(InitExistentialRefInst *AEI) {
*this << getIDAndType(AEI->getOperand()) << " : $"
*this << getIDAndForcedPrintedType(AEI->getOperand()) << " : $"
<< AEI->getFormalConcreteType() << ", " << AEI->getType();
printConformances(AEI->getConformances());
printForwardingOwnershipKind(AEI, AEI->getOperand());
Expand Down
32 changes: 25 additions & 7 deletions lib/SIL/Parser/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1504,14 +1504,23 @@ bool SILParser::parseTypedValueRef(SILValue &Result, SourceLoc &Loc,
Loc = P.Tok.getLoc();

UnresolvedValueName Name;
SILType Ty;
if (parseValueName(Name) ||
P.parseToken(tok::colon, diag::expected_sil_colon_value_ref) ||
parseSILType(Ty))
if (parseValueName(Name))
return true;

Result = getLocalValue(Name, Ty, RegularLocation(Loc), B);
return false;

if (P.consumeIf(tok::colon)) {
SILType Ty;
parseSILType(Ty);
Result = getLocalValue(Name, Ty, RegularLocation(Loc), B);
return false;
} else {
ValueBase *&Entry = LocalValues[Name.Name];
if (!Entry) {
P.diagnose(Name.NameLoc, diag::sil_forward_ref_value_needs_type, Name.Name);
return true;
}
Result = SILValue(Entry);
return false;
}
}

/// Look up whether the given string corresponds to a SIL opcode.
Expand Down Expand Up @@ -7432,6 +7441,15 @@ bool SILParserState::parseDeclSIL(Parser &P) {
}

FunctionState.F->setLinkage(resolveSILLinkage(FnLinkage, isDefinition));
switch (FunctionState.F->getLinkage()) {
case SILLinkage::PublicExternal:
case SILLinkage::PackageExternal:
if (!FunctionState.F->isExternalDeclaration() && !FunctionState.F->isAnySerialized())
FunctionState.F->getModule().setParsedAsSerializedSIL();
break;
default:
break;
}
}

if (FunctionState.diagnoseProblems())
Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SIL/Parse/sildeclref.sil
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-sil-opt %s -module-name=sildeclref_parse | %target-sil-opt -module-name=sildeclref_parse | %FileCheck %s
// RUN: %target-sil-opt -sil-print-types %s -module-name=sildeclref_parse | %target-sil-opt -sil-print-types -module-name=sildeclref_parse | %FileCheck %s
// Parse AutoDiff derivative SILDeclRefs via `witness_method` and `class_method` instructions.

import Swift
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// RUN: %empty-directory(%t)
// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name main
// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.sil -module-name main
// RUN: %target-sil-opt -sil-print-types %s -emit-sib -o %t/tmp.sib -module-name main
// RUN: %target-sil-opt -sil-print-types %t/tmp.sib -o %t/tmp.sil -module-name main

// https://github.com/apple/swift/issues/54526
// Workaround because import declarations are not preserved in .sib files.
// RUN: sed -e 's/import Swift$/import Swift; import _Differentiation/' %t/tmp.sil > %t/tmp_fixed.sil
// RUN: %target-sil-opt %t/tmp_fixed.sil -module-name main -emit-sorted-sil | %FileCheck %s
// RUN: %target-sil-opt -sil-print-types %t/tmp_fixed.sil -module-name main -emit-sorted-sil | %FileCheck %s

// `shell` is required only to run `sed` as a
// https://github.com/apple/swift/issues/54526 workaround.
Expand Down
8 changes: 4 additions & 4 deletions test/AutoDiff/SIL/differentiable_function_inst.sil
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Round-trip parsing/printing test.

// RUN: %target-sil-opt %s -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL
// RUN: %target-sil-opt -sil-print-types %s -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL

// Round-trip serialization-deserialization test.

// RUN: %empty-directory(%t)
// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name main
// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.sil -module-name main
// RUN: %target-sil-opt -sil-print-types %s -emit-sib -o %t/tmp.sib -module-name main
// RUN: %target-sil-opt -sil-print-types %t/tmp.sib -o %t/tmp.sil -module-name main

// https://github.com/apple/swift/issues/54526
// Workaround because import declarations are not preserved in .sib files.
// RUN: sed -e 's/import Swift$/import Swift; import _Differentiation/' %t/tmp.sil > %t/tmp_fixed.sil
// RUN: %target-sil-opt %t/tmp_fixed.sil -module-name main -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL
// RUN: %target-sil-opt -sil-print-types %t/tmp_fixed.sil -module-name main -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL

// IRGen test.

Expand Down
8 changes: 4 additions & 4 deletions test/AutoDiff/SIL/linear_function_inst.sil
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Round-trip parsing/printing test.

// RUN: %target-sil-opt %s -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL
// RUN: %target-sil-opt -sil-print-types %s -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL

// Round-trip serialization-deserialization test.

// RUN: %empty-directory(%t)
// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name main
// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.sil -module-name main
// RUN: %target-sil-opt -sil-print-types %s -emit-sib -o %t/tmp.sib -module-name main
// RUN: %target-sil-opt -sil-print-types %t/tmp.sib -o %t/tmp.sil -module-name main

// https://github.com/apple/swift/issues/54526
// Workaround because import declarations are not preserved in .sib files.
// RUN: sed -e 's/import Swift$/import Swift; import _Differentiation/' %t/tmp.sil > %t/tmp_fixed.sil
// RUN: %target-sil-opt %t/tmp_fixed.sil -module-name main -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL
// RUN: %target-sil-opt -sil-print-types %t/tmp_fixed.sil -module-name main -emit-sorted-sil | %FileCheck %s --check-prefix=CHECK-SIL


sil_stage raw
Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SILGen/autodiff_builtins.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -parse-stdlib -emit-silgen %s | %FileCheck %s
// RUN: %target-swift-frontend -parse-stdlib -Xllvm -sil-print-types -emit-silgen %s | %FileCheck %s

import _Differentiation
import Swift
Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SILGen/differentiable_function.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-silgen %s | %FileCheck %s

// Test SILGen for `@differentiable` function typed values.

Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SILGen/nil_coalescing.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil -verify %s | %FileCheck %s
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-sil -verify %s | %FileCheck %s

import _Differentiation

Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SILGen/reabstraction.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-silgen %s | %FileCheck %s

import _Differentiation

Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SILGen/vtable.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-silgen %s | %FileCheck %s

// Test derivative function vtable entries for `@differentiable` class members:
// - Methods.
Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SILOptimizer/closure_specialization.sil
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-sil-opt -test-runner %s -o /dev/null 2>&1 | %FileCheck %s
// RUN: %target-sil-opt -sil-print-types -test-runner %s -o /dev/null 2>&1 | %FileCheck %s

// REQUIRES: swift_in_compiler

Expand Down
2 changes: 1 addition & 1 deletion test/AutoDiff/SILOptimizer/derivative_sil.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil -enable-experimental-forward-mode-differentiation -verify -Xllvm -sil-print-after=differentiation -o /dev/null 2>&1 %s | %FileCheck %s -check-prefix=CHECK-SIL
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-sil -enable-experimental-forward-mode-differentiation -verify -Xllvm -sil-print-after=differentiation -o /dev/null 2>&1 %s | %FileCheck %s -check-prefix=CHECK-SIL
// REQUIRES: asserts

// Simple generated derivative code FileCheck tests.
Expand Down
Loading