Skip to content

Commit eca36c4

Browse files
committed
remove-firstprivate pass
1 parent ee388d3 commit eca36c4

File tree

4 files changed

+176
-16
lines changed

4 files changed

+176
-16
lines changed

include/tsar/Support/Directives.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def RegionName : Clause<"name", Region,
155155
[LParen, PPIdentifier, ZeroOrMore<[Comma, PPIdentifier]>, RParen]>;
156156

157157
def RemoveFirstPrivate : Clause<"removefirstprivate", Transform,
158-
[LParen, Identifier, Comma, OneOf<[Identifier, NumericConstant]>, RParen, ZeroOrMore<[Comma, LParen, Identifier, Comma, OneOf<[Identifier, NumericConstant]>, RParen]>]>;
158+
[LParen, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[Comma, Identifier, Equal, OneOf<[Identifier, NumericConstant]>]>, RParen]>;
159159

160160
def ReplaceMetadata : Clause<"replace", Metadata,
161161
[LParen,

include/tsar/Transform/Clang/Passes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ llvm::ModulePass * createClangRenameLocalPass();
5757
void initializeClangRenameLocalPassPass(PassRegistry &Registry);
5858

5959
/// Creates a pass to perform remove-firstprivate.
60-
ModulePass * createClangRemoveFirstPrivate();
60+
FunctionPass * createClangRemoveFirstPrivate();
6161

6262
/// Initializes a pass to perform remove-firstprivate.
6363
void initializeClangRemoveFirstPrivatePass(PassRegistry &Registry);
@@ -101,4 +101,4 @@ void initializeClangLoopReversePass(PassRegistry &Registry);
101101
/// Create a pass to reverse loop.
102102
ModulePass *createClangLoopReverse();
103103
}
104-
#endif//TSAR_CLANG_TRANSFORM_PASSES_H
104+
#endif//TSAR_CLANG_TRANSFORM_PASSES_H

include/tsar/Transform/Clang/RemoveFirstPrivate.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@
3131

