Skip to content

Commit f8b19cc

Browse files
author
Max Andriychuk
committed
Move TBR call to DiffCollector
1 parent 817279b commit f8b19cc

8 files changed

Lines changed: 89 additions & 51 deletions

File tree

include/clad/Differentiator/DiffPlanner.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "clang/AST/Decl.h"
1111
#include "clang/AST/ExprCXX.h"
1212
#include "clang/AST/RecursiveASTVisitor.h"
13+
#include "clang/Analysis/AnalysisDeclContext.h"
1314

1415
#include "llvm/ADT/DenseSet.h"
1516
#include "llvm/Support/Compiler.h"
@@ -56,6 +57,8 @@ struct DiffRequest {
5657
public:
5758
/// Function to be differentiated.
5859
const clang::FunctionDecl* Function = nullptr;
60+
/// Stores info relevant to the analysis(CFG, ASTContext).
61+
clang::AnalysisDeclContext* AnalysisDC = nullptr;
5962
/// Name of the base function to be differentiated. Can be different from
6063
/// function->getNameAsString() when higher-order derivatives are computed.
6164
std::string BaseFunctionName = {};
@@ -178,6 +181,10 @@ struct DiffRequest {
178181
std::string ComputeDerivativeName() const;
179182
bool HasIndependentParameter(const clang::ParmVarDecl* PVD) const;
180183

184+
std::set<clang::SourceLocation>& getToBeRecorded() const {
185+
m_TbrRunInfo.HasAnalysisRun = true;
186+
return m_TbrRunInfo.ToBeRecorded;
187+
}
181188
void addVariedDecl(const clang::VarDecl* init) {
182189
m_ActivityRunInfo.VariedDecls.insert(init);
183190
}

lib/Differentiator/ActivityAnalyzer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ using namespace clang;
66
namespace clad {
77

88
void VariedAnalyzer::Analyze(const FunctionDecl* FD) {
9-
m_BlockData.resize(m_ADContext.getCFG()->size());
9+
m_BlockData.resize(m_AnalysisDC->getCFG()->size());
1010
// Set current block ID to the ID of entry the block.
11-
CFGBlock* entry = &m_ADContext.getCFG()->getEntry();
11+
CFGBlock* entry = &m_AnalysisDC->getCFG()->getEntry();
1212
m_CurBlockID = entry->getBlockID();
1313
m_BlockData[m_CurBlockID] = createNewVarsData({});
1414
for (const VarDecl* i : m_VariedDecls)
@@ -34,7 +34,7 @@ void mergeVarsData(std::set<const clang::VarDecl*>* targetData,
3434
}
3535

3636
CFGBlock* VariedAnalyzer::getCFGBlockByID(unsigned ID) {
37-
return *(m_ADContext.getCFG()->begin() + ID);
37+
return *(m_AnalysisDC->getCFG()->begin() + ID);
3838
}
3939

4040
void VariedAnalyzer::AnalyzeCFGBlock(const CFGBlock& block) {

lib/Differentiator/ActivityAnalyzer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class VariedAnalyzer : public clang::RecursiveASTVisitor<VariedAnalyzer> {
3636

3737
clang::CFGBlock* getCFGBlockByID(unsigned ID);
3838

39-
clang::AnalysisDeclContext& m_ADContext;
39+
clang::AnalysisDeclContext* m_AnalysisDC;
4040
std::vector<std::unique_ptr<VarsData>> m_BlockData;
4141
unsigned m_CurBlockID{};
4242
std::set<unsigned> m_CFGQueue;
@@ -55,9 +55,9 @@ class VariedAnalyzer : public clang::RecursiveASTVisitor<VariedAnalyzer> {
5555

5656
public:
5757
/// Constructor
58-
VariedAnalyzer(clang::AnalysisDeclContext& ADContext,
58+
VariedAnalyzer(clang::AnalysisDeclContext* AnalysisDC,
5959
std::set<const clang::VarDecl*>& Decls)
60-
: m_VariedDecls(Decls), m_ADContext(ADContext) {}
60+
: m_VariedDecls(Decls), m_AnalysisDC(AnalysisDC) {}
6161

6262
/// Destructor
6363
~VariedAnalyzer() = default;

lib/Differentiator/DiffPlanner.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -649,12 +649,10 @@ DeclRefExpr* getArgFunction(CallExpr* call, Sema& SemaRef) {
649649

650650
if (!m_TbrRunInfo.HasAnalysisRun) {
651651
TimedAnalysisRegion R("TBR " + BaseFunctionName);
652-
653-
TBRAnalyzer analyzer(Function->getASTContext(),
654-
m_TbrRunInfo.ToBeRecorded);
652+
TBRAnalyzer analyzer(AnalysisDC, getToBeRecorded());
655653
analyzer.Analyze(Function);
656-
m_TbrRunInfo.HasAnalysisRun = true;
657654
}
655+
658656
auto found = m_TbrRunInfo.ToBeRecorded.find(E->getBeginLoc());
659657
return found != m_TbrRunInfo.ToBeRecorded.end();
660658
}
@@ -1214,23 +1212,31 @@ DeclRefExpr* getArgFunction(CallExpr* call, Sema& SemaRef) {
12141212

12151213
if (!LookupCustomDerivativeDecl(request)) {
12161214
// Create analysis manager once for all analyses.
1217-
AnalysisDeclContextManager ADCM(request.Function->getASTContext());
1215+
AnalysisDeclContextManager* ADCM =
1216+
new AnalysisDeclContextManager(request.Function->getASTContext());
12181217
clang::CFG::BuildOptions Options;
1219-
AnalysisDeclContext ADC(&ADCM, request.Function, Options);
1220-
ADC.getCFG();
1218+
request.AnalysisDC =
1219+
new AnalysisDeclContext(ADCM, request.Function, Options);
12211220

12221221
if (m_TopMostReq->EnableVariedAnalysis) {
12231222
TimedAnalysisRegion R("VA " + request.BaseFunctionName);
1224-
VariedAnalyzer analyzer(ADC, request.getVariedDecls());
1223+
VariedAnalyzer analyzer(request.AnalysisDC, request.getVariedDecls());
12251224
analyzer.Analyze(request.Function);
12261225
}
12271226

12281227
if (m_TopMostReq->EnableUsefulAnalysis) {
12291228
TimedAnalysisRegion R("UA " + request.BaseFunctionName);
1230-
UsefulAnalyzer analyzer(ADC, request.getUsefulDecls());
1229+
UsefulAnalyzer analyzer(request.AnalysisDC, request.getUsefulDecls());
12311230
analyzer.Analyze(request.Function);
12321231
}
12331232

1233+
if (request.Function->isDefined() && m_TopMostReq->EnableTBRAnalysis &&
1234+
(request.Mode == DiffMode::reverse ||
1235+
request.Mode == DiffMode::pullback)) {
1236+
TimedAnalysisRegion R("TBR " + request.BaseFunctionName);
1237+
TBRAnalyzer analyzer(request.AnalysisDC, request.getToBeRecorded());
1238+
analyzer.Analyze(request.Function);
1239+
}
12341240
// Recurse into call graph.
12351241
TraverseFunctionDeclOnce(request.Function);
12361242
}
@@ -1314,9 +1320,23 @@ DeclRefExpr* getArgFunction(CallExpr* call, Sema& SemaRef) {
13141320
if (m_Sema.isStdInitializerList(recordTy, /*elemType=*/nullptr))
13151321
return true;
13161322

1317-
if (!LookupCustomDerivativeDecl(request))
1323+
if (!LookupCustomDerivativeDecl(request)) {
1324+
AnalysisDeclContextManager* ADCM =
1325+
new AnalysisDeclContextManager(request.Function->getASTContext());
1326+
clang::CFG::BuildOptions Options;
1327+
request.AnalysisDC =
1328+
new AnalysisDeclContext(ADCM, request.Function, Options);
1329+
1330+
if (m_TopMostReq->EnableTBRAnalysis &&
1331+
(request.Mode == DiffMode::reverse ||
1332+
request.Mode == DiffMode::pullback)) {
1333+
TimedAnalysisRegion R("TBR " + request.BaseFunctionName);
1334+
TBRAnalyzer analyzer(request.AnalysisDC, request.getToBeRecorded());
1335+
analyzer.Analyze(request.Function);
1336+
}
13181337
// Recurse into call graph.
13191338
TraverseFunctionDeclOnce(request.Function);
1339+
}
13201340
m_DiffRequestGraph.addNode(request, /*isSource=*/true);
13211341

13221342
return true;

lib/Differentiator/TBRAnalyzer.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,20 @@ TBRAnalyzer::VarData::VarData(QualType QT, const ASTContext& C,
198198
const auto* recordDecl = recordType->getDecl();
199199
auto& newArrMap = m_Val.m_ArrData;
200200
newArrMap = std::unique_ptr<ArrMap>(new ArrMap());
201-
for (const auto* field : recordDecl->fields()) {
202-
const auto varType = field->getType();
203-
(*newArrMap)[getProfileID(field)] = VarData(varType, C);
204-
}
201+
202+
// FIXME: For some reason if a variable is of kokkos-type we start creating
203+
// infinite amount of VarData objects.
204+
bool isInKokkosNS = false;
205+
if (const auto* ns =
206+
llvm::dyn_cast<clang::NamespaceDecl>(recordDecl->getDeclContext()))
207+
if (ns->getName() == "Kokkos")
208+
isInKokkosNS = true;
209+
210+
if (!isInKokkosNS)
211+
for (const auto* field : recordDecl->fields()) {
212+
const auto varType = field->getType();
213+
(*newArrMap)[getProfileID(field)] = VarData(varType, C);
214+
}
205215
}
206216
}
207217

@@ -250,11 +260,13 @@ void TBRAnalyzer::addVar(const clang::VarDecl* VD, bool forceNonRefType) {
250260
varType = arrayParam->getOriginalType();
251261
else
252262
varType = VD->getType();
263+
253264
// If varType represents auto or auto*, get the type of init.
254265
if (utils::IsAutoOrAutoPtrType(varType))
255266
varType = VD->getInit()->getType();
256267

257-
curBranch[VD] = VarData(varType, m_Context, forceNonRefType);
268+
curBranch[VD] =
269+
VarData(varType, m_AnalysisDC->getASTContext(), forceNonRefType);
258270
}
259271

260272
void TBRAnalyzer::markLocation(const clang::Expr* E) {
@@ -301,15 +313,11 @@ TBRAnalyzer::getVarDataFromDecl(const clang::VarDecl* VD) {
301313
}
302314

303315
void TBRAnalyzer::Analyze(const FunctionDecl* FD) {
304-
// Build the CFG (control-flow graph) of FD.
305-
clang::CFG::BuildOptions Options;
306-
m_CFG = clang::CFG::buildCFG(FD, FD->getBody(), &m_Context, Options);
307-
308-
m_BlockData.resize(m_CFG->size());
309-
m_BlockPassCounter.resize(m_CFG->size(), 0);
316+
m_BlockData.resize(m_AnalysisDC->getCFG()->size());
317+
m_BlockPassCounter.resize(m_AnalysisDC->getCFG()->size(), 0);
310318

311319
// Set current block ID to the ID of entry the block.
312-
auto* entry = &m_CFG->getEntry();
320+
auto* entry = &m_AnalysisDC->getCFG()->getEntry();
313321
m_CurBlockID = entry->getBlockID();
314322
m_BlockData[m_CurBlockID] = std::unique_ptr<VarsData>(new VarsData());
315323

@@ -319,7 +327,8 @@ void TBRAnalyzer::Analyze(const FunctionDecl* FD) {
319327
if (MD && !MD->isStatic()) {
320328
const Type* recordType = MD->getParent()->getTypeForDecl();
321329
VarData& thisData = getCurBlockVarsData()[nullptr];
322-
thisData = VarData(QualType::getFromOpaquePtr(recordType), m_Context);
330+
thisData = VarData(QualType::getFromOpaquePtr(recordType),
331+
m_AnalysisDC->getASTContext());
323332
// We have to set all pointer/reference parameters to tbr
324333
// since method pullbacks aren't supposed to change objects.
325334
setIsRequired(thisData);
@@ -347,7 +356,7 @@ void TBRAnalyzer::Analyze(const FunctionDecl* FD) {
347356
LLVM_DEBUG(llvm::dbgs() << "successor: " << succ->getBlockID() << "\n");
348357
}
349358

350-
clang::SourceManager& SM = m_Context.getSourceManager();
359+
clang::SourceManager& SM = m_AnalysisDC->getASTContext().getSourceManager();
351360
for (SourceLocation Loc : m_TBRLocs) {
352361
unsigned line = SM.getPresumedLoc(Loc).getLine();
353362
unsigned column = SM.getPresumedLoc(Loc).getColumn();
@@ -415,7 +424,7 @@ void TBRAnalyzer::VisitCFGBlock(const CFGBlock& block) {
415424
}
416425

417426
CFGBlock* TBRAnalyzer::getCFGBlockByID(unsigned ID) {
418-
return *(m_CFG->begin() + ID);
427+
return *(m_AnalysisDC->getCFG()->begin() + ID);
419428
}
420429

421430
TBRAnalyzer::VarsData*
@@ -571,9 +580,11 @@ bool TBRAnalyzer::TraverseDeclStmt(DeclStmt* DS) {
571580
if (auto* VD = dyn_cast<VarDecl>(D)) {
572581
addVar(VD);
573582
if (clang::Expr* init = VD->getInit()) {
583+
574584
setMode(Mode::kMarkingMode);
575585
TraverseStmt(init);
576586
resetMode();
587+
577588
auto& VDExpr = getCurBlockVarsData()[VD];
578589
// if the declared variable is ref type attach its VarData to the
579590
// VarData of the RHS variable.
@@ -622,9 +633,10 @@ bool TBRAnalyzer::TraverseBinaryOperator(BinaryOperator* BinOp) {
622633
// Multiplication results in a linear expression if and only if one of the
623634
// factors is constant.
624635
Expr::EvalResult dummy;
625-
bool nonLinear =
626-
!clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context) &&
627-
!clad_compat::Expr_EvaluateAsConstantExpr(L, dummy, m_Context);
636+
bool nonLinear = !clad_compat::Expr_EvaluateAsConstantExpr(
637+
R, dummy, m_AnalysisDC->getASTContext()) &&
638+
!clad_compat::Expr_EvaluateAsConstantExpr(
639+
L, dummy, m_AnalysisDC->getASTContext());
628640
if (nonLinear)
629641
startNonLinearMode();
630642

@@ -637,8 +649,8 @@ bool TBRAnalyzer::TraverseBinaryOperator(BinaryOperator* BinOp) {
637649
// Division normally only results in a linear expression when the
638650
// denominator is constant.
639651
Expr::EvalResult dummy;
640-
bool nonLinear =
641-
!clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context);
652+
bool nonLinear = !clad_compat::Expr_EvaluateAsConstantExpr(
653+
R, dummy, m_AnalysisDC->getASTContext());
642654
if (nonLinear)
643655
startNonLinearMode();
644656

@@ -663,8 +675,8 @@ bool TBRAnalyzer::TraverseBinaryOperator(BinaryOperator* BinOp) {
663675
// represents the same operation as 'x = x * y' ('x = x / y') and,
664676
// therefore, LHS has to be visited in kMarkingMode|kNonLinearMode.
665677
Expr::EvalResult dummy;
666-
bool RisNotConst =
667-
!clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context);
678+
bool RisNotConst = !clad_compat::Expr_EvaluateAsConstantExpr(
679+
R, dummy, m_AnalysisDC->getASTContext());
668680
if (RisNotConst)
669681
setMode(Mode::kMarkingMode | Mode::kNonLinearMode);
670682
TraverseStmt(L);

lib/Differentiator/TBRAnalyzer.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "clang/AST/ExprCXX.h"
55
#include "clang/AST/RecursiveASTVisitor.h"
66
#include "clang/AST/Stmt.h"
7+
#include "clang/Analysis/AnalysisDeclContext.h"
78
#include "clang/Analysis/CFG.h"
89

910
#include "clad/Differentiator/CladUtils.h"
@@ -31,7 +32,7 @@ class TBRAnalyzer : public clang::RecursiveASTVisitor<TBRAnalyzer> {
3132

3233
ProfileID getProfileID(const Expr* E) const {
3334
ProfileID profID;
34-
E->Profile(profID, m_Context, /* Canonical */ true);
35+
E->Profile(profID, m_AnalysisDC->getASTContext(), /* Canonical */ true);
3536
return profID;
3637
}
3738

@@ -229,10 +230,7 @@ class TBRAnalyzer : public clang::RecursiveASTVisitor<TBRAnalyzer> {
229230
/// a new one).
230231
std::vector<int> m_ModeStack;
231232

232-
ASTContext& m_Context;
233-
234-
/// clang::CFG of the function being analysed.
235-
std::unique_ptr<clang::CFG> m_CFG;
233+
clang::AnalysisDeclContext* m_AnalysisDC;
236234

237235
/// Stores VarsData structures for CFG blocks (the indices in
238236
/// the vector correspond to CFG blocks' IDs)
@@ -282,8 +280,9 @@ class TBRAnalyzer : public clang::RecursiveASTVisitor<TBRAnalyzer> {
282280

283281
public:
284282
/// Constructor
285-
TBRAnalyzer(ASTContext& Context, std::set<clang::SourceLocation>& Locs)
286-
: m_TBRLocs(Locs), m_Context(Context) {
283+
TBRAnalyzer(clang::AnalysisDeclContext* AnalysisDC,
284+
std::set<clang::SourceLocation>& Locs)
285+
: m_TBRLocs(Locs), m_AnalysisDC(AnalysisDC) {
287286
m_ModeStack.push_back(0);
288287
}
289288

lib/Differentiator/UsefulAnalyzer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ namespace clad {
66

77
void UsefulAnalyzer::Analyze(const FunctionDecl* FD) {
88
// Build the CFG (control-flow graph) of FD.
9-
m_BlockData.resize(m_ADContext.getCFG()->size());
9+
m_BlockData.resize(m_AnalysisDC->getCFG()->size());
1010
// Set current block ID to the ID of entry the block.
11-
CFGBlock* exit = &m_ADContext.getCFG()->getExit();
11+
CFGBlock* exit = &m_AnalysisDC->getCFG()->getExit();
1212
m_CurBlockID = exit->getBlockID();
1313
m_BlockData[m_CurBlockID] = createNewVarsData({});
1414
// Add the entry block to the queue.
@@ -25,7 +25,7 @@ void UsefulAnalyzer::Analyze(const FunctionDecl* FD) {
2525
}
2626

2727
CFGBlock* UsefulAnalyzer::getCFGBlockByID(unsigned ID) {
28-
return *(m_ADContext.getCFG()->begin() + ID);
28+
return *(m_AnalysisDC->getCFG()->begin() + ID);
2929
}
3030

3131
bool UsefulAnalyzer::isUseful(const VarDecl* VD) const {

lib/Differentiator/UsefulAnalyzer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class UsefulAnalyzer : public clang::RecursiveASTVisitor<UsefulAnalyzer> {
3131

3232
clang::CFGBlock* getCFGBlockByID(unsigned ID);
3333

34-
clang::AnalysisDeclContext& m_ADContext;
34+
clang::AnalysisDeclContext* m_AnalysisDC;
3535
std::unique_ptr<clang::CFG> m_CFG;
3636
std::vector<std::unique_ptr<VarsData>> m_BlockData;
3737
unsigned m_CurBlockID{};
@@ -46,9 +46,9 @@ class UsefulAnalyzer : public clang::RecursiveASTVisitor<UsefulAnalyzer> {
4646

4747
public:
4848
/// Constructor
49-
UsefulAnalyzer(clang::AnalysisDeclContext& ADContext,
49+
UsefulAnalyzer(clang::AnalysisDeclContext* AnalysisDC,
5050
std::set<const clang::VarDecl*>& Decls)
51-
: m_UsefulDecls(Decls), m_ADContext(ADContext) {}
51+
: m_UsefulDecls(Decls), m_AnalysisDC(AnalysisDC) {}
5252

5353
/// Destructor
5454
~UsefulAnalyzer() = default;

0 commit comments

Comments
 (0)