From 1a38f4e4f6c2d220649f0b0c66c5501a31dec909 Mon Sep 17 00:00:00 2001 From: Kari Rummukainen Date: Thu, 4 Mar 2021 21:30:00 +0200 Subject: [PATCH] Hilapp now compiles with clang-12 - look for __clang__ -macros to see version dependent bits Former-commit-id: 7991e342a0c41aa0423fd9bcb6345c28c1ccc56e --- hilapp/Makefile | 7 +-- hilapp/src/codegen.cpp | 2 +- hilapp/src/hilapp.cpp | 1 - hilapp/src/hilapp.h | 24 ++++----- hilapp/src/toplevelvisitor.cpp | 91 ++++++++++++++++++++++------------ howto/HOWTO_GET_CLANG | 6 +-- 6 files changed, 78 insertions(+), 53 deletions(-) diff --git a/hilapp/Makefile b/hilapp/Makefile index 4e89d256..adb3f71b 100644 --- a/hilapp/Makefile +++ b/hilapp/Makefile @@ -99,10 +99,11 @@ endif # These are required when compiling vs. a source distribution of Clang. For # binary distributions llvm-config --cxxflags gives the right path. # -#CLANG_INCLUDES := \ +# CLANG_INCLUDES := \ # -I$(LLVM_SRC_PATH)/include \ -# -I$(LLVM_SRC_PATH)/tools/clang/include \ -# -I$(LLVM_BUILD_PATH)/tools/clang/include +# -I$(LLVM_BUILD_PATH)/tools/clang/include \ +# -I$(LLVM_SRC_PATH)/tools/clang/include + # List of Clang libraries to link. The proper -L will be provided by the diff --git a/hilapp/src/codegen.cpp b/hilapp/src/codegen.cpp index 7c71fdd2..c9856d19 100644 --- a/hilapp/src/codegen.cpp +++ b/hilapp/src/codegen.cpp @@ -152,7 +152,7 @@ void TopLevelVisitor::generate_code(Stmt *S) { if (cmdline::check_initialization) { - std::string fname = srcMgr.getFilename(S->getSourceRange().getBegin()); + std::string fname = srcMgr.getFilename(S->getSourceRange().getBegin()).str(); code << "if (!" << l.new_name << ".is_initialized(" << init_par << ")){\noutput0 << \"File " << fname << " on line " << srcMgr.getSpellingLineNumber(S->getSourceRange().getBegin()) diff --git a/hilapp/src/hilapp.cpp b/hilapp/src/hilapp.cpp index 39193319..373e7f39 100644 --- a/hilapp/src/hilapp.cpp +++ b/hilapp/src/hilapp.cpp @@ -40,7 +40,6 @@ std::list field_info_list = {}; std::list array_ref_list = {}; std::list vector_reduction_ref_list = {}; std::list special_function_call_list = {}; -std::vector remove_expr_list = {}; bool state::compile_errors_occurred = false; diff --git a/hilapp/src/hilapp.h b/hilapp/src/hilapp.h index 0c9d270c..6cd18cf2 100644 --- a/hilapp/src/hilapp.h +++ b/hilapp/src/hilapp.h @@ -257,23 +257,22 @@ struct var_info { } }; -/// Store non-var code sections which can be replaced. These happen thus far pretty much -/// only with array references -struct replace_expr { - Expr * E; // expression to be replaced - std::string type; // type of expression - std::string repl_name; // name of the replace - -} - -/// Stores onformation for a single reference to an array +/// Stores information for a single reference to an loop-extern array or related variable /// These are similar to variable references, but often /// need to be handled differently struct array_ref { - ArraySubscriptExpr *ref; - std::string new_name; + Expr *E; // the whole expression + ArraySubscriptExpr *ref; // as type says + std::string new_name; std::string type; + bool replace_expr_with_var; // if true replace the whole expression with variable + + array_ref() { + E = nullptr; + ref = nullptr; + replace_expr_with_var = false; + } }; /// store necessary information for vector reductions @@ -439,6 +438,5 @@ extern std::list field_info_list; extern std::list array_ref_list; extern std::list vector_reduction_ref_list; extern std::list special_function_call_list; -extern std::vector remove_expr_list; #endif diff --git a/hilapp/src/toplevelvisitor.cpp b/hilapp/src/toplevelvisitor.cpp index 233fe5d3..e57ed259 100644 --- a/hilapp/src/toplevelvisitor.cpp +++ b/hilapp/src/toplevelvisitor.cpp @@ -2,7 +2,6 @@ #include "hilapp.h" #include "toplevelvisitor.h" #include "specialization_db.h" -#include "clang/Analysis/CallGraph.h" #include #include #include @@ -230,9 +229,17 @@ bool TopLevelVisitor::handle_field_X_expr(Expr *e, bool is_assign, bool is_also_ } Expr *dirE = Op->getArg(1)->IgnoreImplicit(); - llvm::APSInt result; - if (dirE->isIntegerConstantExpr(result, *Context)) { - // Got constant + if (dirE->isIntegerConstantExpr(*Context)) { + llvm::APSInt result; + + // Got constant -- interface changes in clang 12 or 13(!) +#if defined(__clang_major__) && (__clang_major__ <= 11) + dirE->isIntegerConstantExpr(result,*Context); +#else + auto res = dirE->getIntegerConstantExpr(*Context); + result = res.getValue(); +#endif + lfe.is_constant_direction = true; lfe.constant_value = result.getExtValue(); // llvm::errs() << " GOT DIR CONST, value " << lfe.constant_value << " @@ -322,16 +329,16 @@ bool TopLevelVisitor::is_variable_loop_local(VarDecl *decl) { return false; } -/// handle an array subscript expression -/// Check if array itself is loop extern or intern -/// -> if intern, nothing special needs to be done -/// -> if extern, check index: -/// -> if site dep, mark loop_info.has_site_dep_cond_or_index -/// -> if contains loop local var ref || site dep: -/// -> whole array is input to loop: need to know array size -/// If size not knowable, flag error -/// -> if !site dep and !loop local: -/// -> it is sufficient to read in this array element only, +/// handle an array subscript expression. Operations depend +/// on whether the array is defined loop extern or intern: +/// - if intern, nothing special needs to be done +/// - if extern, check index: +/// - if site dependent, mark loop_info.has_site_dep_cond_or_index +/// - if contains loop local var ref or is site dependent: +/// whole array is input to loop: need to know array size. +/// If size not knowable, flag error +/// - If index is not site dependent or loop local: +/// - it is sufficient to read in this array element only, /// and remove var references to variables in index /// int TopLevelVisitor::handle_array_var_ref(ArraySubscriptExpr *E, bool is_assign, @@ -346,10 +353,12 @@ int TopLevelVisitor::handle_array_var_ref(ArraySubscriptExpr *E, bool is_assign, return 0; } + llvm::errs() << " %% Inside array reference\n"; + // Check if it's local - VarDecl *decl = dyn_cast(DRE->getDecl()); + VarDecl *vd = dyn_cast(DRE->getDecl()); - if (is_variable_loop_local(decl)) { + if (is_variable_loop_local(vd)) { // if array is declared within the loop, nothing special needs to // be done. Let us anyway put it through the std handler in order to // flag it. @@ -382,28 +391,44 @@ int TopLevelVisitor::handle_array_var_ref(ArraySubscriptExpr *E, bool is_assign, // Note: multiple refrences are not checked, thus, same element can be // referred more than once. TODO? (small optimization) - // misusing the var_info_list here - var_info vi; + // use the array_ref_list to note this + array_ref ar; + ar.replace_expr_with_var = true; + ar.E = E; + array_ref_list.push_back(ar); + llvm::errs() << " %%% found fully extern array reference\n"; + parsing_state.skip_children = 1; // no need to look inside the replacement + // variable refs inside should not be recorded + return 1; } - if (!site_dep) { - bool index_local = contains_loop_local_var(E->getIdx(), nullptr); - if (!index) - } + // Now there is site dep/loop local stuff in index. Whole array has to be taken + // "in". + + const ConstantArrayType *cat = Context->getAsConstantArrayType(vd->getType()); + if (cat) { + llvm::errs() << " %%% Found constant array type expr, size " << cat->getSize() + << "\n"; - if (!) - DRE = dyn_cast(E->getIdx()->IgnoreImplicit()); - if (DRE) { - decl = dyn_cast(DRE->getDecl()); - index_local = is_variable_loop_local(decl); } else { - // This happens when the index is not a variable. - // It's probably a compile time constant - index_local = true; + const VariableArrayType *vat = Context->getAsVariableArrayType(vd->getType()); + if (vat) { + llvm::errs() << " %%% Found variable array type expr, size " + << get_stmt_str(vat->getSizeExpr()) << "\n"; + } else { + + // Now different array type - flag as error + reportDiag(DiagnosticsEngine::Level::Error, E->getSourceRange().getBegin(), + "Array size is unknown - recommend use of Vector<>, " + "std::array<> or std::vector<> instead"); + return 1; + } } +#if 0 + // Now handling depends on wether it's local, global, or something else if (!array_local) { // llvm::errs() << "Non-local array\n"; @@ -445,6 +470,9 @@ int TopLevelVisitor::handle_array_var_ref(ArraySubscriptExpr *E, bool is_assign, // Array and index are local. This does not require any action. } } + +#endif + return 1; } @@ -481,7 +509,6 @@ bool TopLevelVisitor::handle_full_loop_stmt(Stmt *ls, bool field_parity_ok) { parsing_state.in_loop_body = false; parsing_state.ast_depth = 0; - // check and analyze the field expressions check_var_info_list(); check_addrofops_and_refs(ls); // scan through the full loop again @@ -1247,7 +1274,7 @@ void TopLevelVisitor::ast_dump_header(const char *s, const SourceRange sr_in, bool is_function) { SourceRange sr = sr_in; unsigned linenumber = srcMgr.getSpellingLineNumber(sr.getBegin()); - std::string name = srcMgr.getFilename(sr.getBegin()); + std::string name = srcMgr.getFilename(sr.getBegin()).str(); // check if it is macro if (sr.getBegin().isMacroID()) { diff --git a/howto/HOWTO_GET_CLANG b/howto/HOWTO_GET_CLANG index a83b8f56..e31ea40d 100644 --- a/howto/HOWTO_GET_CLANG +++ b/howto/HOWTO_GET_CLANG @@ -45,10 +45,10 @@ git clone https://github.com/llvm/llvm-project.git cd llvm-project mkdir build cd build -cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release ../llvm -make -j4 +cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/install/dir ../llvm +make -j4 # compiles everything +make install # installs to /install/dir, default /usr/local -* This leaves binaries in llvm-project/build/bin -directory. * Build types are Release, MinSizeRel, Debug, RelWithDebInfo