/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Optimized vs unoptimized shader performance tests.
 *//*--------------------------------------------------------------------*/

#include "es3pShaderOptimizationTests.hpp"
#include "glsShaderPerformanceMeasurer.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuStringTemplate.hpp"
#include "deSharedPtr.hpp"
#include "deStringUtil.hpp"
#include "deMath.h"

#include "glwFunctions.hpp"

#include <vector>
#include <string>
#include <map>

using glu::ShaderProgram;
using tcu::TestLog;
using tcu::Vec4;
using de::SharedPtr;
using de::toString;

using std::vector;
using std::string;

namespace deqp
{

using gls::ShaderPerformanceMeasurer;

namespace gles3
{
namespace Performance
{

static inline std::map<string, string> singleMap (const string& key, const string& value)
{
	std::map<string, string> res;
	res[key] = value;
	return res;
}

static inline string repeat (const string& str, int numRepeats, const string& delim = "")
{
	string result = str;
	for (int i = 1; i < numRepeats; i++)
		result += delim + str;
	return result;
}

static inline string repeatIndexedTemplate (const string& strTempl, int numRepeats, const string& delim = "", int ndxStart = 0)
{
	const tcu::StringTemplate	templ(strTempl);
	string						result;
	std::map<string, string>	params;

	for (int i = 0; i < numRepeats; i++)
	{
		params["PREV_NDX"]	= toString(i + ndxStart - 1);
		params["NDX"]		= toString(i + ndxStart);

		result += (i > 0 ? delim : "") + templ.specialize(params);
	}

	return result;
}

namespace
{

enum CaseShaderType
{
	CASESHADERTYPE_VERTEX = 0,
	CASESHADERTYPE_FRAGMENT,

