From 1759c6106e2d2759403ae0458d69ca58ed9fd498 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Thu, 24 Feb 2022 15:16:39 +0300 Subject: [PATCH 01/23] resolve merge conflict --- .../tsar/Transform/Clang/RemoveFirstPrivate.h | 46 ++++++++++++ lib/Transform/Clang/CMakeLists.txt | 2 +- lib/Transform/Clang/RemoveFirstPrivate.cpp | 71 +++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 include/tsar/Transform/Clang/RemoveFirstPrivate.h create mode 100644 lib/Transform/Clang/RemoveFirstPrivate.cpp diff --git a/include/tsar/Transform/Clang/RemoveFirstPrivate.h b/include/tsar/Transform/Clang/RemoveFirstPrivate.h new file mode 100644 index 00000000..93bc4080 --- /dev/null +++ b/include/tsar/Transform/Clang/RemoveFirstPrivate.h @@ -0,0 +1,46 @@ +//=== RemoveFirstPrivate.h - (Clang) ----*- C++ -*===// +// +// Traits Static Analyzer (SAPFOR) +// +// Copyright 2018 DVM System Group +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===---------------------------------------------------------------------===// +// +// TO DO: ADD INFO +// +//===---------------------------------------------------------------------===// + +#ifndef TSAR_CLANG_RFP_H +#define TSAR_CLANG_RFP_H + +#include "tsar/Transform/Clang/Passes.h" +#include +#include + +namespace llvm { + +class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { +public: + static char ID; + + ClangRemoveFirstPrivate() : FunctionPass(ID) { + initializeClangRemoveFirstPrivatePass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; +} +#endif//TSAR_CLANG_RFP_H diff --git a/lib/Transform/Clang/CMakeLists.txt b/lib/Transform/Clang/CMakeLists.txt index d5eef742..c73b6dc2 100644 --- a/lib/Transform/Clang/CMakeLists.txt +++ b/lib/Transform/Clang/CMakeLists.txt @@ -2,7 +2,7 @@ set(TRANSFORM_SOURCES Passes.cpp ExprPropagation.cpp Inline.cpp RenameLocal.cpp DeadDeclsElimination.cpp Format.cpp OpenMPAutoPar.cpp DVMHWriter.cpp SharedMemoryAutoPar.cpp DVMHDirecitves.cpp DVMHSMAutoPar.cpp DVMHDataTransferIPO.cpp StructureReplacement.cpp LoopInterchange.cpp - LoopReversal.cpp) + LoopReversal.cpp RemoveFirstPrivate.cpp) if(MSVC_IDE) file(GLOB_RECURSE TRANSFORM_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp new file mode 100644 index 00000000..958829a6 --- /dev/null +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -0,0 +1,71 @@ +//=== RemoveFirstPrivate.cpp - (Clang) --*- C++ -*===// +// +// Traits Static Analyzer (SAPFOR) +// +// Copyright 2018 DVM System Group +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +// +// +// +//===----------------------------------------------------------------------===// + +#include "tsar/Transform/Clang/RemoveFirstPrivate.h" +#include "tsar/Analysis/Clang/GlobalInfoExtractor.h" +#include "tsar/Analysis/Clang/NoMacroAssert.h" +#include "tsar/Core/Query.h" +#include "tsar/Frontend/Clang/TransformationContext.h" +#include "tsar/Support/Clang/Diagnostic.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace clang; +using namespace llvm; +using namespace tsar; + +#undef DEBUG_TYPE +#define DEBUG_TYPE "remove-firstprivate" + +char ClangRemoveFirstPrivate::ID = 0; + +INITIALIZE_PASS_IN_GROUP_BEGIN(ClangRemoveFirstPrivate, "remove-firstprivate", + "Does something important", false, false, + TransformationQueryManager::getPassRegistry()) +INITIALIZE_PASS_DEPENDENCY(TransformationEnginePass) +INITIALIZE_PASS_DEPENDENCY(ClangGlobalInfoPass) +INITIALIZE_PASS_IN_GROUP_END(ClangRemoveFirstPrivate, "remove-firstprivate", + "Does something important", false, false, + TransformationQueryManager::getPassRegistry()) + + + +void ClangRemoveFirstPrivate::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + AU.setPreservesAll(); +} + +FunctionPass *llvm::createClangRemoveFirstPrivate() { + return new ClangRemoveFirstPrivate(); +} From bfd9a01576fee1d83791a6b7b7217ae7697fa274 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Wed, 20 Oct 2021 17:41:42 +0000 Subject: [PATCH 02/23] try to make a new pass: edit passes.h --- include/tsar/Transform/Clang/Passes.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/tsar/Transform/Clang/Passes.h b/include/tsar/Transform/Clang/Passes.h index dcb9dc5f..d2659622 100644 --- a/include/tsar/Transform/Clang/Passes.h +++ b/include/tsar/Transform/Clang/Passes.h @@ -57,6 +57,13 @@ llvm::ModulePass * createClangRenameLocalPass(); /// Initializes a pass to perform source-level object renaming. void initializeClangRenameLocalPassPass(PassRegistry &Registry); +/// Creates a pass to perform remove-firstprivate. +FunctionPass * createClangRemoveFirstPrivate(); + +/// Initializes a pass to perform remove-firstprivate. +void initializeClangRemoveFirstPrivatePass(PassRegistry &Registry); + + /// Creates a pass to perform elimination of dead declarations. FunctionPass * createClangDeadDeclsElimination(); From 1d9d69d7121e16190609f1aa09d8aff3ab3e8401 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Fri, 29 Oct 2021 13:28:22 +0000 Subject: [PATCH 03/23] add pragma 'removefirstprivate' --- include/tsar/Support/Directives.td | 3 +++ include/tsar/Transform/Clang/Passes.h | 2 +- include/tsar/Transform/Clang/RemoveFirstPrivate.h | 8 ++++---- lib/Transform/Clang/Passes.cpp | 1 + lib/Transform/Clang/RemoveFirstPrivate.cpp | 6 +++++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/tsar/Support/Directives.td b/include/tsar/Support/Directives.td index f0e2024e..441bec81 100644 --- a/include/tsar/Support/Directives.td +++ b/include/tsar/Support/Directives.td @@ -158,6 +158,9 @@ def AssertNoMacro : Clause<"nomacro", Assert>; def RegionName : Clause<"name", Region, [LParen, PPIdentifier, ZeroOrMore<[Comma, PPIdentifier]>, RParen]>; +def RemoveFirstPrivate : Clause<"removefirstprivate", Transform, + [LParen, Identifier, Comma, OneOf<[Identifier, NumericConstant]>, RParen, ZeroOrMore<[Comma, LParen, Identifier, Comma, OneOf<[Identifier, NumericConstant]>, RParen]>]>; + def ReplaceMetadata : Clause<"replace", Metadata, [LParen, Identifier, LParen, diff --git a/include/tsar/Transform/Clang/Passes.h b/include/tsar/Transform/Clang/Passes.h index d2659622..46ae90b7 100644 --- a/include/tsar/Transform/Clang/Passes.h +++ b/include/tsar/Transform/Clang/Passes.h @@ -58,7 +58,7 @@ llvm::ModulePass * createClangRenameLocalPass(); void initializeClangRenameLocalPassPass(PassRegistry &Registry); /// Creates a pass to perform remove-firstprivate. -FunctionPass * createClangRemoveFirstPrivate(); +ModulePass * createClangRemoveFirstPrivate(); /// Initializes a pass to perform remove-firstprivate. void initializeClangRemoveFirstPrivatePass(PassRegistry &Registry); diff --git a/include/tsar/Transform/Clang/RemoveFirstPrivate.h b/include/tsar/Transform/Clang/RemoveFirstPrivate.h index 93bc4080..652d71f9 100644 --- a/include/tsar/Transform/Clang/RemoveFirstPrivate.h +++ b/include/tsar/Transform/Clang/RemoveFirstPrivate.h @@ -31,16 +31,16 @@ namespace llvm { -class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { +class ClangRemoveFirstPrivate : public ModulePass, private bcl::Uncopyable { public: static char ID; - ClangRemoveFirstPrivate() : FunctionPass(ID) { + ClangRemoveFirstPrivate() : ModulePass(ID) { initializeClangRemoveFirstPrivatePass(*PassRegistry::getPassRegistry()); } - bool runOnFunction(Function &F) override; + bool runOnModule(Module &F) override; void getAnalysisUsage(AnalysisUsage &AU) const override; }; } -#endif//TSAR_CLANG_RFP_H +#endif//TSAR_CLANG_RFP_H \ No newline at end of file diff --git a/lib/Transform/Clang/Passes.cpp b/lib/Transform/Clang/Passes.cpp index 1414a706..21040b65 100644 --- a/lib/Transform/Clang/Passes.cpp +++ b/lib/Transform/Clang/Passes.cpp @@ -39,4 +39,5 @@ void llvm::initializeClangTransform(PassRegistry &Registry) { initializeDVMHDataTransferIPOPassPass(Registry); initializeClangLoopInterchangePass(Registry); initializeClangLoopReversePass(Registry); + initializeClangRemoveFirstPrivatePass(Registry); } diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 958829a6..473316e8 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -66,6 +66,10 @@ void ClangRemoveFirstPrivate::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } -FunctionPass *llvm::createClangRemoveFirstPrivate() { +bool ClangRemoveFirstPrivate::runOnModule(Module &M) { + return false; +} + +ModulePass *llvm::createClangRemoveFirstPrivate() { return new ClangRemoveFirstPrivate(); } From 1a632510ce75faa9adce0693d174820ccfa0d431 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Thu, 11 Nov 2021 20:25:24 +0000 Subject: [PATCH 04/23] remove-firstprivate pass --- include/tsar/Support/Directives.td | 2 +- include/tsar/Transform/Clang/Passes.h | 4 +- .../tsar/Transform/Clang/RemoveFirstPrivate.h | 6 +- lib/Transform/Clang/RemoveFirstPrivate.cpp | 180 +++++++++++++++++- 4 files changed, 176 insertions(+), 16 deletions(-) diff --git a/include/tsar/Support/Directives.td b/include/tsar/Support/Directives.td index 441bec81..a68bb115 100644 --- a/include/tsar/Support/Directives.td +++ b/include/tsar/Support/Directives.td @@ -159,7 +159,7 @@ def RegionName : Clause<"name", Region, [LParen, PPIdentifier, ZeroOrMore<[Comma, PPIdentifier]>, RParen]>; def RemoveFirstPrivate : Clause<"removefirstprivate", Transform, - [LParen, Identifier, Comma, OneOf<[Identifier, NumericConstant]>, RParen, ZeroOrMore<[Comma, LParen, Identifier, Comma, OneOf<[Identifier, NumericConstant]>, RParen]>]>; + [LParen, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[Comma, Identifier, Equal, OneOf<[Identifier, NumericConstant]>]>, RParen]>; def ReplaceMetadata : Clause<"replace", Metadata, [LParen, diff --git a/include/tsar/Transform/Clang/Passes.h b/include/tsar/Transform/Clang/Passes.h index 46ae90b7..92e8df35 100644 --- a/include/tsar/Transform/Clang/Passes.h +++ b/include/tsar/Transform/Clang/Passes.h @@ -58,7 +58,7 @@ llvm::ModulePass * createClangRenameLocalPass(); void initializeClangRenameLocalPassPass(PassRegistry &Registry); /// Creates a pass to perform remove-firstprivate. -ModulePass * createClangRemoveFirstPrivate(); +FunctionPass * createClangRemoveFirstPrivate(); /// Initializes a pass to perform remove-firstprivate. void initializeClangRemoveFirstPrivatePass(PassRegistry &Registry); @@ -122,4 +122,4 @@ void initializeClangLoopReversePass(PassRegistry &Registry); /// Create a pass to reverse loop. ModulePass *createClangLoopReverse(); } -#endif//TSAR_CLANG_TRANSFORM_PASSES_H +#endif//TSAR_CLANG_TRANSFORM_PASSES_H \ No newline at end of file diff --git a/include/tsar/Transform/Clang/RemoveFirstPrivate.h b/include/tsar/Transform/Clang/RemoveFirstPrivate.h index 652d71f9..043bb741 100644 --- a/include/tsar/Transform/Clang/RemoveFirstPrivate.h +++ b/include/tsar/Transform/Clang/RemoveFirstPrivate.h @@ -31,15 +31,15 @@ namespace llvm { -class ClangRemoveFirstPrivate : public ModulePass, private bcl::Uncopyable { +class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { public: static char ID; - ClangRemoveFirstPrivate() : ModulePass(ID) { + ClangRemoveFirstPrivate() : FunctionPass(ID) { initializeClangRemoveFirstPrivatePass(*PassRegistry::getPassRegistry()); } - bool runOnModule(Module &F) override; + bool runOnFunction(Function &F) override; void getAnalysisUsage(AnalysisUsage &AU) const override; }; } diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 473316e8..22a77a2f 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -1,4 +1,4 @@ -//=== RemoveFirstPrivate.cpp - (Clang) --*- C++ -*===// +//=== DeadDeclsElimination.cpp - Dead Decls Elimination (Clang) --*- C++ -*===// // // Traits Static Analyzer (SAPFOR) // @@ -18,7 +18,7 @@ // //===----------------------------------------------------------------------===// // -// +// This file implements a pass to initialize firstprivate variables. // //===----------------------------------------------------------------------===// @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -39,26 +40,189 @@ #include #include #include +#include using namespace clang; using namespace llvm; using namespace tsar; #undef DEBUG_TYPE -#define DEBUG_TYPE "remove-firstprivate" +#define DEBUG_TYPE "clang-rfp" char ClangRemoveFirstPrivate::ID = 0; INITIALIZE_PASS_IN_GROUP_BEGIN(ClangRemoveFirstPrivate, "remove-firstprivate", - "Does something important", false, false, + "Initialize variables in for", false, false, TransformationQueryManager::getPassRegistry()) INITIALIZE_PASS_DEPENDENCY(TransformationEnginePass) INITIALIZE_PASS_DEPENDENCY(ClangGlobalInfoPass) INITIALIZE_PASS_IN_GROUP_END(ClangRemoveFirstPrivate, "remove-firstprivate", - "Does something important", false, false, + "Initialize variables in for", false, false, TransformationQueryManager::getPassRegistry()) +namespace { + +class DeclVisitor : public RecursiveASTVisitor { + struct DeclarationInfo { + DeclarationInfo(Stmt *S) : Scope(S) {} + + Stmt *Scope; + SmallVector DeadAccesses; + }; +public: + explicit DeclVisitor(TransformationContext &TfmCtx, const ASTImportInfo &ImportInfo, + ClangGlobalInfoPass::RawInfo &RawInfo) : + mTfmCtx(&TfmCtx), mImportInfo(ImportInfo), + mRawInfo(&RawInfo), mRewriter(TfmCtx.getRewriter()), + mContext(TfmCtx.getContext()), mSrcMgr(mRewriter.getSourceMgr()), + mLangOpts(mRewriter.getLangOpts()) {} + + bool TraverseStmt(Stmt *S) { + if (!S) + return true; + + bool ast = false; + Pragma P(*S); + + if (findClause(P, ClauseId::RemoveFirstPrivate, mClauses)) { + + auto locationForInits = S -> getEndLoc(); + + isInPragma = true; + ast = RecursiveASTVisitor::TraverseStmt(S); + isInPragma = false; + + + std::string txtStr; + std::vector inits; + while (starts.size()) { + SourceRange toInsert(starts.top(), ends.top()); + CharSourceRange txtToInsert(toInsert, true); + starts.pop(); + ends.pop(); + + txtStr = mRewriter.getRewrittenText(txtToInsert); + txtStr += ";\n"; + inits.push_back(txtStr); + } + + llvm::SmallVector ToRemove; + auto IsPossible = pragmaRangeToRemove(P, mClauses, mSrcMgr, mLangOpts, + mImportInfo, ToRemove); + if (!IsPossible.first) + if (IsPossible.second & PragmaFlags::IsInMacro) + toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(), + tsar::diag::warn_remove_directive_in_macro); + else if (IsPossible.second & PragmaFlags::IsInHeader) + toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(), + tsar::diag::warn_remove_directive_in_include); + else + toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(), + tsar::diag::warn_remove_directive); + Rewriter::RewriteOptions RemoveEmptyLine; + /// TODO (kaniandr@gmail.com): it seems that RemoveLineIfEmpty is + /// set to true then removing (in RewriterBuffer) works incorrect. + RemoveEmptyLine.RemoveLineIfEmpty = false; + for (auto SR : ToRemove) + mRewriter.RemoveText(SR, RemoveEmptyLine); // delete each range + + for (std::vector::iterator it = inits.begin(); it != inits.end(); ++it) { + mRewriter.InsertTextAfterToken(locationForInits, *it); + } + return ast; + } + return RecursiveASTVisitor::TraverseStmt(S); + } + + bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { + NamedDecl *named = nullptr; + if (isInPragma) { + + if (waitingForVar) { + starts.push(Ex -> getLocation()); + } else { + ends.push(Ex -> getLocation()); + } + waitingForVar = !waitingForVar; + } + return RecursiveASTVisitor::TraverseDeclRefExpr(Ex); + } +#ifdef LLVM_DEBUG +// debug info +#endif + +private: + /// Return current scope. + Stmt *getScope() { + for (auto I = mScopes.rbegin(), EI = mScopes.rend(); I != EI; ++I) + if (isa(*I) || isa(*I)) + return *I; + return nullptr; + } + + /// Return true if there is a side effect inside a specified statement. + const Stmt * findSideEffect(const Stmt &S) { + if (!isa(S) && + !(isa(S) && cast(S).isAssignmentOp()) && + !(isa(S) && + cast(S).isIncrementDecrementOp())) { + for (auto Child : make_range(S.child_begin(), S.child_end())) + if (Child) + if (auto SideEffect = findSideEffect(*Child)) + return SideEffect; + return nullptr; + } + return &S; + } + + bool isInPragma = false; + bool waitingForVar = true; + std::map mDeadDecls; + std::vector mScopes; + // clang::Rewriter *mRewriter; + DenseSet mMultipleDecls; + DenseMap mTypeDecls; + DeclRefExpr *mSimpleAssignLHS = nullptr; + + TransformationContext *mTfmCtx; + const ASTImportInfo &mImportInfo; + ClangGlobalInfoPass::RawInfo *mRawInfo; + Rewriter &mRewriter; + ASTContext &mContext; + SourceManager &mSrcMgr; + const LangOptions &mLangOpts; + SmallVector mClauses; + + std::stack starts; + std::stack ends; + +}; +} + +bool ClangRemoveFirstPrivate::runOnFunction(Function &F) { + auto *M = F.getParent(); + auto &TfmInfo = getAnalysis(); + auto *TfmCtx{TfmInfo ? TfmInfo->getContext(*M) : nullptr}; + if (!TfmCtx || !TfmCtx->hasInstance()) { + M->getContext().emitError("can not transform sources" + ": transformation context is not available"); + return false; + } + auto FuncDecl = TfmCtx->getDeclForMangledName(F.getName()); + if (!FuncDecl) + return false; + + ASTImportInfo ImportStub; + const auto *ImportInfo = &ImportStub; + if (auto *ImportPass = getAnalysisIfAvailable()) + ImportInfo = &ImportPass->getImportInfo(); + auto &GIP = getAnalysis(); + + DeclVisitor Visitor(*TfmCtx, *ImportInfo, GIP.getRawInfo()); + Visitor.TraverseDecl(FuncDecl); + return false; +} void ClangRemoveFirstPrivate::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -66,10 +230,6 @@ void ClangRemoveFirstPrivate::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } -bool ClangRemoveFirstPrivate::runOnModule(Module &M) { - return false; -} - -ModulePass *llvm::createClangRemoveFirstPrivate() { +FunctionPass *llvm::createClangRemoveFirstPrivate() { return new ClangRemoveFirstPrivate(); } From 6e9f702df58875c240f5e12ab90d58f94e150491 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Thu, 11 Nov 2021 20:53:51 +0000 Subject: [PATCH 05/23] remove unused code --- lib/Transform/Clang/RemoveFirstPrivate.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 22a77a2f..e7a964e5 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -161,21 +161,6 @@ class DeclVisitor : public RecursiveASTVisitor { return nullptr; } - /// Return true if there is a side effect inside a specified statement. - const Stmt * findSideEffect(const Stmt &S) { - if (!isa(S) && - !(isa(S) && cast(S).isAssignmentOp()) && - !(isa(S) && - cast(S).isIncrementDecrementOp())) { - for (auto Child : make_range(S.child_begin(), S.child_end())) - if (Child) - if (auto SideEffect = findSideEffect(*Child)) - return SideEffect; - return nullptr; - } - return &S; - } - bool isInPragma = false; bool waitingForVar = true; std::map mDeadDecls; From 945641d7b285db6997f26418fba6fda490c265a2 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Thu, 25 Nov 2021 17:32:55 +0000 Subject: [PATCH 06/23] add array initialization --- include/tsar/Support/Directives.td | 2 +- lib/Transform/Clang/RemoveFirstPrivate.cpp | 110 ++++++++++++++++----- 2 files changed, 88 insertions(+), 24 deletions(-) diff --git a/include/tsar/Support/Directives.td b/include/tsar/Support/Directives.td index a68bb115..50db34d3 100644 --- a/include/tsar/Support/Directives.td +++ b/include/tsar/Support/Directives.td @@ -159,7 +159,7 @@ def RegionName : Clause<"name", Region, [LParen, PPIdentifier, ZeroOrMore<[Comma, PPIdentifier]>, RParen]>; def RemoveFirstPrivate : Clause<"removefirstprivate", Transform, - [LParen, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[Comma, Identifier, Equal, OneOf<[Identifier, NumericConstant]>]>, RParen]>; + [LParen, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[NumericConstant]>, ZeroOrMore<[Comma, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[NumericConstant]>]>, RParen]>; def ReplaceMetadata : Clause<"replace", Metadata, [LParen, diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index e7a964e5..688c30da 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -1,4 +1,4 @@ -//=== DeadDeclsElimination.cpp - Dead Decls Elimination (Clang) --*- C++ -*===// +//=== RemoveFirstPrivate.cpp - RFP (Clang) --*- C++ -*===// // // Traits Static Analyzer (SAPFOR) // @@ -60,14 +60,43 @@ INITIALIZE_PASS_IN_GROUP_END(ClangRemoveFirstPrivate, "remove-firstprivate", "Initialize variables in for", false, false, TransformationQueryManager::getPassRegistry()) + +bool isNameOfArray(std::string type) { + if (type.find('[') != std::string::npos || type.find('*') != std::string::npos) { + return true; + } + return false; +} + +void replaceSqrBrWithAsterisk(std::string &str) { + size_t openingSqrBracket = str.find("["); + size_t closingSqrBracket = str.find("]"); + str.erase(openingSqrBracket, closingSqrBracket - openingSqrBracket + 1); + str += "*"; +} + +struct vars { // contains information about variables in + std::string var1Type; // removefirstprivate clause + std::string var2Type; + std::string var1Name; + std::string var2Name; + std::string count = ""; +}; + namespace { class DeclVisitor : public RecursiveASTVisitor { + + std::string getStrByLoc(SourceLocation begin, SourceLocation end) { + SourceRange SR(begin, end); + CharSourceRange CSR(SR, true); + return mRewriter.getRewrittenText(CSR); + } + struct DeclarationInfo { DeclarationInfo(Stmt *S) : Scope(S) {} Stmt *Scope; - SmallVector DeadAccesses; }; public: explicit DeclVisitor(TransformationContext &TfmCtx, const ASTImportInfo &ImportInfo, @@ -92,18 +121,37 @@ class DeclVisitor : public RecursiveASTVisitor { ast = RecursiveASTVisitor::TraverseStmt(S); isInPragma = false; - - std::string txtStr; + std::string txtStr, beforeFor, forBody, type1, type2; std::vector inits; - while (starts.size()) { - SourceRange toInsert(starts.top(), ends.top()); - CharSourceRange txtToInsert(toInsert, true); - starts.pop(); - ends.pop(); - - txtStr = mRewriter.getRewrittenText(txtToInsert); - txtStr += ";\n"; + while (varStack.size()) { + if (isNameOfArray(varStack.top().var1Type)) { + if (varStack.top().count.empty()) { + varStack.pop(); + continue; // count is mandatory for arrays, skip initialization if no count found + } + type1 = varStack.top().var1Type; + type2 = varStack.top().var2Type; + if (type1.find('[') != std::string::npos) { + replaceSqrBrWithAsterisk(type1); + } + if (type2.find('[') != std::string::npos) { + replaceSqrBrWithAsterisk(type2); + } + if (isNameOfArray(varStack.top().var2Type)) { // arr1 = arr2 + beforeFor = type1 + "var1Ptr" + " = " + varStack.top().var1Name + ";\n" + + type2 + "var2Ptr" + " = " + varStack.top().var2Name + ";\n"; + forBody = "var1Ptr[i] = var2Ptr[i];\n"; + } else { // arr1 = val + beforeFor = type1 + "var1Ptr" + " = " + varStack.top().var1Name + ";\n"; + forBody = "var1Ptr[i] = " + varStack.top().var2Name + ";\n"; + } + txtStr = beforeFor; + txtStr += "for (int i = 0; i < " + varStack.top().count + "; i++) {\n" + forBody + "\n}\n"; + } else { // Initialize non-array variable + txtStr = varStack.top().var1Name + " = " + varStack.top().var2Name + ";\n"; + } inits.push_back(txtStr); + varStack.pop(); } llvm::SmallVector ToRemove; @@ -135,19 +183,41 @@ class DeclVisitor : public RecursiveASTVisitor { } bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { - NamedDecl *named = nullptr; if (isInPragma) { - + std::string varName = getStrByLoc(Ex -> getBeginLoc(), Ex -> getEndLoc()); if (waitingForVar) { - starts.push(Ex -> getLocation()); + ValueDecl *vd = Ex -> getDecl(); + QualType qt = vd -> getType(); + std::string typeStr = qt.getCanonicalType().getAsString(); + + vars tmp; + tmp.var1Type = typeStr; + tmp.var1Name = varName; + varStack.push(tmp); + } else { - ends.push(Ex -> getLocation()); + + ValueDecl *vd = Ex -> getDecl(); + QualType qt = vd -> getType(); + std::string typeStr = qt.getCanonicalType().getAsString(); + varStack.top().var2Type = typeStr; + varStack.top().var2Name = varName; + } waitingForVar = !waitingForVar; } return RecursiveASTVisitor::TraverseDeclRefExpr(Ex); } + bool TraverseIntegerLiteral(IntegerLiteral *IL) { + if (isInPragma && waitingForVar) { + if (varStack.size()) { + varStack.top().count = getStrByLoc(IL -> getBeginLoc(), IL -> getEndLoc()); + } + } + return RecursiveASTVisitor::TraverseIntegerLiteral(IL); + } + #ifdef LLVM_DEBUG // debug info #endif @@ -163,12 +233,7 @@ class DeclVisitor : public RecursiveASTVisitor { bool isInPragma = false; bool waitingForVar = true; - std::map mDeadDecls; std::vector mScopes; - // clang::Rewriter *mRewriter; - DenseSet mMultipleDecls; - DenseMap mTypeDecls; - DeclRefExpr *mSimpleAssignLHS = nullptr; TransformationContext *mTfmCtx; const ASTImportInfo &mImportInfo; @@ -179,8 +244,7 @@ class DeclVisitor : public RecursiveASTVisitor { const LangOptions &mLangOpts; SmallVector mClauses; - std::stack starts; - std::stack ends; + std::stack varStack; }; } From 34fb122cffa472fc7019cf6e9ae0abafdedd4ae8 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Fri, 3 Dec 2021 07:43:02 +0000 Subject: [PATCH 07/23] improvements --- .../tsar/Transform/Clang/RemoveFirstPrivate.h | 46 --------- lib/Transform/Clang/RemoveFirstPrivate.cpp | 96 +++++++++++-------- 2 files changed, 57 insertions(+), 85 deletions(-) delete mode 100644 include/tsar/Transform/Clang/RemoveFirstPrivate.h diff --git a/include/tsar/Transform/Clang/RemoveFirstPrivate.h b/include/tsar/Transform/Clang/RemoveFirstPrivate.h deleted file mode 100644 index 043bb741..00000000 --- a/include/tsar/Transform/Clang/RemoveFirstPrivate.h +++ /dev/null @@ -1,46 +0,0 @@ -//=== RemoveFirstPrivate.h - (Clang) ----*- C++ -*===// -// -// Traits Static Analyzer (SAPFOR) -// -// Copyright 2018 DVM System Group -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//===---------------------------------------------------------------------===// -// -// TO DO: ADD INFO -// -//===---------------------------------------------------------------------===// - -#ifndef TSAR_CLANG_RFP_H -#define TSAR_CLANG_RFP_H - -#include "tsar/Transform/Clang/Passes.h" -#include -#include - -namespace llvm { - -class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { -public: - static char ID; - - ClangRemoveFirstPrivate() : FunctionPass(ID) { - initializeClangRemoveFirstPrivatePass(*PassRegistry::getPassRegistry()); - } - - bool runOnFunction(Function &F) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; -}; -} -#endif//TSAR_CLANG_RFP_H \ No newline at end of file diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 688c30da..569181a6 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -22,7 +22,6 @@ // //===----------------------------------------------------------------------===// -#include "tsar/Transform/Clang/RemoveFirstPrivate.h" #include "tsar/Analysis/Clang/GlobalInfoExtractor.h" #include "tsar/Analysis/Clang/NoMacroAssert.h" #include "tsar/Core/Query.h" @@ -31,15 +30,17 @@ #include #include #include +#include "tsar/Analysis/Memory/Utils.h" +#include "tsar/Support/MetadataUtils.h" #include -#include -#include #include #include #include #include #include -#include +#include "tsar/Transform/Clang/Passes.h" +#include +#include #include using namespace clang; @@ -49,32 +50,34 @@ using namespace tsar; #undef DEBUG_TYPE #define DEBUG_TYPE "clang-rfp" -char ClangRemoveFirstPrivate::ID = 0; - -INITIALIZE_PASS_IN_GROUP_BEGIN(ClangRemoveFirstPrivate, "remove-firstprivate", - "Initialize variables in for", false, false, - TransformationQueryManager::getPassRegistry()) -INITIALIZE_PASS_DEPENDENCY(TransformationEnginePass) -INITIALIZE_PASS_DEPENDENCY(ClangGlobalInfoPass) -INITIALIZE_PASS_IN_GROUP_END(ClangRemoveFirstPrivate, "remove-firstprivate", - "Initialize variables in for", false, false, - TransformationQueryManager::getPassRegistry()) - - -bool isNameOfArray(std::string type) { +static bool isNameOfArray(std::string type) { if (type.find('[') != std::string::npos || type.find('*') != std::string::npos) { return true; } return false; } -void replaceSqrBrWithAsterisk(std::string &str) { +static void replaceSqrBrWithAsterisk(std::string &str) { size_t openingSqrBracket = str.find("["); size_t closingSqrBracket = str.find("]"); str.erase(openingSqrBracket, closingSqrBracket - openingSqrBracket + 1); str += "*"; } +namespace { + +class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { +public: + static char ID; + + ClangRemoveFirstPrivate() : FunctionPass(ID) { + initializeClangRemoveFirstPrivatePass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + struct vars { // contains information about variables in std::string var1Type; // removefirstprivate clause std::string var2Type; @@ -82,17 +85,23 @@ struct vars { // contains information about variables in std::string var2Name; std::string count = ""; }; +} + +char ClangRemoveFirstPrivate::ID = 0; + +INITIALIZE_PASS_IN_GROUP_BEGIN(ClangRemoveFirstPrivate, "remove-firstprivate", + "Initialize variables in for", false, false, + TransformationQueryManager::getPassRegistry()) +INITIALIZE_PASS_DEPENDENCY(TransformationEnginePass) +INITIALIZE_PASS_DEPENDENCY(ClangGlobalInfoPass) +INITIALIZE_PASS_IN_GROUP_END(ClangRemoveFirstPrivate, "remove-firstprivate", + "Initialize variables in for", false, false, + TransformationQueryManager::getPassRegistry()) namespace { class DeclVisitor : public RecursiveASTVisitor { - std::string getStrByLoc(SourceLocation begin, SourceLocation end) { - SourceRange SR(begin, end); - CharSourceRange CSR(SR, true); - return mRewriter.getRewrittenText(CSR); - } - struct DeclarationInfo { DeclarationInfo(Stmt *S) : Scope(S) {} @@ -129,8 +138,6 @@ class DeclVisitor : public RecursiveASTVisitor { varStack.pop(); continue; // count is mandatory for arrays, skip initialization if no count found } - type1 = varStack.top().var1Type; - type2 = varStack.top().var2Type; if (type1.find('[') != std::string::npos) { replaceSqrBrWithAsterisk(type1); } @@ -138,15 +145,11 @@ class DeclVisitor : public RecursiveASTVisitor { replaceSqrBrWithAsterisk(type2); } if (isNameOfArray(varStack.top().var2Type)) { // arr1 = arr2 - beforeFor = type1 + "var1Ptr" + " = " + varStack.top().var1Name + ";\n" + - type2 + "var2Ptr" + " = " + varStack.top().var2Name + ";\n"; - forBody = "var1Ptr[i] = var2Ptr[i];\n"; + forBody = varStack.top().var1Name + "[i] = " + varStack.top().var2Name + "[i];\n"; } else { // arr1 = val - beforeFor = type1 + "var1Ptr" + " = " + varStack.top().var1Name + ";\n"; - forBody = "var1Ptr[i] = " + varStack.top().var2Name + ";\n"; + forBody = varStack.top().var1Name + "[i] = " + varStack.top().var2Name + ";\n"; } - txtStr = beforeFor; - txtStr += "for (int i = 0; i < " + varStack.top().count + "; i++) {\n" + forBody + "\n}\n"; + txtStr = "for (int i = 0; i < " + varStack.top().count + "; i++) {\n" + forBody + "\n}\n"; } else { // Initialize non-array variable txtStr = varStack.top().var1Name + " = " + varStack.top().var2Name + ";\n"; } @@ -183,8 +186,11 @@ class DeclVisitor : public RecursiveASTVisitor { } bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { + std::string varName; if (isInPragma) { - std::string varName = getStrByLoc(Ex -> getBeginLoc(), Ex -> getEndLoc()); + if (auto *Var{dyn_cast(Ex->getDecl())}) { + varName = Var -> getName(); + } if (waitingForVar) { ValueDecl *vd = Ex -> getDecl(); QualType qt = vd -> getType(); @@ -212,7 +218,7 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseIntegerLiteral(IntegerLiteral *IL) { if (isInPragma && waitingForVar) { if (varStack.size()) { - varStack.top().count = getStrByLoc(IL -> getBeginLoc(), IL -> getEndLoc()); + varStack.top().count = std::to_string(IL -> getValue().getLimitedValue()); } } return RecursiveASTVisitor::TraverseIntegerLiteral(IL); @@ -251,13 +257,25 @@ class DeclVisitor : public RecursiveASTVisitor { bool ClangRemoveFirstPrivate::runOnFunction(Function &F) { auto *M = F.getParent(); - auto &TfmInfo = getAnalysis(); - auto *TfmCtx{TfmInfo ? TfmInfo->getContext(*M) : nullptr}; + + auto *DISub{findMetadata(&F)}; + if (!DISub) + return false; + auto *CU{DISub->getUnit()}; + if (isC(CU->getSourceLanguage()) && isCXX(CU->getSourceLanguage())) + return false; + auto &TfmInfo{getAnalysis()}; + auto *TfmCtx{TfmInfo ? dyn_cast_or_null( + TfmInfo->getContext(*CU)) + : nullptr}; if (!TfmCtx || !TfmCtx->hasInstance()) { - M->getContext().emitError("can not transform sources" - ": transformation context is not available"); + F.getContext().emitError( + "cannot transform sources" + ": transformation context is not available for the '" + + F.getName() + "' function"); return false; } + auto FuncDecl = TfmCtx->getDeclForMangledName(F.getName()); if (!FuncDecl) return false; From 338cdb3fcd9067d59d277ce6a932b766df61c9c4 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Thu, 9 Dec 2021 17:04:38 +0000 Subject: [PATCH 08/23] multidimensional array initialization and improvements --- lib/Transform/Clang/RemoveFirstPrivate.cpp | 121 ++++++++++++++------- 1 file changed, 81 insertions(+), 40 deletions(-) diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 569181a6..8e630daf 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -50,18 +50,20 @@ using namespace tsar; #undef DEBUG_TYPE #define DEBUG_TYPE "clang-rfp" -static bool isNameOfArray(std::string type) { - if (type.find('[') != std::string::npos || type.find('*') != std::string::npos) { - return true; +static int getDimensionsNum(QualType qt) { + int res = 0; + if (qt -> isPointerType()) { // todo: multidimensional dynamyc-sized arrays + return 1; + } + while(1) { + if (qt -> isArrayType()) { + auto at = qt->getAsArrayTypeUnsafe(); + qt = at -> getElementType(); + res++; + } else { + return res; + } } - return false; -} - -static void replaceSqrBrWithAsterisk(std::string &str) { - size_t openingSqrBracket = str.find("["); - size_t closingSqrBracket = str.find("]"); - str.erase(openingSqrBracket, closingSqrBracket - openingSqrBracket + 1); - str += "*"; } namespace { @@ -78,12 +80,13 @@ class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { void getAnalysisUsage(AnalysisUsage &AU) const override; }; -struct vars { // contains information about variables in - std::string var1Type; // removefirstprivate clause - std::string var2Type; - std::string var1Name; - std::string var2Name; +struct vars { // contains information about variables in + bool rvalIsArray = false; // removefirstprivate clause + std::string lvalName; + std::string rvalName; std::string count = ""; + int dimensionsNum; + std::vector dimensions; }; } @@ -130,28 +133,43 @@ class DeclVisitor : public RecursiveASTVisitor { ast = RecursiveASTVisitor::TraverseStmt(S); isInPragma = false; - std::string txtStr, beforeFor, forBody, type1, type2; + std::string txtStr, beforeFor, forBody, lval, rval, indeces; std::vector inits; while (varStack.size()) { - if (isNameOfArray(varStack.top().var1Type)) { + for (std::vector::iterator it = varStack.top().dimensions.begin(); + it != varStack.top().dimensions.end(); + it ++) { + } + if (varStack.top().dimensionsNum) { // lvalue is array if (varStack.top().count.empty()) { varStack.pop(); continue; // count is mandatory for arrays, skip initialization if no count found } - if (type1.find('[') != std::string::npos) { - replaceSqrBrWithAsterisk(type1); + forBody = std::string(); + indeces = std::string(); + lval = varStack.top().lvalName; + rval = varStack.top().rvalName; + txtStr = std::string(); + for (std::vector::iterator it = varStack.top().dimensions.begin(); + it != varStack.top().dimensions.end(); + it ++) { + int intCounter = it - varStack.top().dimensions.begin(); + std::string strCounter = "i" + std::to_string(intCounter); + indeces += "[" + strCounter + "]"; + txtStr += "for (int " + strCounter + "; " + strCounter + " < " + + std::to_string(*it) + "; " + strCounter + "++) {\n"; } - if (type2.find('[') != std::string::npos) { - replaceSqrBrWithAsterisk(type2); + if (varStack.top().rvalIsArray) { + rval += indeces; } - if (isNameOfArray(varStack.top().var2Type)) { // arr1 = arr2 - forBody = varStack.top().var1Name + "[i] = " + varStack.top().var2Name + "[i];\n"; - } else { // arr1 = val - forBody = varStack.top().var1Name + "[i] = " + varStack.top().var2Name + ";\n"; + lval += indeces; + forBody = lval + " = " + rval + ";\n"; + txtStr += forBody; + for (int i = 0; i < varStack.top().dimensionsNum; i++) { + txtStr += "}\n"; } - txtStr = "for (int i = 0; i < " + varStack.top().count + "; i++) {\n" + forBody + "\n}\n"; } else { // Initialize non-array variable - txtStr = varStack.top().var1Name + " = " + varStack.top().var2Name + ";\n"; + txtStr = varStack.top().lvalName + " = " + varStack.top().rvalName + ";\n"; } inits.push_back(txtStr); varStack.pop(); @@ -188,26 +206,34 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { std::string varName; if (isInPragma) { + if (waitingForDimensions && curDimensionNum == varStack.top().dimensionsNum) { + waitingForDimensions = false; + curDimensionNum = 0; + + } if (auto *Var{dyn_cast(Ex->getDecl())}) { varName = Var -> getName(); } - if (waitingForVar) { + if (waitingForVar) { // get lvalue ValueDecl *vd = Ex -> getDecl(); QualType qt = vd -> getType(); std::string typeStr = qt.getCanonicalType().getAsString(); - vars tmp; - tmp.var1Type = typeStr; - tmp.var1Name = varName; - varStack.push(tmp); - - } else { + tmp.lvalName = varName; + tmp.dimensionsNum = getDimensionsNum(qt); + varStack.push(tmp); + } else { // get rvalue ValueDecl *vd = Ex -> getDecl(); QualType qt = vd -> getType(); + if (qt -> isArrayType() || qt -> isPointerType()) { + varStack.top().rvalIsArray = true; + } std::string typeStr = qt.getCanonicalType().getAsString(); - varStack.top().var2Type = typeStr; - varStack.top().var2Name = varName; + varStack.top().rvalName = varName; + if (varStack.top().dimensionsNum > 0) { + waitingForDimensions = true; + } } waitingForVar = !waitingForVar; @@ -216,9 +242,21 @@ class DeclVisitor : public RecursiveASTVisitor { } bool TraverseIntegerLiteral(IntegerLiteral *IL) { - if (isInPragma && waitingForVar) { - if (varStack.size()) { - varStack.top().count = std::to_string(IL -> getValue().getLimitedValue()); + + if (isInPragma) { + int val = IL -> getValue().getLimitedValue(); + if (waitingForDimensions) { + if (varStack.size()) { + varStack.top().dimensions.push_back(val); + curDimensionNum++; + varStack.top().count = std::to_string(val); + } + } else if (!waitingForVar) { // get rvalue + varStack.top().rvalName = std::to_string(val); + waitingForVar = !waitingForVar; + if (varStack.top().dimensionsNum > 0) { + waitingForDimensions = true; + } } } return RecursiveASTVisitor::TraverseIntegerLiteral(IL); @@ -239,6 +277,9 @@ class DeclVisitor : public RecursiveASTVisitor { bool isInPragma = false; bool waitingForVar = true; + bool waitingForDimensions = false; + int curDimensionNum = 0; + std::vector mScopes; TransformationContext *mTfmCtx; From c50822debcf45ae69f24d690996bc7bf3753c3cb Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Fri, 17 Dec 2021 11:33:31 +0000 Subject: [PATCH 09/23] add auto size determination for arrays --- lib/Transform/Clang/RemoveFirstPrivate.cpp | 31 +++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 8e630daf..e5ef7e13 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -42,6 +42,7 @@ #include #include #include +#include using namespace clang; using namespace llvm; @@ -50,7 +51,7 @@ using namespace tsar; #undef DEBUG_TYPE #define DEBUG_TYPE "clang-rfp" -static int getDimensionsNum(QualType qt) { +static int getDimensionsNum(QualType qt, std::vector& default_dimensions) { int res = 0; if (qt -> isPointerType()) { // todo: multidimensional dynamyc-sized arrays return 1; @@ -58,6 +59,10 @@ static int getDimensionsNum(QualType qt) { while(1) { if (qt -> isArrayType()) { auto at = qt->getAsArrayTypeUnsafe(); + if (auto t = dyn_cast_or_null(at)) { // get size + uint64_t dim = t -> getSize().getLimitedValue(); + default_dimensions.push_back(dim); + } qt = at -> getElementType(); res++; } else { @@ -84,9 +89,9 @@ struct vars { // contains information about variables in bool rvalIsArray = false; // removefirstprivate clause std::string lvalName; std::string rvalName; - std::string count = ""; int dimensionsNum; std::vector dimensions; + std::vector default_dimensions; }; } @@ -136,14 +141,14 @@ class DeclVisitor : public RecursiveASTVisitor { std::string txtStr, beforeFor, forBody, lval, rval, indeces; std::vector inits; while (varStack.size()) { - for (std::vector::iterator it = varStack.top().dimensions.begin(); - it != varStack.top().dimensions.end(); - it ++) { - } if (varStack.top().dimensionsNum) { // lvalue is array - if (varStack.top().count.empty()) { - varStack.pop(); - continue; // count is mandatory for arrays, skip initialization if no count found + if (varStack.top().dimensions.size() < varStack.top().dimensionsNum) { + if (varStack.top().default_dimensions.size() == varStack.top().dimensionsNum) { + varStack.top().dimensions = varStack.top().default_dimensions; + } else { + varStack.pop(); + continue; // dimensions ar mandatory for arrays, skip + } // initialization if no dimensions found } forBody = std::string(); indeces = std::string(); @@ -209,7 +214,6 @@ class DeclVisitor : public RecursiveASTVisitor { if (waitingForDimensions && curDimensionNum == varStack.top().dimensionsNum) { waitingForDimensions = false; curDimensionNum = 0; - } if (auto *Var{dyn_cast(Ex->getDecl())}) { varName = Var -> getName(); @@ -221,8 +225,8 @@ class DeclVisitor : public RecursiveASTVisitor { vars tmp; tmp.lvalName = varName; - tmp.dimensionsNum = getDimensionsNum(qt); varStack.push(tmp); + varStack.top().dimensionsNum = getDimensionsNum(qt, varStack.top().default_dimensions); } else { // get rvalue ValueDecl *vd = Ex -> getDecl(); QualType qt = vd -> getType(); @@ -244,12 +248,15 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseIntegerLiteral(IntegerLiteral *IL) { if (isInPragma) { + if (waitingForDimensions && curDimensionNum == varStack.top().dimensionsNum) { + waitingForDimensions = false; + curDimensionNum = 0; + } int val = IL -> getValue().getLimitedValue(); if (waitingForDimensions) { if (varStack.size()) { varStack.top().dimensions.push_back(val); curDimensionNum++; - varStack.top().count = std::to_string(val); } } else if (!waitingForVar) { // get rvalue varStack.top().rvalName = std::to_string(val); From 7386e89f9dd1f51eb923b85bdd5c20eee819cb66 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Wed, 22 Dec 2021 08:19:09 +0000 Subject: [PATCH 10/23] add pointers initialization --- lib/Transform/Clang/RemoveFirstPrivate.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index e5ef7e13..65dccf52 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -42,7 +42,6 @@ #include #include #include -#include using namespace clang; using namespace llvm; @@ -53,20 +52,23 @@ using namespace tsar; static int getDimensionsNum(QualType qt, std::vector& default_dimensions) { int res = 0; - if (qt -> isPointerType()) { // todo: multidimensional dynamyc-sized arrays - return 1; - } + bool sizeIsKnown = true; while(1) { if (qt -> isArrayType()) { auto at = qt->getAsArrayTypeUnsafe(); - if (auto t = dyn_cast_or_null(at)) { // get size - uint64_t dim = t -> getSize().getLimitedValue(); - default_dimensions.push_back(dim); + auto t = dyn_cast_or_null(at); + if (sizeIsKnown && t) { // get size + uint64_t dim = t -> getSize().getLimitedValue(); + default_dimensions.push_back(dim); } qt = at -> getElementType(); res++; + } else if (qt -> isPointerType()) { + sizeIsKnown = false; + qt = qt -> getPointeeType(); + res++; } else { - return res; + return res; } } } From 522e71cb8b1539b5e974ebe9eb8474df00fa6943 Mon Sep 17 00:00:00 2001 From: NikitaGorbov Date: Thu, 23 Dec 2021 12:14:56 +0000 Subject: [PATCH 11/23] removefirstprivate: wrong counter initialization fix --- lib/Transform/Clang/RemoveFirstPrivate.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 65dccf52..90a9dfd6 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -55,7 +55,7 @@ static int getDimensionsNum(QualType qt, std::vector& default_dimensions) { bool sizeIsKnown = true; while(1) { if (qt -> isArrayType()) { - auto at = qt->getAsArrayTypeUnsafe(); + auto at = qt -> getAsArrayTypeUnsafe(); auto t = dyn_cast_or_null(at); if (sizeIsKnown && t) { // get size uint64_t dim = t -> getSize().getLimitedValue(); @@ -133,9 +133,7 @@ class DeclVisitor : public RecursiveASTVisitor { Pragma P(*S); if (findClause(P, ClauseId::RemoveFirstPrivate, mClauses)) { - auto locationForInits = S -> getEndLoc(); - isInPragma = true; ast = RecursiveASTVisitor::TraverseStmt(S); isInPragma = false; @@ -163,7 +161,7 @@ class DeclVisitor : public RecursiveASTVisitor { int intCounter = it - varStack.top().dimensions.begin(); std::string strCounter = "i" + std::to_string(intCounter); indeces += "[" + strCounter + "]"; - txtStr += "for (int " + strCounter + "; " + strCounter + " < " + + txtStr += "for (int " + strCounter + " = 0; " + strCounter + " < " + std::to_string(*it) + "; " + strCounter + "++) {\n"; } if (varStack.top().rvalIsArray) { @@ -223,7 +221,6 @@ class DeclVisitor : public RecursiveASTVisitor { if (waitingForVar) { // get lvalue ValueDecl *vd = Ex -> getDecl(); QualType qt = vd -> getType(); - std::string typeStr = qt.getCanonicalType().getAsString(); vars tmp; tmp.lvalName = varName; @@ -235,7 +232,6 @@ class DeclVisitor : public RecursiveASTVisitor { if (qt -> isArrayType() || qt -> isPointerType()) { varStack.top().rvalIsArray = true; } - std::string typeStr = qt.getCanonicalType().getAsString(); varStack.top().rvalName = varName; if (varStack.top().dimensionsNum > 0) { waitingForDimensions = true; From 1114bfe3faaabcca1131adc53567602afa84f18a Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Thu, 24 Feb 2022 17:19:13 +0300 Subject: [PATCH 12/23] fix incorrect dimension determination in some cases --- lib/Transform/Clang/RemoveFirstPrivate.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/RemoveFirstPrivate.cpp index 90a9dfd6..6533496c 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/RemoveFirstPrivate.cpp @@ -226,6 +226,7 @@ class DeclVisitor : public RecursiveASTVisitor { tmp.lvalName = varName; varStack.push(tmp); varStack.top().dimensionsNum = getDimensionsNum(qt, varStack.top().default_dimensions); + waitingForDimensions = false; } else { // get rvalue ValueDecl *vd = Ex -> getDecl(); QualType qt = vd -> getType(); From 1c44b9f034eb3d42c3c6f760f672daad0229e7a1 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Wed, 16 Mar 2022 09:29:31 +0000 Subject: [PATCH 13/23] Rename pass, change pass syntax, add some improvements --- include/tsar/Support/Directives.td | 4 +- include/tsar/Transform/Clang/Passes.h | 8 +-- lib/Transform/Clang/CMakeLists.txt | 2 +- ...{RemoveFirstPrivate.cpp => Initialize.cpp} | 59 ++++++++----------- lib/Transform/Clang/Passes.cpp | 2 +- 5 files changed, 32 insertions(+), 43 deletions(-) rename lib/Transform/Clang/{RemoveFirstPrivate.cpp => Initialize.cpp} (87%) diff --git a/include/tsar/Support/Directives.td b/include/tsar/Support/Directives.td index 50db34d3..9bea84c2 100644 --- a/include/tsar/Support/Directives.td +++ b/include/tsar/Support/Directives.td @@ -158,8 +158,8 @@ def AssertNoMacro : Clause<"nomacro", Assert>; def RegionName : Clause<"name", Region, [LParen, PPIdentifier, ZeroOrMore<[Comma, PPIdentifier]>, RParen]>; -def RemoveFirstPrivate : Clause<"removefirstprivate", Transform, - [LParen, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[NumericConstant]>, ZeroOrMore<[Comma, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[NumericConstant]>]>, RParen]>; +def Initialize : Clause<"initialize", Transform, + [LParen, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[LSquare, NumericConstant, RSquare]>, ZeroOrMore<[Comma, Identifier, Equal, OneOf<[Identifier, NumericConstant]>, ZeroOrMore<[LSquare, NumericConstant, RSquare]>]>, RParen]>; def ReplaceMetadata : Clause<"replace", Metadata, [LParen, diff --git a/include/tsar/Transform/Clang/Passes.h b/include/tsar/Transform/Clang/Passes.h index 92e8df35..90aee46b 100644 --- a/include/tsar/Transform/Clang/Passes.h +++ b/include/tsar/Transform/Clang/Passes.h @@ -57,11 +57,11 @@ llvm::ModulePass * createClangRenameLocalPass(); /// Initializes a pass to perform source-level object renaming. void initializeClangRenameLocalPassPass(PassRegistry &Registry); -/// Creates a pass to perform remove-firstprivate. -FunctionPass * createClangRemoveFirstPrivate(); +/// Creates a pass to perform initialization. +FunctionPass * createClangInitialize(); -/// Initializes a pass to perform remove-firstprivate. -void initializeClangRemoveFirstPrivatePass(PassRegistry &Registry); +/// Initializes a pass to perform initialization. +void initializeClangInitializePass(PassRegistry &Registry); /// Creates a pass to perform elimination of dead declarations. diff --git a/lib/Transform/Clang/CMakeLists.txt b/lib/Transform/Clang/CMakeLists.txt index c73b6dc2..dedea7b8 100644 --- a/lib/Transform/Clang/CMakeLists.txt +++ b/lib/Transform/Clang/CMakeLists.txt @@ -2,7 +2,7 @@ set(TRANSFORM_SOURCES Passes.cpp ExprPropagation.cpp Inline.cpp RenameLocal.cpp DeadDeclsElimination.cpp Format.cpp OpenMPAutoPar.cpp DVMHWriter.cpp SharedMemoryAutoPar.cpp DVMHDirecitves.cpp DVMHSMAutoPar.cpp DVMHDataTransferIPO.cpp StructureReplacement.cpp LoopInterchange.cpp - LoopReversal.cpp RemoveFirstPrivate.cpp) + LoopReversal.cpp Initialize.cpp) if(MSVC_IDE) file(GLOB_RECURSE TRANSFORM_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/lib/Transform/Clang/RemoveFirstPrivate.cpp b/lib/Transform/Clang/Initialize.cpp similarity index 87% rename from lib/Transform/Clang/RemoveFirstPrivate.cpp rename to lib/Transform/Clang/Initialize.cpp index 6533496c..2d607e98 100644 --- a/lib/Transform/Clang/RemoveFirstPrivate.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -1,8 +1,8 @@ -//=== RemoveFirstPrivate.cpp - RFP (Clang) --*- C++ -*===// +//=== Initialize.cpp (Clang) --*- C++ -*===// // // Traits Static Analyzer (SAPFOR) // -// Copyright 2018 DVM System Group +// Copyright 2022 DVM System Group // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements a pass to initialize firstprivate variables. +// This file implements a pass to initialize arrays and variables. // //===----------------------------------------------------------------------===// @@ -75,12 +75,12 @@ static int getDimensionsNum(QualType qt, std::vector& default_dimensions) { namespace { -class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { +class ClangInitialize : public FunctionPass, private bcl::Uncopyable { public: static char ID; - ClangRemoveFirstPrivate() : FunctionPass(ID) { - initializeClangRemoveFirstPrivatePass(*PassRegistry::getPassRegistry()); + ClangInitialize() : FunctionPass(ID) { + initializeClangInitializePass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override; @@ -88,7 +88,7 @@ class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable { }; struct vars { // contains information about variables in - bool rvalIsArray = false; // removefirstprivate clause + bool rvalIsArray = false; // initialize clause std::string lvalName; std::string rvalName; int dimensionsNum; @@ -97,14 +97,14 @@ struct vars { // contains information about variables in }; } -char ClangRemoveFirstPrivate::ID = 0; +char ClangInitialize::ID = 0; -INITIALIZE_PASS_IN_GROUP_BEGIN(ClangRemoveFirstPrivate, "remove-firstprivate", +INITIALIZE_PASS_IN_GROUP_BEGIN(ClangInitialize, "initialize", "Initialize variables in for", false, false, TransformationQueryManager::getPassRegistry()) INITIALIZE_PASS_DEPENDENCY(TransformationEnginePass) INITIALIZE_PASS_DEPENDENCY(ClangGlobalInfoPass) -INITIALIZE_PASS_IN_GROUP_END(ClangRemoveFirstPrivate, "remove-firstprivate", +INITIALIZE_PASS_IN_GROUP_END(ClangInitialize, "initialize", "Initialize variables in for", false, false, TransformationQueryManager::getPassRegistry()) @@ -118,12 +118,11 @@ class DeclVisitor : public RecursiveASTVisitor { Stmt *Scope; }; public: - explicit DeclVisitor(TransformationContext &TfmCtx, const ASTImportInfo &ImportInfo, - ClangGlobalInfoPass::RawInfo &RawInfo) : - mTfmCtx(&TfmCtx), mImportInfo(ImportInfo), - mRawInfo(&RawInfo), mRewriter(TfmCtx.getRewriter()), - mContext(TfmCtx.getContext()), mSrcMgr(mRewriter.getSourceMgr()), - mLangOpts(mRewriter.getLangOpts()) {} + explicit DeclVisitor(ClangTransformationContext &TfmCtx, + const ASTImportInfo &ImportInfo) + : mTfmCtx(&TfmCtx), mImportInfo(ImportInfo), + mRewriter(TfmCtx.getRewriter()), mContext(TfmCtx.getContext()), + mSrcMgr(mRewriter.getSourceMgr()), mLangOpts(mRewriter.getLangOpts()) {} bool TraverseStmt(Stmt *S) { if (!S) @@ -132,7 +131,7 @@ class DeclVisitor : public RecursiveASTVisitor { bool ast = false; Pragma P(*S); - if (findClause(P, ClauseId::RemoveFirstPrivate, mClauses)) { + if (findClause(P, ClauseId::Initialize, mClauses)) { auto locationForInits = S -> getEndLoc(); isInPragma = true; ast = RecursiveASTVisitor::TraverseStmt(S); @@ -268,10 +267,6 @@ class DeclVisitor : public RecursiveASTVisitor { return RecursiveASTVisitor::TraverseIntegerLiteral(IL); } -#ifdef LLVM_DEBUG -// debug info -#endif - private: /// Return current scope. Stmt *getScope() { @@ -285,26 +280,20 @@ class DeclVisitor : public RecursiveASTVisitor { bool waitingForVar = true; bool waitingForDimensions = false; int curDimensionNum = 0; - std::vector mScopes; - - TransformationContext *mTfmCtx; + ClangTransformationContext *mTfmCtx; const ASTImportInfo &mImportInfo; - ClangGlobalInfoPass::RawInfo *mRawInfo; Rewriter &mRewriter; ASTContext &mContext; SourceManager &mSrcMgr; const LangOptions &mLangOpts; SmallVector mClauses; - std::stack varStack; - }; } -bool ClangRemoveFirstPrivate::runOnFunction(Function &F) { +bool ClangInitialize::runOnFunction(Function &F) { auto *M = F.getParent(); - auto *DISub{findMetadata(&F)}; if (!DISub) return false; @@ -322,28 +311,28 @@ bool ClangRemoveFirstPrivate::runOnFunction(Function &F) { F.getName() + "' function"); return false; } - auto FuncDecl = TfmCtx->getDeclForMangledName(F.getName()); if (!FuncDecl) return false; - ASTImportInfo ImportStub; const auto *ImportInfo = &ImportStub; if (auto *ImportPass = getAnalysisIfAvailable()) ImportInfo = &ImportPass->getImportInfo(); auto &GIP = getAnalysis(); + auto *GI{GIP.getGlobalInfo(TfmCtx)}; + assert(GI && "Global declaration must be collected!"); + DeclVisitor Visitor(*TfmCtx, *ImportInfo); - DeclVisitor Visitor(*TfmCtx, *ImportInfo, GIP.getRawInfo()); Visitor.TraverseDecl(FuncDecl); return false; } -void ClangRemoveFirstPrivate::getAnalysisUsage(AnalysisUsage &AU) const { +void ClangInitialize::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); AU.setPreservesAll(); } -FunctionPass *llvm::createClangRemoveFirstPrivate() { - return new ClangRemoveFirstPrivate(); +FunctionPass *llvm::createClangInitialize() { + return new ClangInitialize(); } diff --git a/lib/Transform/Clang/Passes.cpp b/lib/Transform/Clang/Passes.cpp index 21040b65..38ab858c 100644 --- a/lib/Transform/Clang/Passes.cpp +++ b/lib/Transform/Clang/Passes.cpp @@ -39,5 +39,5 @@ void llvm::initializeClangTransform(PassRegistry &Registry) { initializeDVMHDataTransferIPOPassPass(Registry); initializeClangLoopInterchangePass(Registry); initializeClangLoopReversePass(Registry); - initializeClangRemoveFirstPrivatePass(Registry); + initializeClangInitializePass(Registry); } From 906f162ea754500b16a435175bc79f223af83733 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Wed, 16 Mar 2022 09:30:48 +0000 Subject: [PATCH 14/23] better formating --- lib/Transform/Clang/Initialize.cpp | 118 +++++++++++++++-------------- 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index 2d607e98..e79de584 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -24,23 +24,23 @@ #include "tsar/Analysis/Clang/GlobalInfoExtractor.h" #include "tsar/Analysis/Clang/NoMacroAssert.h" +#include "tsar/Analysis/Memory/Utils.h" #include "tsar/Core/Query.h" #include "tsar/Frontend/Clang/TransformationContext.h" #include "tsar/Support/Clang/Diagnostic.h" +#include "tsar/Support/MetadataUtils.h" +#include "tsar/Transform/Clang/Passes.h" +#include #include #include #include -#include "tsar/Analysis/Memory/Utils.h" -#include "tsar/Support/MetadataUtils.h" #include #include #include #include +#include #include #include -#include "tsar/Transform/Clang/Passes.h" -#include -#include #include using namespace clang; @@ -50,25 +50,25 @@ using namespace tsar; #undef DEBUG_TYPE #define DEBUG_TYPE "clang-rfp" -static int getDimensionsNum(QualType qt, std::vector& default_dimensions) { +static int getDimensionsNum(QualType qt, std::vector &default_dimensions) { int res = 0; bool sizeIsKnown = true; - while(1) { - if (qt -> isArrayType()) { - auto at = qt -> getAsArrayTypeUnsafe(); - auto t = dyn_cast_or_null(at); + while (1) { + if (qt->isArrayType()) { + auto at = qt->getAsArrayTypeUnsafe(); + auto t = dyn_cast_or_null(at); if (sizeIsKnown && t) { // get size - uint64_t dim = t -> getSize().getLimitedValue(); + uint64_t dim = t->getSize().getLimitedValue(); default_dimensions.push_back(dim); } - qt = at -> getElementType(); + qt = at->getElementType(); + res++; + } else if (qt->isPointerType()) { + sizeIsKnown = false; + qt = qt->getPointeeType(); res++; - } else if (qt -> isPointerType()) { - sizeIsKnown = false; - qt = qt -> getPointeeType(); - res++; } else { - return res; + return res; } } } @@ -87,26 +87,26 @@ class ClangInitialize : public FunctionPass, private bcl::Uncopyable { void getAnalysisUsage(AnalysisUsage &AU) const override; }; -struct vars { // contains information about variables in - bool rvalIsArray = false; // initialize clause +struct vars { // contains information about variables in + bool rvalIsArray = false; // initialize clause std::string lvalName; std::string rvalName; int dimensionsNum; std::vector dimensions; std::vector default_dimensions; }; -} +} // namespace char ClangInitialize::ID = 0; INITIALIZE_PASS_IN_GROUP_BEGIN(ClangInitialize, "initialize", - "Initialize variables in for", false, false, - TransformationQueryManager::getPassRegistry()) + "Initialize variables in for", false, false, + TransformationQueryManager::getPassRegistry()) INITIALIZE_PASS_DEPENDENCY(TransformationEnginePass) INITIALIZE_PASS_DEPENDENCY(ClangGlobalInfoPass) INITIALIZE_PASS_IN_GROUP_END(ClangInitialize, "initialize", - "Initialize variables in for", false, false, - TransformationQueryManager::getPassRegistry()) + "Initialize variables in for", false, false, + TransformationQueryManager::getPassRegistry()) namespace { @@ -117,6 +117,7 @@ class DeclVisitor : public RecursiveASTVisitor { Stmt *Scope; }; + public: explicit DeclVisitor(ClangTransformationContext &TfmCtx, const ASTImportInfo &ImportInfo) @@ -132,7 +133,7 @@ class DeclVisitor : public RecursiveASTVisitor { Pragma P(*S); if (findClause(P, ClauseId::Initialize, mClauses)) { - auto locationForInits = S -> getEndLoc(); + auto locationForInits = S->getEndLoc(); isInPragma = true; ast = RecursiveASTVisitor::TraverseStmt(S); isInPragma = false; @@ -140,23 +141,24 @@ class DeclVisitor : public RecursiveASTVisitor { std::string txtStr, beforeFor, forBody, lval, rval, indeces; std::vector inits; while (varStack.size()) { - if (varStack.top().dimensionsNum) { // lvalue is array + if (varStack.top().dimensionsNum) { // lvalue is array if (varStack.top().dimensions.size() < varStack.top().dimensionsNum) { - if (varStack.top().default_dimensions.size() == varStack.top().dimensionsNum) { + if (varStack.top().default_dimensions.size() == + varStack.top().dimensionsNum) { varStack.top().dimensions = varStack.top().default_dimensions; } else { varStack.pop(); - continue; // dimensions ar mandatory for arrays, skip - } // initialization if no dimensions found + continue; // dimensions ar mandatory for arrays, skip + } // initialization if no dimensions found } forBody = std::string(); indeces = std::string(); lval = varStack.top().lvalName; rval = varStack.top().rvalName; txtStr = std::string(); - for (std::vector::iterator it = varStack.top().dimensions.begin(); - it != varStack.top().dimensions.end(); - it ++) { + for (std::vector::iterator it = + varStack.top().dimensions.begin(); + it != varStack.top().dimensions.end(); it++) { int intCounter = it - varStack.top().dimensions.begin(); std::string strCounter = "i" + std::to_string(intCounter); indeces += "[" + strCounter + "]"; @@ -172,8 +174,9 @@ class DeclVisitor : public RecursiveASTVisitor { for (int i = 0; i < varStack.top().dimensionsNum; i++) { txtStr += "}\n"; } - } else { // Initialize non-array variable - txtStr = varStack.top().lvalName + " = " + varStack.top().rvalName + ";\n"; + } else { // Initialize non-array variable + txtStr = + varStack.top().lvalName + " = " + varStack.top().rvalName + ";\n"; } inits.push_back(txtStr); varStack.pop(); @@ -185,13 +188,13 @@ class DeclVisitor : public RecursiveASTVisitor { if (!IsPossible.first) if (IsPossible.second & PragmaFlags::IsInMacro) toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(), - tsar::diag::warn_remove_directive_in_macro); + tsar::diag::warn_remove_directive_in_macro); else if (IsPossible.second & PragmaFlags::IsInHeader) toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(), - tsar::diag::warn_remove_directive_in_include); + tsar::diag::warn_remove_directive_in_include); else toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(), - tsar::diag::warn_remove_directive); + tsar::diag::warn_remove_directive); Rewriter::RewriteOptions RemoveEmptyLine; /// TODO (kaniandr@gmail.com): it seems that RemoveLineIfEmpty is /// set to true then removing (in RewriterBuffer) works incorrect. @@ -199,7 +202,8 @@ class DeclVisitor : public RecursiveASTVisitor { for (auto SR : ToRemove) mRewriter.RemoveText(SR, RemoveEmptyLine); // delete each range - for (std::vector::iterator it = inits.begin(); it != inits.end(); ++it) { + for (std::vector::iterator it = inits.begin(); + it != inits.end(); ++it) { mRewriter.InsertTextAfterToken(locationForInits, *it); } return ast; @@ -210,33 +214,34 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { std::string varName; if (isInPragma) { - if (waitingForDimensions && curDimensionNum == varStack.top().dimensionsNum) { + if (waitingForDimensions && + curDimensionNum == varStack.top().dimensionsNum) { waitingForDimensions = false; curDimensionNum = 0; } if (auto *Var{dyn_cast(Ex->getDecl())}) { - varName = Var -> getName(); + varName = Var->getName(); } - if (waitingForVar) { // get lvalue - ValueDecl *vd = Ex -> getDecl(); - QualType qt = vd -> getType(); + if (waitingForVar) { // get lvalue + ValueDecl *vd = Ex->getDecl(); + QualType qt = vd->getType(); vars tmp; tmp.lvalName = varName; varStack.push(tmp); - varStack.top().dimensionsNum = getDimensionsNum(qt, varStack.top().default_dimensions); + varStack.top().dimensionsNum = + getDimensionsNum(qt, varStack.top().default_dimensions); waitingForDimensions = false; - } else { // get rvalue - ValueDecl *vd = Ex -> getDecl(); - QualType qt = vd -> getType(); - if (qt -> isArrayType() || qt -> isPointerType()) { + } else { // get rvalue + ValueDecl *vd = Ex->getDecl(); + QualType qt = vd->getType(); + if (qt->isArrayType() || qt->isPointerType()) { varStack.top().rvalIsArray = true; } varStack.top().rvalName = varName; if (varStack.top().dimensionsNum > 0) { waitingForDimensions = true; } - } waitingForVar = !waitingForVar; } @@ -246,17 +251,18 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseIntegerLiteral(IntegerLiteral *IL) { if (isInPragma) { - if (waitingForDimensions && curDimensionNum == varStack.top().dimensionsNum) { + if (waitingForDimensions && + curDimensionNum == varStack.top().dimensionsNum) { waitingForDimensions = false; curDimensionNum = 0; } - int val = IL -> getValue().getLimitedValue(); + int val = IL->getValue().getLimitedValue(); if (waitingForDimensions) { if (varStack.size()) { varStack.top().dimensions.push_back(val); curDimensionNum++; } - } else if (!waitingForVar) { // get rvalue + } else if (!waitingForVar) { // get rvalue varStack.top().rvalName = std::to_string(val); waitingForVar = !waitingForVar; if (varStack.top().dimensionsNum > 0) { @@ -280,7 +286,7 @@ class DeclVisitor : public RecursiveASTVisitor { bool waitingForVar = true; bool waitingForDimensions = false; int curDimensionNum = 0; - std::vector mScopes; + std::vector mScopes; ClangTransformationContext *mTfmCtx; const ASTImportInfo &mImportInfo; Rewriter &mRewriter; @@ -290,7 +296,7 @@ class DeclVisitor : public RecursiveASTVisitor { SmallVector mClauses; std::stack varStack; }; -} +} // namespace bool ClangInitialize::runOnFunction(Function &F) { auto *M = F.getParent(); @@ -333,6 +339,4 @@ void ClangInitialize::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } -FunctionPass *llvm::createClangInitialize() { - return new ClangInitialize(); -} +FunctionPass *llvm::createClangInitialize() { return new ClangInitialize(); } From 5d8c0c4d870b5b41781a98f6cb1f290505ba60c5 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Fri, 18 Mar 2022 14:27:52 +0000 Subject: [PATCH 15/23] rename variables, change some var declarations --- lib/Transform/Clang/Initialize.cpp | 186 ++++++++++++++--------------- 1 file changed, 92 insertions(+), 94 deletions(-) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index e79de584..7ac8da6d 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -12,7 +12,7 @@ // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expRess or implied. // See the License for the specific language governing permissions and // limitations under the License. // @@ -48,27 +48,27 @@ using namespace llvm; using namespace tsar; #undef DEBUG_TYPE -#define DEBUG_TYPE "clang-rfp" +#define DEBUG_TYPE "clang-init" -static int getDimensionsNum(QualType qt, std::vector &default_dimensions) { - int res = 0; - bool sizeIsKnown = true; +static int getDimensionsNum(QualType QT, std::vector &DefaultDimensions) { + int Res = 0; + bool SizeIsKnown = true; while (1) { - if (qt->isArrayType()) { - auto at = qt->getAsArrayTypeUnsafe(); - auto t = dyn_cast_or_null(at); - if (sizeIsKnown && t) { // get size - uint64_t dim = t->getSize().getLimitedValue(); - default_dimensions.push_back(dim); + if (QT->isArrayType()) { + auto AT = QT->getAsArrayTypeUnsafe(); + auto T = dyn_cast_or_null(AT); + if (SizeIsKnown && T) { // get size + uint64_t Dim = T->getSize().getLimitedValue(); + DefaultDimensions.push_back(Dim); } - qt = at->getElementType(); - res++; - } else if (qt->isPointerType()) { - sizeIsKnown = false; - qt = qt->getPointeeType(); - res++; + QT = AT->getElementType(); + Res++; + } else if (QT->isPointerType()) { + SizeIsKnown = false; + QT = QT->getPointeeType(); + Res++; } else { - return res; + return Res; } } } @@ -87,13 +87,15 @@ class ClangInitialize : public FunctionPass, private bcl::Uncopyable { void getAnalysisUsage(AnalysisUsage &AU) const override; }; -struct vars { // contains information about variables in - bool rvalIsArray = false; // initialize clause - std::string lvalName; - std::string rvalName; - int dimensionsNum; - std::vector dimensions; - std::vector default_dimensions; +// contains information about variables in +// initialize clause +struct Vars { + bool RvalIsArray = false; + std::string LvalName; + std::string RvalName; + int DimensionsNum; + std::vector Dimensions; + std::vector DefaultDimensions; }; } // namespace @@ -134,52 +136,48 @@ class DeclVisitor : public RecursiveASTVisitor { if (findClause(P, ClauseId::Initialize, mClauses)) { auto locationForInits = S->getEndLoc(); - isInPragma = true; + mIsInPragma = true; ast = RecursiveASTVisitor::TraverseStmt(S); - isInPragma = false; - - std::string txtStr, beforeFor, forBody, lval, rval, indeces; + mIsInPragma = false; std::vector inits; - while (varStack.size()) { - if (varStack.top().dimensionsNum) { // lvalue is array - if (varStack.top().dimensions.size() < varStack.top().dimensionsNum) { - if (varStack.top().default_dimensions.size() == - varStack.top().dimensionsNum) { - varStack.top().dimensions = varStack.top().default_dimensions; + while (mVarStack.size()) { + std::string txtStr, beforeFor, forBody, lval, rval, indeces; + if (mVarStack.top().DimensionsNum) { // lvalue is array + if (mVarStack.top().Dimensions.size() < mVarStack.top().DimensionsNum) { + if (mVarStack.top().DefaultDimensions.size() == + mVarStack.top().DimensionsNum) { + mVarStack.top().Dimensions = mVarStack.top().DefaultDimensions; } else { - varStack.pop(); + mVarStack.pop(); continue; // dimensions ar mandatory for arrays, skip } // initialization if no dimensions found } - forBody = std::string(); - indeces = std::string(); - lval = varStack.top().lvalName; - rval = varStack.top().rvalName; - txtStr = std::string(); - for (std::vector::iterator it = - varStack.top().dimensions.begin(); - it != varStack.top().dimensions.end(); it++) { - int intCounter = it - varStack.top().dimensions.begin(); + lval = mVarStack.top().LvalName; + rval = mVarStack.top().RvalName; + for (auto it{mVarStack.top().Dimensions.begin()}, + EI{mVarStack.top().Dimensions.end()}; + it != EI; ++it) { + int intCounter = it - mVarStack.top().Dimensions.begin(); std::string strCounter = "i" + std::to_string(intCounter); indeces += "[" + strCounter + "]"; txtStr += "for (int " + strCounter + " = 0; " + strCounter + " < " + std::to_string(*it) + "; " + strCounter + "++) {\n"; } - if (varStack.top().rvalIsArray) { + if (mVarStack.top().RvalIsArray) { rval += indeces; } lval += indeces; forBody = lval + " = " + rval + ";\n"; txtStr += forBody; - for (int i = 0; i < varStack.top().dimensionsNum; i++) { + for (int i = 0; i < mVarStack.top().DimensionsNum; i++) { txtStr += "}\n"; } } else { // Initialize non-array variable txtStr = - varStack.top().lvalName + " = " + varStack.top().rvalName + ";\n"; + mVarStack.top().LvalName + " = " + mVarStack.top().RvalName + ";\n"; } inits.push_back(txtStr); - varStack.pop(); + mVarStack.pop(); } llvm::SmallVector ToRemove; @@ -212,61 +210,61 @@ class DeclVisitor : public RecursiveASTVisitor { } bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { - std::string varName; - if (isInPragma) { - if (waitingForDimensions && - curDimensionNum == varStack.top().dimensionsNum) { - waitingForDimensions = false; - curDimensionNum = 0; + std::string VarName; + if (mIsInPragma) { + if (mWaitingForDimensions && + mCurDimensionNum == mVarStack.top().DimensionsNum) { + mWaitingForDimensions = false; + mCurDimensionNum = 0; } if (auto *Var{dyn_cast(Ex->getDecl())}) { - varName = Var->getName(); + VarName = Var->getName(); } - if (waitingForVar) { // get lvalue - ValueDecl *vd = Ex->getDecl(); - QualType qt = vd->getType(); - vars tmp; - - tmp.lvalName = varName; - varStack.push(tmp); - varStack.top().dimensionsNum = - getDimensionsNum(qt, varStack.top().default_dimensions); - waitingForDimensions = false; + if (mWaitingForVar) { // get lvalue + ValueDecl *VD = Ex->getDecl(); + QualType QT = VD->getType(); + Vars Tmp; + + Tmp.LvalName = VarName; + mVarStack.push(Tmp); + mVarStack.top().DimensionsNum = + getDimensionsNum(QT, mVarStack.top().DefaultDimensions); + mWaitingForDimensions = false; } else { // get rvalue - ValueDecl *vd = Ex->getDecl(); - QualType qt = vd->getType(); - if (qt->isArrayType() || qt->isPointerType()) { - varStack.top().rvalIsArray = true; + ValueDecl *VD = Ex->getDecl(); + QualType QT = VD->getType(); + if (QT->isArrayType() || QT->isPointerType()) { + mVarStack.top().RvalIsArray = true; } - varStack.top().rvalName = varName; - if (varStack.top().dimensionsNum > 0) { - waitingForDimensions = true; + mVarStack.top().RvalName = VarName; + if (mVarStack.top().DimensionsNum > 0) { + mWaitingForDimensions = true; } } - waitingForVar = !waitingForVar; + mWaitingForVar = !mWaitingForVar; } return RecursiveASTVisitor::TraverseDeclRefExpr(Ex); } bool TraverseIntegerLiteral(IntegerLiteral *IL) { - if (isInPragma) { - if (waitingForDimensions && - curDimensionNum == varStack.top().dimensionsNum) { - waitingForDimensions = false; - curDimensionNum = 0; + if (mIsInPragma) { + if (mWaitingForDimensions && + mCurDimensionNum == mVarStack.top().DimensionsNum) { + mWaitingForDimensions = false; + mCurDimensionNum = 0; } - int val = IL->getValue().getLimitedValue(); - if (waitingForDimensions) { - if (varStack.size()) { - varStack.top().dimensions.push_back(val); - curDimensionNum++; + int Val = IL->getValue().getLimitedValue(); + if (mWaitingForDimensions) { + if (mVarStack.size()) { + mVarStack.top().Dimensions.push_back(Val); + mCurDimensionNum++; } - } else if (!waitingForVar) { // get rvalue - varStack.top().rvalName = std::to_string(val); - waitingForVar = !waitingForVar; - if (varStack.top().dimensionsNum > 0) { - waitingForDimensions = true; + } else if (!mWaitingForVar) { // get rvalue + mVarStack.top().RvalName = std::to_string(Val); + mWaitingForVar = !mWaitingForVar; + if (mVarStack.top().DimensionsNum > 0) { + mWaitingForDimensions = true; } } } @@ -282,10 +280,10 @@ class DeclVisitor : public RecursiveASTVisitor { return nullptr; } - bool isInPragma = false; - bool waitingForVar = true; - bool waitingForDimensions = false; - int curDimensionNum = 0; + bool mIsInPragma = false; + bool mWaitingForVar = true; + bool mWaitingForDimensions = false; + int mCurDimensionNum = 0; std::vector mScopes; ClangTransformationContext *mTfmCtx; const ASTImportInfo &mImportInfo; @@ -294,7 +292,7 @@ class DeclVisitor : public RecursiveASTVisitor { SourceManager &mSrcMgr; const LangOptions &mLangOpts; SmallVector mClauses; - std::stack varStack; + std::stack mVarStack; }; } // namespace From 05e69bf1bbc6ec3e06cb53889f3a7cce77df38e1 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Tue, 22 Mar 2022 15:17:56 +0000 Subject: [PATCH 16/23] remove some vars, change some types --- lib/Transform/Clang/Initialize.cpp | 63 +++++++++++++----------------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index 7ac8da6d..30ea1da1 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -130,18 +130,16 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseStmt(Stmt *S) { if (!S) return true; - - bool ast = false; Pragma P(*S); if (findClause(P, ClauseId::Initialize, mClauses)) { auto locationForInits = S->getEndLoc(); mIsInPragma = true; - ast = RecursiveASTVisitor::TraverseStmt(S); + bool Ast = RecursiveASTVisitor::TraverseStmt(S); mIsInPragma = false; - std::vector inits; + std::vector Inits; while (mVarStack.size()) { - std::string txtStr, beforeFor, forBody, lval, rval, indeces; + std::string TxtStr, BeforeFor, ForBody, Lval, Rval, Indeces; if (mVarStack.top().DimensionsNum) { // lvalue is array if (mVarStack.top().Dimensions.size() < mVarStack.top().DimensionsNum) { if (mVarStack.top().DefaultDimensions.size() == @@ -152,31 +150,30 @@ class DeclVisitor : public RecursiveASTVisitor { continue; // dimensions ar mandatory for arrays, skip } // initialization if no dimensions found } - lval = mVarStack.top().LvalName; - rval = mVarStack.top().RvalName; + Lval = mVarStack.top().LvalName; + Rval = mVarStack.top().RvalName; for (auto it{mVarStack.top().Dimensions.begin()}, EI{mVarStack.top().Dimensions.end()}; it != EI; ++it) { - int intCounter = it - mVarStack.top().Dimensions.begin(); - std::string strCounter = "i" + std::to_string(intCounter); - indeces += "[" + strCounter + "]"; - txtStr += "for (int " + strCounter + " = 0; " + strCounter + " < " + + int IntCounter = it - mVarStack.top().Dimensions.begin(); + std::string strCounter = "i" + std::to_string(IntCounter); + Indeces += "[" + strCounter + "]"; + TxtStr += "for (int " + strCounter + " = 0; " + strCounter + " < " + std::to_string(*it) + "; " + strCounter + "++) {\n"; } - if (mVarStack.top().RvalIsArray) { - rval += indeces; - } - lval += indeces; - forBody = lval + " = " + rval + ";\n"; - txtStr += forBody; + if (mVarStack.top().RvalIsArray) + Rval += Indeces; + Lval += Indeces; + ForBody = Lval + " = " + Rval + ";\n"; + TxtStr += ForBody; for (int i = 0; i < mVarStack.top().DimensionsNum; i++) { - txtStr += "}\n"; + TxtStr += "}\n"; } } else { // Initialize non-array variable - txtStr = + TxtStr = mVarStack.top().LvalName + " = " + mVarStack.top().RvalName + ";\n"; } - inits.push_back(txtStr); + Inits.push_back(TxtStr); mVarStack.pop(); } @@ -200,46 +197,43 @@ class DeclVisitor : public RecursiveASTVisitor { for (auto SR : ToRemove) mRewriter.RemoveText(SR, RemoveEmptyLine); // delete each range - for (std::vector::iterator it = inits.begin(); - it != inits.end(); ++it) { - mRewriter.InsertTextAfterToken(locationForInits, *it); + for (std::vector::iterator It = Inits.begin(); + It != Inits.end(); ++It) { + mRewriter.InsertTextAfterToken(locationForInits, *It); } - return ast; + return Ast; } return RecursiveASTVisitor::TraverseStmt(S); } bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { - std::string VarName; + llvm::StringRef VarName; if (mIsInPragma) { if (mWaitingForDimensions && mCurDimensionNum == mVarStack.top().DimensionsNum) { mWaitingForDimensions = false; mCurDimensionNum = 0; } - if (auto *Var{dyn_cast(Ex->getDecl())}) { + if (auto *Var{dyn_cast(Ex->getDecl())}) VarName = Var->getName(); - } if (mWaitingForVar) { // get lvalue ValueDecl *VD = Ex->getDecl(); QualType QT = VD->getType(); Vars Tmp; Tmp.LvalName = VarName; - mVarStack.push(Tmp); + mVarStack.push(std::move(Tmp)); mVarStack.top().DimensionsNum = getDimensionsNum(QT, mVarStack.top().DefaultDimensions); mWaitingForDimensions = false; } else { // get rvalue ValueDecl *VD = Ex->getDecl(); QualType QT = VD->getType(); - if (QT->isArrayType() || QT->isPointerType()) { + if (QT->isArrayType() || QT->isPointerType()) mVarStack.top().RvalIsArray = true; - } mVarStack.top().RvalName = VarName; - if (mVarStack.top().DimensionsNum > 0) { + if (mVarStack.top().DimensionsNum > 0) mWaitingForDimensions = true; - } } mWaitingForVar = !mWaitingForVar; } @@ -254,7 +248,7 @@ class DeclVisitor : public RecursiveASTVisitor { mWaitingForDimensions = false; mCurDimensionNum = 0; } - int Val = IL->getValue().getLimitedValue(); + auto Val = IL->getValue().getLimitedValue(); if (mWaitingForDimensions) { if (mVarStack.size()) { mVarStack.top().Dimensions.push_back(Val); @@ -263,9 +257,8 @@ class DeclVisitor : public RecursiveASTVisitor { } else if (!mWaitingForVar) { // get rvalue mVarStack.top().RvalName = std::to_string(Val); mWaitingForVar = !mWaitingForVar; - if (mVarStack.top().DimensionsNum > 0) { + if (mVarStack.top().DimensionsNum > 0) mWaitingForDimensions = true; - } } } return RecursiveASTVisitor::TraverseIntegerLiteral(IL); From 24b8cae3c7865b987457f7de5e6d2efcf1bf732d Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Fri, 25 Mar 2022 10:40:34 +0000 Subject: [PATCH 17/23] add checks and warnings --- include/tsar/Support/DiagnosticKinds.td | 4 ++ lib/Transform/Clang/Initialize.cpp | 85 +++++++++++++++---------- 2 files changed, 54 insertions(+), 35 deletions(-) diff --git a/include/tsar/Support/DiagnosticKinds.td b/include/tsar/Support/DiagnosticKinds.td index a6cda4cc..14b7f0fa 100644 --- a/include/tsar/Support/DiagnosticKinds.td +++ b/include/tsar/Support/DiagnosticKinds.td @@ -217,5 +217,9 @@ def warn_reverse_increment_complex: Warning<"complex increment expression preven def warn_reverse_condition_complex: Warning<"complex conditional expression prevents loop reversal">; def warn_reverse_initialization_complex: Warning<"complex initialization expression prevents loop reversal">; +def warn_unknown_dimensions : Warning<"Unknown array dimensions. Specify them manually">; +def warn_dimensions_do_not_match : Warning<"Array dimensions do not match">; +def warn_too_many_dimensions : Warning<"Too many dimensions given">; + // Fortran-specific diagnostics. def warn_fortran_no_execution_part: Warning<"unable to locate execution-part statmenets">; diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index 30ea1da1..72d33624 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -12,7 +12,7 @@ // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expRess or implied. +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // @@ -30,18 +30,6 @@ #include "tsar/Support/Clang/Diagnostic.h" #include "tsar/Support/MetadataUtils.h" #include "tsar/Transform/Clang/Passes.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include using namespace clang; using namespace llvm; @@ -50,7 +38,8 @@ using namespace tsar; #undef DEBUG_TYPE #define DEBUG_TYPE "clang-init" -static int getDimensionsNum(QualType QT, std::vector &DefaultDimensions) { +static int getDimensionsNum(QualType QT, std::vector &DefaultDimensions, + bool &ArrSizeIsKnown) { int Res = 0; bool SizeIsKnown = true; while (1) { @@ -68,6 +57,7 @@ static int getDimensionsNum(QualType QT, std::vector &DefaultDimensions) { QT = QT->getPointeeType(); Res++; } else { + ArrSizeIsKnown = SizeIsKnown; return Res; } } @@ -93,9 +83,13 @@ struct Vars { bool RvalIsArray = false; std::string LvalName; std::string RvalName; - int DimensionsNum; + bool RSizeIsKnown; + bool LSizeIsKnown; + int LDimensionsNum = 0; + int RDimensionsNum = 0; std::vector Dimensions; - std::vector DefaultDimensions; + std::vector LDefaultDimensions; + std::vector RDefaultDimensions; }; } // namespace @@ -139,14 +133,25 @@ class DeclVisitor : public RecursiveASTVisitor { mIsInPragma = false; std::vector Inits; while (mVarStack.size()) { + int LDimensionsNum = mVarStack.top().LDimensionsNum; + int RDimensionsNum = mVarStack.top().RDimensionsNum; std::string TxtStr, BeforeFor, ForBody, Lval, Rval, Indeces; - if (mVarStack.top().DimensionsNum) { // lvalue is array - if (mVarStack.top().Dimensions.size() < mVarStack.top().DimensionsNum) { - if (mVarStack.top().DefaultDimensions.size() == - mVarStack.top().DimensionsNum) { - mVarStack.top().Dimensions = mVarStack.top().DefaultDimensions; + if (mVarStack.top().LSizeIsKnown && LDimensionsNum < RDimensionsNum || + mVarStack.top().RSizeIsKnown && mVarStack.top().RvalIsArray && + RDimensionsNum < LDimensionsNum) { + mVarStack.pop(); + continue; + } + if (LDimensionsNum) { // lvalue is array + if (mVarStack.top().Dimensions.size() < LDimensionsNum) { + if ((mVarStack.top().LDefaultDimensions.size() == LDimensionsNum) && + (!RDimensionsNum || mVarStack.top().LDefaultDimensions == + mVarStack.top().RDefaultDimensions)) { + mVarStack.top().Dimensions = mVarStack.top().LDefaultDimensions; } else { mVarStack.pop(); + toDiag(mSrcMgr.getDiagnostics(), S->getBeginLoc(), + tsar::diag::warn_unknown_dimensions); continue; // dimensions ar mandatory for arrays, skip } // initialization if no dimensions found } @@ -166,12 +171,12 @@ class DeclVisitor : public RecursiveASTVisitor { Lval += Indeces; ForBody = Lval + " = " + Rval + ";\n"; TxtStr += ForBody; - for (int i = 0; i < mVarStack.top().DimensionsNum; i++) { + for (int i = 0; i < LDimensionsNum; i++) { TxtStr += "}\n"; } } else { // Initialize non-array variable - TxtStr = - mVarStack.top().LvalName + " = " + mVarStack.top().RvalName + ";\n"; + TxtStr = mVarStack.top().LvalName + " = " + mVarStack.top().RvalName + + ";\n"; } Inits.push_back(TxtStr); mVarStack.pop(); @@ -210,29 +215,30 @@ class DeclVisitor : public RecursiveASTVisitor { llvm::StringRef VarName; if (mIsInPragma) { if (mWaitingForDimensions && - mCurDimensionNum == mVarStack.top().DimensionsNum) { + mCurDimensionNum == mVarStack.top().LDimensionsNum) { mWaitingForDimensions = false; mCurDimensionNum = 0; } if (auto *Var{dyn_cast(Ex->getDecl())}) VarName = Var->getName(); + ValueDecl *VD = Ex->getDecl(); + QualType QT = VD->getType(); if (mWaitingForVar) { // get lvalue - ValueDecl *VD = Ex->getDecl(); - QualType QT = VD->getType(); Vars Tmp; - Tmp.LvalName = VarName; mVarStack.push(std::move(Tmp)); - mVarStack.top().DimensionsNum = - getDimensionsNum(QT, mVarStack.top().DefaultDimensions); + mVarStack.top().LDimensionsNum = + getDimensionsNum(QT, mVarStack.top().LDefaultDimensions, + mVarStack.top().LSizeIsKnown); mWaitingForDimensions = false; } else { // get rvalue - ValueDecl *VD = Ex->getDecl(); - QualType QT = VD->getType(); + mVarStack.top().RDimensionsNum = + getDimensionsNum(QT, mVarStack.top().RDefaultDimensions, + mVarStack.top().RSizeIsKnown); if (QT->isArrayType() || QT->isPointerType()) mVarStack.top().RvalIsArray = true; mVarStack.top().RvalName = VarName; - if (mVarStack.top().DimensionsNum > 0) + if (mVarStack.top().LDimensionsNum > 0) mWaitingForDimensions = true; } mWaitingForVar = !mWaitingForVar; @@ -243,8 +249,17 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseIntegerLiteral(IntegerLiteral *IL) { if (mIsInPragma) { + if ((mVarStack.top().LSizeIsKnown && + mVarStack.top().Dimensions.size() > + mVarStack.top().LDimensionsNum) || + (mVarStack.top().RSizeIsKnown && + mVarStack.top().Dimensions.size() > + mVarStack.top().LDimensionsNum)) { + toDiag(mSrcMgr.getDiagnostics(), IL->getBeginLoc(), + tsar::diag::warn_too_many_dimensions); + } if (mWaitingForDimensions && - mCurDimensionNum == mVarStack.top().DimensionsNum) { + mCurDimensionNum == mVarStack.top().LDimensionsNum) { mWaitingForDimensions = false; mCurDimensionNum = 0; } @@ -257,7 +272,7 @@ class DeclVisitor : public RecursiveASTVisitor { } else if (!mWaitingForVar) { // get rvalue mVarStack.top().RvalName = std::to_string(Val); mWaitingForVar = !mWaitingForVar; - if (mVarStack.top().DimensionsNum > 0) + if (mVarStack.top().LDimensionsNum > 0) mWaitingForDimensions = true; } } From 67e4ca4e0175dfbda6c0db9265c9c3a7c23565ac Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Thu, 31 Mar 2022 12:47:11 +0000 Subject: [PATCH 18/23] add error_not_var, fix wrong conditions for warning printing, change std::string to llvm::SmallString in some places --- include/tsar/Support/DiagnosticKinds.td | 1 + lib/Transform/Clang/Initialize.cpp | 37 +++++++++++++++---------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/tsar/Support/DiagnosticKinds.td b/include/tsar/Support/DiagnosticKinds.td index 14b7f0fa..8ae1242c 100644 --- a/include/tsar/Support/DiagnosticKinds.td +++ b/include/tsar/Support/DiagnosticKinds.td @@ -220,6 +220,7 @@ def warn_reverse_initialization_complex: Warning<"complex initialization express def warn_unknown_dimensions : Warning<"Unknown array dimensions. Specify them manually">; def warn_dimensions_do_not_match : Warning<"Array dimensions do not match">; def warn_too_many_dimensions : Warning<"Too many dimensions given">; +def error_not_var : Error<"Given DeclRefExpr is not a variable">; // Fortran-specific diagnostics. def warn_fortran_no_execution_part: Warning<"unable to locate execution-part statmenets">; diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index 72d33624..faa10f0d 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -81,8 +81,8 @@ class ClangInitialize : public FunctionPass, private bcl::Uncopyable { // initialize clause struct Vars { bool RvalIsArray = false; - std::string LvalName; - std::string RvalName; + llvm::SmallString<64> LvalName; + llvm::SmallString<64> RvalName; bool RSizeIsKnown; bool LSizeIsKnown; int LDimensionsNum = 0; @@ -135,11 +135,14 @@ class DeclVisitor : public RecursiveASTVisitor { while (mVarStack.size()) { int LDimensionsNum = mVarStack.top().LDimensionsNum; int RDimensionsNum = mVarStack.top().RDimensionsNum; - std::string TxtStr, BeforeFor, ForBody, Lval, Rval, Indeces; + llvm::SmallString<128> BeforeFor, ForBody, Lval, Rval, Indeces; + std::string TxtStr; if (mVarStack.top().LSizeIsKnown && LDimensionsNum < RDimensionsNum || mVarStack.top().RSizeIsKnown && mVarStack.top().RvalIsArray && RDimensionsNum < LDimensionsNum) { mVarStack.pop(); + toDiag(mSrcMgr.getDiagnostics(), S->getBeginLoc(), + tsar::diag::warn_dimensions_do_not_match); continue; } if (LDimensionsNum) { // lvalue is array @@ -157,11 +160,13 @@ class DeclVisitor : public RecursiveASTVisitor { } Lval = mVarStack.top().LvalName; Rval = mVarStack.top().RvalName; + TxtStr = ""; for (auto it{mVarStack.top().Dimensions.begin()}, EI{mVarStack.top().Dimensions.end()}; it != EI; ++it) { int IntCounter = it - mVarStack.top().Dimensions.begin(); std::string strCounter = "i" + std::to_string(IntCounter); + llvm::StringRef IndecesPart("[" + strCounter + "]"); Indeces += "[" + strCounter + "]"; TxtStr += "for (int " + strCounter + " = 0; " + strCounter + " < " + std::to_string(*it) + "; " + strCounter + "++) {\n"; @@ -169,15 +174,13 @@ class DeclVisitor : public RecursiveASTVisitor { if (mVarStack.top().RvalIsArray) Rval += Indeces; Lval += Indeces; - ForBody = Lval + " = " + Rval + ";\n"; + (Lval + " = " + Rval + ";\n").toStringRef(ForBody); TxtStr += ForBody; for (int i = 0; i < LDimensionsNum; i++) { TxtStr += "}\n"; } - } else { // Initialize non-array variable - TxtStr = mVarStack.top().LvalName + " = " + mVarStack.top().RvalName + - ";\n"; - } + } else // Initialize non-array variable + TxtStr = (mVarStack.top().LvalName + " = " + mVarStack.top().RvalName + ";\n").str(); Inits.push_back(TxtStr); mVarStack.pop(); } @@ -201,7 +204,6 @@ class DeclVisitor : public RecursiveASTVisitor { RemoveEmptyLine.RemoveLineIfEmpty = false; for (auto SR : ToRemove) mRewriter.RemoveText(SR, RemoveEmptyLine); // delete each range - for (std::vector::iterator It = Inits.begin(); It != Inits.end(); ++It) { mRewriter.InsertTextAfterToken(locationForInits, *It); @@ -214,6 +216,13 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) { llvm::StringRef VarName; if (mIsInPragma) { + NamedDecl *test = Ex->getFoundDecl(); + auto type = Ex->getDecl()->getType(); + if (type->isFunctionType() || type->isFunctionPointerType() || + type->isStructureOrClassType()) { + toDiag(mSrcMgr.getDiagnostics(), Ex->getBeginLoc(), + tsar::diag::error_not_var); + } if (mWaitingForDimensions && mCurDimensionNum == mVarStack.top().LDimensionsNum) { mWaitingForDimensions = false; @@ -250,10 +259,10 @@ class DeclVisitor : public RecursiveASTVisitor { if (mIsInPragma) { if ((mVarStack.top().LSizeIsKnown && - mVarStack.top().Dimensions.size() > + mVarStack.top().Dimensions.size() >= mVarStack.top().LDimensionsNum) || (mVarStack.top().RSizeIsKnown && - mVarStack.top().Dimensions.size() > + mVarStack.top().Dimensions.size() >= mVarStack.top().LDimensionsNum)) { toDiag(mSrcMgr.getDiagnostics(), IL->getBeginLoc(), tsar::diag::warn_too_many_dimensions); @@ -263,14 +272,14 @@ class DeclVisitor : public RecursiveASTVisitor { mWaitingForDimensions = false; mCurDimensionNum = 0; } - auto Val = IL->getValue().getLimitedValue(); + auto Val = IL->getValue(); if (mWaitingForDimensions) { if (mVarStack.size()) { - mVarStack.top().Dimensions.push_back(Val); + mVarStack.top().Dimensions.push_back(Val.getLimitedValue()); mCurDimensionNum++; } } else if (!mWaitingForVar) { // get rvalue - mVarStack.top().RvalName = std::to_string(Val); + Val.toStringUnsigned(mVarStack.top().RvalName); mWaitingForVar = !mWaitingForVar; if (mVarStack.top().LDimensionsNum > 0) mWaitingForDimensions = true; From 090c25dfc8b4d066db662a64eaafc3041a7fc8ee Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Thu, 31 Mar 2022 12:49:52 +0000 Subject: [PATCH 19/23] clear redundant code --- lib/Transform/Clang/Initialize.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index faa10f0d..ab4af626 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -160,13 +160,11 @@ class DeclVisitor : public RecursiveASTVisitor { } Lval = mVarStack.top().LvalName; Rval = mVarStack.top().RvalName; - TxtStr = ""; for (auto it{mVarStack.top().Dimensions.begin()}, EI{mVarStack.top().Dimensions.end()}; it != EI; ++it) { int IntCounter = it - mVarStack.top().Dimensions.begin(); std::string strCounter = "i" + std::to_string(IntCounter); - llvm::StringRef IndecesPart("[" + strCounter + "]"); Indeces += "[" + strCounter + "]"; TxtStr += "for (int " + strCounter + " = 0; " + strCounter + " < " + std::to_string(*it) + "; " + strCounter + "++) {\n"; From a543fc0498885eb614b1e43987b87f36fba5ce88 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Fri, 8 Apr 2022 08:57:08 +0000 Subject: [PATCH 20/23] fix warning messages --- lib/Transform/Clang/Initialize.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index ab4af626..ae2fe9b7 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -137,12 +137,11 @@ class DeclVisitor : public RecursiveASTVisitor { int RDimensionsNum = mVarStack.top().RDimensionsNum; llvm::SmallString<128> BeforeFor, ForBody, Lval, Rval, Indeces; std::string TxtStr; - if (mVarStack.top().LSizeIsKnown && LDimensionsNum < RDimensionsNum || - mVarStack.top().RSizeIsKnown && mVarStack.top().RvalIsArray && - RDimensionsNum < LDimensionsNum) { + if (LDimensionsNum < RDimensionsNum || + mVarStack.top().RvalIsArray && RDimensionsNum < LDimensionsNum) { mVarStack.pop(); toDiag(mSrcMgr.getDiagnostics(), S->getBeginLoc(), - tsar::diag::warn_dimensions_do_not_match); + tsar::diag::warn_dimensions_do_not_match); continue; } if (LDimensionsNum) { // lvalue is array @@ -178,7 +177,9 @@ class DeclVisitor : public RecursiveASTVisitor { TxtStr += "}\n"; } } else // Initialize non-array variable - TxtStr = (mVarStack.top().LvalName + " = " + mVarStack.top().RvalName + ";\n").str(); + TxtStr = (mVarStack.top().LvalName + " = " + + mVarStack.top().RvalName + ";\n") + .str(); Inits.push_back(TxtStr); mVarStack.pop(); } @@ -256,12 +257,10 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseIntegerLiteral(IntegerLiteral *IL) { if (mIsInPragma) { - if ((mVarStack.top().LSizeIsKnown && - mVarStack.top().Dimensions.size() >= - mVarStack.top().LDimensionsNum) || - (mVarStack.top().RSizeIsKnown && - mVarStack.top().Dimensions.size() >= - mVarStack.top().LDimensionsNum)) { + if (mWaitingForDimensions && (mVarStack.top().Dimensions.size() >= + mVarStack.top().LDimensionsNum || + mVarStack.top().Dimensions.size() >= + mVarStack.top().LDimensionsNum)) { toDiag(mSrcMgr.getDiagnostics(), IL->getBeginLoc(), tsar::diag::warn_too_many_dimensions); } From 43c9f2f26e043d22c15824a2df4338c6a3cf1c03 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Wed, 13 Apr 2022 12:08:11 +0000 Subject: [PATCH 21/23] exit if incorrect pragma parameter found --- lib/Transform/Clang/Initialize.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index ae2fe9b7..cc45ee7c 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -221,6 +221,7 @@ class DeclVisitor : public RecursiveASTVisitor { type->isStructureOrClassType()) { toDiag(mSrcMgr.getDiagnostics(), Ex->getBeginLoc(), tsar::diag::error_not_var); + exit(1); } if (mWaitingForDimensions && mCurDimensionNum == mVarStack.top().LDimensionsNum) { From 19f6aead6afec7eedd3b7d8762a5506fe35175d3 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Wed, 13 Apr 2022 12:18:38 +0000 Subject: [PATCH 22/23] add error flag --- lib/Transform/Clang/Initialize.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index cc45ee7c..1ce68592 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -80,6 +80,7 @@ class ClangInitialize : public FunctionPass, private bcl::Uncopyable { // contains information about variables in // initialize clause struct Vars { + bool ErrorFlag = false; bool RvalIsArray = false; llvm::SmallString<64> LvalName; llvm::SmallString<64> RvalName; @@ -131,6 +132,9 @@ class DeclVisitor : public RecursiveASTVisitor { mIsInPragma = true; bool Ast = RecursiveASTVisitor::TraverseStmt(S); mIsInPragma = false; + if (mErrorFlag) { + return true; + } std::vector Inits; while (mVarStack.size()) { int LDimensionsNum = mVarStack.top().LDimensionsNum; @@ -221,7 +225,7 @@ class DeclVisitor : public RecursiveASTVisitor { type->isStructureOrClassType()) { toDiag(mSrcMgr.getDiagnostics(), Ex->getBeginLoc(), tsar::diag::error_not_var); - exit(1); + mErrorFlag = true; } if (mWaitingForDimensions && mCurDimensionNum == mVarStack.top().LDimensionsNum) { @@ -295,6 +299,7 @@ class DeclVisitor : public RecursiveASTVisitor { return nullptr; } + bool mErrorFlag = false; bool mIsInPragma = false; bool mWaitingForVar = true; bool mWaitingForDimensions = false; From 8d8910746082a409a941a93e9894209c8a744fe3 Mon Sep 17 00:00:00 2001 From: Nikita Gorbov Date: Thu, 28 Apr 2022 11:38:31 +0000 Subject: [PATCH 23/23] change initialization order --- lib/Transform/Clang/Initialize.cpp | 79 ++++++++++++++---------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/lib/Transform/Clang/Initialize.cpp b/lib/Transform/Clang/Initialize.cpp index 1ce68592..c7f7a041 100644 --- a/lib/Transform/Clang/Initialize.cpp +++ b/lib/Transform/Clang/Initialize.cpp @@ -136,43 +136,41 @@ class DeclVisitor : public RecursiveASTVisitor { return true; } std::vector Inits; - while (mVarStack.size()) { - int LDimensionsNum = mVarStack.top().LDimensionsNum; - int RDimensionsNum = mVarStack.top().RDimensionsNum; + for(std::vector::iterator It = mVarVector.begin(); It != mVarVector.end(); ++It) { + int LDimensionsNum = It->LDimensionsNum; + int RDimensionsNum = It->RDimensionsNum; llvm::SmallString<128> BeforeFor, ForBody, Lval, Rval, Indeces; std::string TxtStr; if (LDimensionsNum < RDimensionsNum || - mVarStack.top().RvalIsArray && RDimensionsNum < LDimensionsNum) { - mVarStack.pop(); + It->RvalIsArray && RDimensionsNum < LDimensionsNum) { toDiag(mSrcMgr.getDiagnostics(), S->getBeginLoc(), tsar::diag::warn_dimensions_do_not_match); continue; } if (LDimensionsNum) { // lvalue is array - if (mVarStack.top().Dimensions.size() < LDimensionsNum) { - if ((mVarStack.top().LDefaultDimensions.size() == LDimensionsNum) && - (!RDimensionsNum || mVarStack.top().LDefaultDimensions == - mVarStack.top().RDefaultDimensions)) { - mVarStack.top().Dimensions = mVarStack.top().LDefaultDimensions; + if (It->Dimensions.size() < LDimensionsNum) { + if ((It->LDefaultDimensions.size() == LDimensionsNum) && + (!RDimensionsNum || It->LDefaultDimensions == + It->RDefaultDimensions)) { + It->Dimensions = It->LDefaultDimensions; } else { - mVarStack.pop(); toDiag(mSrcMgr.getDiagnostics(), S->getBeginLoc(), tsar::diag::warn_unknown_dimensions); continue; // dimensions ar mandatory for arrays, skip } // initialization if no dimensions found } - Lval = mVarStack.top().LvalName; - Rval = mVarStack.top().RvalName; - for (auto it{mVarStack.top().Dimensions.begin()}, - EI{mVarStack.top().Dimensions.end()}; + Lval = It->LvalName; + Rval = It->RvalName; + for (auto it{It->Dimensions.begin()}, + EI{It->Dimensions.end()}; it != EI; ++it) { - int IntCounter = it - mVarStack.top().Dimensions.begin(); + int IntCounter = it - It->Dimensions.begin(); std::string strCounter = "i" + std::to_string(IntCounter); Indeces += "[" + strCounter + "]"; TxtStr += "for (int " + strCounter + " = 0; " + strCounter + " < " + std::to_string(*it) + "; " + strCounter + "++) {\n"; } - if (mVarStack.top().RvalIsArray) + if (It->RvalIsArray) Rval += Indeces; Lval += Indeces; (Lval + " = " + Rval + ";\n").toStringRef(ForBody); @@ -181,11 +179,10 @@ class DeclVisitor : public RecursiveASTVisitor { TxtStr += "}\n"; } } else // Initialize non-array variable - TxtStr = (mVarStack.top().LvalName + " = " + - mVarStack.top().RvalName + ";\n") + TxtStr = (It->LvalName + " = " + + It->RvalName + ";\n") .str(); Inits.push_back(TxtStr); - mVarStack.pop(); } llvm::SmallVector ToRemove; @@ -228,7 +225,7 @@ class DeclVisitor : public RecursiveASTVisitor { mErrorFlag = true; } if (mWaitingForDimensions && - mCurDimensionNum == mVarStack.top().LDimensionsNum) { + mCurDimensionNum == mVarVector.back().LDimensionsNum) { mWaitingForDimensions = false; mCurDimensionNum = 0; } @@ -239,19 +236,19 @@ class DeclVisitor : public RecursiveASTVisitor { if (mWaitingForVar) { // get lvalue Vars Tmp; Tmp.LvalName = VarName; - mVarStack.push(std::move(Tmp)); - mVarStack.top().LDimensionsNum = - getDimensionsNum(QT, mVarStack.top().LDefaultDimensions, - mVarStack.top().LSizeIsKnown); + mVarVector.push_back(std::move(Tmp)); + mVarVector.back().LDimensionsNum = + getDimensionsNum(QT, mVarVector.back().LDefaultDimensions, + mVarVector.back().LSizeIsKnown); mWaitingForDimensions = false; } else { // get rvalue - mVarStack.top().RDimensionsNum = - getDimensionsNum(QT, mVarStack.top().RDefaultDimensions, - mVarStack.top().RSizeIsKnown); + mVarVector.back().RDimensionsNum = + getDimensionsNum(QT, mVarVector.back().RDefaultDimensions, + mVarVector.back().RSizeIsKnown); if (QT->isArrayType() || QT->isPointerType()) - mVarStack.top().RvalIsArray = true; - mVarStack.top().RvalName = VarName; - if (mVarStack.top().LDimensionsNum > 0) + mVarVector.back().RvalIsArray = true; + mVarVector.back().RvalName = VarName; + if (mVarVector.back().LDimensionsNum > 0) mWaitingForDimensions = true; } mWaitingForVar = !mWaitingForVar; @@ -262,28 +259,28 @@ class DeclVisitor : public RecursiveASTVisitor { bool TraverseIntegerLiteral(IntegerLiteral *IL) { if (mIsInPragma) { - if (mWaitingForDimensions && (mVarStack.top().Dimensions.size() >= - mVarStack.top().LDimensionsNum || - mVarStack.top().Dimensions.size() >= - mVarStack.top().LDimensionsNum)) { + if (mWaitingForDimensions && (mVarVector.back().Dimensions.size() >= + mVarVector.back().LDimensionsNum || + mVarVector.back().Dimensions.size() >= + mVarVector.back().LDimensionsNum)) { toDiag(mSrcMgr.getDiagnostics(), IL->getBeginLoc(), tsar::diag::warn_too_many_dimensions); } if (mWaitingForDimensions && - mCurDimensionNum == mVarStack.top().LDimensionsNum) { + mCurDimensionNum == mVarVector.back().LDimensionsNum) { mWaitingForDimensions = false; mCurDimensionNum = 0; } auto Val = IL->getValue(); if (mWaitingForDimensions) { - if (mVarStack.size()) { - mVarStack.top().Dimensions.push_back(Val.getLimitedValue()); + if (mVarVector.size()) { + mVarVector.back().Dimensions.push_back(Val.getLimitedValue()); mCurDimensionNum++; } } else if (!mWaitingForVar) { // get rvalue - Val.toStringUnsigned(mVarStack.top().RvalName); + Val.toStringUnsigned(mVarVector.back().RvalName); mWaitingForVar = !mWaitingForVar; - if (mVarStack.top().LDimensionsNum > 0) + if (mVarVector.back().LDimensionsNum > 0) mWaitingForDimensions = true; } } @@ -312,7 +309,7 @@ class DeclVisitor : public RecursiveASTVisitor { SourceManager &mSrcMgr; const LangOptions &mLangOpts; SmallVector mClauses; - std::stack mVarStack; + std::vector mVarVector; }; } // namespace