@@ -1767,7 +1767,6 @@ Expr* ReverseModeVisitor::getStdInitListSizeExpr(const Expr* E) {
17671767 // Stores differentiation result of implicit `this` object, if any.
17681768 StmtDiff baseDiff;
17691769 Expr* baseExpr = nullptr ;
1770- Stmt* baseDiffPush = nullptr ;
17711770 size_t idx = 0 ;
17721771
17731772 // / Add base derivative expression in the derived call output args list if
@@ -1797,26 +1796,11 @@ Expr* ReverseModeVisitor::getStdInitListSizeExpr(const Expr* E) {
17971796 if (baseTy->isPointerType ())
17981797 baseTy = baseTy->getPointeeType ();
17991798 CXXRecordDecl* baseRD = baseTy->getAsCXXRecordDecl ();
1800- bool shouldStore = utils::isCopyable (baseRD);
1801- if (shouldStore) {
1802- if (!isPassedByRef || MD ->isConst ()) {
1803- // FIXME: Custom _reverse_forw functions take the base by pointer.
1804- // This means we cannot pass temporary values and because of that,
1805- // we need to store. For now, only emit the store stmt if a custom
1806- // reverse_forw is found.
1807- beginBlock (direction::forward);
1808- Expr* baseDiffStore =
1809- StoreAndRef (baseDiff.getExpr (), direction::forward);
1810- baseDiffPush =
1811- utils::unwrapIfSingleStmt (endBlock (direction::forward));
1812- baseExpr = baseDiffStore;
1813- } else {
1814- Expr* baseDiffStore =
1815- GlobalStoreAndRef (baseDiff.getExpr (), " _t" , /* force=*/ true );
1816- Expr* assign =
1817- BuildOp (BO_Assign, baseDiff.getExpr (), baseDiffStore);
1818- PreCallStmts.push_back (assign);
1819- }
1799+ if (isPassedByRef && !MD ->isConst () && utils::isCopyable (baseRD)) {
1800+ Expr* baseDiffStore =
1801+ GlobalStoreAndRef (baseDiff.getExpr (), " _t" , /* force=*/ true );
1802+ Expr* assign = BuildOp (BO_Assign, baseDiff.getExpr (), baseDiffStore);
1803+ PreCallStmts.push_back (assign);
18201804 }
18211805 Expr* baseDerivative = baseDiff.getExpr_dx ();
18221806 if (!baseDerivative->getType ()->isPointerType ())
@@ -2017,61 +2001,52 @@ Expr* ReverseModeVisitor::getStdInitListSizeExpr(const Expr* E) {
20172001 return StmtDiff (Clone (CE ));
20182002
20192003 Expr* call = nullptr ;
2020- // Stores the dx of the call arguments for the function to be derived
2021- for (std::size_t i = 0 , e = CE ->getNumArgs () - isMethodOperatorCall; i != e;
2022- ++i) {
2023- const Expr* arg = CE ->getArg (i + isMethodOperatorCall);
2024- if (!utils::IsReferenceOrPointerArg (arg) || arg->isXValue ())
2025- CallArgDx[i] = getZeroInit (arg->getType ());
2026- }
2027- if (baseDiff.getExpr_dx () &&
2028- !baseDiff.getExpr_dx ()->getType ()->isPointerType ())
2029- CallArgDx.insert (CallArgDx.begin (), BuildOp (UnaryOperatorKind::UO_AddrOf,
2030- baseDiff.getExpr_dx (), Loc));
2031-
2032- if (Expr* customForwardPassCE =
2033- BuildCallToCustomForwPassFn (CE , CallArgs, CallArgDx, baseExpr)) {
2034- addToCurrentBlock (baseDiffPush, direction::forward);
2035- if (!needsForwPass)
2036- return StmtDiff{customForwardPassCE};
2037- Expr* callRes = nullptr ;
2038- if (isInsideLoop)
2039- callRes = GlobalStoreAndRef (customForwardPassCE, /* prefix=*/ " _t" ,
2040- /* force=*/ true );
2041- else
2042- callRes = StoreAndRef (customForwardPassCE);
2043- auto * resValue =
2044- utils::BuildMemberExpr (m_Sema, getCurrentScope (), callRes, " value" );
2045- auto * resAdjoint =
2046- utils::BuildMemberExpr (m_Sema, getCurrentScope (), callRes, " adjoint" );
2047- return StmtDiff (resValue, resAdjoint);
2048- }
2049- if (needsForwPass) {
2050- DiffRequest calleeFnForwPassReq;
2051- calleeFnForwPassReq.Function = FD ;
2052- calleeFnForwPassReq.Mode = DiffMode::reverse_mode_forward_pass;
2053- calleeFnForwPassReq.BaseFunctionName =
2054- clad::utils::ComputeEffectiveFnName (FD );
2055- calleeFnForwPassReq.VerboseDiags = true ;
2056-
2057- FunctionDecl* calleeFnForwPassFD =
2058- m_Builder.HandleNestedDiffRequest (calleeFnForwPassReq);
2059-
2060- assert (calleeFnForwPassFD &&
2061- " Clad failed to generate callee function forward pass function" );
2062-
2004+ // Lookup a reverse_forw function and build if necessary.
2005+ DiffRequest calleeFnForwPassReq;
2006+ calleeFnForwPassReq.Function = FD ;
2007+ calleeFnForwPassReq.Mode = DiffMode::reverse_mode_forward_pass;
2008+ calleeFnForwPassReq.BaseFunctionName =
2009+ clad::utils::ComputeEffectiveFnName (FD );
2010+ calleeFnForwPassReq.VerboseDiags = true ;
2011+
2012+ FunctionDecl* calleeFnForwPassFD = FindDerivedFunction (calleeFnForwPassReq);
2013+ if (calleeFnForwPassFD) {
2014+ for (std::size_t i = 0 , e = CE ->getNumArgs () - isMethodOperatorCall;
2015+ i != e; ++i) {
2016+ const Expr* arg = CE ->getArg (i + isMethodOperatorCall);
2017+ if (!utils::IsReferenceOrPointerArg (arg) || arg->isXValue ())
2018+ CallArgDx[i] = getZeroInit (arg->getType ());
2019+ }
2020+ if (baseDiff.getExpr_dx () &&
2021+ !baseDiff.getExpr_dx ()->getType ()->isPointerType ())
2022+ CallArgDx.insert (
2023+ CallArgDx.begin (),
2024+ BuildOp (UnaryOperatorKind::UO_AddrOf, baseDiff.getExpr_dx (), Loc));
20632025 CallArgs.insert (CallArgs.end (), CallArgDx.begin (), CallArgDx.end ());
2064- if (Expr* baseE = baseDiff.getExpr ()) {
2065- call = BuildCallExprToMemFn (baseE, calleeFnForwPassFD->getName (),
2066- CallArgs, Loc);
2026+ const auto * forwPassMD = dyn_cast<CXXMethodDecl>(calleeFnForwPassFD);
2027+ Expr* baseE = baseDiff.getExpr ();
2028+ if (forwPassMD && forwPassMD->isInstance ()) {
2029+ call = BuildCallExprToMemFn (
2030+ baseDiff.getExpr (), calleeFnForwPassFD->getName (), CallArgs, Loc);
20672031 } else {
2032+ if (baseE) {
2033+ baseE = BuildOp (UO_AddrOf, baseE);
2034+ CallArgs.insert (CallArgs.begin (), baseE);
2035+ }
20682036 call = m_Sema
20692037 .ActOnCallExpr (getCurrentScope (),
20702038 BuildDeclRef (calleeFnForwPassFD), Loc,
20712039 CallArgs, Loc, CUDAExecConfig)
20722040 .get ();
20732041 }
2074- auto * callRes = StoreAndRef (call);
2042+ if (call->getType ()->isVoidType ())
2043+ return StmtDiff (call);
2044+ Expr* callRes = nullptr ;
2045+ if (isInsideLoop)
2046+ callRes = GlobalStoreAndRef (call, /* prefix=*/ " _t" ,
2047+ /* force=*/ true );
2048+ else
2049+ callRes = StoreAndRef (call);
20752050 auto * resValue =
20762051 utils::BuildMemberExpr (m_Sema, getCurrentScope (), callRes, " value" );
20772052 auto * resAdjoint =
0 commit comments