	CASESHADERTYPE_LAST
};

static inline string getShaderPrecision (CaseShaderType shaderType)
{
	switch (shaderType)
	{
		case CASESHADERTYPE_VERTEX:		return "highp";
		case CASESHADERTYPE_FRAGMENT:	return "highp";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

struct ProgramData
{
	glu::ProgramSources			sources;
	vector<gls::AttribSpec>		attributes; //!< \note Shouldn't contain a_position; that one is set by gls::ShaderPerformanceMeasurer.

	ProgramData (void) {}
	ProgramData (const glu::ProgramSources& sources_, const vector<gls::AttribSpec>& attributes_ = vector<gls::AttribSpec>())	: sources(sources_), attributes(attributes_)	{}
	ProgramData (const glu::ProgramSources& sources_, const gls::AttribSpec& attribute)											: sources(sources_), attributes(1, attribute)	{}
};

//! Shader boilerplate helper; most cases have similar basic shader structure.
static inline ProgramData defaultProgramData (CaseShaderType shaderType, const string& funcDefs, const string& mainStatements)
{
	const bool		isVertexCase	= shaderType == CASESHADERTYPE_VERTEX;
	const bool		isFragmentCase	= shaderType == CASESHADERTYPE_FRAGMENT;
	const string	vtxPrec			= getShaderPrecision(CASESHADERTYPE_VERTEX);
	const string	fragPrec		= getShaderPrecision(CASESHADERTYPE_FRAGMENT);

	return ProgramData(glu::ProgramSources() << glu::VertexSource(		"#version 300 es\n"
																		"in " + vtxPrec + " vec4 a_position;\n"
																		"in " + vtxPrec + " vec4 a_value;\n"
																		"out " + fragPrec + " vec4 v_value;\n"
																		+ (isVertexCase ? funcDefs : "") +
																		"void main (void)\n"
																		"{\n"
																		"	gl_Position = a_position;\n"
																		"	" + vtxPrec + " vec4 value = a_value;\n"
																		+ (isVertexCase ? mainStatements : "") +
																		"	v_value = value;\n"
																		"}\n")

											 << glu::FragmentSource(	"#version 300 es\n"
																		"layout (location = 0) out " + fragPrec + " vec4 o_color;\n"
																		"in " + fragPrec + " vec4 v_value;\n"
																		+ (isFragmentCase ? funcDefs : "") +
																		"void main (void)\n"
																		"{\n"
																		"	" + fragPrec + " vec4 value = v_value;\n"
																		+ (isFragmentCase ? mainStatements : "") +
																		"	o_color = value;\n"
																		"}\n"),
					  gls::AttribSpec("a_value",
									  Vec4(1.0f, 0.0f, 0.0f, 0.0f),
									  Vec4(0.0f, 1.0f, 0.0f, 0.0f),
									  Vec4(0.0f, 0.0f, 1.0f, 0.0f),
									  Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
}

static inline ProgramData defaultProgramData (CaseShaderType shaderType, const string& mainStatements)
{
	return defaultProgramData(shaderType, "", mainStatements);
}

class ShaderOptimizationCase : public TestCase
{
public:
	ShaderOptimizationCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType)
		: TestCase				(context, tcu::NODETYPE_PERFORMANCE, name, description)
		, m_caseShaderType		(caseShaderType)
		, m_state				(STATE_LAST)
		, m_measurer			(context.getRenderContext(), caseShaderType == CASESHADERTYPE_VERTEX	? gls::CASETYPE_VERTEX
														   : caseShaderType == CASESHADERTYPE_FRAGMENT	? gls::CASETYPE_FRAGMENT
														   : gls::CASETYPE_LAST)
		, m_unoptimizedResult	(-1.0f, -1.0f)
		, m_optimizedResult		(-1.0f, -1.0f)
	{
	}

	virtual ~ShaderOptimizationCase (void) {}

	void			init		(void);
	IterateResult	iterate		(void);

protected:
	virtual ProgramData		generateProgramData (bool optimized) const = 0;

	const CaseShaderType	m_caseShaderType;

private:
	enum State
	{
		STATE_INIT_UNOPTIMIZED = 0,
		STATE_MEASURE_UNOPTIMIZED,
		STATE_INIT_OPTIMIZED,
		STATE_MEASURE_OPTIMIZED,
		STATE_FINISHED,

		STATE_LAST
	};

	ProgramData&						programData		(bool optimized) { return optimized ? m_optimizedData		: m_unoptimizedData;		}
	SharedPtr<const ShaderProgram>&		program			(bool optimized) { return optimized ? m_optimizedProgram	: m_unoptimizedProgram;		}
	ShaderPerformanceMeasurer::Result&	result			(bool optimized) { return optimized ? m_optimizedResult		: m_unoptimizedResult;		}

	State								m_state;
	ShaderPerformanceMeasurer			m_measurer;

	ProgramData							m_unoptimizedData;
	ProgramData							m_optimizedData;
	SharedPtr<const ShaderProgram>		m_unoptimizedProgram;
	SharedPtr<const ShaderProgram>		m_optimizedProgram;
	ShaderPerformanceMeasurer::Result	m_unoptimizedResult;
	ShaderPerformanceMeasurer::Result	m_optimizedResult;
};

void ShaderOptimizationCase::init (void)
{
	const glu::RenderContext&	renderCtx	= m_context.getRenderContext();
	TestLog&					log			= m_testCtx.getLog();

	m_measurer.logParameters(log);

	for (int ndx = 0; ndx < 2; ndx++)
	{
		const bool optimized = ndx == 1;

		programData(optimized) = generateProgramData(optimized);

		for (int i = 0; i < (int)programData(optimized).attributes.size(); i++)
			DE_ASSERT(programData(optimized).attributes[i].name != "a_position"); // \note Position attribute is set by m_measurer.

		program(optimized) = SharedPtr<const ShaderProgram>(new ShaderProgram(renderCtx, programData(optimized).sources));

		{
			const tcu::ScopedLogSection section(log, optimized ? "OptimizedProgram"			: "UnoptimizedProgram",
													 optimized ? "Hand-optimized program"	: "Unoptimized program");
			log << *program(optimized);
		}

		if (!program(optimized)->isOk())
			TCU_FAIL("Shader compilation failed");
	}

	m_state = STATE_INIT_UNOPTIMIZED;
}

ShaderOptimizationCase::IterateResult ShaderOptimizationCase::iterate (void)
{
	TestLog& log = m_testCtx.getLog();

	if (m_state == STATE_INIT_UNOPTIMIZED || m_state == STATE_INIT_OPTIMIZED)
	{
		const bool optimized = m_state == STATE_INIT_OPTIMIZED;
		m_measurer.init(program(optimized)->getProgram(), programData(optimized).attributes, 1);
		m_state = optimized ? STATE_MEASURE_OPTIMIZED : STATE_MEASURE_UNOPTIMIZED;

		return CONTINUE;
	}
	else if (m_state == STATE_MEASURE_UNOPTIMIZED || m_state == STATE_MEASURE_OPTIMIZED)
	{
		m_measurer.iterate();

		if (m_measurer.isFinished())
		{
			const bool						optimized	= m_state == STATE_MEASURE_OPTIMIZED;
			const tcu::ScopedLogSection		section		(log, optimized ? "OptimizedResult"									: "UnoptimizedResult",
															  optimized ? "Measurement results for hand-optimized program"	: "Measurement result for unoptimized program");
			m_measurer.logMeasurementInfo(log);
			result(optimized) = m_measurer.getResult();
			m_measurer.deinit();
			m_state = optimized ? STATE_FINISHED : STATE_INIT_OPTIMIZED;
		}

		return CONTINUE;
	}
	else
	{
		DE_ASSERT(m_state == STATE_FINISHED);

		const float			unoptimizedRelevantResult	= m_caseShaderType == CASESHADERTYPE_VERTEX ? m_unoptimizedResult.megaVertPerSec	: m_unoptimizedResult.megaFragPerSec;
		const float			optimizedRelevantResult		= m_caseShaderType == CASESHADERTYPE_VERTEX ? m_optimizedResult.megaVertPerSec		: m_optimizedResult.megaFragPerSec;
		const char* const	relevantResultName			= m_caseShaderType == CASESHADERTYPE_VERTEX ? "vertex"								: "fragment";
		const float			ratio						= unoptimizedRelevantResult / optimizedRelevantResult;
		const int			handOptimizationGain		= (int)deFloatRound(100.0f/ratio) - 100;

		log << TestLog::Message << "Unoptimized / optimized " << relevantResultName << " performance ratio: " << ratio << TestLog::EndMessage;

		if (handOptimizationGain >= 0)
			log << TestLog::Message << "Note: " << handOptimizationGain << "% performance gain was achieved with hand-optimized version" << TestLog::EndMessage;
		else
			log << TestLog::Message << "Note: hand-optimization degraded performance by " << -handOptimizationGain << "%" << TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(ratio, 2).c_str());

		return STOP;
	}
}

class LoopUnrollCase : public ShaderOptimizationCase
{
public:
	enum CaseType
	{
		CASETYPE_INDEPENDENT = 0,
		CASETYPE_DEPENDENT,

		CASETYPE_LAST
	};

	LoopUnrollCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType, int numRepetitions)
		: ShaderOptimizationCase	(context, name, description, caseShaderType)
		, m_numRepetitions			(numRepetitions)
		, m_caseType				(caseType)
	{
	}

protected:
	ProgramData generateProgramData (bool optimized) const
	{
		const string repetition = optimized ? repeatIndexedTemplate("\t" + expressionTemplate(m_caseType) + ";\n", m_numRepetitions)
											: loop(m_numRepetitions, expressionTemplate(m_caseType));

		return defaultProgramData(m_caseShaderType, "\t" + getShaderPrecision(m_caseShaderType) + " vec4 valueOrig = value;\n" + repetition);
	}

private:
	const int		m_numRepetitions;
	const CaseType	m_caseType;

	static inline string expressionTemplate (CaseType caseType)
	{
		switch (caseType)
		{
			case CASETYPE_INDEPENDENT:	return "value += sin(float(${NDX}+1)*valueOrig)";
			case CASETYPE_DEPENDENT:	return "value = sin(value)";
			default:
				DE_ASSERT(false);
				return DE_NULL;
		}
	}

	static inline string loop (int iterations, const string& innerExpr)
	{
		return "\tfor (int i = 0; i < " + toString(iterations) + "; i++)\n\t\t" + tcu::StringTemplate(innerExpr).specialize(singleMap("NDX", "i")) + ";\n";
	}
};

class LoopInvariantCodeMotionCase : public ShaderOptimizationCase
{
public:
	LoopInvariantCodeMotionCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, int numLoopIterations)
		: ShaderOptimizationCase	(context, name, description, caseShaderType)
		, m_numLoopIterations		(numLoopIterations)
	{
	}

protected:
	ProgramData generateProgramData (bool optimized) const
	{
		float scale = 0.0f;
		for (int i = 0; i < m_numLoopIterations; i++)
			scale += 3.2f*(float)i + 4.6f;
		scale = 1.0f / scale;

		const string precision		= getShaderPrecision(m_caseShaderType);
		const string statements		= optimized ?	"	" + precision + " vec4 valueOrig = value;\n"
													"	" + precision + " vec4 y = sin(cos(sin(valueOrig)));\n"
													"	for (int i = 0; i < " + toString(m_numLoopIterations) + "; i++)\n"
													"	{\n"
													"		" + precision + " float x = 3.2*float(i) + 4.6;\n"
													"		value += x*y;\n"
													"	}\n"
													"	value *= " + toString(scale) + ";\n"

												:	"	" + precision + " vec4 valueOrig = value;\n"
													"	for (int i = 0; i < " + toString(m_numLoopIterations) + "; i++)\n"
													"	{\n"
													"		" + precision + " float x = 3.2*float(i) + 4.6;\n"
													"		" + precision + " vec4 y = sin(cos(sin(valueOrig)));\n"
													"		value += x*y;\n"
													"	}\n"
													"	value *= " + toString(scale) + ";\n";

		return defaultProgramData(m_caseShaderType, statements);
	}

private:
	const int m_numLoopIterations;
};

class FunctionInliningCase : public ShaderOptimizationCase
{
public:
	FunctionInliningCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, int callNestingDepth)
		: ShaderOptimizationCase	(context, name, description, caseShaderType)
		, m_callNestingDepth		(callNestingDepth)
	{
	}

protected:
	ProgramData generateProgramData (bool optimized) const
	{
		const string precision				= getShaderPrecision(m_caseShaderType);
		const string expression				= "value*vec4(0.8, 0.7, 0.6, 0.9)";
		const string maybeFuncDefs			= optimized ? "" : funcDefinitions(m_callNestingDepth, precision, expression);
		const string mainValueStatement		= (optimized ? "\tvalue = " + expression : "\tvalue = func" + toString(m_callNestingDepth-1) + "(value)") + ";\n";

		return defaultProgramData(m_caseShaderType, maybeFuncDefs, mainValueStatement);
	}

private:
	const int m_callNestingDepth;

