13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Random Shader Generator
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Variable manager.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgVariableManager.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set;
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rsg
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SubValueRangeIterator
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									SubValueRangeIterator			(const ConstValueRangeAccess& valueRange);
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~SubValueRangeIterator			(void) {}
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool							hasItem							(void) const;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstValueRangeAccess			getItem							(void) const;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							next							(void);
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ConstValueRangeAccess>	m_stack;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySubValueRangeIterator::SubValueRangeIterator (const ConstValueRangeAccess& valueRange)
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_stack.push_back(valueRange);
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool SubValueRangeIterator::hasItem (void) const
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return !m_stack.empty();
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline ConstValueRangeAccess SubValueRangeIterator::getItem (void) const
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_stack[m_stack.size()-1];
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SubValueRangeIterator::next (void)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstValueRangeAccess curItem = getItem();
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_stack.pop_back(); // Remove current
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (curItem.getType().getBaseType())
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_ARRAY:
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int numElements = curItem.getType().getNumElements();
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < numElements; ndx++)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_stack.push_back(curItem.member(ndx));
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_STRUCT:
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int numMembers = (int)curItem.getType().getMembers().size();
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < numMembers; ndx++)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_stack.push_back(curItem.member(ndx));
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // \todo [2011-02-03 pyry] Swizzle control?
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryValueEntry::ValueEntry (const Variable* variable)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_variable	(variable)
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_valueRange	(variable->getType())
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableScope::VariableScope (void)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableScope::~VariableScope (void)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Variable*>::iterator i = m_declaredVariables.begin(); i != m_declaredVariables.end(); i++)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Variable*>::iterator i = m_liveVariables.begin(); i != m_liveVariables.end(); i++)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariable* VariableScope::allocate (const VariableType& type, Variable::Storage storage, const char* name)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Variable* variable = new Variable(type, storage, name);
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_liveVariables.push_back(variable);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return variable;
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete variable;
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableScope::declare (Variable* variable)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_declaredVariables.push_back(variable);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	removeLive(variable);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableScope::removeLive (const Variable* variable)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Variable*>::iterator pos = std::find(m_liveVariables.begin(), m_liveVariables.end(), variable);
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(pos != m_liveVariables.end());
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [pyry] Not so efficient
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_liveVariables.erase(pos);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko PoyryValueScope::ValueScope (void)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryValueScope::~ValueScope (void)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clear();
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ValueScope::clear (void)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<ValueEntry*>::iterator i = m_entries.begin(); i != m_entries.end(); i++)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_entries.clear();
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryValueEntry* ValueScope::allocate (const Variable* variable)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueEntry* entry = new ValueEntry(variable);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_entries.push_back(entry);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return entry;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete entry;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CompareEntryVariable
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CompareEntryVariable (const Variable* variable)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_variable(variable)
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator== (const ValueEntry* entry) const
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return entry->getVariable() == m_variable;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Variable* m_variable;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool operator== (const ValueEntry* entry, const CompareEntryVariable& cmp)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return cmp == entry;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryValueEntry* ValueScope::findEntry (const Variable* variable) const
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ValueEntry*>::const_iterator pos = std::find(m_entries.begin(), m_entries.end(), CompareEntryVariable(variable));
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return pos != m_entries.end() ? *pos : DE_NULL;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ValueScope::setValue (const Variable* variable, ConstValueRangeAccess value)
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueEntry* entry = findEntry(variable);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(entry);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueRangeAccess dst = entry->getValueRange();
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst.getMin() = value.getMin().value();
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst.getMax() = value.getMax().value();
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ValueScope::removeValue (const Variable* variable)
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ValueEntry*>::iterator pos = std::find(m_entries.begin(), m_entries.end(), CompareEntryVariable(variable));
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (pos != m_entries.end())
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueEntry* entry = *pos;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_entries.erase(pos);
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete entry;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableManager::VariableManager (NameAllocator& nameAllocator)
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numAllocatedScalars				(0)
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numAllocatedShaderInScalars		(0)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numAllocatedShaderInVariables	(0)
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numAllocatedUniformScalars		(0)
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_nameAllocator					(nameAllocator)
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableManager::~VariableManager (void)
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariable* VariableManager::allocate (const VariableType& type)
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return allocate(type, Variable::STORAGE_LOCAL, m_nameAllocator.allocate().c_str());
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariable* VariableManager::allocate (const VariableType& type, Variable::Storage storage, const char* name)
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VariableScope&	varScope	= getCurVariableScope();
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueScope&		valueScope	= getCurValueScope();
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numScalars	= type.getScalarSize();
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Allocate in current scope
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Variable* variable = varScope.allocate(type, Variable::STORAGE_LOCAL, name);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Allocate value entry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueEntry* valueEntry = valueScope.allocate(variable);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Add to cache
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_entryCache.push_back(valueEntry);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numAllocatedScalars += numScalars;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set actual storage - affects uniform/shader in allocations.
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setStorage(variable, storage);
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return variable;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::setStorage (Variable* variable, Variable::Storage storage)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numScalars = variable->getType().getScalarSize();
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Decrement old.
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (variable->getStorage() == Variable::STORAGE_SHADER_IN)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_numAllocatedShaderInScalars	-= numScalars;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_numAllocatedShaderInVariables	-= 1;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (variable->getStorage() == Variable::STORAGE_UNIFORM)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_numAllocatedUniformScalars -= numScalars;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Add new.
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (storage == Variable::STORAGE_SHADER_IN)
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_numAllocatedShaderInScalars	+= numScalars;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_numAllocatedShaderInVariables	+= 1;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (storage == Variable::STORAGE_UNIFORM)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_numAllocatedUniformScalars += numScalars;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	variable->setStorage(storage);
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool VariableManager::canDeclareInCurrentScope (const Variable* variable) const
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<Variable*>& curLiveVars = getCurVariableScope().getLiveVariables();
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::find(curLiveVars.begin(), curLiveVars.end(), variable) != curLiveVars.end();
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst vector<Variable*>& VariableManager::getLiveVariables (void) const
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getCurVariableScope().getLiveVariables();
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::declareVariable (Variable* variable)
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove from cache if exists in there.
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<const ValueEntry*>::iterator pos = std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (pos != m_entryCache.end())
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_entryCache.erase(pos);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable)) == m_entryCache.end());
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove from scope stack.
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<ValueScope*>::const_iterator stackIter = m_valueScopeStack.begin(); stackIter != m_valueScopeStack.end(); stackIter++)
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueScope* scope = *stackIter;
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		scope->removeValue(variable);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Declare in current scope.
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCurVariableScope().declare(variable);
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst ValueEntry* VariableManager::getValue (const Variable* variable) const
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<const ValueEntry*>::const_iterator pos = std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return pos != m_entryCache.end() ? *pos : DE_NULL;
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::removeValueFromCurrentScope (const Variable* variable)
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove from cache
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<const ValueEntry*>::iterator pos = std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(pos != m_entryCache.end());
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_entryCache.erase(pos);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove from current scope \note May not exist in there.
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCurValueScope().removeValue(variable);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst ValueEntry* VariableManager::getParentValue (const Variable* variable) const
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_valueScopeStack.size() < 2)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL; // Only single value scope
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<ValueScope*>::const_reverse_iterator i = m_valueScopeStack.rbegin()+1; i != m_valueScopeStack.rend(); i++)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ValueScope*	scope	= *i;
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueEntry*			entry	= scope->findEntry(variable);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (entry)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return entry;
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_NULL; // Not found in stack
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::setValue (const Variable* variable, ConstValueRangeAccess value)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueScope& curScope = getCurValueScope();
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!curScope.findEntry(variable))
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// New value, allocate and update cache.
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueEntry*									newEntry	= curScope.allocate(variable);
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<const ValueEntry*>::iterator	cachePos	= std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (cachePos != m_entryCache.end())
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*cachePos = newEntry;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_entryCache.push_back(newEntry);
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	curScope.setValue(variable, value);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::reserve (ReservedScalars& store, int numScalars)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(store.numScalars == 0);
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	store.numScalars		 = numScalars;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numAllocatedScalars	+= numScalars;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::release (ReservedScalars& store)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numAllocatedScalars	-= store.numScalars;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	store.numScalars		 = 0;
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::pushVariableScope (VariableScope& scope)
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Expects emtpy scope
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(scope.getDeclaredVariables().size() == 0);
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(scope.getLiveVariables().size() == 0);
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_variableScopeStack.push_back(&scope);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::popVariableScope (void)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VariableScope& curScope = getCurVariableScope();
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Migrate live variables to parent scope.
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Variables allocated in child scopes can be declared in any parent scope but not the other way around.
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_variableScopeStack.size() > 1)
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VariableScope&		parentScope		= *m_variableScopeStack[m_variableScopeStack.size()-2];
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<Variable*>&	curLiveVars		= curScope.getLiveVariables();
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<Variable*>&	parenLiveVars	= parentScope.getLiveVariables();
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (!curLiveVars.empty())
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Variable* liveVar = curLiveVars.back();
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			parenLiveVars.push_back(liveVar);
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			curLiveVars.pop_back();
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// All variables should be either migrated to parent or declared (in case of root scope).
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(curScope.getLiveVariables().size() == 0);
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_variableScopeStack.pop_back();
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::pushValueScope (ValueScope& scope)
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Value scope should be empty
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(scope.getValues().size() == 0);
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_valueScopeStack.push_back(&scope);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableManager::popValueScope (void)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueScope& oldScope = getCurValueScope();
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Pop scope and clear cache.
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_valueScopeStack.pop_back();
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_entryCache.clear();
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Re-build entry cache.
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_valueScopeStack.empty())
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueScope& newTopScope = getCurValueScope();
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Speed up computing intersections.
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		map<const Variable*, const ValueEntry*>	oldValues;
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<ValueEntry*>&				oldEntries = oldScope.getValues();
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<ValueEntry*>::const_iterator valueIter = oldEntries.begin(); valueIter != oldEntries.end(); valueIter++)
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			oldValues[(*valueIter)->getVariable()] = *valueIter;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		set<const Variable*> addedVars;
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Re-build based on current stack.
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<ValueScope*>::reverse_iterator scopeIter = m_valueScopeStack.rbegin(); scopeIter != m_valueScopeStack.rend(); scopeIter++)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ValueScope*			scope			= *scopeIter;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<ValueEntry*>&	valueEntries	= scope->getValues();
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<ValueEntry*>::const_iterator valueIter = valueEntries.begin(); valueIter != valueEntries.end(); valueIter++)
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const ValueEntry*	entry	= *valueIter;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Variable*		var		= entry->getVariable();
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (addedVars.find(var) != addedVars.end())
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue; // Already in cache, set deeper in scope stack.
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(var)) == m_entryCache.end());
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (oldValues.find(var) != oldValues.end())
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const ValueEntry* oldEntry = oldValues[var];
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Build new intersected value and store into current scope.
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ValueRange intersectedValue(var->getType());
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(oldEntry->getValueRange().intersects(entry->getValueRange())); // Must intersect
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ValueRange::computeIntersection(intersectedValue, entry->getValueRange(), oldEntry->getValueRange());
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!newTopScope.findEntry(var))
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						newTopScope.allocate(var);
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					newTopScope.setValue(var, intersectedValue);
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Add entry from top scope to cache.
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_entryCache.push_back(newTopScope.findEntry(var));
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_entryCache.push_back(entry); // Just add to cache.
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				addedVars.insert(var); // Record as cached variable.
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy entries from popped scope that don't yet exist in the stack.
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<ValueEntry*>::const_iterator valueIter = oldEntries.begin(); valueIter != oldEntries.end(); valueIter++)
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ValueEntry*	oldEntry	= *valueIter;
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Variable*		var			= oldEntry->getVariable();
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (addedVars.find(var) == addedVars.end())
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				setValue(var, oldEntry->getValueRange());
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rsg
505