Initialize uninitialized GLSL arrays in a for loop

Previously, creating nodes for initializing each single array element
could result in memory bloat during translation when dealing with
large arrays. The resulting shader could also end up very long.
Initialize most arrays using a simple for loop instead. The loop is
compatible with ESSL 1.00 Appendix A limitations.

An exception is made for fragment outputs, so that they are not
indexed by non-constant values.

On some platforms using the a loop to initialize variables can cause
problems, so we also have a compiler flag for turning this behavior
off. The flag was already added earlier for a staggered rollout of
this functionality.

BUG=chromium:735497
TEST=angle_unittests, angle_end2end_tests, WebGL conformance tests

Change-Id: Iec727821d8137db56b440ddbe007879b1b55f61f
Reviewed-on: https://chromium-review.googlesource.com/707195
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 7b3418e..4784171 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -595,7 +595,9 @@
     // on ESSL >= 3.00, and the initializers that need to be deferred can only exist in ESSL < 3.00.
     bool initializeLocalsAndGlobals =
         (compileOptions & SH_INITIALIZE_UNINITIALIZED_LOCALS) && !IsOutputHLSL(getOutputType());
-    DeferGlobalInitializers(root, initializeLocalsAndGlobals, &symbolTable);
+    bool canUseLoopsToInitialize = !(compileOptions & SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES);
+    DeferGlobalInitializers(root, initializeLocalsAndGlobals, canUseLoopsToInitialize, &symbolTable);
+
 
     if (initializeLocalsAndGlobals)
     {
@@ -615,7 +617,8 @@
                                    &getSymbolTable(), getShaderVersion());
         }
 
-        InitializeUninitializedLocals(root, getShaderVersion());
+        InitializeUninitializedLocals(root, getShaderVersion(), canUseLoopsToInitialize,
+                                      &getSymbolTable());
     }
 
     if (getShaderType() == GL_VERTEX_SHADER && (compileOptions & SH_CLAMP_POINT_SIZE))
@@ -1055,7 +1058,7 @@
     sh::ShaderVariable var(GL_FLOAT_VEC4);
     var.name = "gl_Position";
     list.push_back(var);
-    InitializeVariables(root, list, symbolTable, shaderVersion, extensionBehavior);
+    InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false);
 }
 
 void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
@@ -1097,7 +1100,7 @@
             list.push_back(var);
         }
     }
-    InitializeVariables(root, list, symbolTable, shaderVersion, extensionBehavior);
+    InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false);
 }
 
 const TExtensionBehavior &TCompiler::getExtensionBehavior() const