3232
namespace llvm {
3333

34-
class ClangRemoveFirstPrivate : public ModulePass, private bcl::Uncopyable {
34+
class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable {
3535
public:
3636
static char ID;
3737

38-
ClangRemoveFirstPrivate() : ModulePass(ID) {
38+
ClangRemoveFirstPrivate() : FunctionPass(ID) {
3939
initializeClangRemoveFirstPrivatePass(*PassRegistry::getPassRegistry());
4040
}
4141

42-
bool runOnModule(Module &F) override;
42+
bool runOnFunction(Function &F) override;
4343
void getAnalysisUsage(AnalysisUsage &AU) const override;
4444
};
4545
}

lib/Transform/Clang/RemoveFirstPrivate.cpp

Lines changed: 170 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//=== RemoveFirstPrivate.cpp - (Clang) --*- C++ -*===//
1+
//=== DeadDeclsElimination.cpp - Dead Decls Elimination (Clang) --*- C++ -*===//
22
//
33
// Traits Static Analyzer (SAPFOR)
44
//
@@ -18,7 +18,7 @@
1818
//
1919
//===----------------------------------------------------------------------===//
2020
//
21-
//
21+
// This file implements a pass to initialize firstprivate variables.
2222
//
2323
//===----------------------------------------------------------------------===//
2424

@@ -31,6 +31,7 @@
3131
#include <clang/AST/Decl.h>
3232
#include <clang/AST/RecursiveASTVisitor.h>
3333
#include <clang/AST/Stmt.h>
34+
#include <clang/Basic/SourceLocation.h>
3435
#include <llvm/ADT/DenseMap.h>
3536
#include <llvm/ADT/DenseSet.h>
3637
#include <llvm/ADT/SmallVector.h>
@@ -39,37 +40,196 @@
3940
#include <llvm/Support/Debug.h>
4041
#include <llvm/Support/raw_ostream.h>
4142
#include <vector>
43+
#include <stack>
4244

4345
using namespace clang;
4446
using namespace llvm;
4547
using namespace tsar;
4648

4749
#undef DEBUG_TYPE
48-
#define DEBUG_TYPE "remove-firstprivate"
50+
#define DEBUG_TYPE "clang-rfp"
4951

5052
char ClangRemoveFirstPrivate::ID = 0;
5153

5254
INITIALIZE_PASS_IN_GROUP_BEGIN(ClangRemoveFirstPrivate, "remove-firstprivate",
53-
"Does something important", false, false,
55+
"Initialize variables in for", false, false,
5456
TransformationQueryManager::getPassRegistry())
5557
INITIALIZE_PASS_DEPENDENCY(TransformationEnginePass)
5658
INITIALIZE_PASS_DEPENDENCY(ClangGlobalInfoPass)
5759
INITIALIZE_PASS_IN_GROUP_END(ClangRemoveFirstPrivate, "remove-firstprivate",
58-
"Does something important", false, false,
60+
"Initialize variables in for", false, false,
5961
TransformationQueryManager::getPassRegistry())
6062

63+
namespace {
64+
65+
class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
66+
struct DeclarationInfo {
67+
DeclarationInfo(Stmt *S) : Scope(S) {}
68+
69+
Stmt *Scope;
70+
SmallVector<Stmt *, 16> DeadAccesses;
71+
};
72+
public:
73+
explicit DeclVisitor(TransformationContext &TfmCtx, const ASTImportInfo &ImportInfo,
74+
ClangGlobalInfoPass::RawInfo &RawInfo) :
75+
mTfmCtx(&TfmCtx), mImportInfo(ImportInfo),
76+
mRawInfo(&RawInfo), mRewriter(TfmCtx.getRewriter()),
77+
mContext(TfmCtx.getContext()), mSrcMgr(mRewriter.getSourceMgr()),
78+
mLangOpts(mRewriter.getLangOpts()) {}
79+
80+
bool TraverseStmt(Stmt *S) {
81+
if (!S)
82+
return true;
83+
84+
bool ast = false;
85+
Pragma P(*S);
86+
87+
if (findClause(P, ClauseId::RemoveFirstPrivate, mClauses)) {
88+
89+
auto locationForInits = S -> getEndLoc();
90+
91+
isInPragma = true;
92+
ast = RecursiveASTVisitor::TraverseStmt(S);
93+
isInPragma = false;
94+
95+
96+
std::string txtStr;
97+
std::vector<std::string> inits;
98+
while (starts.size()) {
99+
SourceRange toInsert(starts.top(), ends.top());
100+
CharSourceRange txtToInsert(toInsert, true);
101+
starts.pop();
102+
ends.pop();
103+
104+
txtStr = mRewriter.getRewrittenText(txtToInsert);
105+
txtStr += ";\n";
106+
inits.push_back(txtStr);
107+
}
108+
109+
llvm::SmallVector<clang::CharSourceRange, 8> ToRemove;
110+
auto IsPossible = pragmaRangeToRemove(P, mClauses, mSrcMgr, mLangOpts,
111+
mImportInfo, ToRemove);
112+
if (!IsPossible.first)
113+
if (IsPossible.second & PragmaFlags::IsInMacro)
114+
toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(),
115+
tsar::diag::warn_remove_directive_in_macro);
116+
else if (IsPossible.second & PragmaFlags::IsInHeader)
117+
toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(),
118+
tsar::diag::warn_remove_directive_in_include);
119+
else
120+
toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(),
121+
tsar::diag::warn_remove_directive);
122+
Rewriter::RewriteOptions RemoveEmptyLine;
123+
/// TODO ([email protected]): it seems that RemoveLineIfEmpty is
124+
/// set to true then removing (in RewriterBuffer) works incorrect.
125+
RemoveEmptyLine.RemoveLineIfEmpty = false;
126+
for (auto SR : ToRemove)
127+
mRewriter.RemoveText(SR, RemoveEmptyLine); // delete each range
128+
129+
for (std::vector<std::string>::iterator it = inits.begin(); it != inits.end(); ++it) {
130+
mRewriter.InsertTextAfterToken(locationForInits, *it);
131+
}
132+
return ast;
133+
}
134+
return RecursiveASTVisitor::TraverseStmt(S);
135+
}
136+
137+
bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) {
138+
NamedDecl *named = nullptr;
139+
if (isInPragma) {
140+
141+
if (waitingForVar) {
142+
starts.push(Ex -> getLocation());
143+
} else {
144+
ends.push(Ex -> getLocation());
145+
}
146+
waitingForVar = !waitingForVar;
147+
}
148+
return RecursiveASTVisitor::TraverseDeclRefExpr(Ex);
149+
}
61150