	static inline string funcDefinitions (int callNestingDepth, const string& precision, const string& expression)
	{
		string result = precision + " vec4 func0 (" + precision + " vec4 value) { return " + expression + "; }\n";

		for (int i = 1; i < callNestingDepth; i++)
			result += precision + " vec4 func" + toString(i) + " (" + precision + " vec4 v) { return func" + toString(i-1) + "(v); }\n";

		return result;
	}
};

class ConstantPropagationCase : public ShaderOptimizationCase
{
public:
	enum CaseType
	{
		CASETYPE_BUILT_IN_FUNCTIONS = 0,
		CASETYPE_ARRAY,
		CASETYPE_STRUCT,

		CASETYPE_LAST
	};

	ConstantPropagationCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType, bool useConstantExpressionsOnly)
		: ShaderOptimizationCase			(context, name, description, caseShaderType)
		, m_caseType						(caseType)
		, m_useConstantExpressionsOnly		(useConstantExpressionsOnly)
	{
	}

protected:
	ProgramData generateProgramData (bool optimized) const
	{
		const bool		isVertexCase	= m_caseShaderType == CASESHADERTYPE_VERTEX;
		const string	precision		= getShaderPrecision(m_caseShaderType);
		const string	statements		= m_caseType == CASETYPE_BUILT_IN_FUNCTIONS		? builtinFunctionsCaseStatements	(optimized, m_useConstantExpressionsOnly, precision, isVertexCase)
										: m_caseType == CASETYPE_ARRAY					? arrayCaseStatements				(optimized, m_useConstantExpressionsOnly, precision, isVertexCase)
										: m_caseType == CASETYPE_STRUCT					? structCaseStatements				(optimized, m_useConstantExpressionsOnly, precision, isVertexCase)
										: DE_NULL;

		return defaultProgramData(m_caseShaderType, statements);
	}

private:
	const CaseType	m_caseType;
	const bool		m_useConstantExpressionsOnly;

