Skip to content
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
4 changes: 3 additions & 1 deletion include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -914,15 +914,17 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
/// Pretty-print the value.
void dump() const;
void print(raw_ostream &OS) const;
void print(SILPrintContext &ctx) const;

/// Pretty-print the value with DebugInfo.
void dump(bool DebugInfo) const;

/// Pretty-print the value in context, preceded by its operands (if the
/// value represents the result of an instruction) and followed by its
/// users.
void dumpInContext() const;
void printInContext(raw_ostream &OS) const;
void printInContext(SILPrintContext &ctx) const;
void dumpInContext() const;

static bool classof(SILNodePointer node) {
return node->getKind() >= SILNodeKind::First_SILInstruction &&
Expand Down
2 changes: 1 addition & 1 deletion include/swift/SIL/SILModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SILModule &M){
void verificationFailure(const Twine &complaint,
const SILInstruction *atInstruction,
const SILArgument *atArgument,
llvm::function_ref<void(llvm::raw_ostream &OS)> extraContext);
llvm::function_ref<void(SILPrintContext &ctx)> extraContext);

inline bool SILOptions::supportsLexicalLifetimes(const SILModule &mod) const {
switch (mod.getStage()) {
Expand Down
3 changes: 3 additions & 0 deletions include/swift/SIL/SILNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class NonSingleValueInstruction;
class SILModule;
class ValueBase;
class SILNode;
class SILPrintContext;
class SILValue;

/// An enumeration which contains values for all the nodes in SILNodes.def.
Expand Down Expand Up @@ -430,12 +431,14 @@ class alignas(8) SILNode :
/// will be valid SIL assembly; otherwise, it will be an arbitrary
/// format suitable for debugging.
void print(raw_ostream &OS) const;
void print(SILPrintContext &ctx) const;
void dump() const;

/// Pretty-print the node in context, preceded by its operands (if the
/// value represents the result of an instruction) and followed by its
/// users.
void printInContext(raw_ostream &OS) const;
void printInContext(SILPrintContext &ctx) const;
void dumpInContext() const;

// Cast to SingleValueInstruction. This is an implementation detail
Expand Down
20 changes: 15 additions & 5 deletions lib/SIL/IR/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3372,6 +3372,9 @@ void SILNode::dump() const {

void SILNode::print(raw_ostream &OS) const {
SILPrintContext Ctx(OS);
print(Ctx);
}
void SILNode::print(SILPrintContext &Ctx) const {
SILPrinter(Ctx).print(this);
}

Expand All @@ -3391,6 +3394,9 @@ void SingleValueInstruction::dump() const {

void SILInstruction::print(raw_ostream &OS) const {
SILPrintContext Ctx(OS);
print(Ctx);
}
void SILInstruction::print(SILPrintContext &Ctx) const {
SILPrinter(Ctx).print(this);
}

Expand All @@ -3413,7 +3419,9 @@ void SILBasicBlock::dump(bool DebugInfo) const {
/// Pretty-print the SILBasicBlock to the designated stream.
void SILBasicBlock::print(raw_ostream &OS) const {
SILPrintContext Ctx(OS);

print(Ctx);
}
void SILBasicBlock::print(SILPrintContext &Ctx) const {
// Print the debug scope (and compute if we didn't do it already).
auto &SM = this->getParent()->getModule().getASTContext().SourceMgr;
for (auto &I : *this) {
Expand All @@ -3424,10 +3432,6 @@ void SILBasicBlock::print(raw_ostream &OS) const {
SILPrinter(Ctx).print(this);
}

void SILBasicBlock::print(SILPrintContext &Ctx) const {
SILPrinter(Ctx).print(this);
}

void SILBasicBlock::dumpID(bool newline) const {
#ifndef NDEBUG
printID(llvm::errs(), newline);
Expand Down Expand Up @@ -4234,6 +4238,9 @@ void SILNode::dumpInContext() const {
}
void SILNode::printInContext(llvm::raw_ostream &OS) const {
SILPrintContext Ctx(OS);
printInContext(Ctx);
}
void SILNode::printInContext(SILPrintContext &Ctx) const {
SILPrinter(Ctx).printInContext(this);
}

Expand All @@ -4242,6 +4249,9 @@ void SILInstruction::dumpInContext() const {
}
void SILInstruction::printInContext(llvm::raw_ostream &OS) const {
SILPrintContext Ctx(OS);
printInContext(Ctx);
}
void SILInstruction::printInContext(SILPrintContext &Ctx) const {
SILPrinter(Ctx).printInContext(asSILNode());
}

Expand Down
7 changes: 3 additions & 4 deletions lib/SIL/Utils/BasicBlockUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,13 +615,12 @@ static FunctionTest DeadEndEdgesTest("dead_end_edges", [](auto &function,
auto visitingSet = edges.createVisitingSet(/*includeUnreachable*/ true);

auto &out = llvm::outs();
SILPrintContext ctx(out);
for (auto &srcBB : function) {
for (auto *dstBB : srcBB.getSuccessorBlocks()) {
if (auto regionIndex = edges.entersDeadEndRegion(&srcBB, dstBB)) {
srcBB.printID(out, false);
out << " -> ";
dstBB->printID(out, false);
out << " (region " << *regionIndex << "; ";
out << ctx.getID(&srcBB) << " -> " << ctx.getID(dstBB)
<< " (region " << *regionIndex << "; ";
if (visitingSet.visitEdgeTo(dstBB)) {
out << "last edge)";
} else {
Expand Down
87 changes: 45 additions & 42 deletions lib/SIL/Verifier/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ extern llvm::cl::opt<bool> SILPrintDebugInfo;
void swift::verificationFailure(const Twine &complaint,
const SILInstruction *atInstruction,
const SILArgument *atArgument,
llvm::function_ref<void(llvm::raw_ostream &out)> extraContext) {
llvm::function_ref<void(SILPrintContext &ctx)> extraContext) {
llvm::raw_ostream &out = llvm::dbgs();
SILPrintContext ctx(out);

const SILFunction *f = nullptr;
StringRef funcName = "?";
Expand All @@ -116,14 +117,14 @@ void swift::verificationFailure(const Twine &complaint,

out << "SIL verification failed: " << complaint << "\n";
if (extraContext)
extraContext(out);
extraContext(ctx);

if (atInstruction) {
out << "Verifying instruction:\n";
atInstruction->printInContext(out);
atInstruction->printInContext(ctx);
} else if (atArgument) {
out << "Verifying argument:\n";
atArgument->printInContext(out);
atArgument->printInContext(ctx);
}
if (ContinueOnFailure) {
out << "End Error in function " << funcName << "\n";
Expand Down Expand Up @@ -978,7 +979,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
}

void _require(bool condition, const Twine &complaint,
llvm::function_ref<void(llvm::raw_ostream &)> extraContext
llvm::function_ref<void(SILPrintContext &)> extraContext
= nullptr) {
if (condition) return;

Expand Down Expand Up @@ -1111,16 +1112,16 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
/// Assert that two types are equal.
void requireSameType(Type type1, Type type2, const Twine &complaint) {
_require(type1->isEqual(type2), complaint,
[&](llvm::raw_ostream &out) {
out << " " << type1 << "\n " << type2 << '\n';
[&](SILPrintContext &ctx) {
ctx.OS() << " " << type1 << "\n " << type2 << '\n';
});
}

/// Assert that two types are equal.
void requireSameType(SILType type1, SILType type2, const Twine &complaint) {
_require(type1 == type2, complaint,
[&](llvm::raw_ostream &out) {
out << " " << type1 << "\n " << type2 << '\n';
[&](SILPrintContext &ctx) {
ctx.OS() << " " << type1 << "\n " << type2 << '\n';
});
}

Expand Down Expand Up @@ -1158,15 +1159,15 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
return;

if (!Result.hasPayload()) {
_require(false, what, [&](llvm::raw_ostream &out) {
out << " " << Result.getMessage().data() << '\n'
<< " " << type1 << "\n " << type2 << '\n';
_require(false, what, [&](SILPrintContext &ctx) {
ctx.OS() << " " << Result.getMessage().data() << '\n'
<< " " << type1 << "\n " << type2 << '\n';
});
} else {
_require(false, what, [&](llvm::raw_ostream &out) {
out << " " << Result.getMessage().data()
<< ".\nParameter: " << Result.getPayload()
<< "\n " << type1 << "\n " << type2 << '\n';
_require(false, what, [&](SILPrintContext &ctx) {
ctx.OS() << " " << Result.getMessage().data()
<< ".\nParameter: " << Result.getPayload()
<< "\n " << type1 << "\n " << type2 << '\n';
});
}
}
Expand All @@ -1193,7 +1194,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
template <class T>
T *requireValueKind(SILValue value, const Twine &what) {
auto match = dyn_cast<T>(value);
_require(match != nullptr, what, [=](llvm::raw_ostream &out) { out << value; });
_require(match != nullptr, what, [=](SILPrintContext &ctx) {
value->print(ctx);
});
return match;
}

Expand Down Expand Up @@ -1891,7 +1894,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
if (subs.getGenericSignature().getCanonicalSignature() !=
fnTy->getInvocationGenericSignature().getCanonicalSignature()) {
_require(false, "Substitution map does not match callee in apply instruction",
[&](llvm::raw_ostream &out) {
[&](SILPrintContext &ctx) {
auto &out = ctx.OS();
out << "substitution map's generic signature: ";
subs.getGenericSignature()->print(out);
out << "\n";
Expand Down Expand Up @@ -6803,22 +6807,22 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
BBState(maybe_movable_ref<BBState> other)
: BBState(std::move(other).construct()) {}

void printStack(llvm::raw_ostream &out, StringRef label) const {
out << label << ": [";
if (!Stack.empty()) out << "\n";
void printStack(SILPrintContext &ctx, StringRef label) const {
ctx.OS() << label << ": [";
if (!Stack.empty()) ctx.OS() << "\n";
for (auto allocation: Stack) {
allocation->print(out);
allocation->print(ctx);
}
out << "]\n";
ctx.OS() << "]\n";
}

void printActiveOps(llvm::raw_ostream &out, StringRef label) const {
out << label << ": [";
if (!ActiveOps.empty()) out << "\n";
void printActiveOps(SILPrintContext &ctx, StringRef label) const {
ctx.OS() << label << ": [";
if (!ActiveOps.empty()) ctx.OS() << "\n";
for (auto op: ActiveOps) {
op->print(out);
op->print(ctx);
}
out << "]\n";
ctx.OS() << "]\n";
}

/// Given that we have two edges to the same block or dead-end region,
Expand Down Expand Up @@ -6877,14 +6881,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
// conservative merge regardless of failure so that we're in a
// coherent state in the successor block.
auto fail = [&](StringRef complaint,
llvm::function_ref<void(llvm::raw_ostream &out)> extra
llvm::function_ref<void(SILPrintContext &out)> extra
= nullptr) {
verificationFailure(complaint, term, nullptr,
[&](llvm::raw_ostream &out) {
out << "Entering basic block ";
succBB->printID(out, /*newline*/ true);
[&](SILPrintContext &ctx) {
ctx.OS() << "Entering basic block " << ctx.getID(succBB) << "\n";

if (extra) extra(out);
if (extra) extra(ctx);
});
};

Expand All @@ -6908,9 +6911,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
if (Stack != otherState.Stack) {
if (!isDeadEndEdge) {
fail("inconsistent stack states entering basic block",
[&](llvm::raw_ostream &out) {
otherState.printStack(out, "Current stack state");
printStack(out, "Recorded stack state");
[&](SILPrintContext &ctx) {
otherState.printStack(ctx, "Current stack state");
printStack(ctx, "Recorded stack state");
});
}

Expand All @@ -6923,9 +6926,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
if (ActiveOps != otherState.ActiveOps) {
if (!isDeadEndEdge) {
fail("inconsistent active-operations sets entering basic block",
[&](llvm::raw_ostream &out) {
otherState.printActiveOps(out, "Current active operations");
printActiveOps(out, "Recorded active operations");
[&](SILPrintContext &ctx) {
otherState.printActiveOps(ctx, "Current active operations");
printActiveOps(ctx, "Recorded active operations");
});
}

Expand Down Expand Up @@ -7021,9 +7024,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
} else {
verificationFailure("deallocating allocation that is not the top of the stack",
&i, nullptr,
[&](llvm::raw_ostream &out) {
state.printStack(out, "Current stack state");
out << "Stack allocation:\n" << *op;
[&](SILPrintContext &ctx) {
state.printStack(ctx, "Current stack state");
ctx.OS() << "Stack allocation:\n" << *op;
// The deallocation is printed out as the focus of the failure.
});
}
Expand Down