151+
#ifdef LLVM_DEBUG
152+
// debug info
153+
#endif
154+
155+
private:
156+
/// Return current scope.
157+
Stmt *getScope() {
158+
for (auto I = mScopes.rbegin(), EI = mScopes.rend(); I != EI; ++I)
159+
if (isa<ForStmt>(*I) || isa<CompoundStmt>(*I))
160+
return *I;
161+
return nullptr;
162+
}
163+
164+
/// Return true if there is a side effect inside a specified statement.
165+
const Stmt * findSideEffect(const Stmt &S) {
166+
if (!isa<CallExpr>(S) &&
167+
!(isa<BinaryOperator>(S) && cast<BinaryOperator>(S).isAssignmentOp()) &&
168+
!(isa<UnaryOperator>(S) &&
169+
cast<UnaryOperator>(S).isIncrementDecrementOp())) {
170+
for (auto Child : make_range(S.child_begin(), S.child_end()))
171+
if (Child)
172+
if (auto SideEffect = findSideEffect(*Child))
173+
return SideEffect;
174+
return nullptr;
175+
}
176+
return &S;
177+
}
178+
179+
bool isInPragma = false;
180+
bool waitingForVar = true;
181+
std::map<NamedDecl *, DeclarationInfo> mDeadDecls;
182+
std::vector<Stmt*> mScopes;
183+
// clang::Rewriter *mRewriter;
184+
DenseSet<DeclStmt*> mMultipleDecls;
185+
DenseMap<const clang::Type *, decltype(mDeadDecls)::const_iterator> mTypeDecls;
186+
DeclRefExpr *mSimpleAssignLHS = nullptr;
187+
188+
TransformationContext *mTfmCtx;
189+
const ASTImportInfo &mImportInfo;
190+
ClangGlobalInfoPass::RawInfo *mRawInfo;
191+
Rewriter &mRewriter;
192+
ASTContext &mContext;
193+
SourceManager &mSrcMgr;
194+
const LangOptions &mLangOpts;
195+
SmallVector<Stmt *, 1> mClauses;
196+
197+
std::stack<SourceLocation> starts;
198+
std::stack<SourceLocation> ends;
199+
200+
};
201+
}
202+
203+
bool ClangRemoveFirstPrivate::runOnFunction(Function &F) {
204+
auto *M = F.getParent();
205+
auto &TfmInfo = getAnalysis<TransformationEnginePass>();
206+
auto *TfmCtx{TfmInfo ? TfmInfo->getContext(*M) : nullptr};
207+
if (!TfmCtx || !TfmCtx->hasInstance()) {
208+
M->getContext().emitError("can not transform sources"
209+
": transformation context is not available");
210+
return false;
211+
}
212+
auto FuncDecl = TfmCtx->getDeclForMangledName(F.getName());
213+
if (!FuncDecl)
214+
return false;
215+
216+
ASTImportInfo ImportStub;
217+
const auto *ImportInfo = &ImportStub;
218+
if (auto *ImportPass = getAnalysisIfAvailable<ImmutableASTImportInfoPass>())
219+
ImportInfo = &ImportPass->getImportInfo();
220+
auto &GIP = getAnalysis<ClangGlobalInfoPass>();
221+
222+
DeclVisitor Visitor(*TfmCtx, *ImportInfo, GIP.getRawInfo());
223+
Visitor.TraverseDecl(FuncDecl);
224+
return false;
225+
}
62226

63227
void ClangRemoveFirstPrivate::getAnalysisUsage(AnalysisUsage &AU) const {
64228
AU.addRequired<TransformationEnginePass>();
65229
AU.addRequired<ClangGlobalInfoPass>();
66230
AU.setPreservesAll();
67231
}
68232

69-
bool ClangRemoveFirstPrivate::runOnModule(Module &M) {
70-
return false;
71-
}
72-
73-
ModulePass *llvm::createClangRemoveFirstPrivate() {
233+
FunctionPass *llvm::createClangRemoveFirstPrivate() {
74234
return new ClangRemoveFirstPrivate();
75235
}

0 commit comments

Comments
 (0)