	static inline string builtinFunctionsCaseStatements (bool optimized, bool constantExpressionsOnly, const string& precision, bool useHeavierWorkload)
	{
		const string	constMaybe = constantExpressionsOnly ? "const " : "";
		const int		numSinRows = useHeavierWorkload ? 12 : 1;

		return optimized ?	"	value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match the one in unoptimized shader, but shouldn't make a difference performance-wise\n"

						 :	"	" + constMaybe + precision + " vec4 a = vec4(sin(0.7), cos(0.2), sin(0.9), abs(-0.5));\n"
							"	" + constMaybe + precision + " vec4 b = cos(a) + fract(3.0*a.xzzw);\n"
							"	" + constMaybe + "bvec4 c = bvec4(true, false, true, true);\n"
							"	" + constMaybe + precision + " vec4 d = exp(b + vec4(c));\n"
							"	" + constMaybe + precision + " vec4 e0 = inversesqrt(mix(d+a, d+b, a));\n"
							+ repeatIndexedTemplate("	" + constMaybe + precision + " vec4 e${NDX} = sin(sin(sin(sin(e${PREV_NDX}))));\n", numSinRows, "", 1) +
							"	" + constMaybe + precision + " vec4 f = abs(e" + toString(numSinRows) + ");\n" +
							"	value = f*value;\n";
	}

	static inline string arrayCaseStatements (bool optimized, bool constantExpressionsOnly, const string& precision, bool useHeavierWorkload)
	{
		const string	constMaybe = constantExpressionsOnly ? "const " : "";
		const int		numSinRows = useHeavierWorkload ? 12 : 1;

		return optimized ?	"	value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match the one in unoptimized shader, but shouldn't make a difference performance-wise\n"

						 :	"	const int arrLen = 4;\n"
							+ (constantExpressionsOnly ?
								"	const " + precision + " vec4 arr[arrLen] =\n"
								"		vec4[](vec4(0.1, 0.5, 0.9, 1.3),\n"
								"		       vec4(0.2, 0.6, 1.0, 1.4),\n"
								"		       vec4(0.3, 0.7, 1.1, 1.5),\n"
								"		       vec4(0.4, 0.8, 1.2, 1.6));\n"

							 :	"	" + precision + " vec4 arr[arrLen];\n"
								"	arr[0] = vec4(0.1, 0.5, 0.9, 1.3);\n"
								"	arr[1] = vec4(0.2, 0.6, 1.0, 1.4);\n"
								"	arr[2] = vec4(0.3, 0.7, 1.1, 1.5);\n"
								"	arr[3] = vec4(0.4, 0.8, 1.2, 1.6);\n"
							) +
							"	" + constMaybe + precision + " vec4 a = (arr[0] + arr[1] + arr[2] + arr[3]) * (1.0 / float(arr.length()));\n"
							"	" + constMaybe + precision + " vec4 b0 = cos(sin(a));\n"
							+ repeatIndexedTemplate("	" + constMaybe + precision + " vec4 b${NDX} = sin(sin(sin(sin(b${PREV_NDX}))));\n", numSinRows, "", 1) +
							"	" + constMaybe + precision + " vec4 c = abs(b" + toString(numSinRows) + ");\n" +
							"	value = c*value;\n";
	}

	static inline string structCaseStatements (bool optimized, bool constantExpressionsOnly, const string& precision, bool useHeavierWorkload)
	{
		const string	constMaybe = constantExpressionsOnly ? "const " : "";
		const int		numSinRows = useHeavierWorkload ? 12 : 1;

		return optimized ?	"	value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match the one in unoptimized shader, but shouldn't make a difference performance-wise\n"

						 :	"	struct S\n"
							"	{\n"
							"		" + precision + " vec4 a;\n"
							"		" + precision + " vec4 b;\n"
							"		" + precision + " vec4 c;\n"
							"		" + precision + " vec4 d;\n"
							"	};\n"
							"\n"
							"	" + constMaybe + "S s =\n"
							"		S(vec4(0.1, 0.5, 0.9, 1.3),\n"
							"		  vec4(0.2, 0.6, 1.0, 1.4),\n"
							"		  vec4(0.3, 0.7, 1.1, 1.5),\n"
							"		  vec4(0.4, 0.8, 1.2, 1.6));\n"
							"	" + constMaybe + precision + " vec4 a = (s.a + s.b + s.c + s.d) * 0.25;\n"
							"	" + constMaybe + precision + " vec4 b0 = cos(sin(a));\n"
							+ repeatIndexedTemplate("	" + constMaybe + precision + " vec4 b${NDX} = sin(sin(sin(sin(b${PREV_NDX}))));\n", numSinRows, "", 1) +
							"	" + constMaybe + precision + " vec4 c = abs(b" + toString(numSinRows) + ");\n" +
							"	value = c*value;\n";
	}
};

class CommonSubexpressionCase : public ShaderOptimizationCase
{
public:
	enum CaseType
	{
		CASETYPE_SINGLE_STATEMENT = 0,
		CASETYPE_MULTIPLE_STATEMENTS,
		CASETYPE_STATIC_BRANCH,
		CASETYPE_LOOP,

