From 3f3a8b4d040226f3097535f9d689e87e0b534d1b Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Tue, 23 Jul 2019 14:07:41 -0400 Subject: [PATCH] First using of loops in zafl --- irdb-libs/libIRDB-deep/src/SConscript | 1 + irdb-libs/libIRDB-deep/src/deep.cpp | 40 +++++++-- irdb-libs/libIRDB-deep/src/deep.hpp | 4 +- irdb-libs/libIRDB-deep/src/loops.cpp | 16 ++++ irdb-libs/libIRDB-deep/src/loops.hpp | 85 +++++++++++++++++++ .../include/MEDS_LoopAnnotation.hpp | 13 ++- .../src/MEDS_LoopAnnotation.cpp | 2 +- irdb-sdk | 2 +- 8 files changed, 148 insertions(+), 15 deletions(-) create mode 100644 irdb-libs/libIRDB-deep/src/loops.cpp create mode 100644 irdb-libs/libIRDB-deep/src/loops.hpp diff --git a/irdb-libs/libIRDB-deep/src/SConscript b/irdb-libs/libIRDB-deep/src/SConscript index 15daf24c7..4fee56b3a 100644 --- a/irdb-libs/libIRDB-deep/src/SConscript +++ b/irdb-libs/libIRDB-deep/src/SConscript @@ -7,6 +7,7 @@ myenv=env libname="irdb-deep" files= ''' deep.cpp + loops.cpp ''' cpppath=''' $IRDB_SDK/include/ diff --git a/irdb-libs/libIRDB-deep/src/deep.cpp b/irdb-libs/libIRDB-deep/src/deep.cpp index 5efbd3457..16f39f74d 100644 --- a/irdb-libs/libIRDB-deep/src/deep.cpp +++ b/irdb-libs/libIRDB-deep/src/deep.cpp @@ -3,9 +3,11 @@ #include <set> #include <memory> #include <deep.hpp> +#include <loops.hpp> #include <MEDS_DeadRegAnnotation.hpp> #include <MEDS_MemoryRangeAnnotation.hpp> #include <MEDS_SafeFuncAnnotation.hpp> +#include <MEDS_LoopAnnotation.hpp> using namespace libIRDB; @@ -40,7 +42,7 @@ unique_ptr<IRDB_SDK::FunctionSet_t> StarsDeepAnalysis_t::getLeafFunctions() /* for each annotation for this instruction */ for (auto it = the_range.first; it != the_range.second; ++it) { - auto p_annotation=dynamic_cast<MEDS_SafeFuncAnnotation*>(it->second); + const auto p_annotation=dynamic_cast<MEDS_SafeFuncAnnotation*>(it->second); if(p_annotation==nullptr) continue; @@ -142,22 +144,44 @@ unique_ptr<IRDB_SDK::RangeSentinelSet_t> StarsDeepAnalysis_t::getRangeSentinels( return ret; } -unique_ptr<IRDB_SDK::LoopNest_t> StarsDeepAnalysis_t::getLoopNest(const IRDB_SDK::Function_t* f) const +unique_ptr<IRDB_SDK::LoopNest_t> StarsDeepAnalysis_t::getLoops(IRDB_SDK::Function_t* f) const { - auto ret = unique_ptr<IRDB_SDK::LoopNest_t>(); + auto cfg = IRDB_SDK::ControlFlowGraph_t::factory(f); + auto ret = getLoops(cfg.get()); + auto real_nest = dynamic_cast<libIRDB::LoopNest_t*>(ret.get()); + real_nest->saveCFG(move(cfg)); + return ret; } -unique_ptr<IRDB_SDK::LoopNest_t> StarsDeepAnalysis_t::getLoopNest(const IRDB_SDK::ControlFlowGraph_t* cfg) const +unique_ptr<IRDB_SDK::LoopNest_t> StarsDeepAnalysis_t::getLoops(IRDB_SDK::ControlFlowGraph_t* cfg) const { - auto ret = unique_ptr<IRDB_SDK::LoopNest_t>(); - return ret; -} + auto func = cfg->getFunction(); + auto id_to_block_map = map<IRDB_SDK::DatabaseID_t, IRDB_SDK::BasicBlock_t*>(); + for(auto blk : cfg->getBlocks()) + id_to_block_map[blk->getInstructions()[0]->getBaseID()]=blk; + + auto meds_ap=stars_analysis_engine.getAnnotations(); + const auto the_range = meds_ap.getAnnotations().equal_range(func->getBaseID()); + auto ret = unique_ptr<IRDB_SDK::LoopNest_t>(new LoopNest_t(cfg)); + for (auto it = the_range.first; it != the_range.second; ++it) + { + auto p_annotation=dynamic_cast<MEDS_LoopAnnotation*>(it->second); + if(p_annotation==nullptr) continue; + if(!p_annotation->isValid()) continue; + + const auto header_id = p_annotation -> getHeaderID(); + const auto loop_id = p_annotation -> getLoopID(); + auto the_loop = unique_ptr<Loop_t>(new Loop_t(id_to_block_map[header_id])); + dynamic_cast<libIRDB::LoopNest_t*>(ret.get())->addLoop(loop_id,move(the_loop)); + } + + return move(ret); +} unique_ptr<IRDB_SDK::DeepAnalysis_t> IRDB_SDK::DeepAnalysis_t::factory(FileIR_t* firp, const AnalysisEngine_t& ae, const vector<string>& options) { - auto ret=unique_ptr<IRDB_SDK::DeepAnalysis_t>(); switch(ae) diff --git a/irdb-libs/libIRDB-deep/src/deep.hpp b/irdb-libs/libIRDB-deep/src/deep.hpp index bba46a9ee..176e8cd93 100644 --- a/irdb-libs/libIRDB-deep/src/deep.hpp +++ b/irdb-libs/libIRDB-deep/src/deep.hpp @@ -27,8 +27,8 @@ namespace libIRDB virtual unique_ptr<IRDB_SDK::StaticGlobalStartMap_t> getStaticGlobalRanges() const override; virtual unique_ptr<IRDB_SDK::RangeSentinelSet_t > getRangeSentinels() const override; - virtual unique_ptr<IRDB_SDK::LoopNest_t> getLoopNest(const IRDB_SDK::Function_t* f) const override; - virtual unique_ptr<IRDB_SDK::LoopNest_t> getLoopNest(const IRDB_SDK::ControlFlowGraph_t* cfg) const override; + virtual unique_ptr<IRDB_SDK::LoopNest_t> getLoops(IRDB_SDK::Function_t* f) const override; + virtual unique_ptr<IRDB_SDK::LoopNest_t> getLoops(IRDB_SDK::ControlFlowGraph_t* cfg) const override; private: diff --git a/irdb-libs/libIRDB-deep/src/loops.cpp b/irdb-libs/libIRDB-deep/src/loops.cpp new file mode 100644 index 000000000..a60bd1ece --- /dev/null +++ b/irdb-libs/libIRDB-deep/src/loops.cpp @@ -0,0 +1,16 @@ + +#include <loops.hpp> + +using namespace libIRDB; +using namespace std; + +IRDB_SDK::LoopSet_t LoopNest_t::getAllLoops() const +{ + auto ret=IRDB_SDK::LoopSet_t(); + for(const auto &p : loops) + { + ret.insert(p.second.get()); + } + return ret; +} + diff --git a/irdb-libs/libIRDB-deep/src/loops.hpp b/irdb-libs/libIRDB-deep/src/loops.hpp new file mode 100644 index 000000000..7953edf73 --- /dev/null +++ b/irdb-libs/libIRDB-deep/src/loops.hpp @@ -0,0 +1,85 @@ +/* + Copyright 2018-2019 Zephyr Software, LLC. + + 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 <irdb-core> +#include <irdb-cfg> +#include <irdb-deep> +#include <set> +#include <map> + +namespace libIRDB +{ + using namespace std; + + class Loop_t : public IRDB_SDK::Loop_t + { + public: + Loop_t() = delete; + Loop_t(IRDB_SDK::BasicBlock_t* header_blk) + : + preheader(nullptr) + { + header = header_blk; + assert(header != nullptr); + } + Loop_t(const Loop_t& copy) = delete; + virtual ~Loop_t() {} + + virtual IRDB_SDK::BasicBlock_t* getPreheader() const override { assert(0); } + virtual IRDB_SDK::BasicBlock_t* getHeader() const override { return header; } + virtual IRDB_SDK::BasicBlockSet_t getAllBlocks() const override { assert(0); } + virtual IRDB_SDK::BasicBlockSet_t getOuterBlocks() const override { assert(0); } + virtual IRDB_SDK::LoopSet_t getInnerLoops() const override { assert(0); } + + virtual bool isBlockInLoop (const IRDB_SDK::BasicBlock_t* blk) const override { assert(0); } + virtual bool isBlockInInnerLoop (const IRDB_SDK::BasicBlock_t* blk) const override { assert(0); } + virtual bool isBlockOuterLoopOnly(const IRDB_SDK::BasicBlock_t* blk) const override { assert(0); } + private: + IRDB_SDK::BasicBlock_t* preheader; + IRDB_SDK::BasicBlock_t* header; + IRDB_SDK::BasicBlockSet_t blocks; + IRDB_SDK::LoopSet_t inner_loops; + }; + + class LoopNest_t : public IRDB_SDK::LoopNest_t + { + public: + LoopNest_t(IRDB_SDK::ControlFlowGraph_t* p_cfg) + : + cfg(p_cfg) + {} + + LoopNest_t(const LoopNest_t& copy) = delete; + virtual ~LoopNest_t() {} + + virtual IRDB_SDK::LoopSet_t getAllLoops() const override ; + virtual IRDB_SDK::LoopSet_t getOuterLoops() const override { assert(0); } + + virtual IRDB_SDK::Function_t* getFunction() const override { return cfg->getFunction(); } + virtual IRDB_SDK::ControlFlowGraph_t* getCFG() const override { return cfg; }; + + + void addLoop(const uint64_t loop_id, unique_ptr<IRDB_SDK::Loop_t> loop_ptr) { loops[loop_id]=move(loop_ptr); } + void saveCFG(unique_ptr<IRDB_SDK::ControlFlowGraph_t> cfg_ptr ) { saved_cfg = move(cfg_ptr); } + private: + unique_ptr<IRDB_SDK::ControlFlowGraph_t> saved_cfg; + IRDB_SDK::ControlFlowGraph_t* cfg; + map<uint64_t,unique_ptr<IRDB_SDK::Loop_t> > loops; + + + }; +} diff --git a/irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp b/irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp index f72630926..5b58745b0 100644 --- a/irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp +++ b/irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp @@ -50,6 +50,13 @@ class MEDS_LoopAnnotation : public MEDS_AnnotationBase virtual const string toString() const { return "loop annot "; } + uint64_t getHeaderID() const { return header; } + uint64_t getPreheaderID() const { return preheader; } + uint64_t getLoopID() const { return loop_no; } + + const set<uint64_t>& getBlockIDs() const { return all_blocks; } + const set<uint64_t>& getInnerLoopIDs() const { return sub_loops; } + private: void init(); void parse(); @@ -57,9 +64,9 @@ class MEDS_LoopAnnotation : public MEDS_AnnotationBase string m_rawInputLine; uint64_t loop_no; - IRDB_SDK::VirtualOffset_t preheader; - IRDB_SDK::VirtualOffset_t header; - set<IRDB_SDK::VirtualOffset_t> all_blocks; + uint64_t preheader; + uint64_t header; + set<uint64_t> all_blocks; set<uint64_t> sub_loops; }; diff --git a/irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp b/irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp index c13f378ec..4fb13be65 100644 --- a/irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp +++ b/irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp @@ -125,7 +125,7 @@ void MEDS_LoopAnnotation::parse() preheader = readInt<decltype(preheader)>(m_rawInputLine, " PREHEADER ", true); all_blocks = readAddrSet<IRDB_SDK::VirtualOffset_t>(m_rawInputLine, " BLOCKLIST ", true); - sub_loops = readAddrSet<uint64_t >(m_rawInputLine, " BLOCKLIST ", false); + sub_loops = readAddrSet<uint64_t >(m_rawInputLine, " INNERLOOPS ", false); setValid(); // no additional info recorded for right now. } diff --git a/irdb-sdk b/irdb-sdk index 21c2c99f8..3267ac263 160000 --- a/irdb-sdk +++ b/irdb-sdk @@ -1 +1 @@ -Subproject commit 21c2c99f8d6f0a37fadd91b0cc3877df5a4ab735 +Subproject commit 3267ac26338c701dffa3267da6c6ca15475b4999 -- GitLab