KSeExpr  4.0.4.0
ExprEnv.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2 // SPDX-License-Identifier: LicenseRef-Apache-2.0
3 // SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 
6 #pragma once
7 
8 #include <cassert>
9 #include <iostream>
10 #include <memory>
11 #include <map>
12 #include <utility>
13 #include <vector>
14 
15 #include "ExprLLVM.h"
16 #include "ExprType.h"
17 
18 namespace KSeExpr
19 {
20 class ExprVarRef;
21 class ExprLocalVar;
22 class ExprNode;
23 class ExprLocalFunctionNode;
24 class Interpreter;
25 
28 {
29 private:
31  ExprLocalVar *_phi {nullptr};
32  mutable LLVM_VALUE _varPtr {0};
33 
34 public:
36  : _type(type)
37  {
38  }
39 
40  virtual ~ExprLocalVar() = default;
41  ExprLocalVar(ExprLocalVar &) = default;
42  ExprLocalVar(ExprLocalVar &&) = default;
43  ExprLocalVar &operator=(const ExprLocalVar &) = default;
45 
47  const ExprLocalVar *getPhi() const
48  {
49  return _phi;
50  }
52  ExprType type() const
53  {
54  return _type;
55  }
56 
58  virtual void setType(const ExprType &type)
59  {
60  _type = type;
61  }
63  virtual void setPhi(ExprLocalVar *phi)
64  {
65  _phi = phi;
66  }
67 
69  virtual LLVM_VALUE codegen(LLVM_BUILDER, const std::string &, LLVM_VALUE) LLVM_BASE;
70 
72  virtual LLVM_VALUE varPtr()
73  {
74  return _varPtr;
75  }
76 
78  int buildInterpreter(Interpreter *interpreter) const;
79 };
80 
82 // This is basically like single assignment form inspired. hence the phi node nomenclature.
84 {
85 public:
86  ExprLocalVarPhi(const ExprType &condLife, ExprLocalVar *thenVar, ExprLocalVar *elseVar)
88  , _thenVar(thenVar)
89  , _elseVar(elseVar)
90  {
91  // find the compatible common-denominator lifetime
92  ExprType firstType = _thenVar->type();
93  ExprType secondType = _elseVar->type();
95  setType(((firstType.isFP(1) ? secondType : firstType).setLifetime(firstType, secondType)));
96  }
97  // lifetime should be the minimum (error=0,varying=1,uniform=2,constant=3).
98  // i.e. you can only guarantee something is constant if the condition, ifvar, and else var are the same
99  setType(type().setLifetime(firstType, secondType, condLife));
100  }
101 
102  bool valid() const
103  {
104  return !type().isError();
105  }
106 
107  void setPhi(ExprLocalVar *phi) override
108  {
110  _thenVar->setPhi(phi);
111  _elseVar->setPhi(phi);
112  }
113 
114  ExprNode *_condNode {nullptr};
115  ExprLocalVar *_thenVar {nullptr}, *_elseVar {nullptr};
116 };
117 
120 {
121 private:
122  using VarDictType = std::map<std::string, std::unique_ptr<ExprLocalVar>>;
124  using FuncDictType = std::map<std::string, ExprLocalFunctionNode *>;
126 
128  // i.e. a=3;a=[1,2,3];a=[2];a will yield 2 entries in shadowedVariables
129  std::vector<std::unique_ptr<ExprLocalVar>> shadowedVariables;
130 
132  std::vector<std::vector<std::pair<std::string, ExprLocalVarPhi *>>> _mergedVariables;
133 
135  ExprVarEnv *_parent {nullptr};
136 
137 protected:
140 
141 public:
142  // TODO: figure out when anotherOwns is needed
144  ExprVarEnv() = default;
145 
146  ~ExprVarEnv() = default;
147 
148  ExprVarEnv(ExprVarEnv &&) = default;
150 
152  void resetAndSetParent(ExprVarEnv *parent);
154  ExprLocalFunctionNode *findFunction(const std::string &name);
156  ExprLocalVar *find(const std::string &name);
158  ExprLocalVar const *lookup(const std::string &name) const;
160  void addFunction(const std::string &name, ExprLocalFunctionNode *prototype);
162  void add(const std::string &name, std::unique_ptr<ExprLocalVar> var);
164  // void add(ExprVarEnv & env,const ExprType & modifyingType);
166  // static bool branchesMatch(const ExprVarEnv & env1, const ExprVarEnv & env2);
167  size_t mergeBranches(const ExprType &type, ExprVarEnv &env1, ExprVarEnv &env2);
168  // Code generate merges.
170  // Query merges
171  std::vector<std::pair<std::string, ExprLocalVarPhi *>> &merge(size_t index)
172  {
173  return _mergedVariables[index];
174  }
175 };
176 
178 // scopes
179 // It is inspired by IRBuilder's notion of a basic block insertion point
181 {
182 public:
185  {
186  reset();
187  }
189  void reset()
190  {
191  std::unique_ptr<ExprVarEnv> newEnv(new ExprVarEnv);
192  _currentEnv = newEnv.get();
193  all.emplace_back(std::move(newEnv));
194  }
197  {
198  return _currentEnv;
199  }
202  {
203  _currentEnv = env;
204  }
207  {
208  std::unique_ptr<ExprVarEnv> newEnv(new ExprVarEnv);
209  newEnv->resetAndSetParent(parent);
210  all.emplace_back(std::move(newEnv));
211  return all.back().get();
212  }
213 
214 private:
216  std::vector<std::unique_ptr<ExprVarEnv>> all;
219 };
220 
223  ExprEvalResult() = default;
224  ExprEvalResult(int n, double *fp)
225  : n(n)
226  , fp(fp)
227  {
228  }
229  ExprEvalResult(const char **c)
230  : n(1)
231  , str(c)
232  {
233  }
234  ExprEvalResult(int n, double *fp, const char **c)
235  : n(n)
236  , fp(fp)
237  , str(c)
238  {
239  }
240 
241  int n {0};
242  double *fp {nullptr};
243  const char **str {nullptr};
244 };
245 } // namespace KSeExpr
double LLVM_BUILDER
Definition: ExprLLVM.h:26
#define LLVM_BASE
Definition: ExprLLVM.h:27
double LLVM_VALUE
Definition: ExprLLVM.h:25
Node that contains local function.
Definition: ExprNode.h:351
ExprLocalVar join (merge) references. Remembers which variables are possible assigners to this.
Definition: ExprEnv.h:84
ExprLocalVar * _thenVar
Definition: ExprEnv.h:115
ExprLocalVarPhi(const ExprType &condLife, ExprLocalVar *thenVar, ExprLocalVar *elseVar)
Definition: ExprEnv.h:86
bool valid() const
Definition: ExprEnv.h:102
void setPhi(ExprLocalVar *phi) override
sets the representative phi node (like a brute force set unioning operation) phi is the set represent...
Definition: ExprEnv.h:107
ExprNode * _condNode
Definition: ExprEnv.h:114
ExprLocalVar * _elseVar
Definition: ExprEnv.h:115
ExprLocalVar reference, all local variables in seexpr are subclasses of this or this itself.
Definition: ExprEnv.h:28
virtual LLVM_VALUE codegen(LLVM_BUILDER, const std::string &, LLVM_VALUE) LLVM_BASE
LLVM value that has been allocated.
ExprLocalVar & operator=(ExprLocalVar &&)=default
ExprLocalVar(ExprLocalVar &&)=default
ExprLocalVar(const ExprType &type)
Definition: ExprEnv.h:35
virtual void setType(const ExprType &type)
setter for variable type
Definition: ExprEnv.h:58
ExprLocalVar & operator=(const ExprLocalVar &)=default
virtual void setPhi(ExprLocalVar *phi)
sets the representative phi node (like a brute force set unioning operation) phi is the set represent...
Definition: ExprEnv.h:63
ExprLocalVar(ExprLocalVar &)=default
ExprLocalVar * _phi
Definition: ExprEnv.h:31
virtual LLVM_VALUE varPtr()
LLVM value that has been pre-done.
Definition: ExprEnv.h:72
LLVM_VALUE _varPtr
Definition: ExprEnv.h:32
int buildInterpreter(Interpreter *interpreter) const
Allocates variable for interpreter.
virtual ~ExprLocalVar()=default
const ExprLocalVar * getPhi() const
get the primary representative phi node (i.e. the global parent of a dependent phi node)
Definition: ExprEnv.h:47
ExprType type() const
returns type of the variable
Definition: ExprEnv.h:52
bool isError() const
Definition: ExprType.h:206
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:190
static bool valuesCompatible(const ExprType &a, const ExprType &b)
Checks if value types are compatible.
Definition: ExprType.h:220
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
Definition: ExprEnv.h:181
void setCurrent(ExprVarEnv *env)
Set a new current variable scope.
Definition: ExprEnv.h:201
ExprVarEnv * createDescendant(ExprVarEnv *parent)
Create a descendant scope from the provided parent, does not clobber current.
Definition: ExprEnv.h:206
ExprVarEnvBuilder()
Creates an empty builder with one current scope entry.
Definition: ExprEnv.h:184
ExprVarEnv * _currentEnv
The current symbol table (should be a pointer owned by all)
Definition: ExprEnv.h:218
void reset()
Reset to factory state (one empty environment that is current)
Definition: ExprEnv.h:189
ExprVarEnv * current()
Return the current variable scope.
Definition: ExprEnv.h:196
std::vector< std::unique_ptr< ExprVarEnv > > all
All owned symbol tables.
Definition: ExprEnv.h:216
Variable scope for tracking variable lookup.
Definition: ExprEnv.h:120
ExprLocalVar * find(const std::string &name)
Find a variable name by name (recursive to parents)
Definition: ExprEnv.cpp:17
ExprLocalVar const * lookup(const std::string &name) const
Find a const variable reference name by name (recursive to parents)
Definition: ExprEnv.cpp:39
FuncDictType _functions
Definition: ExprEnv.h:125
std::vector< std::pair< std::string, ExprLocalVarPhi * > > & merge(size_t index)
Definition: ExprEnv.h:171
std::map< std::string, ExprLocalFunctionNode * > FuncDictType
Definition: ExprEnv.h:124
LLVM_VALUE codegenMerges(LLVM_BUILDER, int) LLVM_BASE
ExprLocalFunctionNode * findFunction(const std::string &name)
Find a function by name (recursive to parents)
Definition: ExprEnv.cpp:28
ExprVarEnv(ExprVarEnv &&)=default
ExprVarEnv()=default
Create a scope with no parent.
void addFunction(const std::string &name, ExprLocalFunctionNode *prototype)
Add a function.
Definition: ExprEnv.cpp:49
VarDictType _map
Definition: ExprEnv.h:123
std::vector< std::vector< std::pair< std::string, ExprLocalVarPhi * > > > _mergedVariables
Keep track of all merged variables in.
Definition: ExprEnv.h:132
ExprVarEnv(ExprVarEnv &other)
void add(const std::string &name, std::unique_ptr< ExprLocalVar > var)
Add a variable refernece.
Definition: ExprEnv.cpp:63
std::vector< std::unique_ptr< ExprLocalVar > > shadowedVariables
Variables that have been superceded (and thus are inaccessible)
Definition: ExprEnv.h:129
ExprVarEnv * _parent
Parent variable environment has all variablesf rom previou scope (for lookup)
Definition: ExprEnv.h:135
ExprVarEnv & operator=(ExprVarEnv &&)=default
ExprVarEnv & operator=(const ExprVarEnv &other)
void resetAndSetParent(ExprVarEnv *parent)
Resets the scope (deletes all variables) and sets parent.
Definition: ExprEnv.cpp:12
size_t mergeBranches(const ExprType &type, ExprVarEnv &env1, ExprVarEnv &env2)
Add all variables into scope by name, but modify their lifetimes to the given type's lifetime.
Definition: ExprEnv.cpp:74
std::map< std::string, std::unique_ptr< ExprLocalVar > > VarDictType
Definition: ExprEnv.h:122
Evaluation result.
Definition: ExprEnv.h:222
ExprEvalResult(int n, double *fp, const char **c)
Definition: ExprEnv.h:234
const char ** str
Definition: ExprEnv.h:243
ExprEvalResult(int n, double *fp)
Definition: ExprEnv.h:224
ExprEvalResult(const char **c)
Definition: ExprEnv.h:229