		CASETYPE_LAST
	};

	CommonSubexpressionCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType)
		: ShaderOptimizationCase	(context, name, description, caseShaderType)
		, m_caseType				(caseType)
	{
	}

protected:
	ProgramData generateProgramData (bool optimized) const
	{
		const bool		isVertexCase	= m_caseShaderType == CASESHADERTYPE_VERTEX;
		const string	precision		= getShaderPrecision(m_caseShaderType);
		const string	statements		= m_caseType == CASETYPE_SINGLE_STATEMENT		? singleStatementCaseStatements		(optimized, precision, isVertexCase)
										: m_caseType == CASETYPE_MULTIPLE_STATEMENTS	? multipleStatementsCaseStatements	(optimized, precision, isVertexCase)
										: m_caseType == CASETYPE_STATIC_BRANCH			? staticBranchCaseStatements		(optimized, precision, isVertexCase)
										: m_caseType == CASETYPE_LOOP					? loopCaseStatements				(optimized, precision, isVertexCase)
										: DE_NULL;

		return defaultProgramData(m_caseShaderType, statements);
	}

private:
	const CaseType m_caseType;

	static inline string singleStatementCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numTopLevelRepeats = useHeavierWorkload ? 4 : 1;

		return optimized ?	"	" + precision + " vec4 s = sin(value);\n"
							"	" + precision + " vec4 cs = cos(s);\n"
							"	" + precision + " vec4 d = fract(s + cs) + sqrt(s + exp(cs));\n"
							"	value = " + repeat("d", numTopLevelRepeats, "+") + ";\n"

						 :	"	value = " + repeat("fract(sin(value) + cos(sin(value))) + sqrt(sin(value) + exp(cos(sin(value))))", numTopLevelRepeats, "\n\t      + ") + ";\n";
	}

	static inline string multipleStatementsCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numTopLevelRepeats = useHeavierWorkload ? 4 : 2;
		DE_ASSERT(numTopLevelRepeats >= 2);

		return optimized ?	"	" + precision + " vec4 a = sin(value) + cos(exp(value));\n"
							"	" + precision + " vec4 b = cos(cos(a));\n"
							"	a = fract(exp(sqrt(b)));\n"
							"\n"
							+ repeat("\tvalue += a*b;\n", numTopLevelRepeats)

						 :	repeatIndexedTemplate(	"	" + precision + " vec4 a${NDX} = sin(value) + cos(exp(value));\n"
													"	" + precision + " vec4 b${NDX} = cos(cos(a${NDX}));\n"
													"	a${NDX} = fract(exp(sqrt(b${NDX})));\n"
													"\n",
													numTopLevelRepeats) +

							repeatIndexedTemplate(	"	value += a${NDX}*b${NDX};\n", numTopLevelRepeats);
	}

	static inline string staticBranchCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numTopLevelRepeats = useHeavierWorkload ? 4 : 2;
		DE_ASSERT(numTopLevelRepeats >= 2);

		if (optimized)
		{
			return "	" + precision + " vec4 a = sin(value) + cos(exp(value));\n"
				   "	" + precision + " vec4 b = cos(a);\n"
				   "	b = cos(b);\n"
				   "	a = fract(exp(sqrt(b)));\n"
				   "\n"
				   + repeat("	value += a*b;\n", numTopLevelRepeats);
		}
		else
		{
			string result;

			for (int i = 0; i < numTopLevelRepeats; i++)
			{
				result +=	"	" + precision + " vec4 a" + toString(i) + " = sin(value) + cos(exp(value));\n"
							"	" + precision + " vec4 b" + toString(i) + " = cos(a" + toString(i) + ");\n";

				if (i % 3 == 0)
					result +=	"	if (1 < 2)\n"
								"		b" + toString(i) + " = cos(b" + toString(i) + ");\n";
				else if (i % 3 == 1)
					result +=	"	b" + toString(i) + " = cos(b" + toString(i) + ");\n";
				else if (i % 3 == 2)
					result +=	"	if (2 < 1);\n"
								"	else\n"
								"		b" + toString(i) + " = cos(b" + toString(i) + ");\n";
				else
					DE_ASSERT(false);

				result +=	"	a" + toString(i) + " = fract(exp(sqrt(b" + toString(i) + ")));\n\n";
			}

			result += repeatIndexedTemplate("	value += a${NDX}*b${NDX};\n", numTopLevelRepeats);

			return result;
		}
	}

	static inline string loopCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numLoopIterations = useHeavierWorkload ? 32 : 4;

		return optimized ?	"	" + precision + " vec4 acc = value;\n"
							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
							"		acc = sin(acc);\n"
							"\n"
							"	value += acc;\n"
							"	value += acc;\n"

						 :	"	" + precision + " vec4 acc0 = value;\n"
							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
							"		acc0 = sin(acc0);\n"
							"\n"
							"	" + precision + " vec4 acc1 = value;\n"
							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
							"		acc1 = sin(acc1);\n"
							"\n"
							"	value += acc0;\n"
							"	value += acc1;\n";
	}
};

