Skip to content

Commit e31fe6c

Browse files
committed
Implement more descriptive pretty stack printing for generated derivatives.
1 parent a81370d commit e31fe6c

5 files changed

Lines changed: 59 additions & 0 deletions

File tree

include/clad/Differentiator/BaseForwardModeVisitor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ class BaseForwardModeVisitor
3939
///
4040
DerivativeAndOverload Derive() override;
4141

42+
virtual StmtDiff Visit(const clang::Stmt* S) {
43+
m_CurVisitedStmt = S;
44+
return clang::ConstStmtVisitor<BaseForwardModeVisitor, StmtDiff>::Visit(S);
45+
}
46+
4247
virtual void ExecuteInsidePushforwardFunctionBlock() {}
4348

4449
virtual StmtDiff

include/clad/Differentiator/VisitorBase.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ namespace clad {
136136
// expression to be of object type in the reverse mode as well.
137137
clang::Expr* m_ThisExprDerivative = nullptr;
138138

139+
/// The currently visited statement. Useful for crash pretty-printing.
140+
const clang::Stmt* m_CurVisitedStmt = nullptr;
141+
139142
/// A function used to wrap result of visiting E in a lambda. Returns a call
140143
/// to the built lambda. Func is a functor that will be invoked inside
141144
/// lambda scope and block. Statements inside lambda are expected to be
@@ -671,6 +674,23 @@ namespace clad {
671674
clang::TemplateDecl* m_CladConstructorPushforwardTag = nullptr;
672675
clang::TemplateDecl* m_CladConstructorReverseForwTag = nullptr;
673676
};
677+
678+
/// A class that generates prettier stack traces when we crash on generating
679+
/// a derivative.
680+
class PrettyStackTraceDerivative : public llvm::PrettyStackTraceEntry {
681+
const DiffRequest& m_DiffReq;
682+
using Blocks = std::vector<llvm::SmallVector<clang::Stmt*, 16>>;
683+
const Blocks& m_Blocks;
684+
const clang::Sema& m_Sema;
685+
const clang::Stmt** m_Stmt = nullptr;
686+
687+
public:
688+
PrettyStackTraceDerivative(const DiffRequest& DiffReq, const Blocks& B,
689+
const clang::Sema& Sema, const clang::Stmt** S)
690+
: m_DiffReq(DiffReq), m_Blocks(B), m_Sema(Sema), m_Stmt(S) {}
691+
void print(llvm::raw_ostream& OS) const override;
692+
};
693+
674694
} // end namespace clad
675695

676696
#endif // CLAD_VISITOR_BASE_H

lib/Differentiator/BaseForwardModeVisitor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ DerivativeAndOverload BaseForwardModeVisitor::Derive() {
6363
assert(!m_DerivativeInFlight &&
6464
"Doesn't support recursive diff. Use DiffPlan.");
6565

66+
PrettyStackTraceDerivative CrashInfo(m_DiffReq, m_Blocks, m_Sema,
67+
&m_CurVisitedStmt);
68+
6669
llvm::SaveAndRestore<bool> saveInFlight(m_DerivativeInFlight,
6770
/*NewValue=*/true);
6871

lib/Differentiator/ReverseModeVisitor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ Expr* ReverseModeVisitor::getStdInitListSizeExpr(const Expr* E) {
234234

235235
DerivativeAndOverload ReverseModeVisitor::Derive() {
236236
assert(m_DiffReq.Function && "Must not be null.");
237+
238+
PrettyStackTraceDerivative CrashInfo(m_DiffReq, m_Blocks, m_Sema,
239+
&m_CurVisitedStmt);
240+
237241
if (m_ExternalSource)
238242
m_ExternalSource->ActOnStartOfDerive();
239243
if (m_DiffReq.Mode == DiffMode::error_estimation)

lib/Differentiator/VisitorBase.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,4 +1072,31 @@ namespace clad {
10721072
}
10731073
return nullptr;
10741074
}
1075+
1076+
void PrettyStackTraceDerivative::print(llvm::raw_ostream& OS) const {
1077+
OS << "Building code for '" << (std::string)m_DiffReq << "'\n";
1078+
clang::PrintingPolicy P(m_Sema.getASTContext().getLangOpts());
1079+
if (m_Stmt) {
1080+
const Stmt* S = *m_Stmt;
1081+
clang::SourceLocation B = S->getBeginLoc(), E = S->getEndLoc();
1082+
clang::SourceManager& SM = m_Sema.getSourceManager();
1083+
1084+
OS << "While visiting <" << S->getStmtClassName() << ">"
1085+
<< " [ '";
1086+
B.print(OS, SM);
1087+
OS << "', '";
1088+
E.print(OS, SM);
1089+
OS << "']\n";
1090+
1091+
OS << "\nBegin Stmt Dump ---\n";
1092+
(*m_Stmt)->printPretty(OS, /*Helper=*/nullptr, P);
1093+
OS << "\nEnd Stmt Dump ---\n";
1094+
}
1095+
1096+
if (!m_Blocks.empty() && !m_Blocks.back().empty()) {
1097+
OS << "Last forward statement ";
1098+
m_Blocks.back().back()->printPretty(OS, /*Helper=*/nullptr, P);
1099+
}
1100+
}
1101+
10751102
} // end namespace clad

0 commit comments

Comments
 (0)