xref: /aosp_15_r20/external/deqp/framework/randomshaders/rsgVariableManager.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Random Shader Generator
3*35238bceSAndroid Build Coastguard Worker  * ----------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Variable manager.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "rsgVariableManager.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include <algorithm>
27*35238bceSAndroid Build Coastguard Worker #include <map>
28*35238bceSAndroid Build Coastguard Worker #include <set>
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker using std::map;
31*35238bceSAndroid Build Coastguard Worker using std::set;
32*35238bceSAndroid Build Coastguard Worker using std::vector;
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker namespace rsg
35*35238bceSAndroid Build Coastguard Worker {
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker class SubValueRangeIterator
38*35238bceSAndroid Build Coastguard Worker {
39*35238bceSAndroid Build Coastguard Worker public:
40*35238bceSAndroid Build Coastguard Worker     SubValueRangeIterator(const ConstValueRangeAccess &valueRange);
~SubValueRangeIterator(void)41*35238bceSAndroid Build Coastguard Worker     ~SubValueRangeIterator(void)
42*35238bceSAndroid Build Coastguard Worker     {
43*35238bceSAndroid Build Coastguard Worker     }
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker     bool hasItem(void) const;
46*35238bceSAndroid Build Coastguard Worker     ConstValueRangeAccess getItem(void) const;
47*35238bceSAndroid Build Coastguard Worker     void next(void);
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker private:
50*35238bceSAndroid Build Coastguard Worker     vector<ConstValueRangeAccess> m_stack;
51*35238bceSAndroid Build Coastguard Worker };
52*35238bceSAndroid Build Coastguard Worker 
SubValueRangeIterator(const ConstValueRangeAccess & valueRange)53*35238bceSAndroid Build Coastguard Worker SubValueRangeIterator::SubValueRangeIterator(const ConstValueRangeAccess &valueRange)
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker     m_stack.push_back(valueRange);
56*35238bceSAndroid Build Coastguard Worker }
57*35238bceSAndroid Build Coastguard Worker 
hasItem(void) const58*35238bceSAndroid Build Coastguard Worker inline bool SubValueRangeIterator::hasItem(void) const
59*35238bceSAndroid Build Coastguard Worker {
60*35238bceSAndroid Build Coastguard Worker     return !m_stack.empty();
61*35238bceSAndroid Build Coastguard Worker }
62*35238bceSAndroid Build Coastguard Worker 
getItem(void) const63*35238bceSAndroid Build Coastguard Worker inline ConstValueRangeAccess SubValueRangeIterator::getItem(void) const
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker     return m_stack[m_stack.size() - 1];
66*35238bceSAndroid Build Coastguard Worker }
67*35238bceSAndroid Build Coastguard Worker 
next(void)68*35238bceSAndroid Build Coastguard Worker void SubValueRangeIterator::next(void)
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker     ConstValueRangeAccess curItem = getItem();
71*35238bceSAndroid Build Coastguard Worker     m_stack.pop_back(); // Remove current
72*35238bceSAndroid Build Coastguard Worker 
73*35238bceSAndroid Build Coastguard Worker     switch (curItem.getType().getBaseType())
74*35238bceSAndroid Build Coastguard Worker     {
75*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_ARRAY:
76*35238bceSAndroid Build Coastguard Worker     {
77*35238bceSAndroid Build Coastguard Worker         int numElements = curItem.getType().getNumElements();
78*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < numElements; ndx++)
79*35238bceSAndroid Build Coastguard Worker             m_stack.push_back(curItem.member(ndx));
80*35238bceSAndroid Build Coastguard Worker         break;
81*35238bceSAndroid Build Coastguard Worker     }
82*35238bceSAndroid Build Coastguard Worker 
83*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_STRUCT:
84*35238bceSAndroid Build Coastguard Worker     {
85*35238bceSAndroid Build Coastguard Worker         int numMembers = (int)curItem.getType().getMembers().size();
86*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < numMembers; ndx++)
87*35238bceSAndroid Build Coastguard Worker             m_stack.push_back(curItem.member(ndx));
88*35238bceSAndroid Build Coastguard Worker         break;
89*35238bceSAndroid Build Coastguard Worker     }
90*35238bceSAndroid Build Coastguard Worker 
91*35238bceSAndroid Build Coastguard Worker     default:
92*35238bceSAndroid Build Coastguard Worker         break; // \todo [2011-02-03 pyry] Swizzle control?
93*35238bceSAndroid Build Coastguard Worker     }
94*35238bceSAndroid Build Coastguard Worker }
95*35238bceSAndroid Build Coastguard Worker 
ValueEntry(const Variable * variable)96*35238bceSAndroid Build Coastguard Worker ValueEntry::ValueEntry(const Variable *variable) : m_variable(variable), m_valueRange(variable->getType())
97*35238bceSAndroid Build Coastguard Worker {
98*35238bceSAndroid Build Coastguard Worker }
99*35238bceSAndroid Build Coastguard Worker 
VariableScope(void)100*35238bceSAndroid Build Coastguard Worker VariableScope::VariableScope(void)
101*35238bceSAndroid Build Coastguard Worker {
102*35238bceSAndroid Build Coastguard Worker }
103*35238bceSAndroid Build Coastguard Worker 
~VariableScope(void)104*35238bceSAndroid Build Coastguard Worker VariableScope::~VariableScope(void)
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker     for (vector<Variable *>::iterator i = m_declaredVariables.begin(); i != m_declaredVariables.end(); i++)
107*35238bceSAndroid Build Coastguard Worker         delete *i;
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker     for (vector<Variable *>::iterator i = m_liveVariables.begin(); i != m_liveVariables.end(); i++)
110*35238bceSAndroid Build Coastguard Worker         delete *i;
111*35238bceSAndroid Build Coastguard Worker }
112*35238bceSAndroid Build Coastguard Worker 
allocate(const VariableType & type,Variable::Storage storage,const char * name)113*35238bceSAndroid Build Coastguard Worker Variable *VariableScope::allocate(const VariableType &type, Variable::Storage storage, const char *name)
114*35238bceSAndroid Build Coastguard Worker {
115*35238bceSAndroid Build Coastguard Worker     Variable *variable = new Variable(type, storage, name);
116*35238bceSAndroid Build Coastguard Worker     try
117*35238bceSAndroid Build Coastguard Worker     {
118*35238bceSAndroid Build Coastguard Worker         m_liveVariables.push_back(variable);
119*35238bceSAndroid Build Coastguard Worker         return variable;
120*35238bceSAndroid Build Coastguard Worker     }
121*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &)
122*35238bceSAndroid Build Coastguard Worker     {
123*35238bceSAndroid Build Coastguard Worker         delete variable;
124*35238bceSAndroid Build Coastguard Worker         throw;
125*35238bceSAndroid Build Coastguard Worker     }
126*35238bceSAndroid Build Coastguard Worker }
127*35238bceSAndroid Build Coastguard Worker 
declare(Variable * variable)128*35238bceSAndroid Build Coastguard Worker void VariableScope::declare(Variable *variable)
129*35238bceSAndroid Build Coastguard Worker {
130*35238bceSAndroid Build Coastguard Worker     m_declaredVariables.push_back(variable);
131*35238bceSAndroid Build Coastguard Worker     removeLive(variable);
132*35238bceSAndroid Build Coastguard Worker }
133*35238bceSAndroid Build Coastguard Worker 
removeLive(const Variable * variable)134*35238bceSAndroid Build Coastguard Worker void VariableScope::removeLive(const Variable *variable)
135*35238bceSAndroid Build Coastguard Worker {
136*35238bceSAndroid Build Coastguard Worker     vector<Variable *>::iterator pos = std::find(m_liveVariables.begin(), m_liveVariables.end(), variable);
137*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(pos != m_liveVariables.end());
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker     // \todo [pyry] Not so efficient
140*35238bceSAndroid Build Coastguard Worker     m_liveVariables.erase(pos);
141*35238bceSAndroid Build Coastguard Worker }
142*35238bceSAndroid Build Coastguard Worker 
ValueScope(void)143*35238bceSAndroid Build Coastguard Worker ValueScope::ValueScope(void)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker }
146*35238bceSAndroid Build Coastguard Worker 
~ValueScope(void)147*35238bceSAndroid Build Coastguard Worker ValueScope::~ValueScope(void)
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker     clear();
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker 
clear(void)152*35238bceSAndroid Build Coastguard Worker void ValueScope::clear(void)
153*35238bceSAndroid Build Coastguard Worker {
154*35238bceSAndroid Build Coastguard Worker     for (vector<ValueEntry *>::iterator i = m_entries.begin(); i != m_entries.end(); i++)
155*35238bceSAndroid Build Coastguard Worker         delete *i;
156*35238bceSAndroid Build Coastguard Worker     m_entries.clear();
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker 
allocate(const Variable * variable)159*35238bceSAndroid Build Coastguard Worker ValueEntry *ValueScope::allocate(const Variable *variable)
160*35238bceSAndroid Build Coastguard Worker {
161*35238bceSAndroid Build Coastguard Worker     ValueEntry *entry = new ValueEntry(variable);
162*35238bceSAndroid Build Coastguard Worker     try
163*35238bceSAndroid Build Coastguard Worker     {
164*35238bceSAndroid Build Coastguard Worker         m_entries.push_back(entry);
165*35238bceSAndroid Build Coastguard Worker         return entry;
166*35238bceSAndroid Build Coastguard Worker     }
167*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &)
168*35238bceSAndroid Build Coastguard Worker     {
169*35238bceSAndroid Build Coastguard Worker         delete entry;
170*35238bceSAndroid Build Coastguard Worker         throw;
171*35238bceSAndroid Build Coastguard Worker     }
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker 
174*35238bceSAndroid Build Coastguard Worker class CompareEntryVariable
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker public:
CompareEntryVariable(const Variable * variable)177*35238bceSAndroid Build Coastguard Worker     CompareEntryVariable(const Variable *variable) : m_variable(variable)
178*35238bceSAndroid Build Coastguard Worker     {
179*35238bceSAndroid Build Coastguard Worker     }
180*35238bceSAndroid Build Coastguard Worker 
operator ==(const ValueEntry * entry) const181*35238bceSAndroid Build Coastguard Worker     bool operator==(const ValueEntry *entry) const
182*35238bceSAndroid Build Coastguard Worker     {
183*35238bceSAndroid Build Coastguard Worker         return entry->getVariable() == m_variable;
184*35238bceSAndroid Build Coastguard Worker     }
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker private:
187*35238bceSAndroid Build Coastguard Worker     const Variable *m_variable;
188*35238bceSAndroid Build Coastguard Worker };
189*35238bceSAndroid Build Coastguard Worker 
operator ==(const ValueEntry * entry,const CompareEntryVariable & cmp)190*35238bceSAndroid Build Coastguard Worker bool operator==(const ValueEntry *entry, const CompareEntryVariable &cmp)
191*35238bceSAndroid Build Coastguard Worker {
192*35238bceSAndroid Build Coastguard Worker     return cmp == entry;
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker 
findEntry(const Variable * variable) const195*35238bceSAndroid Build Coastguard Worker ValueEntry *ValueScope::findEntry(const Variable *variable) const
196*35238bceSAndroid Build Coastguard Worker {
197*35238bceSAndroid Build Coastguard Worker     vector<ValueEntry *>::const_iterator pos =
198*35238bceSAndroid Build Coastguard Worker         std::find(m_entries.begin(), m_entries.end(), CompareEntryVariable(variable));
199*35238bceSAndroid Build Coastguard Worker     return pos != m_entries.end() ? *pos : DE_NULL;
200*35238bceSAndroid Build Coastguard Worker }
201*35238bceSAndroid Build Coastguard Worker 
setValue(const Variable * variable,ConstValueRangeAccess value)202*35238bceSAndroid Build Coastguard Worker void ValueScope::setValue(const Variable *variable, ConstValueRangeAccess value)
203*35238bceSAndroid Build Coastguard Worker {
204*35238bceSAndroid Build Coastguard Worker     ValueEntry *entry = findEntry(variable);
205*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(entry);
206*35238bceSAndroid Build Coastguard Worker 
207*35238bceSAndroid Build Coastguard Worker     ValueRangeAccess dst = entry->getValueRange();
208*35238bceSAndroid Build Coastguard Worker     dst.getMin()         = value.getMin().value();
209*35238bceSAndroid Build Coastguard Worker     dst.getMax()         = value.getMax().value();
210*35238bceSAndroid Build Coastguard Worker }
211*35238bceSAndroid Build Coastguard Worker 
removeValue(const Variable * variable)212*35238bceSAndroid Build Coastguard Worker void ValueScope::removeValue(const Variable *variable)
213*35238bceSAndroid Build Coastguard Worker {
214*35238bceSAndroid Build Coastguard Worker     vector<ValueEntry *>::iterator pos = std::find(m_entries.begin(), m_entries.end(), CompareEntryVariable(variable));
215*35238bceSAndroid Build Coastguard Worker     if (pos != m_entries.end())
216*35238bceSAndroid Build Coastguard Worker     {
217*35238bceSAndroid Build Coastguard Worker         ValueEntry *entry = *pos;
218*35238bceSAndroid Build Coastguard Worker         m_entries.erase(pos);
219*35238bceSAndroid Build Coastguard Worker         delete entry;
220*35238bceSAndroid Build Coastguard Worker     }
221*35238bceSAndroid Build Coastguard Worker }
222*35238bceSAndroid Build Coastguard Worker 
VariableManager(NameAllocator & nameAllocator)223*35238bceSAndroid Build Coastguard Worker VariableManager::VariableManager(NameAllocator &nameAllocator)
224*35238bceSAndroid Build Coastguard Worker     : m_numAllocatedScalars(0)
225*35238bceSAndroid Build Coastguard Worker     , m_numAllocatedShaderInScalars(0)
226*35238bceSAndroid Build Coastguard Worker     , m_numAllocatedShaderInVariables(0)
227*35238bceSAndroid Build Coastguard Worker     , m_numAllocatedUniformScalars(0)
228*35238bceSAndroid Build Coastguard Worker     , m_nameAllocator(nameAllocator)
229*35238bceSAndroid Build Coastguard Worker {
230*35238bceSAndroid Build Coastguard Worker }
231*35238bceSAndroid Build Coastguard Worker 
~VariableManager(void)232*35238bceSAndroid Build Coastguard Worker VariableManager::~VariableManager(void)
233*35238bceSAndroid Build Coastguard Worker {
234*35238bceSAndroid Build Coastguard Worker }
235*35238bceSAndroid Build Coastguard Worker 
allocate(const VariableType & type)236*35238bceSAndroid Build Coastguard Worker Variable *VariableManager::allocate(const VariableType &type)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker     return allocate(type, Variable::STORAGE_LOCAL, m_nameAllocator.allocate().c_str());
239*35238bceSAndroid Build Coastguard Worker }
240*35238bceSAndroid Build Coastguard Worker 
allocate(const VariableType & type,Variable::Storage storage,const char * name)241*35238bceSAndroid Build Coastguard Worker Variable *VariableManager::allocate(const VariableType &type, Variable::Storage storage, const char *name)
242*35238bceSAndroid Build Coastguard Worker {
243*35238bceSAndroid Build Coastguard Worker     VariableScope &varScope = getCurVariableScope();
244*35238bceSAndroid Build Coastguard Worker     ValueScope &valueScope  = getCurValueScope();
245*35238bceSAndroid Build Coastguard Worker     int numScalars          = type.getScalarSize();
246*35238bceSAndroid Build Coastguard Worker 
247*35238bceSAndroid Build Coastguard Worker     // Allocate in current scope
248*35238bceSAndroid Build Coastguard Worker     Variable *variable = varScope.allocate(type, Variable::STORAGE_LOCAL, name);
249*35238bceSAndroid Build Coastguard Worker 
250*35238bceSAndroid Build Coastguard Worker     // Allocate value entry
251*35238bceSAndroid Build Coastguard Worker     ValueEntry *valueEntry = valueScope.allocate(variable);
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     // Add to cache
254*35238bceSAndroid Build Coastguard Worker     m_entryCache.push_back(valueEntry);
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker     m_numAllocatedScalars += numScalars;
257*35238bceSAndroid Build Coastguard Worker 
258*35238bceSAndroid Build Coastguard Worker     // Set actual storage - affects uniform/shader in allocations.
259*35238bceSAndroid Build Coastguard Worker     setStorage(variable, storage);
260*35238bceSAndroid Build Coastguard Worker 
261*35238bceSAndroid Build Coastguard Worker     return variable;
262*35238bceSAndroid Build Coastguard Worker }
263*35238bceSAndroid Build Coastguard Worker 
setStorage(Variable * variable,Variable::Storage storage)264*35238bceSAndroid Build Coastguard Worker void VariableManager::setStorage(Variable *variable, Variable::Storage storage)
265*35238bceSAndroid Build Coastguard Worker {
266*35238bceSAndroid Build Coastguard Worker     int numScalars = variable->getType().getScalarSize();
267*35238bceSAndroid Build Coastguard Worker 
268*35238bceSAndroid Build Coastguard Worker     // Decrement old.
269*35238bceSAndroid Build Coastguard Worker     if (variable->getStorage() == Variable::STORAGE_SHADER_IN)
270*35238bceSAndroid Build Coastguard Worker     {
271*35238bceSAndroid Build Coastguard Worker         m_numAllocatedShaderInScalars -= numScalars;
272*35238bceSAndroid Build Coastguard Worker         m_numAllocatedShaderInVariables -= 1;
273*35238bceSAndroid Build Coastguard Worker     }
274*35238bceSAndroid Build Coastguard Worker     else if (variable->getStorage() == Variable::STORAGE_UNIFORM)
275*35238bceSAndroid Build Coastguard Worker         m_numAllocatedUniformScalars -= numScalars;
276*35238bceSAndroid Build Coastguard Worker 
277*35238bceSAndroid Build Coastguard Worker     // Add new.
278*35238bceSAndroid Build Coastguard Worker     if (storage == Variable::STORAGE_SHADER_IN)
279*35238bceSAndroid Build Coastguard Worker     {
280*35238bceSAndroid Build Coastguard Worker         m_numAllocatedShaderInScalars += numScalars;
281*35238bceSAndroid Build Coastguard Worker         m_numAllocatedShaderInVariables += 1;
282*35238bceSAndroid Build Coastguard Worker     }
283*35238bceSAndroid Build Coastguard Worker     else if (storage == Variable::STORAGE_UNIFORM)
284*35238bceSAndroid Build Coastguard Worker         m_numAllocatedUniformScalars += numScalars;
285*35238bceSAndroid Build Coastguard Worker 
286*35238bceSAndroid Build Coastguard Worker     variable->setStorage(storage);
287*35238bceSAndroid Build Coastguard Worker }
288*35238bceSAndroid Build Coastguard Worker 
canDeclareInCurrentScope(const Variable * variable) const289*35238bceSAndroid Build Coastguard Worker bool VariableManager::canDeclareInCurrentScope(const Variable *variable) const
290*35238bceSAndroid Build Coastguard Worker {
291*35238bceSAndroid Build Coastguard Worker     const vector<Variable *> &curLiveVars = getCurVariableScope().getLiveVariables();
292*35238bceSAndroid Build Coastguard Worker     return std::find(curLiveVars.begin(), curLiveVars.end(), variable) != curLiveVars.end();
293*35238bceSAndroid Build Coastguard Worker }
294*35238bceSAndroid Build Coastguard Worker 
getLiveVariables(void) const295*35238bceSAndroid Build Coastguard Worker const vector<Variable *> &VariableManager::getLiveVariables(void) const
296*35238bceSAndroid Build Coastguard Worker {
297*35238bceSAndroid Build Coastguard Worker     return getCurVariableScope().getLiveVariables();
298*35238bceSAndroid Build Coastguard Worker }
299*35238bceSAndroid Build Coastguard Worker 
declareVariable(Variable * variable)300*35238bceSAndroid Build Coastguard Worker void VariableManager::declareVariable(Variable *variable)
301*35238bceSAndroid Build Coastguard Worker {
302*35238bceSAndroid Build Coastguard Worker     // Remove from cache if exists in there.
303*35238bceSAndroid Build Coastguard Worker     std::vector<const ValueEntry *>::iterator pos =
304*35238bceSAndroid Build Coastguard Worker         std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
305*35238bceSAndroid Build Coastguard Worker     if (pos != m_entryCache.end())
306*35238bceSAndroid Build Coastguard Worker         m_entryCache.erase(pos);
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable)) ==
309*35238bceSAndroid Build Coastguard Worker               m_entryCache.end());
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker     // Remove from scope stack.
312*35238bceSAndroid Build Coastguard Worker     for (vector<ValueScope *>::const_iterator stackIter = m_valueScopeStack.begin();
313*35238bceSAndroid Build Coastguard Worker          stackIter != m_valueScopeStack.end(); stackIter++)
314*35238bceSAndroid Build Coastguard Worker     {
315*35238bceSAndroid Build Coastguard Worker         ValueScope *scope = *stackIter;
316*35238bceSAndroid Build Coastguard Worker         scope->removeValue(variable);
317*35238bceSAndroid Build Coastguard Worker     }
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker     // Declare in current scope.
320*35238bceSAndroid Build Coastguard Worker     getCurVariableScope().declare(variable);
321*35238bceSAndroid Build Coastguard Worker }
322*35238bceSAndroid Build Coastguard Worker 
getValue(const Variable * variable) const323*35238bceSAndroid Build Coastguard Worker const ValueEntry *VariableManager::getValue(const Variable *variable) const
324*35238bceSAndroid Build Coastguard Worker {
325*35238bceSAndroid Build Coastguard Worker     vector<const ValueEntry *>::const_iterator pos =
326*35238bceSAndroid Build Coastguard Worker         std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
327*35238bceSAndroid Build Coastguard Worker     return pos != m_entryCache.end() ? *pos : DE_NULL;
328*35238bceSAndroid Build Coastguard Worker }
329*35238bceSAndroid Build Coastguard Worker 
removeValueFromCurrentScope(const Variable * variable)330*35238bceSAndroid Build Coastguard Worker void VariableManager::removeValueFromCurrentScope(const Variable *variable)
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker     // Remove from cache
333*35238bceSAndroid Build Coastguard Worker     std::vector<const ValueEntry *>::iterator pos =
334*35238bceSAndroid Build Coastguard Worker         std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
335*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(pos != m_entryCache.end());
336*35238bceSAndroid Build Coastguard Worker     m_entryCache.erase(pos);
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker     // Remove from current scope \note May not exist in there.
339*35238bceSAndroid Build Coastguard Worker     getCurValueScope().removeValue(variable);
340*35238bceSAndroid Build Coastguard Worker }
341*35238bceSAndroid Build Coastguard Worker 
getParentValue(const Variable * variable) const342*35238bceSAndroid Build Coastguard Worker const ValueEntry *VariableManager::getParentValue(const Variable *variable) const
343*35238bceSAndroid Build Coastguard Worker {
344*35238bceSAndroid Build Coastguard Worker     if (m_valueScopeStack.size() < 2)
345*35238bceSAndroid Build Coastguard Worker         return DE_NULL; // Only single value scope
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker     for (vector<ValueScope *>::const_reverse_iterator i = m_valueScopeStack.rbegin() + 1; i != m_valueScopeStack.rend();
348*35238bceSAndroid Build Coastguard Worker          i++)
349*35238bceSAndroid Build Coastguard Worker     {
350*35238bceSAndroid Build Coastguard Worker         const ValueScope *scope = *i;
351*35238bceSAndroid Build Coastguard Worker         ValueEntry *entry       = scope->findEntry(variable);
352*35238bceSAndroid Build Coastguard Worker 
353*35238bceSAndroid Build Coastguard Worker         if (entry)
354*35238bceSAndroid Build Coastguard Worker             return entry;
355*35238bceSAndroid Build Coastguard Worker     }
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker     return DE_NULL; // Not found in stack
358*35238bceSAndroid Build Coastguard Worker }
359*35238bceSAndroid Build Coastguard Worker 
setValue(const Variable * variable,ConstValueRangeAccess value)360*35238bceSAndroid Build Coastguard Worker void VariableManager::setValue(const Variable *variable, ConstValueRangeAccess value)
361*35238bceSAndroid Build Coastguard Worker {
362*35238bceSAndroid Build Coastguard Worker     ValueScope &curScope = getCurValueScope();
363*35238bceSAndroid Build Coastguard Worker 
364*35238bceSAndroid Build Coastguard Worker     if (!curScope.findEntry(variable))
365*35238bceSAndroid Build Coastguard Worker     {
366*35238bceSAndroid Build Coastguard Worker         // New value, allocate and update cache.
367*35238bceSAndroid Build Coastguard Worker         ValueEntry *newEntry = curScope.allocate(variable);
368*35238bceSAndroid Build Coastguard Worker         std::vector<const ValueEntry *>::iterator cachePos =
369*35238bceSAndroid Build Coastguard Worker             std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker         if (cachePos != m_entryCache.end())
372*35238bceSAndroid Build Coastguard Worker             *cachePos = newEntry;
373*35238bceSAndroid Build Coastguard Worker         else
374*35238bceSAndroid Build Coastguard Worker             m_entryCache.push_back(newEntry);
375*35238bceSAndroid Build Coastguard Worker     }
376*35238bceSAndroid Build Coastguard Worker 
377*35238bceSAndroid Build Coastguard Worker     curScope.setValue(variable, value);
378*35238bceSAndroid Build Coastguard Worker }
379*35238bceSAndroid Build Coastguard Worker 
reserve(ReservedScalars & store,int numScalars)380*35238bceSAndroid Build Coastguard Worker void VariableManager::reserve(ReservedScalars &store, int numScalars)
381*35238bceSAndroid Build Coastguard Worker {
382*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(store.numScalars == 0);
383*35238bceSAndroid Build Coastguard Worker     store.numScalars = numScalars;
384*35238bceSAndroid Build Coastguard Worker     m_numAllocatedScalars += numScalars;
385*35238bceSAndroid Build Coastguard Worker }
386*35238bceSAndroid Build Coastguard Worker 
release(ReservedScalars & store)387*35238bceSAndroid Build Coastguard Worker void VariableManager::release(ReservedScalars &store)
388*35238bceSAndroid Build Coastguard Worker {
389*35238bceSAndroid Build Coastguard Worker     m_numAllocatedScalars -= store.numScalars;
390*35238bceSAndroid Build Coastguard Worker     store.numScalars = 0;
391*35238bceSAndroid Build Coastguard Worker }
392*35238bceSAndroid Build Coastguard Worker 
pushVariableScope(VariableScope & scope)393*35238bceSAndroid Build Coastguard Worker void VariableManager::pushVariableScope(VariableScope &scope)
394*35238bceSAndroid Build Coastguard Worker {
395*35238bceSAndroid Build Coastguard Worker     // Expects emtpy scope
396*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(scope.getDeclaredVariables().size() == 0);
397*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(scope.getLiveVariables().size() == 0);
398*35238bceSAndroid Build Coastguard Worker 
399*35238bceSAndroid Build Coastguard Worker     m_variableScopeStack.push_back(&scope);
400*35238bceSAndroid Build Coastguard Worker }
401*35238bceSAndroid Build Coastguard Worker 
popVariableScope(void)402*35238bceSAndroid Build Coastguard Worker void VariableManager::popVariableScope(void)
403*35238bceSAndroid Build Coastguard Worker {
404*35238bceSAndroid Build Coastguard Worker     VariableScope &curScope = getCurVariableScope();
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker     // Migrate live variables to parent scope.
407*35238bceSAndroid Build Coastguard Worker     // Variables allocated in child scopes can be declared in any parent scope but not the other way around.
408*35238bceSAndroid Build Coastguard Worker     if (m_variableScopeStack.size() > 1)
409*35238bceSAndroid Build Coastguard Worker     {
410*35238bceSAndroid Build Coastguard Worker         VariableScope &parentScope        = *m_variableScopeStack[m_variableScopeStack.size() - 2];
411*35238bceSAndroid Build Coastguard Worker         vector<Variable *> &curLiveVars   = curScope.getLiveVariables();
412*35238bceSAndroid Build Coastguard Worker         vector<Variable *> &parenLiveVars = parentScope.getLiveVariables();
413*35238bceSAndroid Build Coastguard Worker 
414*35238bceSAndroid Build Coastguard Worker         while (!curLiveVars.empty())
415*35238bceSAndroid Build Coastguard Worker         {
416*35238bceSAndroid Build Coastguard Worker             Variable *liveVar = curLiveVars.back();
417*35238bceSAndroid Build Coastguard Worker             parenLiveVars.push_back(liveVar);
418*35238bceSAndroid Build Coastguard Worker             curLiveVars.pop_back();
419*35238bceSAndroid Build Coastguard Worker         }
420*35238bceSAndroid Build Coastguard Worker     }
421*35238bceSAndroid Build Coastguard Worker 
422*35238bceSAndroid Build Coastguard Worker     // All variables should be either migrated to parent or declared (in case of root scope).
423*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(curScope.getLiveVariables().size() == 0);
424*35238bceSAndroid Build Coastguard Worker 
425*35238bceSAndroid Build Coastguard Worker     m_variableScopeStack.pop_back();
426*35238bceSAndroid Build Coastguard Worker }
427*35238bceSAndroid Build Coastguard Worker 
pushValueScope(ValueScope & scope)428*35238bceSAndroid Build Coastguard Worker void VariableManager::pushValueScope(ValueScope &scope)
429*35238bceSAndroid Build Coastguard Worker {
430*35238bceSAndroid Build Coastguard Worker     // Value scope should be empty
431*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(scope.getValues().size() == 0);
432*35238bceSAndroid Build Coastguard Worker 
433*35238bceSAndroid Build Coastguard Worker     m_valueScopeStack.push_back(&scope);
434*35238bceSAndroid Build Coastguard Worker }
435*35238bceSAndroid Build Coastguard Worker 
popValueScope(void)436*35238bceSAndroid Build Coastguard Worker void VariableManager::popValueScope(void)
437*35238bceSAndroid Build Coastguard Worker {
438*35238bceSAndroid Build Coastguard Worker     ValueScope &oldScope = getCurValueScope();
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker     // Pop scope and clear cache.
441*35238bceSAndroid Build Coastguard Worker     m_valueScopeStack.pop_back();
442*35238bceSAndroid Build Coastguard Worker     m_entryCache.clear();
443*35238bceSAndroid Build Coastguard Worker 
444*35238bceSAndroid Build Coastguard Worker     // Re-build entry cache.
445*35238bceSAndroid Build Coastguard Worker     if (!m_valueScopeStack.empty())
446*35238bceSAndroid Build Coastguard Worker     {
447*35238bceSAndroid Build Coastguard Worker         ValueScope &newTopScope = getCurValueScope();
448*35238bceSAndroid Build Coastguard Worker 
449*35238bceSAndroid Build Coastguard Worker         // Speed up computing intersections.
450*35238bceSAndroid Build Coastguard Worker         map<const Variable *, const ValueEntry *> oldValues;
451*35238bceSAndroid Build Coastguard Worker         const vector<ValueEntry *> &oldEntries = oldScope.getValues();
452*35238bceSAndroid Build Coastguard Worker 
453*35238bceSAndroid Build Coastguard Worker         for (vector<ValueEntry *>::const_iterator valueIter = oldEntries.begin(); valueIter != oldEntries.end();
454*35238bceSAndroid Build Coastguard Worker              valueIter++)
455*35238bceSAndroid Build Coastguard Worker             oldValues[(*valueIter)->getVariable()] = *valueIter;
456*35238bceSAndroid Build Coastguard Worker 
457*35238bceSAndroid Build Coastguard Worker         set<const Variable *> addedVars;
458*35238bceSAndroid Build Coastguard Worker 
459*35238bceSAndroid Build Coastguard Worker         // Re-build based on current stack.
460*35238bceSAndroid Build Coastguard Worker         for (vector<ValueScope *>::reverse_iterator scopeIter = m_valueScopeStack.rbegin();
461*35238bceSAndroid Build Coastguard Worker              scopeIter != m_valueScopeStack.rend(); scopeIter++)
462*35238bceSAndroid Build Coastguard Worker         {
463*35238bceSAndroid Build Coastguard Worker             const ValueScope *scope                  = *scopeIter;
464*35238bceSAndroid Build Coastguard Worker             const vector<ValueEntry *> &valueEntries = scope->getValues();
465*35238bceSAndroid Build Coastguard Worker 
466*35238bceSAndroid Build Coastguard Worker             for (vector<ValueEntry *>::const_iterator valueIter = valueEntries.begin(); valueIter != valueEntries.end();
467*35238bceSAndroid Build Coastguard Worker                  valueIter++)
468*35238bceSAndroid Build Coastguard Worker             {
469*35238bceSAndroid Build Coastguard Worker                 const ValueEntry *entry = *valueIter;
470*35238bceSAndroid Build Coastguard Worker                 const Variable *var     = entry->getVariable();
471*35238bceSAndroid Build Coastguard Worker 
472*35238bceSAndroid Build Coastguard Worker                 if (addedVars.find(var) != addedVars.end())
473*35238bceSAndroid Build Coastguard Worker                     continue; // Already in cache, set deeper in scope stack.
474*35238bceSAndroid Build Coastguard Worker 
475*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(var)) ==
476*35238bceSAndroid Build Coastguard Worker                           m_entryCache.end());
477*35238bceSAndroid Build Coastguard Worker 
478*35238bceSAndroid Build Coastguard Worker                 if (oldValues.find(var) != oldValues.end())
479*35238bceSAndroid Build Coastguard Worker                 {
480*35238bceSAndroid Build Coastguard Worker                     const ValueEntry *oldEntry = oldValues[var];
481*35238bceSAndroid Build Coastguard Worker 
482*35238bceSAndroid Build Coastguard Worker                     // Build new intersected value and store into current scope.
483*35238bceSAndroid Build Coastguard Worker                     ValueRange intersectedValue(var->getType());
484*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(oldEntry->getValueRange().intersects(entry->getValueRange())); // Must intersect
485*35238bceSAndroid Build Coastguard Worker                     ValueRange::computeIntersection(intersectedValue, entry->getValueRange(),
486*35238bceSAndroid Build Coastguard Worker                                                     oldEntry->getValueRange());
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker                     if (!newTopScope.findEntry(var))
489*35238bceSAndroid Build Coastguard Worker                         newTopScope.allocate(var);
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker                     newTopScope.setValue(var, intersectedValue.asAccess());
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker                     // Add entry from top scope to cache.
494*35238bceSAndroid Build Coastguard Worker                     m_entryCache.push_back(newTopScope.findEntry(var));
495*35238bceSAndroid Build Coastguard Worker                 }
496*35238bceSAndroid Build Coastguard Worker                 else
497*35238bceSAndroid Build Coastguard Worker                     m_entryCache.push_back(entry); // Just add to cache.
498*35238bceSAndroid Build Coastguard Worker 
499*35238bceSAndroid Build Coastguard Worker                 addedVars.insert(var); // Record as cached variable.
500*35238bceSAndroid Build Coastguard Worker             }
501*35238bceSAndroid Build Coastguard Worker         }
502*35238bceSAndroid Build Coastguard Worker 
503*35238bceSAndroid Build Coastguard Worker         // Copy entries from popped scope that don't yet exist in the stack.
504*35238bceSAndroid Build Coastguard Worker         for (vector<ValueEntry *>::const_iterator valueIter = oldEntries.begin(); valueIter != oldEntries.end();
505*35238bceSAndroid Build Coastguard Worker              valueIter++)
506*35238bceSAndroid Build Coastguard Worker         {
507*35238bceSAndroid Build Coastguard Worker             const ValueEntry *oldEntry = *valueIter;
508*35238bceSAndroid Build Coastguard Worker             const Variable *var        = oldEntry->getVariable();
509*35238bceSAndroid Build Coastguard Worker 
510*35238bceSAndroid Build Coastguard Worker             if (addedVars.find(var) == addedVars.end())
511*35238bceSAndroid Build Coastguard Worker                 setValue(var, oldEntry->getValueRange());
512*35238bceSAndroid Build Coastguard Worker         }
513*35238bceSAndroid Build Coastguard Worker     }
514*35238bceSAndroid Build Coastguard Worker }
515*35238bceSAndroid Build Coastguard Worker 
516*35238bceSAndroid Build Coastguard Worker } // namespace rsg
517