class DeadCodeEliminationCase : public ShaderOptimizationCase
{
public:
	enum CaseType
	{
		CASETYPE_DEAD_BRANCH_SIMPLE = 0,
		CASETYPE_DEAD_BRANCH_COMPLEX,
		CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST,
		CASETYPE_DEAD_BRANCH_FUNC_CALL,
		CASETYPE_UNUSED_VALUE_BASIC,
		CASETYPE_UNUSED_VALUE_LOOP,
		CASETYPE_UNUSED_VALUE_DEAD_BRANCH,
		CASETYPE_UNUSED_VALUE_AFTER_RETURN,
		CASETYPE_UNUSED_VALUE_MUL_ZERO,

		CASETYPE_LAST
	};

	DeadCodeEliminationCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType)
		: ShaderOptimizationCase	(context, name, description, caseShaderType)
		, m_caseType				(caseType)
	{
	}

protected:
	ProgramData generateProgramData (bool optimized) const
	{
		const bool		isVertexCase	= m_caseShaderType == CASESHADERTYPE_VERTEX;
		const string	precision		= getShaderPrecision(m_caseShaderType);
		const string	funcDefs		= m_caseType == CASETYPE_DEAD_BRANCH_FUNC_CALL		? deadBranchFuncCallCaseFuncDefs		(optimized, precision)
										: m_caseType == CASETYPE_UNUSED_VALUE_AFTER_RETURN	? unusedValueAfterReturnCaseFuncDefs	(optimized, precision, isVertexCase)
										: "";

		const string	statements		= m_caseType == CASETYPE_DEAD_BRANCH_SIMPLE				? deadBranchSimpleCaseStatements			(optimized, isVertexCase)
										: m_caseType == CASETYPE_DEAD_BRANCH_COMPLEX			? deadBranchComplexCaseStatements			(optimized, precision, true,	isVertexCase)
										: m_caseType == CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST	? deadBranchComplexCaseStatements			(optimized, precision, false,	isVertexCase)
										: m_caseType == CASETYPE_DEAD_BRANCH_FUNC_CALL			? deadBranchFuncCallCaseStatements			(optimized, isVertexCase)
										: m_caseType == CASETYPE_UNUSED_VALUE_BASIC				? unusedValueBasicCaseStatements			(optimized, precision, isVertexCase)
										: m_caseType == CASETYPE_UNUSED_VALUE_LOOP				? unusedValueLoopCaseStatements				(optimized, precision, isVertexCase)
										: m_caseType == CASETYPE_UNUSED_VALUE_DEAD_BRANCH		? unusedValueDeadBranchCaseStatements		(optimized, precision, isVertexCase)
										: m_caseType == CASETYPE_UNUSED_VALUE_AFTER_RETURN		? unusedValueAfterReturnCaseStatements		()
										: m_caseType == CASETYPE_UNUSED_VALUE_MUL_ZERO			? unusedValueMulZeroCaseStatements			(optimized, precision, isVertexCase)
										: DE_NULL;

		return defaultProgramData(m_caseShaderType, funcDefs, statements);
	}

private:
	const CaseType m_caseType;

	static inline string deadBranchSimpleCaseStatements (bool optimized, bool useHeavierWorkload)
	{
		const int numLoopIterations = useHeavierWorkload ? 16 : 4;

		return optimized ?	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"

						 :	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	if (2 < 1)\n"
							"	{\n"
							"		value = cos(exp(sin(value))*log(sqrt(value)));\n"
							"		for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
							"			value = sin(value);\n"
							"	}\n";
	}

	static inline string deadBranchComplexCaseStatements (bool optimized, const string& precision, bool useConst, bool useHeavierWorkload)
	{
		const string	constMaybe			= useConst ? "const " : "";
		const int		numLoopIterations	= useHeavierWorkload ? 16 : 4;

		return optimized ?	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"

						 :	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	" + constMaybe + precision + " vec4 a = vec4(sin(0.7), cos(0.2), sin(0.9), abs(-0.5));\n"
							"	" + constMaybe + precision + " vec4 b = cos(a) + fract(3.0*a.xzzw);\n"
							"	" + constMaybe + "bvec4 c = bvec4(true, false, true, true);\n"
							"	" + constMaybe + precision + " vec4 d = exp(b + vec4(c));\n"
							"	" + constMaybe + precision + " vec4 e = 1.8*abs(sin(sin(inversesqrt(mix(d+a, d+b, a)))));\n"
							"	if (e.x > 1.0)\n"
							"	{\n"
							"		value = cos(exp(sin(value))*log(sqrt(value)));\n"
							"		for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
							"			value = sin(value);\n"
							"	}\n";
	}

	static inline string deadBranchFuncCallCaseFuncDefs (bool optimized, const string& precision)
	{
		return optimized ? "" : precision + " float func (" + precision + " float x) { return 2.0*x; }\n";
	}

	static inline string deadBranchFuncCallCaseStatements (bool optimized, bool useHeavierWorkload)
	{
		const int numLoopIterations = useHeavierWorkload ? 16 : 4;

		return optimized ?	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"

						 :	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	if (func(0.3) > 1.0)\n"
							"	{\n"
							"		value = cos(exp(sin(value))*log(sqrt(value)));\n"
							"		for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
							"			value = sin(value);\n"
							"	}\n";
	}

	static inline string unusedValueBasicCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numSinRows = useHeavierWorkload ? 12 : 1;

		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	value = used;\n"

						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value))) + used;\n"
							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
							"	value = used;\n";
	}

	static inline string unusedValueLoopCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numLoopIterations = useHeavierWorkload ? 16 : 4;

		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	value = used;\n"

						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n"
							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
							"		unused = sin(unused + used);\n"
							"	value = used;\n";
	}

	static inline string unusedValueAfterReturnCaseFuncDefs (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numSinRows = useHeavierWorkload ? 12 : 1;

		return optimized ?	precision + " vec4 func (" + precision + " vec4 v)\n"
							"{\n"
							"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * v;\n"
							"	return used;\n"
							"}\n"

						 :	precision + " vec4 func (" + precision + " vec4 v)\n"
							"{\n"
							"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * v;\n"
							"	" + precision + " vec4 unused = cos(exp(sin(v))*log(sqrt(v)));\n"
							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
							"	return used;\n"
							"	used = used*unused;"
							"	return used;\n"
							"}\n";
	}

	static inline string unusedValueAfterReturnCaseStatements (void)
	{
		return "	value = func(value);\n";
	}

	static inline string unusedValueDeadBranchCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numSinRows = useHeavierWorkload ? 12 : 1;

		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	value = used;\n"

						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n"
							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
							"	if (2 < 1)\n"
							"		used = used*unused;\n"
							"	value = used;\n";
	}

	static inline string unusedValueMulZeroCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
	{
		const int numSinRows = useHeavierWorkload ? 12 : 1;

		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	value = used;\n"

						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n"
							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
							"	value = used + unused*float(1-1);\n";
	}
};

} // anonymous

