Skip to content

Commit 0750b0b

Browse files
committed
[generics] Add an option that causes the generic specializer to validate newly specialized functions earlier when we have more information that we can put into a pretty stack trace.
I also added support for creating a PrettyStackTraceSILFunction from a twine.
1 parent 6fcfbaa commit 0750b0b

File tree

3 files changed

+68
-18
lines changed

3 files changed

+68
-18
lines changed

include/swift/SIL/PrettyStackTrace.h

+18-5
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,25 @@ class PrettyStackTraceSILLocation : public llvm::PrettyStackTraceEntry {
4545

4646
/// Observe that we are doing some processing of a SIL function.
4747
class PrettyStackTraceSILFunction : public llvm::PrettyStackTraceEntry {
48-
const SILFunction *TheFn;
49-
const char *Action;
48+
const SILFunction *func;
49+
50+
/// An inline buffer of characters used if we are passed a twine.
51+
SmallString<256> data;
52+
53+
/// This points either at a user provided const char * string or points at the
54+
/// inline message buffer that is initialized with data from a twine on
55+
/// construction.
56+
StringRef action;
57+
5058
public:
51-
PrettyStackTraceSILFunction(const char *action, const SILFunction *F)
52-
: TheFn(F), Action(action) {}
53-
virtual void print(llvm::raw_ostream &OS) const;
59+
PrettyStackTraceSILFunction(const char *action, const SILFunction *func)
60+
: func(func), data(), action(action) {}
61+
62+
PrettyStackTraceSILFunction(llvm::Twine &&twine, const SILFunction *func)
63+
: func(func), data(), action(twine.toNullTerminatedStringRef(data)) {}
64+
65+
virtual void print(llvm::raw_ostream &os) const;
66+
5467
protected:
5568
void printFunctionInfo(llvm::raw_ostream &out) const;
5669
};

lib/SIL/Utils/PrettyStackTrace.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ void PrettyStackTraceSILLocation::print(llvm::raw_ostream &out) const {
7575
}
7676

7777
void PrettyStackTraceSILFunction::print(llvm::raw_ostream &out) const {
78-
out << "While " << Action << " SIL function ";
79-
if (!TheFn) {
78+
out << "While " << action << " SIL function ";
79+
if (!func) {
8080
out << " <<null>>";
8181
return;
8282
}
@@ -86,16 +86,16 @@ void PrettyStackTraceSILFunction::print(llvm::raw_ostream &out) const {
8686

8787
void PrettyStackTraceSILFunction::printFunctionInfo(llvm::raw_ostream &out) const {
8888
out << "\"";
89-
TheFn->printName(out);
89+
func->printName(out);
9090
out << "\".\n";
9191

92-
if (!TheFn->getLocation().isNull()) {
92+
if (!func->getLocation().isNull()) {
9393
out << " for ";
94-
printSILLocationDescription(out, TheFn->getLocation(),
95-
TheFn->getModule().getASTContext());
94+
printSILLocationDescription(out, func->getLocation(),
95+
func->getModule().getASTContext());
9696
}
9797
if (SILPrintOnError)
98-
TheFn->print(out);
98+
func->print(out);
9999
}
100100

101101
void PrettyStackTraceSILNode::print(llvm::raw_ostream &out) const {

lib/SILOptimizer/Utils/Generics.cpp

+43-6
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,22 @@
1313
#define DEBUG_TYPE "generic-specializer"
1414

1515
#include "swift/SILOptimizer/Utils/Generics.h"
16-
#include "swift/AST/GenericEnvironment.h"
17-
#include "swift/AST/TypeMatcher.h"
1816
#include "swift/AST/DiagnosticEngine.h"
1917
#include "swift/AST/DiagnosticsSIL.h"
18+
#include "swift/AST/GenericEnvironment.h"
2019
#include "swift/AST/SemanticAttrs.h"
21-
#include "swift/Basic/Statistic.h"
2220
#include "swift/AST/TypeCheckRequests.h"
23-
#include "swift/Serialization/SerializedSILLoader.h"
21+
#include "swift/AST/TypeMatcher.h"
22+
#include "swift/Basic/Statistic.h"
23+
#include "swift/Demangling/ManglingMacros.h"
2424
#include "swift/SIL/DebugUtils.h"
2525
#include "swift/SIL/InstructionUtils.h"
2626
#include "swift/SIL/OptimizationRemark.h"
27-
#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
27+
#include "swift/SIL/PrettyStackTrace.h"
2828
#include "swift/SILOptimizer/Utils/GenericCloner.h"
29+
#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
2930
#include "swift/SILOptimizer/Utils/SpecializationMangler.h"
30-
#include "swift/Demangling/ManglingMacros.h"
31+
#include "swift/Serialization/SerializedSILLoader.h"
3132
#include "swift/Strings.h"
3233

3334
using namespace swift;
@@ -58,6 +59,12 @@ llvm::cl::opt<bool> PrintGenericSpecializationLoops(
5859
llvm::cl::desc("Print detected infinite generic specialization loops that "
5960
"were prevented"));
6061

62+
llvm::cl::opt<bool> VerifyFunctionsAfterSpecialization(
63+
"sil-generic-verify-after-specialization", llvm::cl::init(false),
64+
llvm::cl::desc(
65+
"Verify functions after they are specialized "
66+
"'PrettyStackTraceFunction'-ing the original function if we fail."));
67+
6168
static bool OptimizeGenericSubstitutions = false;
6269

6370
/// Max depth of a type which can be processed by the generic
@@ -1871,6 +1878,15 @@ SILFunction *GenericFuncSpecializer::tryCreateSpecialization() {
18711878
SpecializedF->setClassSubclassScope(SubclassScope::NotApplicable);
18721879
SpecializedF->setSpecializationInfo(
18731880
GenericSpecializationInformation::create(Caller, GenericFunc, Subs));
1881+
1882+
if (VerifyFunctionsAfterSpecialization) {
1883+
PrettyStackTraceSILFunction SILFunctionDumper(
1884+
llvm::Twine("Generic function: ") + GenericFunc->getName() +
1885+
". Specialized Function: " + SpecializedF->getName(),
1886+
GenericFunc);
1887+
SpecializedF->verify();
1888+
}
1889+
18741890
return SpecializedF;
18751891
}
18761892

@@ -2443,6 +2459,20 @@ void swift::trySpecializeApplyOfGeneric(
24432459
<< NV("FuncType", OS.str());
24442460
});
24452461

2462+
// Verify our function after we have finished fixing up call sites/etc. Dump
2463+
// the generic function if there is an assertion failure (or a crash) to make
2464+
// it easier to debug such problems since the original generic function is
2465+
// easily at hand.
2466+
SWIFT_DEFER {
2467+
if (VerifyFunctionsAfterSpecialization) {
2468+
PrettyStackTraceSILFunction SILFunctionDumper(
2469+
llvm::Twine("Generic function: ") + RefF->getName() +
2470+
". Specialized Function: " + SpecializedF->getName(),
2471+
RefF);
2472+
SpecializedF->verify();
2473+
}
2474+
};
2475+
24462476
assert(ReInfo.getSpecializedType()
24472477
== SpecializedF->getLoweredFunctionType() &&
24482478
"Previously specialized function does not match expected type.");
@@ -2457,6 +2487,13 @@ void swift::trySpecializeApplyOfGeneric(
24572487
SILFunction *Thunk =
24582488
ReabstractionThunkGenerator(FuncBuilder, ReInfo, PAI, SpecializedF)
24592489
.createThunk();
2490+
if (VerifyFunctionsAfterSpecialization) {
2491+
PrettyStackTraceSILFunction SILFunctionDumper(
2492+
llvm::Twine("Thunk For Generic function: ") + RefF->getName() +
2493+
". Specialized Function: " + SpecializedF->getName(),
2494+
RefF);
2495+
Thunk->verify();
2496+
}
24602497
NewFunctions.push_back(Thunk);
24612498
SILBuilderWithScope Builder(PAI);
24622499
auto *FRI = Builder.createFunctionRef(PAI->getLoc(), Thunk);

0 commit comments

Comments
 (0)