KSeExpr 6.0.0.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
18namespace KSeExpr
19{
20class ExprVarRef;
21class ExprLocalVar;
22class ExprNode;
23class ExprLocalFunctionNode;
24class Interpreter;
25
28{
29private:
31 ExprLocalVar *_phi {nullptr};
32 mutable LLVM_VALUE _varPtr {0};
33
34public:
36 : _type(type)
37 {
38 }
39
40 virtual ~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
73 {
74 return _varPtr;
75 }
76
79};
80
82// This is basically like single assignment form inspired. hence the phi node nomenclature.
84{
85public:
90 {
91 // find the compatible common-denominator lifetime
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 {
112 }
113
114 ExprNode *_condNode {nullptr};
115 ExprLocalVar *_thenVar {nullptr}, *_elseVar {nullptr};
116};
117
120{
121private:
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
137protected:
140
141public:
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{
182public:
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 {
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
214private:
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
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
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(ExprLocalVar &&)=default
ExprLocalVar(const ExprType &type)
Definition ExprEnv.h:35
virtual void setType(const ExprType &type)
setter for variable type
Definition ExprEnv.h:58
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 & operator=(ExprLocalVar &&)=default
ExprLocalVar(ExprLocalVar &)=default
ExprLocalVar * _phi
Definition ExprEnv.h:31
const ExprLocalVar * getPhi() const
get the primary representative phi node (i.e. the global parent of a dependent phi node)
Definition ExprEnv.h:47
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
ExprLocalVar & operator=(const ExprLocalVar &)=default
ExprType type() const
returns type of the variable
Definition ExprEnv.h:52
bool isError() const
Definition ExprType.h:206
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
ExprVarEnvBuilder()
Creates an empty builder with one current scope entry.
Definition ExprEnv.h:184
ExprVarEnv * current()
Return the current variable scope.
Definition ExprEnv.h:196
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 * createDescendant(ExprVarEnv *parent)
Create a descendant scope from the provided parent, does not clobber current.
Definition ExprEnv.h:206
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::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 & operator=(ExprVarEnv &&)=default
ExprVarEnv()=default
Create a scope with no parent.
std::vector< std::pair< std::string, ExprLocalVarPhi * > > & merge(size_t index)
Definition ExprEnv.h:171
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
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
ExprVarEnv & operator=(const ExprVarEnv &other)
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