diff --git a/QTCreator-PandA-GitHub.includes b/QTCreator-PandA-GitHub.includes index bdee737ed..9f13689d2 100644 --- a/QTCreator-PandA-GitHub.includes +++ b/QTCreator-PandA-GitHub.includes @@ -85,6 +85,7 @@ ext/or-tools/ortools/base ext/or-tools/ortools/graph ext/or-tools/ortools/util ext/sollya +ext/pugixml src src/HLS src/HLS/architecture_creation diff --git a/etc/clang_plugin/plugin_ASTAnalyzer.cpp b/etc/clang_plugin/plugin_ASTAnalyzer.cpp index 879c7c25a..3c9801c4f 100644 --- a/etc/clang_plugin/plugin_ASTAnalyzer.cpp +++ b/etc/clang_plugin/plugin_ASTAnalyzer.cpp @@ -38,7 +38,7 @@ * @author Michele Fiorito * */ -// #undef NDEBUG +//#undef NDEBUG #include "plugin_includes.hpp" #include @@ -837,10 +837,9 @@ class DataflowHLSPragmaHandler : public HLSPragmaAnalyzer, public HLSPragmaParse forceNoInline(FD); for(auto* stmt : FD->getBody()->children()) { - auto callExpr = dyn_cast(stmt); - if(callExpr) + if(auto callExpr = dyn_cast(stmt)) { - const auto calleeDecl = dyn_cast(callExpr->getCalleeDecl()); + const auto calleeDecl = callExpr->getDirectCallee(); if(calleeDecl) { LLVM_DEBUG(dbgs() << " -> " << MangledName(calleeDecl) << "\n"); @@ -850,6 +849,10 @@ class DataflowHLSPragmaHandler : public HLSPragmaAnalyzer, public HLSPragmaParse hasModule = true; } + else if(callExpr->isTypeDependent()) + { + return; + } } } if(!hasModule) diff --git a/etc/clang_plugin/plugin_topfname.cpp b/etc/clang_plugin/plugin_topfname.cpp index a85b218a4..6600b24a7 100644 --- a/etc/clang_plugin/plugin_topfname.cpp +++ b/etc/clang_plugin/plugin_topfname.cpp @@ -41,6 +41,7 @@ // #undef NDEBUG #include "plugin_includes.hpp" +#include "llvm/Analysis/CallGraph.h" #include #include #include @@ -166,6 +167,7 @@ namespace llvm CLANG_VERSION_SYMBOL(_plugin_topfname) () : ModulePass(ID) { + initializeCallGraphWrapperPassPass(*PassRegistry::getPassRegistry()); } #if __clang_major__ >= 13 @@ -175,16 +177,57 @@ namespace llvm } #endif - bool exec(Module& M) + bool exec(Module& M, const CallGraph& CG) { bool changed = false; bool hasTopFun = false; + std::list symbolList; + std::vector Starting_TopFunctionNames; std::vector TopFunctionNames; + + const auto handleFunction = [&](Function* F, const std::string& fsymbol, const std::string& fname) { + if(!F->isIntrinsic() && !F->isDeclaration()) + { + LLVM_DEBUG(llvm::dbgs() << "Checking function: " << fsymbol << " | " << fname << " (" << F->getLinkage() + << ")\n"); + if(is_builtin_fn(fsymbol) || is_builtin_fn(fname)) + { + LLVM_DEBUG(llvm::dbgs() << " builtin\n"); + symbolList.push_back(fsymbol); + } + if(llvm::find(TopFunctionNames, fsymbol) != TopFunctionNames.end() || + llvm::find(TopFunctionNames, fname) != TopFunctionNames.end()) + { + LLVM_DEBUG(llvm::dbgs() << " top function\n"); + F->addFnAttr(Attribute::NoInline); + F->setLinkage(GlobalValue::LinkageTypes::ExternalLinkage); +#if __clang_major__ >= 7 + F->setDSOLocal(false); +#endif + symbolList.push_back(fsymbol); + hasTopFun = true; + /// in case add noalias + if(add_noalias) + { + for(auto& par : F->args()) + { + if(!par.hasNoAliasAttr() && par.getType()->isPointerTy()) + { + par.addAttr(llvm::Attribute::NoAlias); + } + } + } + } + } + }; + + // Initialize top functions list for(std::size_t last = 0, it = 0; it < TopFunctionName_TFP.size(); last = it + 1) { it = TopFunctionName_TFP.find(",", last); const auto func_symbol = TopFunctionName_TFP.substr(last, it); LLVM_DEBUG(dbgs() << " - " << func_symbol << "\n"); + Starting_TopFunctionNames.push_back(func_symbol); TopFunctionNames.push_back(func_symbol); } pugi::xml_document doc; @@ -204,12 +247,12 @@ namespace llvm } } } - if(TopFunctionNames.empty()) + if(Starting_TopFunctionNames.empty()) { LLVM_DEBUG(llvm::dbgs() << "No top function specified\n"); return false; } - std::list symbolList; + // Initialize external symbols list if(!ExternSymbolsList.empty()) { std::stringstream ss(ExternSymbolsList); @@ -221,45 +264,56 @@ namespace llvm symbolList.push_back(substr); } } - /// check if the translation unit has the top function name - for(auto& fun : M.getFunctionList()) + + SmallPtrSet Reachable; + for(auto&& CGN : CG) { - if(!fun.isIntrinsic() && !fun.isDeclaration()) + if(!CGN.second) { - const auto funName = fun.getName().str(); - const auto demangled = getDemangled(funName); - LLVM_DEBUG(llvm::dbgs() << "Checking function: " << funName << " | " << demangled << " (" - << fun.getLinkage() << ")\n"); - if(is_builtin_fn(funName) || is_builtin_fn(demangled)) - { - LLVM_DEBUG(llvm::dbgs() << " builtin\n"); - symbolList.push_back(funName); - } - if(llvm::find(TopFunctionNames, funName) != TopFunctionNames.end() || - llvm::find(TopFunctionNames, demangled) != TopFunctionNames.end()) + continue; + } + auto fun = CGN.second->getFunction(); + if(!fun) + { + continue; + } + const auto fsymbol = fun->getName().str(); + const auto fname = getDemangled(fsymbol); + if(!(is_builtin_fn(fsymbol) || is_builtin_fn(fname) || + llvm::find(Starting_TopFunctionNames, fsymbol) != Starting_TopFunctionNames.end() || + llvm::find(Starting_TopFunctionNames, fname) != Starting_TopFunctionNames.end())) + { + continue; + } + + Reachable.insert(fun); + handleFunction(fun, fsymbol, fname); + + SmallVector Tmp({CGN.first}); + do + { + auto F = std::move(Tmp.back()); + Tmp.pop_back(); + + for(auto&& N : *CG[F]) { - LLVM_DEBUG(llvm::dbgs() << " top function\n"); - fun.addFnAttr(Attribute::NoInline); - fun.setLinkage(GlobalValue::LinkageTypes::ExternalLinkage); -#if __clang_major__ >= 7 - fun.setDSOLocal(false); -#endif - symbolList.push_back(funName); - hasTopFun = true; - /// in case add noalias - if(add_noalias) - { - for(auto& par : fun.args()) - { - if(!par.hasNoAliasAttr() && par.getType()->isPointerTy()) - { - par.addAttr(llvm::Attribute::NoAlias); - } - } - } + if(!N.second) + continue; + auto funCalled = N.second->getFunction(); + if(!funCalled) + continue; + if(Reachable.find(funCalled) != Reachable.end()) + continue; + + Tmp.push_back(funCalled); + + const auto _fsymbol = funCalled->getName().str(); + const auto _fname = getDemangled(_fsymbol); + handleFunction(funCalled, _fsymbol, _fname); } - } + } while(!Tmp.empty()); } + if(!hasTopFun) { return changed; @@ -297,7 +351,18 @@ namespace llvm bool runOnModule(Module& M) override { - return exec(M); +#if __clang_major__ < 13 + + CallGraphWrapperPass* CGPass = getAnalysisIfAvailable(); + if(!CGPass) + { + report_fatal_error("not able to retrieve the call graph"); + } + return exec(M, CGPass->getCallGraph()); +#else + report_fatal_error("Call to runOnModule not expected with current LLVM version"); + return false; +#endif } StringRef getPassName() const override @@ -307,12 +372,13 @@ namespace llvm void getAnalysisUsage(AnalysisUsage& AU) const override { + AU.addRequired(); } #if __clang_major__ >= 13 - llvm::PreservedAnalyses run(llvm::Module& M, llvm::ModuleAnalysisManager&) + llvm::PreservedAnalyses run(llvm::Module& M, llvm::ModuleAnalysisManager& MAM) { - const auto changed = exec(M); + const auto changed = exec(M, MAM.getResult(M)); return (changed ? llvm::PreservedAnalyses::none() : llvm::PreservedAnalyses::all()); } #endif diff --git a/src/frontend_analysis/IR_analysis/Range_Analysis.cpp b/src/frontend_analysis/IR_analysis/Range_Analysis.cpp index e99171e20..834831a46 100644 --- a/src/frontend_analysis/IR_analysis/Range_Analysis.cpp +++ b/src/frontend_analysis/IR_analysis/Range_Analysis.cpp @@ -1017,11 +1017,13 @@ namespace case ge_expr_K: return RangeRef(new Range(Regular, bw, Other->getSignedMax(), APInt::getSignedMaxValue(bw))); case gt_expr_K: - return RangeRef(new Range(Regular, bw, Other->getSignedMax() + Range::MinDelta, APInt::getSignedMaxValue(bw))); + return RangeRef( + new Range(Regular, bw, Other->getSignedMax() + Range::MinDelta, APInt::getSignedMaxValue(bw))); case le_expr_K: return RangeRef(new Range(Regular, bw, APInt::getSignedMinValue(bw), Other->getSignedMin())); case lt_expr_K: - return RangeRef(new Range(Regular, bw, APInt::getSignedMinValue(bw), Other->getSignedMin() - Range::MinDelta)); + return RangeRef( + new Range(Regular, bw, APInt::getSignedMinValue(bw), Other->getSignedMin() - Range::MinDelta)); case unge_expr_K: return RangeRef(new Range(Regular, bw, Other->getUnsignedMax(), APInt::getMaxValue(bw))); case ungt_expr_K: diff --git a/src/frontend_analysis/IR_analysis/call_graph_computation.cpp b/src/frontend_analysis/IR_analysis/call_graph_computation.cpp index 70e320f91..246bb18ea 100644 --- a/src/frontend_analysis/IR_analysis/call_graph_computation.cpp +++ b/src/frontend_analysis/IR_analysis/call_graph_computation.cpp @@ -133,10 +133,6 @@ DesignFlowStep_Status call_graph_computation::Exec() "---Root function " + STR(GET_INDEX_CONST_NODE(fnode)) + " - " + symbol); functions.insert(GET_INDEX_CONST_NODE(fnode)); } - else - { - THROW_ERROR("Function " + symbol + " not found in IR"); - } } CGM->SetRootFunctions(functions); diff --git a/src/frontend_analysis/IR_manipulation/create_tree_manager.cpp b/src/frontend_analysis/IR_manipulation/create_tree_manager.cpp index 6230f60d4..4869b67ad 100644 --- a/src/frontend_analysis/IR_manipulation/create_tree_manager.cpp +++ b/src/frontend_analysis/IR_manipulation/create_tree_manager.cpp @@ -392,7 +392,6 @@ DesignFlowStep_Status create_tree_manager::Exec() const auto fnode = TM->GetFunction(symbol); if(!fnode) { - THROW_WARNING("Function specified in architecture XML is missing in the IR: " + symbol); continue; } const auto fd = GetPointer(GET_NODE(fnode));