diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-11-15 18:39:01 +0100 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-11-15 18:39:01 +0100 | 
| commit | a3b4cd4fdd4340c952eaa00bca9bebf817b901ae (patch) | |
| tree | 055d3ae4b9d1e37682c2e49b31a6531f189eebf5 /flowgraph | |
| parent | d07c5bc14edbe071ee7b4f47f174780e95e451aa (diff) | |
Fixed unit tests, prepared hierarchical evaluation via stack (WIP)
Diffstat (limited to 'flowgraph')
| -rw-r--r-- | flowgraph/graph.cpp | 60 | ||||
| -rw-r--r-- | flowgraph/graph.h | 22 | ||||
| -rw-r--r-- | flowgraph/node.cpp | 8 | ||||
| -rw-r--r-- | flowgraph/node.h | 16 | ||||
| -rw-r--r-- | flowgraph/scope.cpp | 28 | ||||
| -rw-r--r-- | flowgraph/scope.h | 29 | ||||
| -rw-r--r-- | flowgraph/storage.cpp | 9 | ||||
| -rw-r--r-- | flowgraph/storage.h | 16 | 
8 files changed, 168 insertions, 20 deletions
| diff --git a/flowgraph/graph.cpp b/flowgraph/graph.cpp index e8b6b5e..6398c68 100644 --- a/flowgraph/graph.cpp +++ b/flowgraph/graph.cpp @@ -1 +1,61 @@  #include "graph.h" + +#include "minicc.h" +#include "node.h" + +#include <string> + +using namespace std::string_literals; + +FlowGraph::Graph::Graph() +{ +} + +FlowGraph::Graph::Graph(const std::deque<std::shared_ptr<Node>>& nodes): std::deque<std::shared_ptr<Node>>(nodes) +{ + auto createLocalScope {std::make_shared<FlowGraph::CreateScopeOp>()}; + this->push_front(createLocalScope); + + auto destroyLocalScope {std::make_shared<FlowGraph::DestroyScopeOp>(createLocalScope->scope())}; + this->push_back(destroyLocalScope); +} + +FlowGraph::Graph::~Graph() +{ +} + +// Assume first node of graph to be CreateScopeOp +FlowGraph::LocalScope& FlowGraph::Graph::scope() const +{ + if (this->empty()) +  throw std::runtime_error("ICE: FlowGraph expected to be non-empty!"); + + auto& front_deref {*front()}; + + if (typeid(front_deref) != typeid(FlowGraph::CreateScopeOp)) +  throw std::runtime_error("ICE: Bad type of first graph element: "s + demangle(typeid(front_deref))); + + FlowGraph::CreateScopeOp& createScope {dynamic_cast<FlowGraph::CreateScopeOp&>(front_deref)}; + + return createScope.scope(); +} + +void FlowGraph::Graph::append(const FlowGraph::Graph& other) +{ + this->insert(this->end() - 1, other.begin() + 1, other.end() - 1); + + this->scope().append(other.scope()); +} + +void FlowGraph::Graph::append(std::shared_ptr<Node> node) +{ + this->insert(this->end() - 1, node); +} + +std::shared_ptr<FlowGraph::Node> FlowGraph::Graph::lastOp() const +{ + if (size() >= 3) +  return *(end() - 2); + + throw std::runtime_error("ICE: No last operation found in graph"); +} diff --git a/flowgraph/graph.h b/flowgraph/graph.h index 265a3bd..15c6aef 100644 --- a/flowgraph/graph.h +++ b/flowgraph/graph.h @@ -2,18 +2,32 @@  #include "node.h" +#include <deque>  #include <exception>  #include <memory> -#include <string>  #include <stdexcept> -#include <vector>  namespace FlowGraph { - class Graph: public std::vector<std::shared_ptr<Node>> + class Graph: public std::deque<std::shared_ptr<Node>>   {   public: -  Graph() {} +  Graph(); +  Graph(const std::deque<std::shared_ptr<Node>>& nodes); +  Graph(const Graph& other) = default; +  ~Graph(); + +  Graph& operator= (const Graph&) = default; + +  // returns the outermost scope inside this graph +  LocalScope& scope() const; + +  // append other graph by joining the respective outermost scopes +  void append(const Graph& other); +   +  void append(std::shared_ptr<Node> node); + +  std::shared_ptr<Node> lastOp() const;   };  } diff --git a/flowgraph/node.cpp b/flowgraph/node.cpp index 9b68d74..e0912dc 100644 --- a/flowgraph/node.cpp +++ b/flowgraph/node.cpp @@ -6,6 +6,14 @@  using namespace FlowGraph; +FlowGraph::Data& Node::destination() +{ + if (mOperands.size() < 1) +  throw std::runtime_error("ICE: No destination operand available"); + + return mOperands[0]; +} +  // 4 byte for now  Data FlowGraph::MakeConstantInt(int i)  { diff --git a/flowgraph/node.h b/flowgraph/node.h index 77395f0..5ea194d 100644 --- a/flowgraph/node.h +++ b/flowgraph/node.h @@ -19,8 +19,11 @@ namespace FlowGraph {   public:    Node(){}    Node(std::vector<Data> operands): mOperands(operands) {} -  std::vector<Data>& operands() { return mOperands; }    virtual ~Node() {}; // force class to be polymorphic (e.g. in a container) +   +  std::vector<Data>& operands() { return mOperands; } +  Data& destination(); // best-effort return of result/destination; else throw +   private:    std::vector<Data> mOperands;   }; @@ -115,7 +118,6 @@ namespace FlowGraph {    Increment,    Decrement,    Negate, -  Store // just take Data as-is to store it at destination   };   class UnaryOperation: public Node @@ -130,6 +132,16 @@ namespace FlowGraph {    UnaryOperationType m_type;   }; + // Just take a value e.g. Immediate and store it for later use. + // Should be optimized out later. + class DataNode: public Node + { + public: +  DataNode(Data& value): +   Node(std::vector<Data>({value})) +   {} + }; +   enum class BinaryOperationType: int   {    Add, diff --git a/flowgraph/scope.cpp b/flowgraph/scope.cpp new file mode 100644 index 0000000..6c2e30c --- /dev/null +++ b/flowgraph/scope.cpp @@ -0,0 +1,28 @@ +#include "scope.h" + +#include "storage.h" + +void FlowGraph::LocalScope::push_back(std::shared_ptr<Data> data) +{ + m_variables.push_back(data); +} + +void FlowGraph::LocalScope::append(const FlowGraph::LocalScope& other) +{ + m_variables.insert(m_variables.end(), other.m_variables.begin(), other.m_variables.end()); +} + +index_t FlowGraph::LocalScope::indexOfStorage(const TemporaryStorage& storage) const +{ + for (index_t i = 0; i < m_variables.size(); i++) { +  FlowGraph::Storage& i_storage {*(m_variables[i]->storage())}; + +  if (typeid(i_storage) == typeid(FlowGraph::TemporaryStorage)) { +   FlowGraph::TemporaryStorage& temporaryStorage{dynamic_cast<FlowGraph::TemporaryStorage&>(i_storage)}; +   if (&temporaryStorage == &storage) // compare addresses +    return i; +  } + } + + throw std::runtime_error("ICE: Storage not found"); +} diff --git a/flowgraph/scope.h b/flowgraph/scope.h new file mode 100644 index 0000000..50003f4 --- /dev/null +++ b/flowgraph/scope.h @@ -0,0 +1,29 @@ +#pragma once + +#include "data.h" + +#include "minicc.h" + +#include <cstddef> +#include <memory> +#include <vector> + +namespace FlowGraph { + + class TemporaryStorage; ///< Forward declaration + + // Provide a context for local temporaries name generation + class LocalScope + { + public: +  LocalScope() = default; + +  void push_back(std::shared_ptr<Data> data); +  void append(const LocalScope& other); +  index_t indexOfStorage(const TemporaryStorage& storage) const; + + private: +  std::vector<std::shared_ptr<Data>> m_variables; + }; + +} diff --git a/flowgraph/storage.cpp b/flowgraph/storage.cpp index f78a65d..7e502de 100644 --- a/flowgraph/storage.cpp +++ b/flowgraph/storage.cpp @@ -3,6 +3,11 @@  using namespace std::string_literals;  FlowGraph::TemporaryStorage::TemporaryStorage(LocalScope& scope): - m_name("__local_"s + std::to_string(scope.getNewIndex())) -{} + m_scope(scope) +{ +} +std::string FlowGraph::TemporaryStorage::name() const +{ + return "__local_"s + std::to_string(m_scope.indexOfStorage(*this)); +} diff --git a/flowgraph/storage.h b/flowgraph/storage.h index fd3c085..7f648b0 100644 --- a/flowgraph/storage.h +++ b/flowgraph/storage.h @@ -2,6 +2,7 @@  #pragma once  #include "data.h" +#include "scope.h"  #include <cstdint>  #include <string> @@ -37,16 +38,7 @@ namespace FlowGraph {    std::string m_name;   }; - // Provide a context for local temporaries name generation - class LocalScope - { - public: -  LocalScope() = default; -  size_t getNewIndex() { return m_index++; } - private: -  size_t m_index{ 0 }; - }; - + // named values   class LocalStorage : public Storage   {   public: @@ -62,9 +54,9 @@ namespace FlowGraph {   {   public:    TemporaryStorage(LocalScope& scope); -  const std::string& name() const { return m_name; } +  std::string name() const;   private: -  std::string m_name; +  LocalScope& m_scope;   };   // dereferenced pointer | 
