Cerata
A library to generate structural hardware designs
expression.h
1 // Copyright 2018-2019 Delft University of Technology
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <utility>
18 #include <optional>
19 #include <string>
20 #include <memory>
21 #include <vector>
22 #include <unordered_map>
23 
24 #include "cerata/object.h"
25 #include "cerata/type.h"
26 #include "cerata/node.h"
27 #include "cerata/pool.h"
28 
29 namespace cerata {
30 
34 class Expression : public MultiOutputNode {
35  public:
37  enum class Op { ADD, SUB, MUL, DIV };
38 
40  static std::shared_ptr<Expression> Make(Op op, std::shared_ptr<Node> lhs, std::shared_ptr<Node> rhs);
41 
43  std::shared_ptr<Object> Copy() const override;
44 
46  Node *CopyOnto(Graph *dst, const std::string &name, NodeMap *rebinding) const override;
48  void AppendReferences(std::vector<Object *> *out) const override;
49 
51  std::string ToString() const override;
52 
54  Node *lhs() const { return lhs_.get(); }
56  Node *rhs() const { return rhs_.get(); }
57 
58  protected:
60  static std::shared_ptr<Node> Minimize(Node *node);
62  static std::shared_ptr<Node> MergeIntLiterals(Expression *exp);
64  static std::shared_ptr<Node> EliminateZeroOne(Expression *exp);
65 
72  Expression(Op op, std::shared_ptr<Node> lhs, std::shared_ptr<Node> rhs);
73 
77  std::shared_ptr<Node> lhs_;
79  std::shared_ptr<Node> rhs_;
80 };
81 
83 std::string ToString(Expression::Op operation);
84 
85 // Macros to generate expression generators
86 #ifndef EXPRESSION_OP_FACTORY
87 #define EXPRESSION_OP_FACTORY(SYMBOL, OPID) \
88 inline std::shared_ptr<Node> operator SYMBOL (const std::shared_ptr<Node>& lhs, \
89  const std::shared_ptr<Node>& rhs) { \
90  return Expression::Make(Expression::Op::OPID, lhs, rhs); \
91 } \
92  \
93 inline std::shared_ptr<Node> operator SYMBOL (const std::shared_ptr<Node>& lhs, \
94  Node* rhs) { \
95  return Expression::Make(Expression::Op::OPID, lhs, rhs->shared_from_this()); \
96 } \
97  \
98 inline std::shared_ptr<Node> operator SYMBOL (const std::shared_ptr<Node>& lhs, int64_t rhs) { \
99  if (lhs->IsLiteral()) { \
100  auto li = std::dynamic_pointer_cast<Literal>(lhs); \
101  if (li->storage_type() == Literal::StorageType::INT) { \
102  return default_node_pool()->GetLiteral(li->IntValue() SYMBOL rhs); \
103  } \
104  } \
105  return lhs SYMBOL intl(rhs); \
106 } \
107  \
108 inline std::shared_ptr<Node> operator SYMBOL (Node& lhs, int64_t rhs) { \
109  if (lhs.IsLiteral()) { \
110  auto& li = dynamic_cast<Literal&>(lhs); \
111  if (li.storage_type() == Literal::StorageType::INT) { \
112  return default_node_pool()->GetLiteral(li.IntValue() SYMBOL rhs); \
113  } \
114  } \
115  return lhs.shared_from_this() SYMBOL intl(rhs); \
116 }
117 #endif
118 
119 EXPRESSION_OP_FACTORY(+, ADD)
120 EXPRESSION_OP_FACTORY(-, SUB)
121 EXPRESSION_OP_FACTORY(*, MUL)
122 EXPRESSION_OP_FACTORY(/, DIV)
123 
124 } // namespace cerata
cerata::Expression::Minimize
static std::shared_ptr< Node > Minimize(Node *node)
Minimize a node, if it is an expression, otherwise just returns a copy of the input.
Definition: expression.cc:121
cerata::Expression::ToString
std::string ToString() const override
Minimize the expression and convert it to a human-readable string.
Definition: expression.cc:159
cerata::Expression::EliminateZeroOne
static std::shared_ptr< Node > EliminateZeroOne(Expression *exp)
Eliminate nodes that have zero or one on either side for specific expressions.
Definition: expression.cc:93
cerata::Expression
A node representing a binary tree of other nodes.
Definition: expression.h:34
cerata::Graph
A graph representing a hardware structure.
Definition: graph.h:37
cerata::Expression::Make
static std::shared_ptr< Expression > Make(Op op, std::shared_ptr< Node > lhs, std::shared_ptr< Node > rhs)
Short-hand to create a smart pointer to an expression.
Definition: expression.cc:35
cerata::Expression::Op
Op
Binary expression operator enum class.
Definition: expression.h:37
cerata::Expression::lhs_
std::shared_ptr< Node > lhs_
The left hand side node.
Definition: expression.h:77
cerata
Contains every Cerata class, function, etc...
Definition: api.h:41
cerata::Node
A node.
Definition: node.h:42
cerata::Expression::lhs
Node * lhs() const
Return the left-hand side node of the expression.
Definition: expression.h:54
cerata::NodeMap
std::unordered_map< const Node *, Node * > NodeMap
A mapping from one object to another object, used in e.g. type generic rebinding.
Definition: node.h:135
cerata::Named::name
std::string name() const
Return the name of the object.
Definition: utils.h:45
cerata::ToString
std::string ToString(Expression::Op operation)
Human-readable expression operator.
Definition: expression.cc:149
cerata::Expression::rhs_
std::shared_ptr< Node > rhs_
The right hand side node.
Definition: expression.h:79
cerata::Expression::rhs
Node * rhs() const
Return the right-hand side node of the expression.
Definition: expression.h:56
cerata::Expression::Expression
Expression(Op op, std::shared_ptr< Node > lhs, std::shared_ptr< Node > rhs)
Construct a new expression.
Definition: expression.cc:53
cerata::Expression::AppendReferences
void AppendReferences(std::vector< Object * > *out) const override
Depth-first traverse the expression tree and add any nodes owned.
Definition: expression.cc:200
cerata::Expression::MergeIntLiterals
static std::shared_ptr< Node > MergeIntLiterals(Expression *exp)
Merge expressions of integer literals into their resulting integer literal.
Definition: expression.cc:74
cerata::Expression::operation_
Op operation_
The binary operator of this expression.
Definition: expression.h:75
cerata::Expression::Copy
std::shared_ptr< Object > Copy() const override
Copy this expression.
Definition: expression.cc:172
cerata::Expression::CopyOnto
Node * CopyOnto(Graph *dst, const std::string &name, NodeMap *rebinding) const override
Copy this expression onto a graph and rebind anything in the expression tree.
Definition: expression.cc:178
cerata::MultiOutputNode
A no-input, multiple-outputs node.
Definition: node.h:140