ShaderOptimizationTests::ShaderOptimizationTests (Context& context)
	: TestCaseGroup(context, "optimization", "Shader Optimization Performance Tests")
{
}

ShaderOptimizationTests::~ShaderOptimizationTests (void)
{
}

void ShaderOptimizationTests::init (void)
{
	TestCaseGroup* const unrollGroup					= new TestCaseGroup(m_context, "loop_unrolling",					"Loop Unrolling Cases");
	TestCaseGroup* const loopInvariantCodeMotionGroup	= new TestCaseGroup(m_context, "loop_invariant_code_motion",		"Loop-Invariant Code Motion Cases");
	TestCaseGroup* const inlineGroup					= new TestCaseGroup(m_context, "function_inlining",					"Function Inlining Cases");
	TestCaseGroup* const constantPropagationGroup		= new TestCaseGroup(m_context, "constant_propagation",				"Constant Propagation Cases");
	TestCaseGroup* const commonSubexpressionGroup		= new TestCaseGroup(m_context, "common_subexpression_elimination",	"Common Subexpression Elimination Cases");
	TestCaseGroup* const deadCodeEliminationGroup		= new TestCaseGroup(m_context, "dead_code_elimination",				"Dead Code Elimination Cases");
	addChild(unrollGroup);
	addChild(loopInvariantCodeMotionGroup);
	addChild(inlineGroup);
	addChild(constantPropagationGroup);
	addChild(commonSubexpressionGroup);
	addChild(deadCodeEliminationGroup);

	for (int caseShaderTypeI = 0; caseShaderTypeI < CASESHADERTYPE_LAST; caseShaderTypeI++)
	{
		const CaseShaderType	caseShaderType			= (CaseShaderType)caseShaderTypeI;
		const char* const		caseShaderTypeSuffix	= caseShaderType == CASESHADERTYPE_VERTEX		? "_vertex"
														: caseShaderType == CASESHADERTYPE_FRAGMENT		? "_fragment"
														: DE_NULL;

		// Loop unrolling cases.

		{
			static const int loopIterationCounts[] = { 4, 8, 32 };

			for (int caseTypeI = 0; caseTypeI < LoopUnrollCase::CASETYPE_LAST; caseTypeI++)
			{
				const LoopUnrollCase::CaseType	caseType		= (LoopUnrollCase::CaseType)caseTypeI;
				const string					caseTypeName	= caseType == LoopUnrollCase::CASETYPE_INDEPENDENT	? "independent_iterations"
																: caseType == LoopUnrollCase::CASETYPE_DEPENDENT	? "dependent_iterations"
																: DE_NULL;
				const string					caseTypeDesc	= caseType == LoopUnrollCase::CASETYPE_INDEPENDENT	? "loop iterations don't depend on each other"
																: caseType == LoopUnrollCase::CASETYPE_DEPENDENT	? "loop iterations depend on each other"
																: DE_NULL;

				for (int loopIterNdx = 0; loopIterNdx < DE_LENGTH_OF_ARRAY(loopIterationCounts); loopIterNdx++)
				{
					const int			loopIterations	= loopIterationCounts[loopIterNdx];
					const string		name			= caseTypeName + "_" + toString(loopIterations) + caseShaderTypeSuffix;
					const string		description		= toString(loopIterations) + " iterations; " + caseTypeDesc;

					unrollGroup->addChild(new LoopUnrollCase(m_context, name.c_str(), description.c_str(), caseShaderType, caseType, loopIterations));
				}
			}
		}

		// Loop-invariant code motion cases.

		{
			static const int loopIterationCounts[] = { 4, 8, 32 };

			for (int loopIterNdx = 0; loopIterNdx < DE_LENGTH_OF_ARRAY(loopIterationCounts); loopIterNdx++)
			{
				const int		loopIterations	= loopIterationCounts[loopIterNdx];
				const string	name			= toString(loopIterations) + "_iterations" + caseShaderTypeSuffix;

				loopInvariantCodeMotionGroup->addChild(new LoopInvariantCodeMotionCase(m_context, name.c_str(), "", caseShaderType, loopIterations));
			}
		}

		// Function inlining cases.

		{
			static const int callNestingDepths[] = { 4, 8, 32 };

			for (int nestDepthNdx = 0; nestDepthNdx < DE_LENGTH_OF_ARRAY(callNestingDepths); nestDepthNdx++)
			{
				const int		nestingDepth	= callNestingDepths[nestDepthNdx];
				const string	name			= toString(nestingDepth) + "_nested" + caseShaderTypeSuffix;

				inlineGroup->addChild(new FunctionInliningCase(m_context, name.c_str(), "", caseShaderType, nestingDepth));
			}
		}

		// Constant propagation cases.

		for (int caseTypeI = 0; caseTypeI < ConstantPropagationCase::CASETYPE_LAST; caseTypeI++)
		{
			const ConstantPropagationCase::CaseType		caseType		= (ConstantPropagationCase::CaseType)caseTypeI;
			const string								caseTypeName	= caseType == ConstantPropagationCase::CASETYPE_BUILT_IN_FUNCTIONS		? "built_in_functions"
																		: caseType == ConstantPropagationCase::CASETYPE_ARRAY					? "array"
																		: caseType == ConstantPropagationCase::CASETYPE_STRUCT					? "struct"
																		: DE_NULL;

			for (int constantExpressionsOnlyI = 0; constantExpressionsOnlyI <= 1; constantExpressionsOnlyI++)
			{
				const bool		constantExpressionsOnly		= constantExpressionsOnlyI != 0;
				const string	name						= caseTypeName + (constantExpressionsOnly ? "" : "_no_const") + caseShaderTypeSuffix;

				constantPropagationGroup->addChild(new ConstantPropagationCase(m_context, name.c_str(), "", caseShaderType, caseType, constantExpressionsOnly));
			}
		}

		// Common subexpression cases.

		for (int caseTypeI = 0; caseTypeI < CommonSubexpressionCase::CASETYPE_LAST; caseTypeI++)
		{
			const CommonSubexpressionCase::CaseType		caseType		= (CommonSubexpressionCase::CaseType)caseTypeI;

			const string								caseTypeName	= caseType == CommonSubexpressionCase::CASETYPE_SINGLE_STATEMENT		? "single_statement"
																		: caseType == CommonSubexpressionCase::CASETYPE_MULTIPLE_STATEMENTS		? "multiple_statements"
																		: caseType == CommonSubexpressionCase::CASETYPE_STATIC_BRANCH			? "static_branch"
																		: caseType == CommonSubexpressionCase::CASETYPE_LOOP					? "loop"
																		: DE_NULL;

			const string								description		= caseType == CommonSubexpressionCase::CASETYPE_SINGLE_STATEMENT		? "A single statement containing multiple uses of same subexpression"
																		: caseType == CommonSubexpressionCase::CASETYPE_MULTIPLE_STATEMENTS		? "Multiple statements performing same computations"
																		: caseType == CommonSubexpressionCase::CASETYPE_STATIC_BRANCH			? "Multiple statements including a static conditional"
																		: caseType == CommonSubexpressionCase::CASETYPE_LOOP					? "Multiple loops performing the same computations"
																		: DE_NULL;

			commonSubexpressionGroup->addChild(new CommonSubexpressionCase(m_context, (caseTypeName + caseShaderTypeSuffix).c_str(), description.c_str(), caseShaderType, caseType));
		}

		// Dead code elimination cases.

		for (int caseTypeI = 0; caseTypeI < DeadCodeEliminationCase::CASETYPE_LAST; caseTypeI++)
		{
			const DeadCodeEliminationCase::CaseType		caseType				= (DeadCodeEliminationCase::CaseType)caseTypeI;
			const char* const							caseTypeName			= caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_SIMPLE				? "dead_branch_simple"
																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX				? "dead_branch_complex"
																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST	? "dead_branch_complex_no_const"
																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_FUNC_CALL			? "dead_branch_func_call"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_BASIC				? "unused_value_basic"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_LOOP				? "unused_value_loop"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_DEAD_BRANCH		? "unused_value_dead_branch"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_AFTER_RETURN		? "unused_value_after_return"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_MUL_ZERO			? "unused_value_mul_zero"
																				: DE_NULL;

			const char* const							caseTypeDescription		= caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_SIMPLE				? "Do computation inside a branch that is never taken (condition is simple false constant expression)"
																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX				? "Do computation inside a branch that is never taken (condition is complex false constant expression)"
																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST	? "Do computation inside a branch that is never taken (condition is complex false expression, not constant expression but still compile-time computable)"
																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_FUNC_CALL			? "Do computation inside a branch that is never taken (condition is compile-time computable false expression containing function call to a simple inlineable function)"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_BASIC				? "Compute a value that is never used even statically"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_LOOP				? "Compute a value, using a loop, that is never used even statically"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_DEAD_BRANCH		? "Compute a value that is used only inside a statically dead branch"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_AFTER_RETURN		? "Compute a value that is used only after a return statement"
																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_MUL_ZERO			? "Compute a value that is used but multiplied by a zero constant expression"
																				: DE_NULL;

			deadCodeEliminationGroup->addChild(new DeadCodeEliminationCase(m_context, (string() + caseTypeName + caseShaderTypeSuffix).c_str(), caseTypeDescription, caseShaderType, caseType));
		}
	}
}

} // Performance
} // gles3
} // deqp
