//===-- sotoc/src/TargetCode ------------------------ ---------------------===////// The LLVM Compiler Infrastructure//// This file is distributed under the University of Illinois Open Source// License. See LICENSE.TXT for details.////===----------------------------------------------------------------------===////===----------------------------------------------------------------------===//#include"clang/AST/PrettyPrinter.h"#include<ctype.h>#include"OmpPragma.h"intClauseParamCounter=-1;voidOmpPragma::printReplacement(llvm::raw_ostream&Out){switch(Kind){caseclang::OpenMPDirectiveKind::OMPD_target_parallel:{Out<<" #pragma omp parallel ";break;}caseclang::OpenMPDirectiveKind::OMPD_teams_distribute_parallel_for:caseclang::OpenMPDirectiveKind::OMPD_target_parallel_for:{Out<<" #pragma omp parallel for ";break;}caseclang::OpenMPDirectiveKind::OMPD_teams_distribute_parallel_for_simd:caseclang::OpenMPDirectiveKind::OMPD_target_parallel_for_simd:{Out<<" #pragma _NEC ivdep\n #pragma omp parallel for simd ";break;}caseclang::OpenMPDirectiveKind::OMPD_distribute_simd:caseclang::OpenMPDirectiveKind::OMPD_teams_distribute_simd:caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute_simd:caseclang::OpenMPDirectiveKind::OMPD_target_simd:{Out<<" #pragma _NEC ivdep\n #pragma omp simd ";break;}caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute_parallel_for:{Out<<" #pragma omp parallel for ";break;}caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute_parallel_for_simd:{Out<<" #pragma _NEC ivdep\n #pragma omp parallel for simd ";break;}default:return;}printClauses(Out);}//TODO: Do we need this?voidOmpPragma::printAddition(llvm::raw_ostream&Out){Out<<" #pragma _NEC ivdep ";}boolOmpPragma::isReplaceable(clang::OMPExecutableDirective*Directive){if(llvm::isa<clang::OMPTeamsDirective>(Directive)||llvm::isa<clang::OMPTeamsDistributeDirective>(Directive)||llvm::isa<clang::OMPTeamsDistributeSimdDirective>(Directive)||llvm::isa<clang::OMPTeamsDistributeParallelForDirective>(Directive)||llvm::isa<clang::OMPTeamsDistributeParallelForSimdDirective>(Directive)||llvm::isa<clang::OMPDistributeDirective>(Directive)){returntrue;}returnfalse;}boolOmpPragma::needsAdditionalPragma(clang::OMPExecutableDirective*Directive){if(llvm::isa<clang::OMPForSimdDirective>(Directive)||llvm::isa<clang::OMPParallelForSimdDirective>(Directive)||llvm::isa<clang::OMPSimdDirective>(Directive)||llvm::isa<clang::OMPTaskLoopSimdDirective>(Directive)){returntrue;}returnfalse;}boolOmpPragma::isClausePrintable(clang::OMPClause*Clause){switch(Kind){caseclang::OpenMPDirectiveKind::OMPD_target:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_if:// case clang::OpenMPClauseKind::OMPC_device:// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_private:// case clang::OpenMPClauseKind::OMPC_nowait:// case clang::OpenMPClauseKind::OMPC_depend:// case clang::OpenMPClauseKind::OMPC_defaultmap:caseclang::OpenMPClauseKind::OMPC_firstprivate:// case clang::OpenMPClauseKind::OMPC_is_device_ptr:// case clang::OpenMPClauseKind::OMPC_reduction:returntrue;default:returnfalse;}}/*case clang::OpenMPDirectiveKind::OMPD_target_teams: { switch (Clause->getClauseKind()) { // case clang::OpenMPClauseKind::OMPC_map: case clang::OpenMPClauseKind::OMPC_default: case clang::OpenMPClauseKind::OMPC_private: case clang::OpenMPClauseKind::OMPC_firstprivate: case clang::OpenMPClauseKind::OMPC_shared: case clang::OpenMPClauseKind::OMPC_reduction: case clang::OpenMPClauseKind::OMPC_num_teams: case clang::OpenMPClauseKind::OMPC_thread_limit: return true; default: return false; } }*/caseclang::OpenMPDirectiveKind::OMPD_target_parallel:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_num_threads:caseclang::OpenMPClauseKind::OMPC_default:caseclang::OpenMPClauseKind::OMPC_proc_bind:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_firstprivate:caseclang::OpenMPClauseKind::OMPC_shared:// case clang::OpenMPClauseKind::OMPC_reduction:returntrue;default:returnfalse;caseclang::OpenMPClauseKind::OMPC_if:clang::OMPIfClause*IC=llvm::dyn_cast_or_null<clang::OMPIfClause>(Clause);if((IC->getNameModifier())==clang::OpenMPDirectiveKind::OMPD_target){returnfalse;}else{returntrue;}}}caseclang::OpenMPDirectiveKind::OMPD_target_parallel_for:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_num_threads:caseclang::OpenMPClauseKind::OMPC_default:caseclang::OpenMPClauseKind::OMPC_proc_bind:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_firstprivate:caseclang::OpenMPClauseKind::OMPC_shared:caseclang::OpenMPClauseKind::OMPC_reduction:caseclang::OpenMPClauseKind::OMPC_lastprivate:caseclang::OpenMPClauseKind::OMPC_collapse:caseclang::OpenMPClauseKind::OMPC_schedule:caseclang::OpenMPClauseKind::OMPC_ordered:caseclang::OpenMPClauseKind::OMPC_linear:returntrue;default:returnfalse;caseclang::OpenMPClauseKind::OMPC_if:clang::OMPIfClause*IC=llvm::dyn_cast_or_null<clang::OMPIfClause>(Clause);if((IC->getNameModifier())==clang::OpenMPDirectiveKind::OMPD_target){returnfalse;}else{returntrue;}}}caseclang::OpenMPDirectiveKind::OMPD_target_parallel_for_simd:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_num_threads:caseclang::OpenMPClauseKind::OMPC_default:caseclang::OpenMPClauseKind::OMPC_proc_bind:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_firstprivate:caseclang::OpenMPClauseKind::OMPC_shared:caseclang::OpenMPClauseKind::OMPC_reduction:caseclang::OpenMPClauseKind::OMPC_lastprivate:caseclang::OpenMPClauseKind::OMPC_collapse:caseclang::OpenMPClauseKind::OMPC_schedule:caseclang::OpenMPClauseKind::OMPC_safelen:caseclang::OpenMPClauseKind::OMPC_simdlen:caseclang::OpenMPClauseKind::OMPC_linear:caseclang::OpenMPClauseKind::OMPC_aligned:caseclang::OpenMPClauseKind::OMPC_ordered:returntrue;default:returnfalse;caseclang::OpenMPClauseKind::OMPC_if:clang::OMPIfClause*IC=llvm::dyn_cast_or_null<clang::OMPIfClause>(Clause);if((IC->getNameModifier())==clang::OpenMPDirectiveKind::OMPD_target){returnfalse;}else{returntrue;}}}caseclang::OpenMPDirectiveKind::OMPD_target_simd:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_lastprivate:caseclang::OpenMPClauseKind::OMPC_linear:caseclang::OpenMPClauseKind::OMPC_aligned:caseclang::OpenMPClauseKind::OMPC_safelen:caseclang::OpenMPClauseKind::OMPC_simdlen:caseclang::OpenMPClauseKind::OMPC_collapse:caseclang::OpenMPClauseKind::OMPC_reduction:returntrue;default:returnfalse;}}caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_default:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_firstprivate:caseclang::OpenMPClauseKind::OMPC_shared:caseclang::OpenMPClauseKind::OMPC_reduction:caseclang::OpenMPClauseKind::OMPC_thread_limit:caseclang::OpenMPClauseKind::OMPC_lastprivate:caseclang::OpenMPClauseKind::OMPC_collapse:caseclang::OpenMPClauseKind::OMPC_dist_schedule:returntrue;default:returnfalse;}}caseclang::OpenMPDirectiveKind::OMPD_teams_distribute_parallel_for:caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute_parallel_for:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_firstprivate:caseclang::OpenMPClauseKind::OMPC_lastprivate:caseclang::OpenMPClauseKind::OMPC_collapse:caseclang::OpenMPClauseKind::OMPC_dist_schedule:caseclang::OpenMPClauseKind::OMPC_num_threads:caseclang::OpenMPClauseKind::OMPC_default:caseclang::OpenMPClauseKind::OMPC_proc_bind:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_shared:caseclang::OpenMPClauseKind::OMPC_reduction:caseclang::OpenMPClauseKind::OMPC_schedule:caseclang::OpenMPClauseKind::OMPC_thread_limit:returntrue;default:returnfalse;caseclang::OpenMPClauseKind::OMPC_if:clang::OMPIfClause*IC=llvm::dyn_cast_or_null<clang::OMPIfClause>(Clause);if((IC->getNameModifier())==clang::OpenMPDirectiveKind::OMPD_target){returnfalse;}else{returntrue;}}}caseclang::OpenMPDirectiveKind::OMPD_teams_distribute_parallel_for_simd:caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute_parallel_for_simd:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_firstprivate:caseclang::OpenMPClauseKind::OMPC_lastprivate:caseclang::OpenMPClauseKind::OMPC_collapse:caseclang::OpenMPClauseKind::OMPC_dist_schedule:caseclang::OpenMPClauseKind::OMPC_num_threads:caseclang::OpenMPClauseKind::OMPC_default:caseclang::OpenMPClauseKind::OMPC_proc_bind:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_shared:caseclang::OpenMPClauseKind::OMPC_reduction:caseclang::OpenMPClauseKind::OMPC_schedule:caseclang::OpenMPClauseKind::OMPC_linear:caseclang::OpenMPClauseKind::OMPC_aligned:caseclang::OpenMPClauseKind::OMPC_safelen:caseclang::OpenMPClauseKind::OMPC_simdlen:caseclang::OpenMPClauseKind::OMPC_thread_limit:returntrue;default:returnfalse;caseclang::OpenMPClauseKind::OMPC_if:clang::OMPIfClause*IC=llvm::dyn_cast_or_null<clang::OMPIfClause>(Clause);if((IC->getNameModifier())==clang::OpenMPDirectiveKind::OMPD_target){returnfalse;}else{returntrue;}}}caseclang::OpenMPDirectiveKind::OMPD_teams_distribute_simd:caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute_simd:{switch(Clause->getClauseKind()){// case clang::OpenMPClauseKind::OMPC_map:caseclang::OpenMPClauseKind::OMPC_default:caseclang::OpenMPClauseKind::OMPC_private:caseclang::OpenMPClauseKind::OMPC_firstprivate:caseclang::OpenMPClauseKind::OMPC_shared:caseclang::OpenMPClauseKind::OMPC_reduction:caseclang::OpenMPClauseKind::OMPC_thread_limit:caseclang::OpenMPClauseKind::OMPC_lastprivate:caseclang::OpenMPClauseKind::OMPC_collapse:caseclang::OpenMPClauseKind::OMPC_dist_schedule:caseclang::OpenMPClauseKind::OMPC_linear:caseclang::OpenMPClauseKind::OMPC_aligned:caseclang::OpenMPClauseKind::OMPC_safelen:caseclang::OpenMPClauseKind::OMPC_simdlen:returntrue;default:returnfalse;caseclang::OpenMPClauseKind::OMPC_if:clang::OMPIfClause*IC=llvm::dyn_cast_or_null<clang::OMPIfClause>(Clause);if((IC->getNameModifier())==clang::OpenMPDirectiveKind::OMPD_target){returnfalse;}else{returntrue;}}}default:break;}returnfalse;}voidOmpPragma::printClauses(llvm::raw_ostream&Out){std::stringInString;llvm::raw_string_ostreamIn(InString);clang::OMPClausePrinterPrinter(In,PP);boolnumThreads=0;std::stringnumThreadsParam;boolthreadLimit=0;std::stringthreadLimitParam;for(autoC:Clauses){// Only print clauses that are both printable (for us) and are actually in// the users code (is explicit)if(isClausePrintable(C)&&!C->isImplicit()){Printer.Visit(C);In.str();size_tinp=InString.find("(")+1;size_tparamlength=InString.length()-inp-1;std::stringparam=InString.substr(inp,paramlength);InString.erase(inp,paramlength);if(C->getClauseKind()==clang::OpenMPClauseKind::OMPC_num_threads){rewriteParam(¶m);numThreadsParam=param;numThreads=true;}elseif(C->getClauseKind()==clang::OpenMPClauseKind::OMPC_thread_limit){rewriteParam(¶m);threadLimitParam=param;threadLimit=true;}else{Out<<InString.insert(inp,param)<<" ";}InString.clear();}}if(numThreads&&threadLimit){Out<<"num_threads(("<<numThreadsParam<<" < "<<threadLimitParam<<") ? "<<numThreadsParam<<" : "<<threadLimitParam<<") ";}elseif(numThreads&&!threadLimit){Out<<"num_threads("<<numThreadsParam<<") ";}elseif(!numThreads&&threadLimit){Out<<"num_threads("<<threadLimitParam<<") ";}}voidOmpPragma::rewriteParam(std::string*In){boolisNumerical=true;for(autoi:*In){if(!isdigit(i)){isNumerical=false;}}if(!isNumerical){*In="__sotoc_clause_param_"+std::to_string(ClauseParamCounter);ClauseParamCounter++;}}boolOmpPragma::needsStructuredBlock(){switch(Kind){caseclang::OpenMPDirectiveKind::OMPD_target_parallel:caseclang::OpenMPDirectiveKind::OMPD_target_simd:caseclang::OpenMPDirectiveKind::OMPD_target_teams_distribute_simd:returntrue;default:returnfalse;}}