Skip to content

Commit 56b1ca8

Browse files
Add support for SourceLocExpr during differentiation to enable code containing assert and other source-location builtins.
1 parent d0e1e2d commit 56b1ca8

7 files changed

Lines changed: 55 additions & 1 deletion

File tree

include/clad/Differentiator/BaseForwardModeVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class BaseForwardModeVisitor
9999
StmtDiff VisitWhileStmt(const clang::WhileStmt* WS);
100100
StmtDiff VisitDoStmt(const clang::DoStmt* DS);
101101
StmtDiff VisitContinueStmt(const clang::ContinueStmt* ContStmt);
102+
StmtDiff VisitSourceLocExpr(const clang::SourceLocExpr* E);
102103

103104
StmtDiff VisitSwitchStmt(const clang::SwitchStmt* SS);
104105
StmtDiff VisitBreakStmt(const clang::BreakStmt* BS);

include/clad/Differentiator/ReverseModeVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ namespace clad {
485485
StmtDiff VisitImplicitCastExpr(const clang::ImplicitCastExpr* ICE);
486486
StmtDiff VisitGNUNullExpr(const clang::GNUNullExpr* E);
487487
StmtDiff VisitPredefinedExpr(const clang::PredefinedExpr* E);
488+
StmtDiff VisitSourceLocExpr(const clang::SourceLocExpr* SLE);
488489

489490
#if CLANG_VERSION_MAJOR > 16
490491
StmtDiff VisitLambdaExpr(const clang::LambdaExpr* LE);

include/clad/Differentiator/StmtClone.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ namespace utils {
7979
DECLARE_CLONE_FN(CXXCatchStmt)
8080
DECLARE_CLONE_FN(CXXTryStmt)
8181
DECLARE_CLONE_FN(PredefinedExpr)
82+
DECLARE_CLONE_FN(SourceLocExpr)
8283
DECLARE_CLONE_FN(CharacterLiteral)
8384
DECLARE_CLONE_FN(FloatingLiteral)
8485
DECLARE_CLONE_FN(ImaginaryLiteral)

lib/Differentiator/BaseForwardModeVisitor.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,8 @@ StmtDiff BaseForwardModeVisitor::VisitConditionalOperator(
581581
.ActOnConditionalOp(noLoc, noLoc, cond, ifTrueDiff.getExpr(),
582582
ifFalseDiff.getExpr())
583583
.get();
584-
584+
if (condExpr->getType()->isVoidType())
585+
return StmtDiff(condExpr, nullptr);
585586
// cond is already used by the value conditional above; clone it for the
586587
// derivative conditional so the two do not share the stored condition.
587588
Expr* condExprDiff =
@@ -1874,6 +1875,13 @@ StmtDiff BaseForwardModeVisitor::VisitStringLiteral(const StringLiteral* SL) {
18741875
SL->getType(), utils::GetValidSLoc(m_Sema)));
18751876
}
18761877

1878+
StmtDiff
1879+
BaseForwardModeVisitor::VisitSourceLocExpr(const clang::SourceLocExpr* E) {
1880+
auto* Constant0 =
1881+
ConstantFolder::synthesizeLiteral(m_Context.IntTy, m_Context, /*val=*/0);
1882+
return StmtDiff(CloneNode(E), Constant0);
1883+
}
1884+
18771885
StmtDiff BaseForwardModeVisitor::VisitWhileStmt(const WhileStmt* WS) {
18781886
// Scope for the whole while loop.
18791887
ScopeRAII whileScope(*this, Scope::ContinueScope | Scope::BreakScope |

lib/Differentiator/ReverseModeVisitor.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,6 +2942,10 @@ Expr* ReverseModeVisitor::getStdInitListSizeExpr(const Expr* E) {
29422942
for (Stmt* S : revBlock)
29432943
addToCurrentBlock(S, direction::reverse);
29442944
return {cloneE, derivedE};
2945+
} else if (opCode == UnaryOperatorKind::UO_Extension) {
2946+
diff = Visit(E);
2947+
ResultRef = diff.getExpr_dx();
2948+
valueForRevPass = diff.getRevSweepAsExpr();
29452949
} else {
29462950
if (opCode != UO_LNot)
29472951
// We should only output warnings on visiting boolean conditions
@@ -3904,6 +3908,13 @@ Expr* ReverseModeVisitor::getStdInitListSizeExpr(const Expr* E) {
39043908
return StmtDiff(CloneNode(E), Constant0);
39053909
}
39063910

3911+
StmtDiff
3912+
ReverseModeVisitor::VisitSourceLocExpr(const clang::SourceLocExpr* E) {
3913+
auto* Constant0 = ConstantFolder::synthesizeLiteral(m_Context.IntTy,
3914+
m_Context, /*val=*/0);
3915+
return StmtDiff(CloneNode(E), Constant0);
3916+
}
3917+
39073918
StmtDiff ReverseModeVisitor::VisitCXXFunctionalCastExpr(
39083919
const clang::CXXFunctionalCastExpr* FCE) {
39093920
StmtDiff castExprDiff = Visit(FCE->getSubExpr(), dfdx());

lib/Differentiator/StmtClone.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ Stmt* StmtClone::VisitPredefinedExpr(PredefinedExpr* Node) {
9292
clad_compat::ExprSetDeps(result, Node);
9393
return result;
9494
}
95+
#if CLANG_VERSION_MAJOR >= 15
96+
DEFINE_CLONE_EXPR(SourceLocExpr,
97+
(Ctx, Node->getIdentKind(), CloneType(Node->getType()),
98+
Node->getBeginLoc(), Node->getEndLoc(),
99+
Node->getParentContext()))
100+
#else
101+
DEFINE_CLONE_EXPR(SourceLocExpr,
102+
(Ctx, Node->getIdentKind(), Node->getBeginLoc(),
103+
Node->getEndLoc(), Node->getParentContext()))
104+
#endif
95105
DEFINE_CLONE_EXPR(CharacterLiteral,
96106
(Node->getValue(), Node->getKind(),
97107
CloneType(Node->getType()), Node->getLocation()))

test/Features/DiffAssert.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %cladclang -std=c++17 -I%S/../../include %s -o %t
2+
// RUN: %t | %filecheck_exec %s
3+
4+
#include <cassert>
5+
#include "clad/Differentiator/Differentiator.h"
6+
7+
double func(double x){
8+
assert(x>0.0);
9+
return x*x*x;
10+
}
11+
12+
int main(){
13+
auto d_func=clad::gradient(func);
14+
double dx=0;
15+
d_func.execute(3.0,&dx);
16+
printf("Diff result: %.2f\n", dx);
17+
//CHECK-EXEC: Diff result: 27.00
18+
auto d_func1=clad::differentiate(func);
19+
auto res=d_func1.execute(3.0);
20+
printf("Diff result: %.2f\n", res);
21+
//CHECK-EXEC: Diff result: 27.00
22+
}

0 commit comments

Comments
 (0)