Bug 1459785 - Update ANGLE to chromium/3396.
authorJeff Gilbert <jgilbert@mozilla.com>
Mon, 07 May 2018 17:38:32 -0700
changeset 419438 b7c91a6f1b0a72da63f430d8f6c57d5374d7e0a7
parent 419437 21af8dc00aa836013d8564dc78bf22f2d3237a01
child 419439 88675b68241a486ab9a206cfb0a8a07a1163d314
push id34037
push userdluca@mozilla.com
push dateWed, 23 May 2018 09:51:55 +0000
treeherdermozilla-central@d36cd8bdbc5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1459785
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1459785 - Update ANGLE to chromium/3396. MozReview-Commit-ID: EA39lUfXuPI
gfx/angle/checkout/include/EGL/eglext_angle.h
gfx/angle/checkout/include/GLSLANG/ShaderLang.h
gfx/angle/checkout/include/GLSLANG/ShaderVars.h
gfx/angle/checkout/include/KHR/khrplatform.h
gfx/angle/checkout/out/gen/angle/id/commit.h
gfx/angle/checkout/src/common/Color.h
gfx/angle/checkout/src/common/FixedVector.h
gfx/angle/checkout/src/common/angleutils.h
gfx/angle/checkout/src/common/bitset_utils.h
gfx/angle/checkout/src/common/mathutil.h
gfx/angle/checkout/src/common/matrix_utils.h
gfx/angle/checkout/src/common/utilities.cpp
gfx/angle/checkout/src/common/utilities.h
gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.cpp
gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.l
gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.cpp
gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.h
gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.cpp
gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.h
gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.h
gfx/angle/checkout/src/compiler/translator/BaseTypes.h
gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.h
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
gfx/angle/checkout/src/compiler/translator/ClampFragDepth.cpp
gfx/angle/checkout/src/compiler/translator/ClampFragDepth.h
gfx/angle/checkout/src/compiler/translator/ClampPointSize.cpp
gfx/angle/checkout/src/compiler/translator/ClampPointSize.h
gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
gfx/angle/checkout/src/compiler/translator/CollectVariables.h
gfx/angle/checkout/src/compiler/translator/Compiler.cpp
gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h
gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.cpp
gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.h
gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.h
gfx/angle/checkout/src/compiler/translator/EmulatePrecision.cpp
gfx/angle/checkout/src/compiler/translator/EmulatePrecision.h
gfx/angle/checkout/src/compiler/translator/ExpandIntegerPowExpressions.cpp
gfx/angle/checkout/src/compiler/translator/ExpandIntegerPowExpressions.h
gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
gfx/angle/checkout/src/compiler/translator/FindMain.cpp
gfx/angle/checkout/src/compiler/translator/FindMain.h
gfx/angle/checkout/src/compiler/translator/FindSymbolNode.cpp
gfx/angle/checkout/src/compiler/translator/FindSymbolNode.h
gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
gfx/angle/checkout/src/compiler/translator/FoldExpressions.cpp
gfx/angle/checkout/src/compiler/translator/FoldExpressions.h
gfx/angle/checkout/src/compiler/translator/ImmutableString.cpp
gfx/angle/checkout/src/compiler/translator/ImmutableString.h
gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
gfx/angle/checkout/src/compiler/translator/InitializeVariables.cpp
gfx/angle/checkout/src/compiler/translator/InitializeVariables.h
gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
gfx/angle/checkout/src/compiler/translator/IntermNode.h
gfx/angle/checkout/src/compiler/translator/IntermNodePatternMatcher.cpp
gfx/angle/checkout/src/compiler/translator/IntermNodePatternMatcher.h
gfx/angle/checkout/src/compiler/translator/IntermNode_util.cpp
gfx/angle/checkout/src/compiler/translator/IntermNode_util.h
gfx/angle/checkout/src/compiler/translator/IntermTraverse.cpp
gfx/angle/checkout/src/compiler/translator/IntermTraverse.h
gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
gfx/angle/checkout/src/compiler/translator/NodeSearch.h
gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
gfx/angle/checkout/src/compiler/translator/ParamType.h
gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
gfx/angle/checkout/src/compiler/translator/ParseContext.h
gfx/angle/checkout/src/compiler/translator/ParseContext_autogen.h
gfx/angle/checkout/src/compiler/translator/PruneNoOps.cpp
gfx/angle/checkout/src/compiler/translator/PruneNoOps.h
gfx/angle/checkout/src/compiler/translator/RecordConstantPrecision.cpp
gfx/angle/checkout/src/compiler/translator/RecordConstantPrecision.h
gfx/angle/checkout/src/compiler/translator/RegenerateStructNames.cpp
gfx/angle/checkout/src/compiler/translator/RegenerateStructNames.h
gfx/angle/checkout/src/compiler/translator/RemoveArrayLengthMethod.cpp
gfx/angle/checkout/src/compiler/translator/RemoveArrayLengthMethod.h
gfx/angle/checkout/src/compiler/translator/RemoveDynamicIndexing.cpp
gfx/angle/checkout/src/compiler/translator/RemoveDynamicIndexing.h
gfx/angle/checkout/src/compiler/translator/RemoveEmptySwitchStatements.cpp
gfx/angle/checkout/src/compiler/translator/RemoveEmptySwitchStatements.h
gfx/angle/checkout/src/compiler/translator/RemoveInvariantDeclaration.cpp
gfx/angle/checkout/src/compiler/translator/RemoveInvariantDeclaration.h
gfx/angle/checkout/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp
gfx/angle/checkout/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h
gfx/angle/checkout/src/compiler/translator/RemovePow.cpp
gfx/angle/checkout/src/compiler/translator/RemovePow.h
gfx/angle/checkout/src/compiler/translator/RemoveSwitchFallThrough.cpp
gfx/angle/checkout/src/compiler/translator/RemoveSwitchFallThrough.h
gfx/angle/checkout/src/compiler/translator/RemoveUnreferencedVariables.cpp
gfx/angle/checkout/src/compiler/translator/RemoveUnreferencedVariables.h
gfx/angle/checkout/src/compiler/translator/ReplaceVariable.cpp
gfx/angle/checkout/src/compiler/translator/ReplaceVariable.h
gfx/angle/checkout/src/compiler/translator/RewriteDoWhile.cpp
gfx/angle/checkout/src/compiler/translator/RewriteDoWhile.h
gfx/angle/checkout/src/compiler/translator/RewriteElseBlocks.cpp
gfx/angle/checkout/src/compiler/translator/RewriteElseBlocks.h
gfx/angle/checkout/src/compiler/translator/RewriteTexelFetchOffset.cpp
gfx/angle/checkout/src/compiler/translator/RewriteTexelFetchOffset.h
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorFloat.h
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp
gfx/angle/checkout/src/compiler/translator/RewriteUnaryMinusOperatorInt.h
gfx/angle/checkout/src/compiler/translator/RunAtTheEndOfShader.cpp
gfx/angle/checkout/src/compiler/translator/RunAtTheEndOfShader.h
gfx/angle/checkout/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
gfx/angle/checkout/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
gfx/angle/checkout/src/compiler/translator/SeparateArrayConstructorStatements.cpp
gfx/angle/checkout/src/compiler/translator/SeparateArrayConstructorStatements.h
gfx/angle/checkout/src/compiler/translator/SeparateArrayInitialization.cpp
gfx/angle/checkout/src/compiler/translator/SeparateArrayInitialization.h
gfx/angle/checkout/src/compiler/translator/SeparateDeclarations.cpp
gfx/angle/checkout/src/compiler/translator/SeparateDeclarations.h
gfx/angle/checkout/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
gfx/angle/checkout/src/compiler/translator/SeparateExpressionsReturningArrays.h
gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
gfx/angle/checkout/src/compiler/translator/SimplifyLoopConditions.cpp
gfx/angle/checkout/src/compiler/translator/SimplifyLoopConditions.h
gfx/angle/checkout/src/compiler/translator/SplitSequenceOperator.cpp
gfx/angle/checkout/src/compiler/translator/SplitSequenceOperator.h
gfx/angle/checkout/src/compiler/translator/StaticType.cpp
gfx/angle/checkout/src/compiler/translator/StaticType.h
gfx/angle/checkout/src/compiler/translator/Symbol.cpp
gfx/angle/checkout/src/compiler/translator/Symbol.h
gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
gfx/angle/checkout/src/compiler/translator/SymbolTable.h
gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.cpp
gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h
gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
gfx/angle/checkout/src/compiler/translator/Types.cpp
gfx/angle/checkout/src/compiler/translator/Types.h
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitAST.cpp
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitAST.h
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitToIf.cpp
gfx/angle/checkout/src/compiler/translator/UnfoldShortCircuitToIf.h
gfx/angle/checkout/src/compiler/translator/UseInterfaceBlockFields.cpp
gfx/angle/checkout/src/compiler/translator/UseInterfaceBlockFields.h
gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
gfx/angle/checkout/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp
gfx/angle/checkout/src/compiler/translator/VectorizeVectorScalarArithmetic.h
gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
gfx/angle/checkout/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp
gfx/angle/checkout/src/compiler/translator/WrapSwitchStatementsInBlocks.h
gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
gfx/angle/checkout/src/compiler/translator/glslang.y
gfx/angle/checkout/src/compiler/translator/glslang_tab.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/AddAndTrueToLoopCondition.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/AddAndTrueToLoopCondition.h
gfx/angle/checkout/src/compiler/translator/tree_ops/AddDefaultReturnStatements.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/AddDefaultReturnStatements.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ArrayReturnValueToOutParameter.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ArrayReturnValueToOutParameter.h
gfx/angle/checkout/src/compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/BreakVariableAliasingInInnerLoops.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampFragDepth.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampFragDepth.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h
gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h
gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulatePrecision.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulatePrecision.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ExpandIntegerPowExpressions.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ExpandIntegerPowExpressions.h
gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h
gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RegenerateStructNames.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RegenerateStructNames.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemovePow.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemovePow.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveSwitchFallThrough.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveSwitchFallThrough.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDoWhile.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDoWhile.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteElseBlocks.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteElseBlocks.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorFloat.h
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteUnaryMinusOperatorInt.h
gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayConstructorStatements.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayConstructorStatements.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayInitialization.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateArrayInitialization.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateExpressionsReturningArrays.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateExpressionsReturningArrays.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h
gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitAST.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitAST.h
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitToIf.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/UnfoldShortCircuitToIf.h
gfx/angle/checkout/src/compiler/translator/tree_ops/UseInterfaceBlockFields.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/UseInterfaceBlockFields.h
gfx/angle/checkout/src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h
gfx/angle/checkout/src/compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.cpp
gfx/angle/checkout/src/compiler/translator/tree_ops/WrapSwitchStatementsInBlocks.h
gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_autogen.h
gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h
gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h
gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h
gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h
gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h
gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp
gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h
gfx/angle/checkout/src/libANGLE/BinaryStream.h
gfx/angle/checkout/src/libANGLE/Buffer.cpp
gfx/angle/checkout/src/libANGLE/Buffer.h
gfx/angle/checkout/src/libANGLE/Caps.cpp
gfx/angle/checkout/src/libANGLE/Caps.h
gfx/angle/checkout/src/libANGLE/Compiler.cpp
gfx/angle/checkout/src/libANGLE/Compiler.h
gfx/angle/checkout/src/libANGLE/Context.cpp
gfx/angle/checkout/src/libANGLE/Context.h
gfx/angle/checkout/src/libANGLE/ContextState.cpp
gfx/angle/checkout/src/libANGLE/ContextState.h
gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp
gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h
gfx/angle/checkout/src/libANGLE/Display.cpp
gfx/angle/checkout/src/libANGLE/Error.h
gfx/angle/checkout/src/libANGLE/Error.inl
gfx/angle/checkout/src/libANGLE/ErrorStrings.h
gfx/angle/checkout/src/libANGLE/Framebuffer.cpp
gfx/angle/checkout/src/libANGLE/Framebuffer.h
gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp
gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h
gfx/angle/checkout/src/libANGLE/GLES1State.cpp
gfx/angle/checkout/src/libANGLE/GLES1State.h
gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp
gfx/angle/checkout/src/libANGLE/Image.cpp
gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
gfx/angle/checkout/src/libANGLE/ImageIndex.h
gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp
gfx/angle/checkout/src/libANGLE/Observer.cpp
gfx/angle/checkout/src/libANGLE/Observer.h
gfx/angle/checkout/src/libANGLE/PackedGLEnums.cpp
gfx/angle/checkout/src/libANGLE/PackedGLEnums.h
gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.cpp
gfx/angle/checkout/src/libANGLE/PackedGLEnums_autogen.h
gfx/angle/checkout/src/libANGLE/Program.cpp
gfx/angle/checkout/src/libANGLE/Program.h
gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp
gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h
gfx/angle/checkout/src/libANGLE/RefCountObject.h
gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
gfx/angle/checkout/src/libANGLE/ResourceManager.cpp
gfx/angle/checkout/src/libANGLE/ResourceManager.h
gfx/angle/checkout/src/libANGLE/Shader.cpp
gfx/angle/checkout/src/libANGLE/Shader.h
gfx/angle/checkout/src/libANGLE/State.cpp
gfx/angle/checkout/src/libANGLE/State.h
gfx/angle/checkout/src/libANGLE/Stream.cpp
gfx/angle/checkout/src/libANGLE/Surface.cpp
gfx/angle/checkout/src/libANGLE/Texture.cpp
gfx/angle/checkout/src/libANGLE/Texture.h
gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp
gfx/angle/checkout/src/libANGLE/TransformFeedback.h
gfx/angle/checkout/src/libANGLE/Uniform.cpp
gfx/angle/checkout/src/libANGLE/Uniform.h
gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp
gfx/angle/checkout/src/libANGLE/VertexArray.cpp
gfx/angle/checkout/src/libANGLE/VertexArray.h
gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp
gfx/angle/checkout/src/libANGLE/VertexAttribute.h
gfx/angle/checkout/src/libANGLE/angletypes.cpp
gfx/angle/checkout/src/libANGLE/angletypes.h
gfx/angle/checkout/src/libANGLE/entry_points_enum_autogen.h
gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp
gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp
gfx/angle/checkout/src/libANGLE/formatutils.cpp
gfx/angle/checkout/src/libANGLE/formatutils.h
gfx/angle/checkout/src/libANGLE/params.cpp
gfx/angle/checkout/src/libANGLE/params.h
gfx/angle/checkout/src/libANGLE/queryconversions.cpp
gfx/angle/checkout/src/libANGLE/queryutils.cpp
gfx/angle/checkout/src/libANGLE/queryutils.h
gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h
gfx/angle/checkout/src/libANGLE/renderer/Format.h
gfx/angle/checkout/src/libANGLE/renderer/Format_ID_autogen.inl
gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp
gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h
gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h
gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp
gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h
gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp
gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp
gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h
gfx/angle/checkout/src/libANGLE/signal_utils.cpp
gfx/angle/checkout/src/libANGLE/signal_utils.h
gfx/angle/checkout/src/libANGLE/validationEGL.cpp
gfx/angle/checkout/src/libANGLE/validationES.cpp
gfx/angle/checkout/src/libANGLE/validationES.h
gfx/angle/checkout/src/libANGLE/validationES1.cpp
gfx/angle/checkout/src/libANGLE/validationES1.h
gfx/angle/checkout/src/libANGLE/validationES2.cpp
gfx/angle/checkout/src/libANGLE/validationES2.h
gfx/angle/checkout/src/libANGLE/validationES3.cpp
gfx/angle/checkout/src/libANGLE/validationES3.h
gfx/angle/checkout/src/libANGLE/validationES31.cpp
gfx/angle/checkout/src/libANGLE/validationES31.h
gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h
gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h
gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_ext.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp
gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h
gfx/angle/checkout/src/libGLESv2/proc_table.h
gfx/angle/checkout/src/third_party/compiler/ArrayBoundsClamper.cpp
gfx/angle/targets/libANGLE/moz.build
gfx/angle/targets/translator/moz.build
--- a/gfx/angle/checkout/include/EGL/eglext_angle.h
+++ b/gfx/angle/checkout/include/EGL/eglext_angle.h
@@ -170,11 +170,16 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCach
 #define EGL_ANGLE_iosurface_client_buffer 1
 #define EGL_IOSURFACE_ANGLE 0x3454
 #define EGL_IOSURFACE_PLANE_ANGLE 0x345A
 #define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
 #define EGL_TEXTURE_TYPE_ANGLE 0x345C
 #define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
 #endif /* EGL_ANGLE_iosurface_client_buffer */
 
+#ifndef EGL_ANGLE_create_context_extensions_enabled
+#define EGL_ANGLE_create_context_extensions_enabled 1
+#define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F
+#endif /* EGL_ANGLE_create_context_extensions_enabled */
+
 // clang-format on
 
 #endif  // INCLUDE_EGL_EGLEXT_ANGLE_
--- a/gfx/angle/checkout/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/checkout/include/GLSLANG/ShaderLang.h
@@ -20,17 +20,17 @@
 // and the shading language compiler.
 //
 
 // Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
 #include "ShaderVars.h"
 
 // Version number for shader translation API.
 // It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 196
+#define ANGLE_SH_VERSION 197
 
 enum ShShaderSpec
 {
     SH_GLES2_SPEC,
     SH_WEBGL_SPEC,
 
     SH_GLES3_SPEC,
     SH_WEBGL2_SPEC,
--- a/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
+++ b/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
@@ -121,17 +121,22 @@ struct ShaderVariable
     // Offset of this variable in parent arrays. In case the parent is an array of arrays, the
     // offset is outerArrayElement * innerArraySize + innerArrayElement.
     // For example, if there's a variable declared as size 3 array of size 4 array of int:
     //   int a[3][4];
     // then the flattenedOffsetInParentArrays of a[2] would be 2.
     // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9.
     unsigned int flattenedOffsetInParentArrays;
 
+    // Static use means that the variable is accessed somewhere in the shader source.
     bool staticUse;
+    // A variable is active unless the compiler determined that it is not accessed by the shader.
+    // All active variables are statically used, but not all statically used variables are
+    // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1.
+    bool active;
     std::vector<ShaderVariable> fields;
     std::string structName;
 
   protected:
     bool isSameVariableAtLinkTime(const ShaderVariable &other,
                                   bool matchPrecision,
                                   bool matchName) const;
 
@@ -274,16 +279,17 @@ struct InterfaceBlock
     BlockLayoutType layout;
 
     // Deprecated. Matrix packing should only be queried from individual fields of the block.
     // TODO(oetuaho): Remove this once it is no longer used in Chromium.
     bool isRowMajorLayout;
 
     int binding;
     bool staticUse;
+    bool active;
     BlockType blockType;
     std::vector<InterfaceBlockField> fields;
 };
 
 struct WorkGroupSize
 {
     // Must have a trivial default constructor since it is used in YYSTYPE.
     WorkGroupSize() = default;
--- a/gfx/angle/checkout/include/KHR/khrplatform.h
+++ b/gfx/angle/checkout/include/KHR/khrplatform.h
@@ -1,13 +1,13 @@
 #ifndef __khrplatform_h_
 #define __khrplatform_h_
 
 /*
-** Copyright (c) 2008-2009 The Khronos Group Inc.
+** Copyright (c) 2008-2018 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
 ** "Materials"), to deal in the Materials without restriction, including
 ** without limitation the rights to use, copy, modify, merge, publish,
 ** distribute, sublicense, and/or sell copies of the Materials, and to
 ** permit persons to whom the Materials are furnished to do so, subject to
 ** the following conditions:
@@ -21,28 +21,26 @@
 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
 
 /* Khronos platform-specific types and definitions.
  *
- * $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
+ * The master copy of khrplatform.h is maintained in the Khronos EGL
+ * Registry repository at https://github.com/KhronosGroup/EGL-Registry
+ * The last semantic modification to khrplatform.h was at commit ID:
+ *      67a3e0864c2d75ea5287b9f3d2eb74a745936692
  *
  * Adopters may modify this file to suit their platform. Adopters are
  * encouraged to submit platform specific modifications to the Khronos
  * group so that they can be included in future versions of this file.
- * Please submit changes by sending them to the public Khronos Bugzilla
- * (http://khronos.org/bugzilla) by filing a bug against product
- * "Khronos (general)" component "Registry".
- *
- * A predefined template which fills in some of the bug fields can be
- * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
- * must create a Bugzilla login first.
+ * Please submit changes by filing pull requests or issues on
+ * the EGL Registry repository linked above.
  *
  *
  * See the Implementer's Guidelines for information about where this file
  * should be located on your system and for more details of its use:
  *    http://www.khronos.org/registry/implementers_guide.pdf
  *
  * This file should be included as
  *        #include <KHR/khrplatform.h>
@@ -97,18 +95,17 @@
  *-------------------------------------------------------------------------
  * This precedes the return type of the function in the function prototype.
  */
 #if defined(_WIN32) && !defined(__SCITECH_SNAP__)
 #   define KHRONOS_APICALL __declspec(dllimport)
 #elif defined (__SYMBIAN32__)
 #   define KHRONOS_APICALL IMPORT_C
 #elif defined(__ANDROID__)
-#   include <sys/cdefs.h>
-#   define KHRONOS_APICALL __attribute__((visibility("default"))) __NDK_FPABI__
+#   define KHRONOS_APICALL __attribute__((visibility("default")))
 #else
 #   define KHRONOS_APICALL
 #endif
 
 /*-------------------------------------------------------------------------
  * Definition of KHRONOS_APIENTRY
  *-------------------------------------------------------------------------
  * This follows the return type of the function  and precedes the function
@@ -277,9 +274,9 @@ typedef khronos_int64_t        khronos_s
  * comparisons should not be made against KHRONOS_TRUE.
  */
 typedef enum {
     KHRONOS_FALSE = 0,
     KHRONOS_TRUE  = 1,
     KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
 } khronos_boolean_enum_t;
 
-#endif /* __khrplatform_h_ */
\ No newline at end of file
+#endif /* __khrplatform_h_ */
--- a/gfx/angle/checkout/out/gen/angle/id/commit.h
+++ b/gfx/angle/checkout/out/gen/angle/id/commit.h
@@ -1,3 +1,3 @@
-#define ANGLE_COMMIT_HASH "fcbca0e873c3"
+#define ANGLE_COMMIT_HASH "2426b097472f"
 #define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2018-04-20 16:07:35 -0700"
+#define ANGLE_COMMIT_DATE "2018-05-22 15:14:46 -0700"
--- a/gfx/angle/checkout/src/common/Color.h
+++ b/gfx/angle/checkout/src/common/Color.h
@@ -10,23 +10,26 @@
 #define COMMON_COLOR_H_
 
 namespace angle
 {
 
 template <typename T>
 struct Color
 {
+    Color();
+    Color(T r, T g, T b, T a);
+
+    const T *data() const { return &red; }
+    T *ptr() { return &red; }
+
     T red;
     T green;
     T blue;
     T alpha;
-
-    Color();
-    Color(T r, T g, T b, T a);
 };
 
 template <typename T>
 bool operator==(const Color<T> &a, const Color<T> &b);
 
 template <typename T>
 bool operator!=(const Color<T> &a, const Color<T> &b);
 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/checkout/src/common/FixedVector.h
@@ -0,0 +1,331 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FixedVector.h:
+//   A vector class with a maximum size and fixed storage.
+//
+
+#ifndef COMMON_FIXEDVECTOR_H_
+#define COMMON_FIXEDVECTOR_H_
+
+#include "common/debug.h"
+
+#include <algorithm>
+#include <array>
+#include <initializer_list>
+
+namespace angle
+{
+template <class T, size_t N, class Storage = std::array<T, N>>
+class FixedVector final
+{
+  public:
+    using value_type             = typename Storage::value_type;
+    using size_type              = typename Storage::size_type;
+    using reference              = typename Storage::reference;
+    using const_reference        = typename Storage::const_reference;
+    using pointer                = typename Storage::pointer;
+    using const_pointer          = typename Storage::const_pointer;
+    using iterator               = typename Storage::iterator;
+    using const_iterator         = typename Storage::const_iterator;
+    using reverse_iterator       = typename Storage::reverse_iterator;
+    using const_reverse_iterator = typename Storage::const_reverse_iterator;
+
+    FixedVector();
+    FixedVector(size_type count, const value_type &value);
+    FixedVector(size_type count);
+
+    FixedVector(const FixedVector<T, N, Storage> &other);
+    FixedVector(FixedVector<T, N, Storage> &&other);
+    FixedVector(std::initializer_list<value_type> init);
+
+    FixedVector<T, N, Storage> &operator=(const FixedVector<T, N, Storage> &other);
+    FixedVector<T, N, Storage> &operator=(FixedVector<T, N, Storage> &&other);
+    FixedVector<T, N, Storage> &operator=(std::initializer_list<value_type> init);
+
+    ~FixedVector();
+
+    reference at(size_type pos);
+    const_reference at(size_type pos) const;
+
+    reference operator[](size_type pos);
+    const_reference operator[](size_type pos) const;
+
+    pointer data();
+    const_pointer data() const;
+
+    iterator begin();
+    const_iterator begin() const;
+
+    iterator end();
+    const_iterator end() const;
+
+    bool empty() const;
+    size_type size() const;
+    size_type max_size() const;
+
+    void clear();
+
+    void push_back(const value_type &value);
+    void push_back(value_type &&value);
+
+    void pop_back();
+    reference back();
+    const_reference back() const;
+
+    void swap(FixedVector<T, N, Storage> &other);
+
+    void resize(size_type count);
+    void resize(size_type count, const value_type &value);
+
+    bool full() const;
+
+  private:
+    void assign_from_initializer_list(std::initializer_list<value_type> init);
+
+    Storage mStorage;
+    size_type mSize = 0;
+};
+
+template <class T, size_t N, class Storage>
+bool operator==(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b)
+{
+    return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
+}
+
+template <class T, size_t N, class Storage>
+bool operator!=(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b)
+{
+    return !(a == b);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector() = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(size_type count, const value_type &value) : mSize(count)
+{
+    ASSERT(count <= N);
+    std::fill(mStorage.begin(), mStorage.begin() + count, value);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(size_type count) : mSize(count)
+{
+    ASSERT(count <= N);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(const FixedVector<T, N, Storage> &other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(FixedVector<T, N, Storage> &&other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(std::initializer_list<value_type> init)
+{
+    ASSERT(init.size() <= N);
+    assign_from_initializer_list(init);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+    const FixedVector<T, N, Storage> &other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+    FixedVector<T, N, Storage> &&other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+    std::initializer_list<value_type> init)
+{
+    clear();
+    ASSERT(init.size() <= N);
+    assign_from_initializer_list(init);
+    return this;
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::~FixedVector()
+{
+    clear();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::at(size_type pos)
+{
+    ASSERT(pos < N);
+    return mStorage.at(pos);
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::at(
+    size_type pos) const
+{
+    ASSERT(pos < N);
+    return mStorage.at(pos);
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::operator[](size_type pos)
+{
+    ASSERT(pos < N);
+    return mStorage[pos];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::operator[](
+    size_type pos) const
+{
+    ASSERT(pos < N);
+    return mStorage[pos];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_pointer angle::FixedVector<T, N, Storage>::data() const
+{
+    return mStorage.data();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::pointer angle::FixedVector<T, N, Storage>::data()
+{
+    return mStorage.data();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::begin()
+{
+    return mStorage.begin();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::begin() const
+{
+    return mStorage.begin();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::end()
+{
+    return mStorage.begin() + mSize;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::end() const
+{
+    return mStorage.begin() + mSize;
+}
+
+template <class T, size_t N, class Storage>
+bool FixedVector<T, N, Storage>::empty() const
+{
+    return mSize == 0;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::size() const
+{
+    return mSize;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::max_size() const
+{
+    return N;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::clear()
+{
+    resize(0);
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::push_back(const value_type &value)
+{
+    ASSERT(mSize < N);
+    mStorage[mSize] = value;
+    mSize++;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::push_back(value_type &&value)
+{
+    ASSERT(mSize < N);
+    mStorage[mSize] = std::move(value);
+    mSize++;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::pop_back()
+{
+    ASSERT(mSize > 0);
+    mSize--;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::back()
+{
+    ASSERT(mSize > 0);
+    return mStorage[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::back() const
+{
+    ASSERT(mSize > 0);
+    return mStorage[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::swap(FixedVector<T, N, Storage> &other)
+{
+    std::swap(mSize, other.mSize);
+    std::swap(mStorage, other.mStorage);
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::resize(size_type count)
+{
+    resize(count, value_type());
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::resize(size_type count, const value_type &value)
+{
+    ASSERT(count <= N);
+    while (mSize > count)
+    {
+        mSize--;
+        mStorage[mSize] = T();
+    }
+    while (mSize < count)
+    {
+        mStorage[mSize] = value;
+        mSize++;
+    }
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::assign_from_initializer_list(
+    std::initializer_list<value_type> init)
+{
+    for (auto element : init)
+    {
+        mStorage[mSize] = std::move(element);
+        mSize++;
+    }
+}
+
+template <class T, size_t N, class Storage>
+bool FixedVector<T, N, Storage>::full() const
+{
+    return (mSize == N);
+}
+}  // namespace angle
+
+#endif  // COMMON_FIXEDVECTOR_H_
--- a/gfx/angle/checkout/src/common/angleutils.h
+++ b/gfx/angle/checkout/src/common/angleutils.h
@@ -186,16 +186,17 @@ std::string ToString(const T &value)
     return o.str();
 }
 
 // snprintf is not defined with MSVC prior to to msvc14
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #define snprintf _snprintf
 #endif
 
+#define GL_A1RGB5_ANGLEX 0x6AC5
 #define GL_BGRX8_ANGLEX 0x6ABA
 #define GL_BGR565_ANGLEX 0x6ABB
 #define GL_BGRA4_ANGLEX 0x6ABC
 #define GL_BGR5_A1_ANGLEX 0x6ABD
 #define GL_INT_64_ANGLEX 0x6ABE
 #define GL_UINT_64_ANGLEX 0x6ABF
 #define GL_BGRA8_SRGB_ANGLEX 0x6AC0
 
--- a/gfx/angle/checkout/src/common/bitset_utils.h
+++ b/gfx/angle/checkout/src/common/bitset_utils.h
@@ -35,20 +35,20 @@ class BitSetT final
             mParent->set(mBit, x);
             return *this;
         }
         explicit operator bool() const { return mParent->test(mBit); }
 
       private:
         friend class BitSetT;
 
-        Reference(BitSetT *parent, std::size_t bit) : mParent(parent), mBit(bit) {}
+        Reference(BitSetT *parent, ParamT bit) : mParent(parent), mBit(bit) {}
 
         BitSetT *mParent;
-        std::size_t mBit;
+        ParamT mBit;
     };
 
     class Iterator final
     {
       public:
         Iterator(const BitSetT &bits);
         Iterator &operator++();
 
@@ -59,18 +59,17 @@ class BitSetT final
       private:
         std::size_t getNextBit();
 
         BitSetT mBitsCopy;
         std::size_t mCurrentBit;
     };
 
     BitSetT();
-    BitSetT(BitsT value);
-    ~BitSetT();
+    constexpr explicit BitSetT(BitsT value);
 
     BitSetT(const BitSetT &other);
     BitSetT &operator=(const BitSetT &other);
 
     bool operator==(const BitSetT &other) const;
     bool operator!=(const BitSetT &other) const;
 
     constexpr bool operator[](ParamT pos) const;
@@ -85,16 +84,20 @@ class BitSetT final
 
     constexpr std::size_t size() const { return N; }
 
     BitSetT &operator&=(const BitSetT &other);
     BitSetT &operator|=(const BitSetT &other);
     BitSetT &operator^=(const BitSetT &other);
     BitSetT operator~() const;
 
+    BitSetT &operator&=(BitsT value);
+    BitSetT &operator|=(BitsT value);
+    BitSetT &operator^=(BitsT value);
+
     BitSetT operator<<(std::size_t pos) const;
     BitSetT &operator<<=(std::size_t pos);
     BitSetT operator>>(std::size_t pos) const;
     BitSetT &operator>>=(std::size_t pos);
 
     BitSetT &set();
     BitSetT &set(ParamT pos, bool value = true);
 
@@ -110,17 +113,21 @@ class BitSetT final
     Iterator begin() const { return Iterator(*this); }
     Iterator end() const { return Iterator(BitSetT()); }
 
   private:
     constexpr static BitsT Bit(ParamT x)
     {
         return (static_cast<BitsT>(1) << static_cast<size_t>(x));
     }
-    constexpr static BitsT Mask(std::size_t x) { return ((Bit(x - 1) - 1) << 1) + 1; }
+    // Produces a mask of ones up to the "x"th bit.
+    constexpr static BitsT Mask(std::size_t x)
+    {
+        return ((Bit(static_cast<ParamT>(x - 1)) - 1) << 1) + 1;
+    }
 
     BitsT mBits;
 };
 
 template <size_t N>
 class IterableBitSet : public std::bitset<N>
 {
   public:
@@ -208,22 +215,17 @@ unsigned long IterableBitSet<N>::Iterato
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT>::BitSetT() : mBits(0)
 {
     static_assert(N > 0, "Bitset type cannot support zero bits.");
     static_assert(N <= sizeof(BitsT) * 8, "Bitset type cannot support a size this large.");
 }
 
 template <size_t N, typename BitsT, typename ParamT>
-BitSetT<N, BitsT, ParamT>::BitSetT(BitsT value) : mBits(value & Mask(N))
-{
-}
-
-template <size_t N, typename BitsT, typename ParamT>
-BitSetT<N, BitsT, ParamT>::~BitSetT()
+constexpr BitSetT<N, BitsT, ParamT>::BitSetT(BitsT value) : mBits(value & Mask(N))
 {
 }
 
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT>::BitSetT(const BitSetT &other) : mBits(other.mBits)
 {
 }
 
@@ -308,16 +310,37 @@ BitSetT<N, BitsT, ParamT> &BitSetT<N, Bi
 
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator~() const
 {
     return BitSetT<N, BitsT, ParamT>(~mBits & Mask(N));
 }
 
 template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator&=(BitsT value)
+{
+    mBits &= value;
+    return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator|=(BitsT value)
+{
+    mBits |= value;
+    return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator^=(BitsT value)
+{
+    mBits ^= value;
+    return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator<<(std::size_t pos) const
 {
     return BitSetT<N, BitsT, ParamT>((mBits << pos) & Mask(N));
 }
 
 template <size_t N, typename BitsT, typename ParamT>
 BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator<<=(std::size_t pos)
 {
--- a/gfx/angle/checkout/src/common/mathutil.h
+++ b/gfx/angle/checkout/src/common/mathutil.h
@@ -4,57 +4,59 @@
 // found in the LICENSE file.
 //
 
 // mathutil.h: Math and bit manipulation functions.
 
 #ifndef COMMON_MATHUTIL_H_
 #define COMMON_MATHUTIL_H_
 
-#include <limits>
-#include <algorithm>
 #include <math.h>
-#include <string.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
+#include <algorithm>
+#include <limits>
 
 #include <anglebase/numerics/safe_math.h>
 
 #include "common/debug.h"
 #include "common/platform.h"
 
 namespace angle
 {
 using base::CheckedNumeric;
 using base::IsValueInRangeForNumericType;
 }
 
 namespace gl
 {
 
-const unsigned int Float32One = 0x3F800000;
+const unsigned int Float32One   = 0x3F800000;
 const unsigned short Float16One = 0x3C00;
 
-template<typename T>
+template <typename T>
 inline bool isPow2(T x)
 {
     static_assert(std::is_integral<T>::value, "isPow2 must be called on an integer type.");
     return (x & (x - 1)) == 0 && (x != 0);
 }
 
 inline int log2(int x)
 {
     int r = 0;
-    while ((x >> r) > 1) r++;
+    while ((x >> r) > 1)
+        r++;
     return r;
 }
 
 inline unsigned int ceilPow2(unsigned int x)
 {
-    if (x != 0) x--;
+    if (x != 0)
+        x--;
     x |= x >> 1;
     x |= x >> 2;
     x |= x >> 4;
     x |= x >> 8;
     x |= x >> 16;
     x++;
 
     return x;
@@ -103,29 +105,29 @@ inline unsigned int clampCast(bool value
 }
 
 template <>
 inline int clampCast(bool value)
 {
     return static_cast<int>(value);
 }
 
-template<typename T, typename MIN, typename MAX>
+template <typename T, typename MIN, typename MAX>
 inline T clamp(T x, MIN min, MAX max)
 {
     // Since NaNs fail all comparison tests, a NaN value will default to min
     return x > min ? (x > max ? max : x) : min;
 }
 
 inline float clamp01(float x)
 {
     return clamp(x, 0.0f, 1.0f);
 }
 
-template<const int n>
+template <const int n>
 inline unsigned int unorm(float x)
 {
     const unsigned int max = 0xFFFFFFFF >> (32 - n);
 
     if (x > 1)
     {
         return max;
     }
@@ -137,17 +139,17 @@ inline unsigned int unorm(float x)
     {
         return (unsigned int)(max * x + 0.5f);
     }
 }
 
 inline bool supportsSSE2()
 {
 #if defined(ANGLE_USE_SSE)
-    static bool checked = false;
+    static bool checked  = false;
     static bool supports = false;
 
     if (checked)
     {
         return supports;
     }
 
 #if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
@@ -177,79 +179,82 @@ destType bitCast(const sourceType &sourc
     destType output;
     memcpy(&output, &source, copySize);
     return output;
 }
 
 inline unsigned short float32ToFloat16(float fp32)
 {
     unsigned int fp32i = bitCast<unsigned int>(fp32);
-    unsigned int sign = (fp32i & 0x80000000) >> 16;
-    unsigned int abs = fp32i & 0x7FFFFFFF;
+    unsigned int sign  = (fp32i & 0x80000000) >> 16;
+    unsigned int abs   = fp32i & 0x7FFFFFFF;
 
-    if(abs > 0x47FFEFFF)   // Infinity
+    if (abs > 0x47FFEFFF)  // Infinity
     {
         return static_cast<unsigned short>(sign | 0x7FFF);
     }
-    else if(abs < 0x38800000)   // Denormal
+    else if (abs < 0x38800000)  // Denormal
     {
         unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
-        int e = 113 - (abs >> 23);
+        int e                 = 113 - (abs >> 23);
 
-        if(e < 24)
+        if (e < 24)
         {
             abs = mantissa >> e;
         }
         else
         {
             abs = 0;
         }
 
         return static_cast<unsigned short>(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
     }
     else
     {
-        return static_cast<unsigned short>(sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
+        return static_cast<unsigned short>(
+            sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
     }
 }
 
 float float16ToFloat32(unsigned short h);
 
 unsigned int convertRGBFloatsTo999E5(float red, float green, float blue);
 void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue);
 
 inline unsigned short float32ToFloat11(float fp32)
 {
-    const unsigned int float32MantissaMask = 0x7FFFFF;
-    const unsigned int float32ExponentMask = 0x7F800000;
-    const unsigned int float32SignMask = 0x80000000;
-    const unsigned int float32ValueMask = ~float32SignMask;
+    const unsigned int float32MantissaMask     = 0x7FFFFF;
+    const unsigned int float32ExponentMask     = 0x7F800000;
+    const unsigned int float32SignMask         = 0x80000000;
+    const unsigned int float32ValueMask        = ~float32SignMask;
     const unsigned int float32ExponentFirstBit = 23;
-    const unsigned int float32ExponentBias = 127;
+    const unsigned int float32ExponentBias     = 127;
 
-    const unsigned short float11Max = 0x7BF;
+    const unsigned short float11Max          = 0x7BF;
     const unsigned short float11MantissaMask = 0x3F;
     const unsigned short float11ExponentMask = 0x7C0;
-    const unsigned short float11BitMask = 0x7FF;
-    const unsigned int float11ExponentBias = 14;
+    const unsigned short float11BitMask      = 0x7FF;
+    const unsigned int float11ExponentBias   = 14;
 
     const unsigned int float32Maxfloat11 = 0x477E0000;
     const unsigned int float32Minfloat11 = 0x38800000;
 
     const unsigned int float32Bits = bitCast<unsigned int>(fp32);
-    const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
+    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;
 
     unsigned int float32Val = float32Bits & float32ValueMask;
 
     if ((float32Val & float32ExponentMask) == float32ExponentMask)
     {
         // INF or NAN
         if ((float32Val & float32MantissaMask) != 0)
         {
-            return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & float11MantissaMask);
+            return float11ExponentMask |
+                   (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) &
+                    float11MantissaMask);
         }
         else if (float32Sign)
         {
             // -INF is clamped to 0 since float11 is positive only
             return 0;
         }
         else
         {
@@ -267,58 +272,62 @@ inline unsigned short float32ToFloat11(f
         return float11Max;
     }
     else
     {
         if (float32Val < float32Minfloat11)
         {
             // The number is too small to be represented as a normalized float11
             // Convert it to a denormalized value.
-            const unsigned int shift = (float32ExponentBias - float11ExponentBias) - (float32Val >> float32ExponentFirstBit);
-            float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
+            const unsigned int shift = (float32ExponentBias - float11ExponentBias) -
+                                       (float32Val >> float32ExponentFirstBit);
+            float32Val =
+                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
         }
         else
         {
             // Rebias the exponent to represent the value as a normalized float11
             float32Val += 0xC8000000;
         }
 
         return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
     }
 }
 
 inline unsigned short float32ToFloat10(float fp32)
 {
-    const unsigned int float32MantissaMask = 0x7FFFFF;
-    const unsigned int float32ExponentMask = 0x7F800000;
-    const unsigned int float32SignMask = 0x80000000;
-    const unsigned int float32ValueMask = ~float32SignMask;
+    const unsigned int float32MantissaMask     = 0x7FFFFF;
+    const unsigned int float32ExponentMask     = 0x7F800000;
+    const unsigned int float32SignMask         = 0x80000000;
+    const unsigned int float32ValueMask        = ~float32SignMask;
     const unsigned int float32ExponentFirstBit = 23;
-    const unsigned int float32ExponentBias = 127;
+    const unsigned int float32ExponentBias     = 127;
 
-    const unsigned short float10Max = 0x3DF;
+    const unsigned short float10Max          = 0x3DF;
     const unsigned short float10MantissaMask = 0x1F;
     const unsigned short float10ExponentMask = 0x3E0;
-    const unsigned short float10BitMask = 0x3FF;
-    const unsigned int float10ExponentBias = 14;
+    const unsigned short float10BitMask      = 0x3FF;
+    const unsigned int float10ExponentBias   = 14;
 
     const unsigned int float32Maxfloat10 = 0x477C0000;
     const unsigned int float32Minfloat10 = 0x38800000;
 
     const unsigned int float32Bits = bitCast<unsigned int>(fp32);
-    const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
+    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;
 
     unsigned int float32Val = float32Bits & float32ValueMask;
 
     if ((float32Val & float32ExponentMask) == float32ExponentMask)
     {
         // INF or NAN
         if ((float32Val & float32MantissaMask) != 0)
         {
-            return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & float10MantissaMask);
+            return float10ExponentMask |
+                   (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) &
+                    float10MantissaMask);
         }
         else if (float32Sign)
         {
             // -INF is clamped to 0 since float11 is positive only
             return 0;
         }
         else
         {
@@ -336,18 +345,20 @@ inline unsigned short float32ToFloat10(f
         return float10Max;
     }
     else
     {
         if (float32Val < float32Minfloat10)
         {
             // The number is too small to be represented as a normalized float11
             // Convert it to a denormalized value.
-            const unsigned int shift = (float32ExponentBias - float10ExponentBias) - (float32Val >> float32ExponentFirstBit);
-            float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
+            const unsigned int shift = (float32ExponentBias - float10ExponentBias) -
+                                       (float32Val >> float32ExponentFirstBit);
+            float32Val =
+                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
         }
         else
         {
             // Rebias the exponent to represent the value as a normalized float11
             float32Val += 0xC8000000;
         }
 
         return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
@@ -374,22 +385,21 @@ inline float float11ToFloat32(unsigned s
         {
             // The value is denormalized
             exponent = 1;
 
             do
             {
                 exponent--;
                 mantissa <<= 1;
-            }
-            while ((mantissa & 0x40) == 0);
+            } while ((mantissa & 0x40) == 0);
 
             mantissa = mantissa & 0x3F;
         }
-        else // The value is zero
+        else  // The value is zero
         {
             exponent = static_cast<unsigned short>(-112);
         }
 
         return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
     }
 }
 
@@ -413,30 +423,55 @@ inline float float10ToFloat32(unsigned s
         {
             // The value is denormalized
             exponent = 1;
 
             do
             {
                 exponent--;
                 mantissa <<= 1;
-            }
-            while ((mantissa & 0x20) == 0);
+            } while ((mantissa & 0x20) == 0);
 
             mantissa = mantissa & 0x1F;
         }
-        else // The value is zero
+        else  // The value is zero
         {
             exponent = static_cast<unsigned short>(-112);
         }
 
         return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
     }
 }
 
+// Convers to and from float and 16.16 fixed point format.
+
+inline float FixedToFloat(uint32_t fixedInput)
+{
+    return static_cast<float>(fixedInput) / 65536.0f;
+}
+
+inline uint32_t FloatToFixed(float floatInput)
+{
+    static constexpr uint32_t kHighest = 32767 * 65536 + 65535;
+    static constexpr uint32_t kLowest  = static_cast<uint32_t>(-32768 * 65536 + 65535);
+
+    if (floatInput > 32767.65535)
+    {
+        return kHighest;
+    }
+    else if (floatInput < -32768.65535)
+    {
+        return kLowest;
+    }
+    else
+    {
+        return static_cast<uint32_t>(floatInput * 65536);
+    }
+}
+
 template <typename T>
 inline float normalizedToFloat(T input)
 {
     static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
 
     const float inverseMax = 1.0f / std::numeric_limits<T>::max();
     return input * inverseMax;
 }
@@ -558,22 +593,26 @@ inline float average(float a, float b)
 
 inline unsigned short averageHalfFloat(unsigned short a, unsigned short b)
 {
     return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f);
 }
 
 inline unsigned int averageFloat11(unsigned int a, unsigned int b)
 {
-    return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) + float11ToFloat32(static_cast<unsigned short>(b))) * 0.5f);
+    return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) +
+                             float11ToFloat32(static_cast<unsigned short>(b))) *
+                            0.5f);
 }
 
 inline unsigned int averageFloat10(unsigned int a, unsigned int b)
 {
-    return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) + float10ToFloat32(static_cast<unsigned short>(b))) * 0.5f);
+    return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) +
+                             float10ToFloat32(static_cast<unsigned short>(b))) *
+                            0.5f);
 }
 
 template <typename T>
 class Range
 {
   public:
     Range() {}
     Range(T lo, T hi) : mLow(lo), mHigh(hi) {}
@@ -682,60 +721,60 @@ inline float Ldexp(float x, int exp)
 // Then, the results are packed into the returned 32-bit unsigned integer.
 // The first float value will be written to the least significant bits of the output;
 // the last float value will be written to the most significant bits.
 // The conversion of each value to fixed point is done as follows :
 // packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0)
 inline uint32_t packSnorm2x16(float f1, float f2)
 {
     int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
-    int16_t mostSignificantBits = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
+    int16_t mostSignificantBits  = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
     return static_cast<uint32_t>(mostSignificantBits) << 16 |
            (static_cast<uint32_t>(leastSignificantBits) & 0xFFFF);
 }
 
-// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each
-// component is converted to a normalized floating-point value to generate the returned two float values.
-// The first float value will be extracted from the least significant bits of the input;
-// the last float value will be extracted from the most-significant bits.
-// The conversion for unpacked fixed-point value to floating point is done as follows:
-// unpackSnorm2x16 : clamp(f / 32767.0, -1, +1)
+// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
+// each component is converted to a normalized floating-point value to generate the returned two
+// float values. The first float value will be extracted from the least significant bits of the
+// input; the last float value will be extracted from the most-significant bits. The conversion for
+// unpacked fixed-point value to floating point is done as follows: unpackSnorm2x16 : clamp(f /
+// 32767.0, -1, +1)
 inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2)
 {
     int16_t leastSignificantBits = static_cast<int16_t>(u & 0xFFFF);
-    int16_t mostSignificantBits = static_cast<int16_t>(u >> 16);
+    int16_t mostSignificantBits  = static_cast<int16_t>(u >> 16);
     *f1 = clamp(static_cast<float>(leastSignificantBits) / 32767.0f, -1.0f, 1.0f);
     *f2 = clamp(static_cast<float>(mostSignificantBits) / 32767.0f, -1.0f, 1.0f);
 }
 
 // First, both normalized floating-point values are converted into 16-bit integer values.
 // Then, the results are packed into the returned 32-bit unsigned integer.
 // The first float value will be written to the least significant bits of the output;
 // the last float value will be written to the most significant bits.
 // The conversion of each value to fixed point is done as follows:
 // packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0)
 inline uint32_t packUnorm2x16(float f1, float f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f));
-    uint16_t mostSignificantBits = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
-    return static_cast<uint32_t>(mostSignificantBits) << 16 | static_cast<uint32_t>(leastSignificantBits);
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
+    return static_cast<uint32_t>(mostSignificantBits) << 16 |
+           static_cast<uint32_t>(leastSignificantBits);
 }
 
-// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each
-// component is converted to a normalized floating-point value to generate the returned two float values.
-// The first float value will be extracted from the least significant bits of the input;
-// the last float value will be extracted from the most-significant bits.
-// The conversion for unpacked fixed-point value to floating point is done as follows:
-// unpackUnorm2x16 : f / 65535.0
+// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
+// each component is converted to a normalized floating-point value to generate the returned two
+// float values. The first float value will be extracted from the least significant bits of the
+// input; the last float value will be extracted from the most-significant bits. The conversion for
+// unpacked fixed-point value to floating point is done as follows: unpackUnorm2x16 : f / 65535.0
 inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
-    uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
-    *f1 = static_cast<float>(leastSignificantBits) / 65535.0f;
-    *f2 = static_cast<float>(mostSignificantBits) / 65535.0f;
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);
+    *f1                           = static_cast<float>(leastSignificantBits) / 65535.0f;
+    *f2                           = static_cast<float>(mostSignificantBits) / 65535.0f;
 }
 
 // Helper functions intended to be used only here.
 namespace priv
 {
 
 inline uint8_t ToPackedUnorm8(float f)
 {
@@ -816,29 +855,30 @@ inline void UnpackSnorm4x8(uint32_t u, f
 // Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit
 // floating-point representation found in the OpenGL ES Specification, and then packing these
 // two 16-bit integers into a 32-bit unsigned integer.
 // f1: The 16 least-significant bits of the result;
 // f2: The 16 most-significant bits.
 inline uint32_t packHalf2x16(float f1, float f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(float32ToFloat16(f1));
-    uint16_t mostSignificantBits = static_cast<uint16_t>(float32ToFloat16(f2));
-    return static_cast<uint32_t>(mostSignificantBits) << 16 | static_cast<uint32_t>(leastSignificantBits);
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(float32ToFloat16(f2));
+    return static_cast<uint32_t>(mostSignificantBits) << 16 |
+           static_cast<uint32_t>(leastSignificantBits);
 }
 
-// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values,
-// interpreting those values as 16-bit floating-point numbers according to the OpenGL ES Specification,
-// and converting them to 32-bit floating-point values.
-// The first float value is obtained from the 16 least-significant bits of u;
-// the second component is obtained from the 16 most-significant bits of u.
+// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of
+// 16-bit values, interpreting those values as 16-bit floating-point numbers according to the OpenGL
+// ES Specification, and converting them to 32-bit floating-point values. The first float value is
+// obtained from the 16 least-significant bits of u; the second component is obtained from the 16
+// most-significant bits of u.
 inline void unpackHalf2x16(uint32_t u, float *f1, float *f2)
 {
     uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
-    uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
+    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);
 
     *f1 = float16ToFloat32(leastSignificantBits);
     *f2 = float16ToFloat32(mostSignificantBits);
 }
 
 inline uint8_t sRGBToLinear(uint8_t srgbValue)
 {
     float value = srgbValue / 255.0f;
@@ -999,31 +1039,35 @@ int FindMSB(T bits)
     }
     else
     {
         return static_cast<int>(ScanReverse(bits));
     }
 }
 
 // Returns whether the argument is Not a Number.
-// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - non-zero.
+// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
+// non-zero.
 inline bool isNaN(float f)
 {
     // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
     // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
-    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && (bitCast<uint32_t>(f) & 0x7fffffu);
+    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
+           (bitCast<uint32_t>(f) & 0x7fffffu);
 }
 
 // Returns whether the argument is infinity.
-// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - zero.
+// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
+// zero.
 inline bool isInf(float f)
 {
     // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
     // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
-    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast<uint32_t>(f) & 0x7fffffu);
+    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
+           !(bitCast<uint32_t>(f) & 0x7fffffu);
 }
 
 namespace priv
 {
 template <unsigned int N, unsigned int R>
 struct iSquareRoot
 {
     static constexpr unsigned int solve()
@@ -1112,31 +1156,30 @@ angle::CheckedNumeric<T> CheckedRoundUp(
 inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
 {
     unsigned int divided = value / divisor;
     return (divided + ((value % divisor == 0) ? 0 : 1));
 }
 
 #if defined(_MSC_VER)
 
-#define ANGLE_ROTL(x,y) _rotl(x,y)
-#define ANGLE_ROTR16(x,y) _rotr16(x,y)
+#define ANGLE_ROTL(x, y) _rotl(x, y)
+#define ANGLE_ROTR16(x, y) _rotr16(x, y)
 
 #else
 
 inline uint32_t RotL(uint32_t x, int8_t r)
 {
     return (x << r) | (x >> (32 - r));
 }
 
 inline uint16_t RotR16(uint16_t x, int8_t r)
 {
     return (x >> r) | (x << (16 - r));
 }
 
 #define ANGLE_ROTL(x, y) ::rx::RotL(x, y)
 #define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y)
 
-#endif // namespace rx
-
+#endif  // namespace rx
 }
 
-#endif   // COMMON_MATHUTIL_H_
+#endif  // COMMON_MATHUTIL_H_
--- a/gfx/angle/checkout/src/common/matrix_utils.h
+++ b/gfx/angle/checkout/src/common/matrix_utils.h
@@ -89,16 +89,38 @@ class Matrix
     {
         ASSERT(columns() == m.rows());
         Matrix<T> res  = (*this) * m;
         size_t numElts = res.elements().size();
         mElements.resize(numElts);
         memcpy(mElements.data(), res.data(), numElts * sizeof(float));
     }
 
+    bool operator==(const Matrix<T> &m) const
+    {
+        ASSERT(columns() == m.columns());
+        ASSERT(rows() == m.rows());
+        return mElements == m.elements();
+    }
+
+    bool operator!=(const Matrix<T> &m) const { return !(mElements == m.elements()); }
+
+    bool nearlyEqual(T epsilon, const Matrix<T> &m) const
+    {
+        ASSERT(columns() == m.columns());
+        ASSERT(rows() == m.rows());
+        const auto &otherElts = m.elements();
+        for (size_t i = 0; i < otherElts.size(); i++)
+        {
+            if ((mElements[i] - otherElts[i] > epsilon) && (otherElts[i] - mElements[i] > epsilon))
+                return false;
+        }
+        return true;
+    }
+
     unsigned int size() const
     {
         ASSERT(rows() == columns());
         return rows();
     }
 
     unsigned int rows() const { return mRows; }
 
--- a/gfx/angle/checkout/src/common/utilities.cpp
+++ b/gfx/angle/checkout/src/common/utilities.cpp
@@ -432,60 +432,16 @@ bool IsAtomicCounterType(GLenum type)
 }
 
 bool IsOpaqueType(GLenum type)
 {
     // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
     return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
 }
 
-GLenum SamplerTypeToTextureType(GLenum samplerType)
-{
-    switch (samplerType)
-    {
-      case GL_SAMPLER_2D:
-      case GL_INT_SAMPLER_2D:
-      case GL_UNSIGNED_INT_SAMPLER_2D:
-      case GL_SAMPLER_2D_SHADOW:
-        return GL_TEXTURE_2D;
-
-      case GL_SAMPLER_EXTERNAL_OES:
-          return GL_TEXTURE_EXTERNAL_OES;
-
-      case GL_SAMPLER_CUBE:
-      case GL_INT_SAMPLER_CUBE:
-      case GL_UNSIGNED_INT_SAMPLER_CUBE:
-      case GL_SAMPLER_CUBE_SHADOW:
-        return GL_TEXTURE_CUBE_MAP;
-
-      case GL_SAMPLER_2D_ARRAY:
-      case GL_INT_SAMPLER_2D_ARRAY:
-      case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
-      case GL_SAMPLER_2D_ARRAY_SHADOW:
-        return GL_TEXTURE_2D_ARRAY;
-
-      case GL_SAMPLER_3D:
-      case GL_INT_SAMPLER_3D:
-      case GL_UNSIGNED_INT_SAMPLER_3D:
-        return GL_TEXTURE_3D;
-
-      case GL_SAMPLER_2D_MULTISAMPLE:
-      case GL_INT_SAMPLER_2D_MULTISAMPLE:
-      case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
-          return GL_TEXTURE_2D_MULTISAMPLE;
-
-      case GL_SAMPLER_2D_RECT_ANGLE:
-          return GL_TEXTURE_RECTANGLE_ANGLE;
-
-      default:
-        UNREACHABLE();
-        return 0;
-    }
-}
-
 bool IsMatrixType(GLenum type)
 {
     return VariableRowCount(type) > 1;
 }
 
 GLenum TransposeMatrixType(GLenum type)
 {
     if (!IsMatrixType(type))
@@ -540,39 +496,16 @@ int AllocateFirstFreeBits(unsigned int *
         }
 
         mask <<= 1;
     }
 
     return -1;
 }
 
-static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
-static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
-
-bool IsCubeMapTextureTarget(GLenum target)
-{
-    return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
-}
-
-size_t CubeMapTextureTargetToLayerIndex(GLenum target)
-{
-    ASSERT(IsCubeMapTextureTarget(target));
-    return target - static_cast<size_t>(FirstCubeMapTextureTarget);
-}
-
-GLenum LayerIndexToCubeMapTextureTarget(size_t index)
-{
-    ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
-    return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
-}
-
 IndexRange ComputeIndexRange(GLenum indexType,
                              const GLvoid *indices,
                              size_t count,
                              bool primitiveRestartEnabled)
 {
     switch (indexType)
     {
         case GL_UNSIGNED_BYTE:
@@ -991,62 +924,16 @@ const char *GetGenericErrorMessage(EGLin
             return "Unknown error.";
     }
 }
 
 }  // namespace egl
 
 namespace egl_gl
 {
-GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
-{
-    ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
-    return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
-}
-
-GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
-{
-    switch (eglTarget)
-    {
-        case EGL_GL_TEXTURE_2D_KHR:
-            return GL_TEXTURE_2D;
-
-        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
-        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
-            return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
-
-        case EGL_GL_TEXTURE_3D_KHR:
-            return GL_TEXTURE_3D;
-
-        default:
-            UNREACHABLE();
-            return GL_NONE;
-    }
-}
-
-GLenum EGLTextureTargetToGLTextureTarget(EGLenum eglTarget)
-{
-    switch (eglTarget)
-    {
-        case EGL_TEXTURE_2D:
-            return GL_TEXTURE_2D;
-
-        case EGL_TEXTURE_RECTANGLE_ANGLE:
-            return GL_TEXTURE_RECTANGLE_ANGLE;
-
-        default:
-            UNREACHABLE();
-            return GL_NONE;
-    }
-}
-
 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
 {
     return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
 }
 }  // namespace egl_gl
 
 namespace gl_egl
 {
--- a/gfx/angle/checkout/src/common/utilities.h
+++ b/gfx/angle/checkout/src/common/utilities.h
@@ -33,33 +33,26 @@ size_t VariableComponentSize(GLenum type
 size_t VariableInternalSize(GLenum type);
 size_t VariableExternalSize(GLenum type);
 int VariableRowCount(GLenum type);
 int VariableColumnCount(GLenum type);
 bool IsSamplerType(GLenum type);
 bool IsImageType(GLenum type);
 bool IsAtomicCounterType(GLenum type);
 bool IsOpaqueType(GLenum type);
-GLenum SamplerTypeToTextureType(GLenum samplerType);
 bool IsMatrixType(GLenum type);
 GLenum TransposeMatrixType(GLenum type);
 int VariableRegisterCount(GLenum type);
 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix);
 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix);
 int VariableSortOrder(GLenum type);
 GLenum VariableBoolVectorType(GLenum type);
 
 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
 
-static const GLenum FirstCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-static const GLenum LastCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
-bool IsCubeMapTextureTarget(GLenum target);
-size_t CubeMapTextureTargetToLayerIndex(GLenum target);
-GLenum LayerIndexToCubeMapTextureTarget(size_t index);
-
 // Parse the base resource name and array indices. Returns the base name of the resource.
 // If the provided name doesn't index an array, the outSubscripts vector will be empty.
 // If the provided name indexes an array, the outSubscripts vector will contain indices with
 // outermost array indices in the back. If an array index is invalid, GL_INVALID_INDEX is added to
 // outSubscripts.
 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts);
 
 // Find the child field which matches 'fullName' == var.name + "." + field.name.
@@ -156,19 +149,16 @@ EGLenum LayerIndexToCubeMapTextureTarget
 bool IsTextureTarget(EGLenum target);
 bool IsRenderbufferTarget(EGLenum target);
 
 const char *GetGenericErrorMessage(EGLint error);
 }  // namespace egl
 
 namespace egl_gl
 {
-GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget);
-GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget);
-GLenum EGLTextureTargetToGLTextureTarget(EGLenum eglTarget);
 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
 }
 
 namespace gl_egl
 {
 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
 }  // namespace gl_egl
 
--- a/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.cpp
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.cpp
@@ -932,16 +932,17 @@ typedef pp::SourceLocation YYLTYPE;
 #define YY_USER_INIT                   \
     do {                               \
         yyfileno = 0;                  \
         yylineno = 1;                  \
         yyextra->leadingSpace = false; \
         yyextra->lineStart = true;     \
     } while(0);
 
+#define YY_NO_INPUT
 #define YY_USER_ACTION                                              \
     do                                                              \
     {                                                               \
         pp::Input* input = &yyextra->input;                         \
         pp::Input::Location* scanLoc = &yyextra->scanLoc;           \
         while ((scanLoc->sIndex < input->count()) &&                \
                (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
         {                                                           \
--- a/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.l
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.l
@@ -59,16 +59,17 @@ typedef pp::SourceLocation YYLTYPE;
 #define YY_USER_INIT                   \
     do {                               \
         yyfileno = 0;                  \
         yylineno = 1;                  \
         yyextra->leadingSpace = false; \
         yyextra->lineStart = true;     \
     } while(0);
 
+#define YY_NO_INPUT
 #define YY_USER_ACTION                                              \
     do                                                              \
     {                                                               \
         pp::Input* input = &yyextra->input;                         \
         pp::Input::Location* scanLoc = &yyextra->scanLoc;           \
         while ((scanLoc->sIndex < input->count()) &&                \
                (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
         {                                                           \
--- a/gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
+++ b/gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
@@ -43,30 +43,17 @@ bool numeric_lex_int(const std::string &
 
     stream >> (*value);
     return !stream.fail();
 }
 
 template <typename FloatType>
 bool numeric_lex_float(const std::string &str, FloatType *value)
 {
-// On 64-bit Intel Android, istringstream is broken.  Until this is fixed in
-// a newer NDK, don't use it.  Android doesn't have locale support, so this
-// doesn't have to force the C locale.
-// TODO(thakis): Remove this once this bug has been fixed in the NDK and
-// that NDK has been rolled into chromium.
-#if defined(ANGLE_PLATFORM_ANDROID) && __x86_64__
-    *value = strtod(str.c_str(), nullptr);
-    return errno != ERANGE;
-#else
-    std::istringstream stream(str);
-    // Force "C" locale so that decimal character is always '.', and
-    // not dependent on the current locale.
-    stream.imbue(std::locale::classic());
-
-    stream >> (*value);
-    return !stream.fail() && std::isfinite(*value);
-#endif
+    // Some platforms have issues with the usage of std::locale and std::stringstream and cause
+    // crashes. Usage of strtod appears to be safe.
+    *value = static_cast<FloatType>(strtod(str.c_str(), nullptr));
+    return errno != ERANGE && std::isfinite(*value);
 }
 
 }  // namespace pp.
 
 #endif  // COMPILER_PREPROCESSOR_NUMERICLEX_H_
--- a/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -4,18 +4,18 @@
 // found in the LICENSE file.
 //
 
 // Analysis of the AST needed for HLSL generation
 
 #include "compiler/translator/ASTMetadataHLSL.h"
 
 #include "compiler/translator/CallDAG.h"
-#include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 namespace sh
 {
 
 namespace
 {
 
 // Class used to traverse the AST of a function definition, checking if the
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/AddAndTrueToLoopCondition.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-// An AST traverser that rewrites for and while loops by replacing "condition" with
-// "condition && true" to work around condition bug on Intel Mac.
-class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
-{
-  public:
-    AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {}
-
-    bool visitLoop(Visit, TIntermLoop *loop) override
-    {
-        // do-while loop doesn't have this bug.
-        if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile)
-        {
-            return true;
-        }
-
-        // For loop may not have a condition.
-        if (loop->getCondition() == nullptr)
-        {
-            return true;
-        }
-
-        // Constant true.
-        TIntermTyped *trueValue = CreateBoolNode(true);
-
-        // CONDITION && true.
-        TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
-        loop->setCondition(andOp);
-
-        return true;
-    }
-};
-
-}  // anonymous namespace
-
-void AddAndTrueToLoopCondition(TIntermNode *root)
-{
-    AddAndTrueToLoopConditionTraverser traverser;
-    root->traverse(&traverser);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddAndTrueToLoopCondition.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Rewrite condition in for and while loops to work around driver bug on Intel Mac.
-
-#ifndef COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
-#define COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void AddAndTrueToLoopCondition(TIntermNode *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// AddDefaultReturnStatements.cpp: Add default return statements to functions that do not end in a
-//                                 return.
-//
-
-#include "compiler/translator/AddDefaultReturnStatements.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/util.h"
-
-namespace sh
-{
-
-namespace
-{
-
-bool NeedsReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
-{
-    *returnType = node->getFunctionPrototype()->getType();
-    if (returnType->getBasicType() == EbtVoid)
-    {
-        return false;
-    }
-
-    TIntermBlock *bodyNode    = node->getBody();
-    TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
-    if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
-    {
-        return false;
-    }
-
-    return true;
-}
-
-}  // anonymous namespace
-
-void AddDefaultReturnStatements(TIntermBlock *root)
-{
-    TType returnType;
-    for (TIntermNode *node : *root->getSequence())
-    {
-        TIntermFunctionDefinition *definition = node->getAsFunctionDefinition();
-        if (definition != nullptr && NeedsReturnStatement(definition, &returnType))
-        {
-            TIntermBranch *branch = new TIntermBranch(EOpReturn, CreateZeroNode(returnType));
-
-            TIntermBlock *bodyNode = definition->getBody();
-            bodyNode->getSequence()->push_back(branch);
-        }
-    }
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/AddDefaultReturnStatements.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// AddDefaultReturnStatements.h: Add default return statements to functions that do not end in a
-//                               return.
-//
-
-#ifndef COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_
-#define COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_
-
-class TIntermBlock;
-
-namespace sh
-{
-
-void AddDefaultReturnStatements(TIntermBlock *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-//
-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// The ArrayReturnValueToOutParameter function changes return values of an array type to out
-// parameters in function definitions, prototypes, and call sites.
-
-#include "compiler/translator/ArrayReturnValueToOutParameter.h"
-
-#include <map>
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kReturnValueVariableName("angle_return");
-
-void CopyAggregateChildren(TIntermAggregateBase *from, TIntermAggregateBase *to)
-{
-    const TIntermSequence *fromSequence = from->getSequence();
-    for (size_t ii = 0; ii < fromSequence->size(); ++ii)
-    {
-        to->getSequence()->push_back(fromSequence->at(ii));
-    }
-}
-
-class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
-{
-  public:
-    static void apply(TIntermNode *root, TSymbolTable *symbolTable);
-
-  private:
-    ArrayReturnValueToOutParameterTraverser(TSymbolTable *symbolTable);
-
-    bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override;
-    bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
-    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
-    bool visitBranch(Visit visit, TIntermBranch *node) override;
-    bool visitBinary(Visit visit, TIntermBinary *node) override;
-
-    TIntermAggregate *createReplacementCall(TIntermAggregate *originalCall,
-                                            TIntermTyped *returnValueTarget);
-
-    // Set when traversal is inside a function with array return value.
-    TIntermFunctionDefinition *mFunctionWithArrayReturnValue;
-
-    struct ChangedFunction
-    {
-        const TVariable *returnValueVariable;
-        const TFunction *func;
-    };
-
-    // Map from function symbol ids to the changed function.
-    std::map<int, ChangedFunction> mChangedFunctions;
-};
-
-TIntermAggregate *ArrayReturnValueToOutParameterTraverser::createReplacementCall(
-    TIntermAggregate *originalCall,
-    TIntermTyped *returnValueTarget)
-{
-    TIntermSequence *replacementArguments = new TIntermSequence();
-    TIntermSequence *originalArguments    = originalCall->getSequence();
-    for (auto &arg : *originalArguments)
-    {
-        replacementArguments->push_back(arg);
-    }
-    replacementArguments->push_back(returnValueTarget);
-    ASSERT(originalCall->getFunction());
-    const TSymbolUniqueId &originalId = originalCall->getFunction()->uniqueId();
-    TIntermAggregate *replacementCall = TIntermAggregate::CreateFunctionCall(
-        *mChangedFunctions[originalId.get()].func, replacementArguments);
-    replacementCall->setLine(originalCall->getLine());
-    return replacementCall;
-}
-
-void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam(symbolTable);
-    root->traverse(&arrayReturnValueToOutParam);
-    arrayReturnValueToOutParam.updateTree();
-}
-
-ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser(
-    TSymbolTable *symbolTable)
-    : TIntermTraverser(true, false, true, symbolTable), mFunctionWithArrayReturnValue(nullptr)
-{
-}
-
-bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition(
-    Visit visit,
-    TIntermFunctionDefinition *node)
-{
-    if (node->getFunctionPrototype()->isArray() && visit == PreVisit)
-    {
-        // Replacing the function header is done on visitFunctionPrototype().
-        mFunctionWithArrayReturnValue = node;
-    }
-    if (visit == PostVisit)
-    {
-        mFunctionWithArrayReturnValue = nullptr;
-    }
-    return true;
-}
-
-bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit,
-                                                                     TIntermFunctionPrototype *node)
-{
-    if (visit == PreVisit && node->isArray())
-    {
-        // Replace the whole prototype node with another node that has the out parameter
-        // added. Also set the function to return void.
-        const TSymbolUniqueId &functionId = node->getFunction()->uniqueId();
-        if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end())
-        {
-            TType *returnValueVariableType = new TType(node->getType());
-            returnValueVariableType->setQualifier(EvqOut);
-            ChangedFunction changedFunction;
-            changedFunction.returnValueVariable =
-                new TVariable(mSymbolTable, kReturnValueVariableName, returnValueVariableType,
-                              SymbolType::AngleInternal);
-            TFunction *func = new TFunction(mSymbolTable, node->getFunction()->name(),
-                                            node->getFunction()->symbolType(),
-                                            StaticType::GetBasic<EbtVoid>(), false);
-            for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i)
-            {
-                func->addParameter(node->getFunction()->getParam(i));
-            }
-            func->addParameter(TConstParameter(
-                kReturnValueVariableName, static_cast<const TType *>(returnValueVariableType)));
-            changedFunction.func                = func;
-            mChangedFunctions[functionId.get()] = changedFunction;
-        }
-        TIntermFunctionPrototype *replacement =
-            new TIntermFunctionPrototype(mChangedFunctions[functionId.get()].func);
-        CopyAggregateChildren(node, replacement);
-        replacement->getSequence()->push_back(
-            new TIntermSymbol(mChangedFunctions[functionId.get()].returnValueVariable));
-        replacement->setLine(node->getLine());
-
-        queueReplacement(replacement, OriginalNode::IS_DROPPED);
-    }
-    return false;
-}
-
-bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
-{
-    ASSERT(!node->isArray() || node->getOp() != EOpCallInternalRawFunction);
-    if (visit == PreVisit && node->isArray() && node->getOp() == EOpCallFunctionInAST)
-    {
-        // Handle call sites where the returned array is not assigned.
-        // Examples where f() is a function returning an array:
-        // 1. f();
-        // 2. another_array == f();
-        // 3. another_function(f());
-        // 4. return f();
-        // Cases 2 to 4 are already converted to simpler cases by
-        // SeparateExpressionsReturningArrays, so we only need to worry about the case where a
-        // function call returning an array forms an expression by itself.
-        TIntermBlock *parentBlock = getParentNode()->getAsBlock();
-        if (parentBlock)
-        {
-            // replace
-            //   f();
-            // with
-            //   type s0[size]; f(s0);
-            TIntermSequence replacements;
-
-            // type s0[size];
-            TIntermDeclaration *returnValueDeclaration = nullptr;
-            TVariable *returnValue = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
-                                                         EvqTemporary, &returnValueDeclaration);
-            replacements.push_back(returnValueDeclaration);
-
-            // f(s0);
-            TIntermSymbol *returnValueSymbol = CreateTempSymbolNode(returnValue);
-            replacements.push_back(createReplacementCall(node, returnValueSymbol));
-            mMultiReplacements.push_back(
-                NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
-        }
-        return false;
-    }
-    return true;
-}
-
-bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBranch *node)
-{
-    if (mFunctionWithArrayReturnValue && node->getFlowOp() == EOpReturn)
-    {
-        // Instead of returning a value, assign to the out parameter and then return.
-        TIntermSequence replacements;
-
-        TIntermTyped *expression = node->getExpression();
-        ASSERT(expression != nullptr);
-        const TSymbolUniqueId &functionId =
-            mFunctionWithArrayReturnValue->getFunction()->uniqueId();
-        ASSERT(mChangedFunctions.find(functionId.get()) != mChangedFunctions.end());
-        TIntermSymbol *returnValueSymbol =
-            new TIntermSymbol(mChangedFunctions[functionId.get()].returnValueVariable);
-        TIntermBinary *replacementAssignment =
-            new TIntermBinary(EOpAssign, returnValueSymbol, expression);
-        replacementAssignment->setLine(expression->getLine());
-        replacements.push_back(replacementAssignment);
-
-        TIntermBranch *replacementBranch = new TIntermBranch(EOpReturn, nullptr);
-        replacementBranch->setLine(node->getLine());
-        replacements.push_back(replacementBranch);
-
-        mMultiReplacements.push_back(
-            NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, replacements));
-    }
-    return false;
-}
-
-bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBinary *node)
-{
-    if (node->getOp() == EOpAssign && node->getLeft()->isArray())
-    {
-        TIntermAggregate *rightAgg = node->getRight()->getAsAggregate();
-        ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpCallInternalRawFunction);
-        if (rightAgg != nullptr && rightAgg->getOp() == EOpCallFunctionInAST)
-        {
-            TIntermAggregate *replacementCall = createReplacementCall(rightAgg, node->getLeft());
-            queueReplacement(replacementCall, OriginalNode::IS_DROPPED);
-        }
-    }
-    return false;
-}
-
-}  // namespace
-
-void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable)
-{
-    ArrayReturnValueToOutParameterTraverser::apply(root, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ArrayReturnValueToOutParameter.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// The ArrayReturnValueToOutParameter function changes return values of an array type to out
-// parameters in function definitions, prototypes and call sites.
-
-#ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
-#define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
-
-namespace sh
-{
-
-class TIntermNode;
-class TSymbolTable;
-
-void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
--- a/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
+++ b/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
@@ -52,28 +52,22 @@ inline const char *getPrecisionString(TP
 //
 enum TBasicType
 {
     EbtVoid,
     EbtFloat,
     EbtInt,
     EbtUInt,
     EbtBool,
-    EbtGVec4,              // non type: represents vec4, ivec4, and uvec4
-    EbtGenType,            // non type: represents float, vec2, vec3, and vec4
-    EbtGenIType,           // non type: represents int, ivec2, ivec3, and ivec4
-    EbtGenUType,           // non type: represents uint, uvec2, uvec3, and uvec4
-    EbtGenBType,           // non type: represents bool, bvec2, bvec3, and bvec4
-    EbtVec,                // non type: represents vec2, vec3, and vec4
-    EbtIVec,               // non type: represents ivec2, ivec3, and ivec4
-    EbtUVec,               // non type: represents uvec2, uvec3, and uvec4
-    EbtBVec,               // non type: represents bvec2, bvec3, and bvec4
+
+    EbtAtomicCounter,
     EbtYuvCscStandardEXT,  // Only valid if EXT_YUV_target exists.
+
     EbtGuardSamplerBegin,  // non type: see implementation of IsSampler()
-    EbtSampler2D,
+    EbtSampler2D = EbtGuardSamplerBegin,
     EbtSampler3D,
     EbtSamplerCube,
     EbtSampler2DArray,
     EbtSamplerExternalOES,       // Only valid if OES_EGL_image_external exists.
     EbtSamplerExternal2DY2YEXT,  // Only valid if GL_EXT_YUV_target exists.
     EbtSampler2DRect,            // Only valid if GL_ARB_texture_rectangle exists.
     EbtSampler2DMS,
     EbtISampler2D,
@@ -84,163 +78,67 @@ enum TBasicType
     EbtUSampler2D,
     EbtUSampler3D,
     EbtUSamplerCube,
     EbtUSampler2DArray,
     EbtUSampler2DMS,
     EbtSampler2DShadow,
     EbtSamplerCubeShadow,
     EbtSampler2DArrayShadow,
-    EbtGuardSamplerEnd,  // non type: see implementation of IsSampler()
-    EbtGSampler2D,       // non type: represents sampler2D, isampler2D, and usampler2D
-    EbtGSampler3D,       // non type: represents sampler3D, isampler3D, and usampler3D
-    EbtGSamplerCube,     // non type: represents samplerCube, isamplerCube, and usamplerCube
-    EbtGSampler2DArray,  // non type: represents sampler2DArray, isampler2DArray, and
-                         // usampler2DArray
-    EbtGSampler2DMS,     // non type: represents sampler2DMS, isampler2DMS, and usampler2DMS
+    EbtGuardSamplerEnd = EbtSampler2DArrayShadow,  // non type: see implementation of IsSampler()
 
     // images
     EbtGuardImageBegin,
-    EbtImage2D,
+    EbtImage2D = EbtGuardImageBegin,
     EbtIImage2D,
     EbtUImage2D,
     EbtImage3D,
     EbtIImage3D,
     EbtUImage3D,
     EbtImage2DArray,
     EbtIImage2DArray,
     EbtUImage2DArray,
     EbtImageCube,
     EbtIImageCube,
     EbtUImageCube,
-    EbtGuardImageEnd,
+    EbtGuardImageEnd = EbtUImageCube,
 
-    EbtGuardGImageBegin,
-    EbtGImage2D,       // non type: represents image2D, uimage2D, iimage2D
-    EbtGImage3D,       // non type: represents image3D, uimage3D, iimage3D
-    EbtGImage2DArray,  // non type: represents image2DArray, uimage2DArray, iimage2DArray
-    EbtGImageCube,     // non type: represents imageCube, uimageCube, iimageCube
-    EbtGuardGImageEnd,
+    EbtLastSimpleType = EbtGuardImageEnd,
 
     EbtStruct,
     EbtInterfaceBlock,
-    EbtAddress,  // should be deprecated??
-
-    EbtAtomicCounter,
 
     // end of list
-    EbtLast
+    EbtLast = EbtInterfaceBlock
 };
 
-constexpr const char *GetBasicMangledName(TBasicType t)
+constexpr char GetBasicMangledName(TBasicType t)
 {
-    switch (t)
+    if (t > EbtLastSimpleType)
     {
-        case EbtFloat:
-            return "f";
-        case EbtInt:
-            return "i";
-        case EbtUInt:
-            return "u";
-        case EbtBool:
-            return "b";
-        case EbtYuvCscStandardEXT:
-            return "ycs";
-        case EbtSampler2D:
-            return "s2";
-        case EbtSampler3D:
-            return "s3";
-        case EbtSamplerCube:
-            return "sC";
-        case EbtSampler2DArray:
-            return "s2a";
-        case EbtSamplerExternalOES:
-            return "sext";
-        case EbtSamplerExternal2DY2YEXT:
-            return "sext2y2y";
-        case EbtSampler2DRect:
-            return "s2r";
-        case EbtSampler2DMS:
-            return "s2ms";
-        case EbtISampler2D:
-            return "is2";
-        case EbtISampler3D:
-            return "is3";
-        case EbtISamplerCube:
-            return "isC";
-        case EbtISampler2DArray:
-            return "is2a";
-        case EbtISampler2DMS:
-            return "is2ms";
-        case EbtUSampler2D:
-            return "us2";
-        case EbtUSampler3D:
-            return "us3";
-        case EbtUSamplerCube:
-            return "usC";
-        case EbtUSampler2DArray:
-            return "us2a";
-        case EbtUSampler2DMS:
-            return "us2ms";
-        case EbtSampler2DShadow:
-            return "s2s";
-        case EbtSamplerCubeShadow:
-            return "sCs";
-        case EbtSampler2DArrayShadow:
-            return "s2as";
-        case EbtImage2D:
-            return "im2";
-        case EbtIImage2D:
-            return "iim2";
-        case EbtUImage2D:
-            return "uim2";
-        case EbtImage3D:
-            return "im3";
-        case EbtIImage3D:
-            return "iim3";
-        case EbtUImage3D:
-            return "uim3";
-        case EbtImage2DArray:
-            return "im2a";
-        case EbtIImage2DArray:
-            return "iim2a";
-        case EbtUImage2DArray:
-            return "uim2a";
-        case EbtImageCube:
-            return "imc";
-        case EbtIImageCube:
-            return "iimc";
-        case EbtUImageCube:
-            return "uimc";
-        case EbtAtomicCounter:
-            return "ac";
-        case EbtStruct:
-        case EbtInterfaceBlock:
-            return nullptr;
-        default:
-            // EbtVoid, EbtAddress and non types
-            return "";
+        return '{';
     }
+    static_assert(EbtLastSimpleType < 52, "We only use alphabetic characters for mangled names");
+    if (t < 26)
+    {
+        return static_cast<char>('A' + t);
+    }
+    return static_cast<char>('a' - 26 + t);
 }
 
 const char *getBasicString(TBasicType t);
 
 inline bool IsSampler(TBasicType type)
 {
-    return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
+    return type >= EbtGuardSamplerBegin && type <= EbtGuardSamplerEnd;
 }
 
 inline bool IsImage(TBasicType type)
 {
-    return type > EbtGuardImageBegin && type < EbtGuardImageEnd;
-}
-
-inline bool IsGImage(TBasicType type)
-{
-    return type > EbtGuardGImageBegin && type < EbtGuardGImageEnd;
+    return type >= EbtGuardImageBegin && type <= EbtGuardImageEnd;
 }
 
 inline bool IsAtomicCounter(TBasicType type)
 {
     return type == EbtAtomicCounter;
 }
 
 inline bool IsOpaqueType(TBasicType type)
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
-//      may record a variable as aliasing another. Sometimes the alias information gets garbled
-//      so we work around this issue by breaking the aliasing chain in inner loops.
-
-#include "BreakVariableAliasingInInnerLoops.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-// A HLSL compiler developer gave us more details on the root cause and the workaround needed:
-//     The root problem is that if the HLSL compiler is applying aliasing information even on
-//     incomplete simulations (in this case, a single pass). The bug is triggered by an assignment
-//     that comes from a series of assignments, possibly with swizzled or ternary operators with
-//     known conditionals, where the source is before the loop.
-//     So, a workaround is to add a +0 term to variables the first time they are assigned to in
-//     an inner loop (if they are declared in an outside scope, otherwise there is no need).
-//     This will break the aliasing chain.
-
-// For simplicity here we add a +0 to any assignment that is in at least two nested loops. Because
-// the bug only shows up with swizzles, and ternary assignment, whole array or whole structure
-// assignment don't need a workaround.
-
-namespace sh
-{
-
-namespace
-{
-
-class AliasingBreaker : public TIntermTraverser
-{
-  public:
-    AliasingBreaker() : TIntermTraverser(true, false, true) {}
-
-  protected:
-    bool visitBinary(Visit visit, TIntermBinary *binary)
-    {
-        if (visit != PreVisit)
-        {
-            return false;
-        }
-
-        if (mLoopLevel < 2 || !binary->isAssignment())
-        {
-            return true;
-        }
-
-        TIntermTyped *B = binary->getRight();
-        TType type      = B->getType();
-
-        if (!type.isScalar() && !type.isVector() && !type.isMatrix())
-        {
-            return true;
-        }
-
-        if (type.isArray() || IsSampler(type.getBasicType()))
-        {
-            return true;
-        }
-
-        // We have a scalar / vector / matrix assignment with loop depth 2.
-        // Transform it from
-        //    A = B
-        // to
-        //    A = (B + typeof<B>(0));
-
-        TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, CreateZeroNode(type));
-        bPlusZero->setLine(B->getLine());
-
-        binary->replaceChildNode(B, bPlusZero);
-
-        return true;
-    }
-
-    bool visitLoop(Visit visit, TIntermLoop *loop)
-    {
-        if (visit == PreVisit)
-        {
-            mLoopLevel++;
-        }
-        else
-        {
-            ASSERT(mLoopLevel > 0);
-            mLoopLevel--;
-        }
-
-        return true;
-    }
-
-  private:
-    int mLoopLevel = 0;
-};
-
-}  // anonymous namespace
-
-void BreakVariableAliasingInInnerLoops(TIntermNode *root)
-{
-    AliasingBreaker breaker;
-    root->traverse(&breaker);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/BreakVariableAliasingInInnerLoops.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
-//      may record a variable as aliasing another. Sometimes the alias information gets garbled
-//      so we work around this issue by breaking the aliasing chain in inner loops.
-
-#ifndef COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
-#define COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
-
-class TIntermNode;
-
-namespace sh
-{
-
-void BreakVariableAliasingInInnerLoops(TIntermNode *root);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -1,174 +1,77 @@
 //
 // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/translator/BuiltInFunctionEmulator.h"
 #include "angle_gl.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 namespace sh
 {
 
 class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
 {
   public:
     BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)
         : TIntermTraverser(true, false, false), mEmulator(emulator)
     {
     }
 
     bool visitUnary(Visit visit, TIntermUnary *node) override
     {
-        if (visit == PreVisit)
+        if (node->getFunction())
         {
-            bool needToEmulate =
-                mEmulator.setFunctionCalled(node->getOp(), node->getOperand()->getType());
+            bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
             if (needToEmulate)
                 node->setUseEmulatedFunction();
         }
         return true;
     }
 
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
-        if (visit == PreVisit)
+        // Here we handle all the built-in functions mapped to ops, not just the ones that are
+        // currently identified as problematic.
+        if (node->isConstructor() || node->isFunctionCall())
         {
-            // Here we handle all the built-in functions mapped to ops, not just the ones that are
-            // currently identified as problematic.
-            if (node->isConstructor() || node->isFunctionCall())
-            {
-                return true;
-            }
-            const TIntermSequence &sequence = *(node->getSequence());
-            bool needToEmulate              = false;
-            // Right now we only handle built-in functions with two to four parameters.
-            if (sequence.size() == 2)
-            {
-                TIntermTyped *param1 = sequence[0]->getAsTyped();
-                TIntermTyped *param2 = sequence[1]->getAsTyped();
-                if (!param1 || !param2)
-                    return true;
-                needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(),
-                                                            param2->getType());
-            }
-            else if (sequence.size() == 3)
-            {
-                TIntermTyped *param1 = sequence[0]->getAsTyped();
-                TIntermTyped *param2 = sequence[1]->getAsTyped();
-                TIntermTyped *param3 = sequence[2]->getAsTyped();
-                if (!param1 || !param2 || !param3)
-                    return true;
-                needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(),
-                                                            param2->getType(), param3->getType());
-            }
-            else if (sequence.size() == 4)
-            {
-                TIntermTyped *param1 = sequence[0]->getAsTyped();
-                TIntermTyped *param2 = sequence[1]->getAsTyped();
-                TIntermTyped *param3 = sequence[2]->getAsTyped();
-                TIntermTyped *param4 = sequence[3]->getAsTyped();
-                if (!param1 || !param2 || !param3 || !param4)
-                    return true;
-                needToEmulate =
-                    mEmulator.setFunctionCalled(node->getOp(), param1->getType(), param2->getType(),
-                                                param3->getType(), param4->getType());
-            }
-            else
-            {
-                return true;
-            }
-
-            if (needToEmulate)
-                node->setUseEmulatedFunction();
+            return true;
         }
+        bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
+        if (needToEmulate)
+            node->setUseEmulatedFunction();
         return true;
     }
 
   private:
     BuiltInFunctionEmulator &mEmulator;
 };
 
 BuiltInFunctionEmulator::BuiltInFunctionEmulator()
 {
 }
 
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param,
-                                                        const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param1,
-                                                        const TType *param2,
-                                                        const char *emulatedFunctionDefinition)
+void BuiltInFunctionEmulator::addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+                                                  const char *emulatedFunctionDefinition)
 {
-    FunctionId id(op, param1, param2);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
-    const FunctionId &dependency,
-    TOperator op,
-    const TType *param1,
-    const TType *param2,
-    const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param1, param2);
-    mEmulatedFunctions[id]    = std::string(emulatedFunctionDefinition);
-    mFunctionDependencies[id] = dependency;
-    return id;
+    mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
 }
 
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param1,
-                                                        const TType *param2,
-                                                        const TType *param3,
-                                                        const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param1, param2, param3);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op,
-                                                        const TType *param1,
-                                                        const TType *param2,
-                                                        const TType *param3,
-                                                        const TType *param4,
-                                                        const char *emulatedFunctionDefinition)
-{
-    FunctionId id(op, param1, param2, param3, param4);
-    mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition);
-    return id;
-}
-
-FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
-    const FunctionId &dependency,
-    TOperator op,
-    const TType *param1,
-    const TType *param2,
-    const TType *param3,
-    const TType *param4,
+void BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
+    const TSymbolUniqueId &dependency,
+    const TSymbolUniqueId &uniqueId,
     const char *emulatedFunctionDefinition)
 {
-    FunctionId id(op, param1, param2, param3, param4);
-    mEmulatedFunctions[id]    = std::string(emulatedFunctionDefinition);
-    mFunctionDependencies[id] = dependency;
-    return id;
+    mEmulatedFunctions[uniqueId.get()]    = std::string(emulatedFunctionDefinition);
+    mFunctionDependencies[uniqueId.get()] = dependency.get();
 }
 
 bool BuiltInFunctionEmulator::isOutputEmpty() const
 {
     return (mFunctions.size() == 0);
 }
 
 void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const
@@ -177,86 +80,61 @@ void BuiltInFunctionEmulator::outputEmul
     {
         const char *body = findEmulatedFunction(function);
         ASSERT(body);
         out << body;
         out << "\n\n";
     }
 }
 
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, const TType &param)
-{
-    return setFunctionCalled(FunctionId(op, &param));
-}
-
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
-                                                const TType &param1,
-                                                const TType &param2)
-{
-    return setFunctionCalled(FunctionId(op, &param1, &param2));
-}
-
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
-                                                const TType &param1,
-                                                const TType &param2,
-                                                const TType &param3)
-{
-    return setFunctionCalled(FunctionId(op, &param1, &param2, &param3));
-}
-
-bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
-                                                const TType &param1,
-                                                const TType &param2,
-                                                const TType &param3,
-                                                const TType &param4)
-{
-    return setFunctionCalled(FunctionId(op, &param1, &param2, &param3, &param4));
-}
-
-const char *BuiltInFunctionEmulator::findEmulatedFunction(const FunctionId &functionId) const
+const char *BuiltInFunctionEmulator::findEmulatedFunction(int uniqueId) const
 {
     for (const auto &queryFunction : mQueryFunctions)
     {
-        const char *result = queryFunction(functionId);
+        const char *result = queryFunction(uniqueId);
         if (result)
         {
             return result;
         }
     }
 
-    const auto &result = mEmulatedFunctions.find(functionId);
+    const auto &result = mEmulatedFunctions.find(uniqueId);
     if (result != mEmulatedFunctions.end())
     {
         return result->second.c_str();
     }
 
     return nullptr;
 }
 
-bool BuiltInFunctionEmulator::setFunctionCalled(const FunctionId &functionId)
+bool BuiltInFunctionEmulator::setFunctionCalled(const TFunction *function)
 {
-    if (!findEmulatedFunction(functionId))
+    ASSERT(function != nullptr);
+    return setFunctionCalled(function->uniqueId().get());
+}
+
+bool BuiltInFunctionEmulator::setFunctionCalled(int uniqueId)
+{
+    if (!findEmulatedFunction(uniqueId))
     {
         return false;
     }
 
     for (size_t i = 0; i < mFunctions.size(); ++i)
     {
-        if (mFunctions[i] == functionId)
+        if (mFunctions[i] == uniqueId)
             return true;
     }
     // If the function depends on another, mark the dependency as called.
-    auto dependency = mFunctionDependencies.find(functionId);
+    auto dependency = mFunctionDependencies.find(uniqueId);
     if (dependency != mFunctionDependencies.end())
     {
         setFunctionCalled((*dependency).second);
     }
-    // Copy the functionId if it needs to be stored, to make sure that the TType pointers inside
-    // remain valid and constant.
-    mFunctions.push_back(functionId.getCopy());
+    mFunctions.push_back(uniqueId);
     return true;
 }
 
 void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root)
 {
     ASSERT(root);
 
     if (mEmulatedFunctions.empty() && mQueryFunctions.empty())
@@ -279,81 +157,9 @@ void BuiltInFunctionEmulator::addFunctio
 
 // static
 void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
 {
     ASSERT(name[strlen(name) - 1] != '(');
     out << name << "_emu";
 }
 
-FunctionId::FunctionId()
-    : mOp(EOpNull),
-      mParam1(StaticType::GetBasic<EbtVoid>()),
-      mParam2(StaticType::GetBasic<EbtVoid>()),
-      mParam3(StaticType::GetBasic<EbtVoid>()),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op, const TType *param)
-    : mOp(op),
-      mParam1(param),
-      mParam2(StaticType::GetBasic<EbtVoid>()),
-      mParam3(StaticType::GetBasic<EbtVoid>()),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2)
-    : mOp(op),
-      mParam1(param1),
-      mParam2(param2),
-      mParam3(StaticType::GetBasic<EbtVoid>()),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3)
-    : mOp(op),
-      mParam1(param1),
-      mParam2(param2),
-      mParam3(param3),
-      mParam4(StaticType::GetBasic<EbtVoid>())
-{
-}
-
-FunctionId::FunctionId(TOperator op,
-                       const TType *param1,
-                       const TType *param2,
-                       const TType *param3,
-                       const TType *param4)
-    : mOp(op), mParam1(param1), mParam2(param2), mParam3(param3), mParam4(param4)
-{
-}
-
-bool FunctionId::operator==(const FunctionId &other) const
-{
-    return (mOp == other.mOp && *mParam1 == *other.mParam1 && *mParam2 == *other.mParam2 &&
-            *mParam3 == *other.mParam3 && *mParam4 == *other.mParam4);
-}
-
-bool FunctionId::operator<(const FunctionId &other) const
-{
-    if (mOp != other.mOp)
-        return mOp < other.mOp;
-    if (*mParam1 != *other.mParam1)
-        return *mParam1 < *other.mParam1;
-    if (*mParam2 != *other.mParam2)
-        return *mParam2 < *other.mParam2;
-    if (*mParam3 != *other.mParam3)
-        return *mParam3 < *other.mParam3;
-    if (*mParam4 != *other.mParam4)
-        return *mParam4 < *other.mParam4;
-    return false;  // all fields are equal
-}
-
-FunctionId FunctionId::getCopy() const
-{
-    return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3),
-                      new TType(*mParam4));
-}
-
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
@@ -3,92 +3,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
 #define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
 
 #include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/ParamType.h"
 
 namespace sh
 {
 
-struct MiniFunctionId
-{
-    constexpr MiniFunctionId(TOperator op         = EOpNull,
-                             ParamType paramType1 = ParamType::Void,
-                             ParamType paramType2 = ParamType::Void,
-                             ParamType paramType3 = ParamType::Void,
-                             ParamType paramType4 = ParamType::Void)
-        : op(op),
-          paramType1(paramType1),
-          paramType2(paramType2),
-          paramType3(paramType3),
-          paramType4(paramType4)
-    {
-    }
-
-    TOperator op;
-    ParamType paramType1;
-    ParamType paramType2;
-    ParamType paramType3;
-    ParamType paramType4;
-};
-
-class FunctionId final
-{
-  public:
-    FunctionId();
-    FunctionId(TOperator op, const TType *param);
-    FunctionId(TOperator op, const TType *param1, const TType *param2);
-    FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3);
-    FunctionId(TOperator op,
-               const TType *param1,
-               const TType *param2,
-               const TType *param3,
-               const TType *param4);
+class TIntermNode;
+class TFunction;
+class TSymbolUniqueId;
 
-    FunctionId(const FunctionId &) = default;
-    FunctionId &operator=(const FunctionId &) = default;
-
-    bool operator==(const FunctionId &other) const;
-    bool operator<(const FunctionId &other) const;
-
-    FunctionId getCopy() const;
-
-  private:
-    friend bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId);
-    TOperator mOp;
-
-    // The memory that these TType objects use is freed by PoolAllocator. The
-    // BuiltInFunctionEmulator's lifetime can extend until after the memory pool is freed, but
-    // that's not an issue since this class never destructs these objects.
-    const TType *mParam1;
-    const TType *mParam2;
-    const TType *mParam3;
-    const TType *mParam4;
-};
-
-inline bool operator==(ParamType paramType, const TType *type)
-{
-    return SameParamType(paramType, type->getBasicType(), type->getNominalSize(),
-                         type->getSecondarySize());
-}
-
-inline bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId)
-{
-    return miniId.op == functionId.mOp && miniId.paramType1 == functionId.mParam1 &&
-           miniId.paramType2 == functionId.mParam2 && miniId.paramType3 == functionId.mParam3 &&
-           miniId.paramType4 == functionId.mParam4;
-}
-
-using BuiltinQueryFunc = const char *(const FunctionId &);
+using BuiltinQueryFunc = const char *(int);
 
 //
 // This class decides which built-in functions need to be replaced with the emulated ones. It can be
 // used to work around driver bugs or implement functions that are not natively implemented on a
 // specific platform.
 //
 class BuiltInFunctionEmulator
 {
@@ -103,81 +36,45 @@ class BuiltInFunctionEmulator
     static void WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name);
 
     bool isOutputEmpty() const;
 
     // Output function emulation definition. This should be before any other shader source.
     void outputEmulatedFunctions(TInfoSinkBase &out) const;
 
     // Add functions that need to be emulated.
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param,
-                                   const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param1,
-                                   const TType *param2,
-                                   const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param1,
-                                   const TType *param2,
-                                   const TType *param3,
-                                   const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunction(TOperator op,
-                                   const TType *param1,
-                                   const TType *param2,
-                                   const TType *param3,
-                                   const TType *param4,
-                                   const char *emulatedFunctionDefinition);
+    void addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+                             const char *emulatedFunctionDefinition);
 
-    FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency,
-                                                 TOperator op,
-                                                 const TType *param1,
-                                                 const TType *param2,
-                                                 const char *emulatedFunctionDefinition);
-    FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency,
-                                                 TOperator op,
-                                                 const TType *param1,
-                                                 const TType *param2,
-                                                 const TType *param3,
-                                                 const TType *param4,
-                                                 const char *emulatedFunctionDefinition);
+    void addEmulatedFunctionWithDependency(const TSymbolUniqueId &dependency,
+                                           const TSymbolUniqueId &uniqueId,
+                                           const char *emulatedFunctionDefinition);
 
     void addFunctionMap(BuiltinQueryFunc queryFunc);
 
   private:
     class BuiltInFunctionEmulationMarker;
 
     // Records that a function is called by the shader and might need to be emulated. If the
     // function is not in mEmulatedFunctions, this becomes a no-op. Returns true if the function
     // call needs to be replaced with an emulated one.
-    bool setFunctionCalled(TOperator op, const TType &param);
-    bool setFunctionCalled(TOperator op, const TType &param1, const TType &param2);
-    bool setFunctionCalled(TOperator op,
-                           const TType &param1,
-                           const TType &param2,
-                           const TType &param3);
-    bool setFunctionCalled(TOperator op,
-                           const TType &param1,
-                           const TType &param2,
-                           const TType &param3,
-                           const TType &param4);
+    bool setFunctionCalled(const TFunction *function);
+    bool setFunctionCalled(int uniqueId);
 
-    bool setFunctionCalled(const FunctionId &functionId);
+    const char *findEmulatedFunction(int uniqueId) const;
 
-    const char *findEmulatedFunction(const FunctionId &functionId) const;
-
-    // Map from function id to emulated function definition
-    std::map<FunctionId, std::string> mEmulatedFunctions;
+    // Map from function unique id to emulated function definition
+    std::map<int, std::string> mEmulatedFunctions;
 
     // Map from dependent functions to their dependencies. This structure allows each function to
     // have at most one dependency.
-    std::map<FunctionId, FunctionId> mFunctionDependencies;
+    std::map<int, int> mFunctionDependencies;
 
     // Called function ids
-    std::vector<FunctionId> mFunctions;
+    std::vector<int> mFunctions;
 
     // Constexpr function tables.
     std::vector<BuiltinQueryFunc *> mQueryFunctions;
 };
 
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -2,178 +2,159 @@
 // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
 #include "angle_gl.h"
 #include "compiler/translator/BuiltInFunctionEmulator.h"
-#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/StaticType.h"
 #include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.h"
 
 namespace sh
 {
 
 void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
                                                       sh::GLenum shaderType)
 {
     if (shaderType == GL_VERTEX_SHADER)
     {
-        const TType *int1 = StaticType::GetBasic<EbtInt>();
-        emu->addEmulatedFunction(EOpAbs, int1, "int abs_emu(int x) { return x * sign(x); }");
+        emu->addEmulatedFunction(BuiltInId::abs_Int1, "int abs_emu(int x) { return x * sign(x); }");
     }
 }
 
 void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
                                                         int targetGLSLVersion)
 {
     // isnan() is supported since GLSL 1.3.
     if (targetGLSLVersion < GLSL_VERSION_130)
         return;
 
-    const TType *float1 = StaticType::GetBasic<EbtFloat>();
-    const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
-    const TType *float3 = StaticType::GetBasic<EbtFloat, 3>();
-    const TType *float4 = StaticType::GetBasic<EbtFloat, 4>();
-
     // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
     emu->addEmulatedFunction(
-        EOpIsnan, float1,
+        BuiltInId::isnan_Float1,
         "bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
     emu->addEmulatedFunction(
-        EOpIsnan, float2,
+        BuiltInId::isnan_Float2,
         "bvec2 isnan_emu(vec2 x)\n"
         "{\n"
         "    bvec2 isnan;\n"
         "    for (int i = 0; i < 2; i++)\n"
         "    {\n"
         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
         "    }\n"
         "    return isnan;\n"
         "}\n");
     emu->addEmulatedFunction(
-        EOpIsnan, float3,
+        BuiltInId::isnan_Float3,
         "bvec3 isnan_emu(vec3 x)\n"
         "{\n"
         "    bvec3 isnan;\n"
         "    for (int i = 0; i < 3; i++)\n"
         "    {\n"
         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
         "    }\n"
         "    return isnan;\n"
         "}\n");
     emu->addEmulatedFunction(
-        EOpIsnan, float4,
+        BuiltInId::isnan_Float4,
         "bvec4 isnan_emu(vec4 x)\n"
         "{\n"
         "    bvec4 isnan;\n"
         "    for (int i = 0; i < 4; i++)\n"
         "    {\n"
         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
         "    }\n"
         "    return isnan;\n"
         "}\n");
 }
 
 void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu)
 {
-    const TType *float1 = StaticType::GetBasic<EbtFloat>();
-    auto floatFuncId    = emu->addEmulatedFunction(
-        EOpAtan, float1, float1,
-        "emu_precision float atan_emu(emu_precision float y, emu_precision "
-        "float x)\n"
-        "{\n"
-        "    if (x > 0.0) return atan(y / x);\n"
-        "    else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n"
-        "    else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n"
-        "    else return 1.57079632 * sign(y);\n"
-        "}\n");
-    static const std::array<const TType *, 5> floatVecs = {
-        nullptr,
-        nullptr,
-        StaticType::GetBasic<EbtFloat, 2>(),
-        StaticType::GetBasic<EbtFloat, 3>(),
-        StaticType::GetBasic<EbtFloat, 4>(),
+    emu->addEmulatedFunction(BuiltInId::atan_Float1_Float1,
+                             "emu_precision float atan_emu(emu_precision float y, emu_precision "
+                             "float x)\n"
+                             "{\n"
+                             "    if (x > 0.0) return atan(y / x);\n"
+                             "    else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n"
+                             "    else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n"
+                             "    else return 1.57079632 * sign(y);\n"
+                             "}\n");
+    static const std::array<TSymbolUniqueId, 4> ids = {
+        BuiltInId::atan_Float1_Float1, BuiltInId::atan_Float2_Float2, BuiltInId::atan_Float3_Float3,
+        BuiltInId::atan_Float4_Float4,
     };
     for (int dim = 2; dim <= 4; ++dim)
     {
-        const TType *floatVec = floatVecs[dim];
         std::stringstream ss;
         ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim
            << " y, emu_precision vec" << dim << " x)\n"
            << "{\n"
               "    return vec"
            << dim << "(";
         for (int i = 0; i < dim; ++i)
         {
             ss << "atan_emu(y[" << i << "], x[" << i << "])";
             if (i < dim - 1)
             {
                 ss << ", ";
             }
         }
         ss << ");\n"
               "}\n";
-        emu->addEmulatedFunctionWithDependency(floatFuncId, EOpAtan, floatVec, floatVec,
+        emu->addEmulatedFunctionWithDependency(BuiltInId::atan_Float1_Float1, ids[dim - 1],
                                                ss.str().c_str());
     }
 }
 
 // Emulate built-in functions missing from GLSL 1.30 and higher
 void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu,
                                                         sh::GLenum shaderType,
                                                         int targetGLSLVersion)
 {
     // Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10)
     if (targetGLSLVersion < GLSL_VERSION_410)
     {
-        const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
-        const TType *uint1  = StaticType::GetBasic<EbtUInt>();
-
         // clang-format off
-        emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
+        emu->addEmulatedFunction(BuiltInId::packUnorm2x16_Float2,
             "uint packUnorm2x16_emu(vec2 v)\n"
             "{\n"
             "    int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n"
             "    int y = int(round(clamp(v.y, 0.0, 1.0) * 65535.0));\n"
             "    return uint((y << 16) | (x & 0xFFFF));\n"
             "}\n");
 
-        emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
+        emu->addEmulatedFunction(BuiltInId::unpackUnorm2x16_UInt1,
             "vec2 unpackUnorm2x16_emu(uint u)\n"
             "{\n"
             "    float x = float(u & 0xFFFFu) / 65535.0;\n"
             "    float y = float(u >> 16) / 65535.0;\n"
             "    return vec2(x, y);\n"
             "}\n");
         // clang-format on
     }
 
     // Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20)
     // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30).
     if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420)
     {
-        const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
-        const TType *uint1  = StaticType::GetBasic<EbtUInt>();
-
         // clang-format off
-        emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
+        emu->addEmulatedFunction(BuiltInId::packSnorm2x16_Float2,
             "uint packSnorm2x16_emu(vec2 v)\n"
             "{\n"
             "    #if defined(GL_ARB_shading_language_packing)\n"
             "        return packSnorm2x16(v);\n"
             "    #else\n"
             "        int x = int(round(clamp(v.x, -1.0, 1.0) * 32767.0));\n"
             "        int y = int(round(clamp(v.y, -1.0, 1.0) * 32767.0));\n"
             "        return uint((y << 16) | (x & 0xFFFF));\n"
             "    #endif\n"
             "}\n");
-        emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
+        emu->addEmulatedFunction(BuiltInId::unpackSnorm2x16_UInt1,
             "#if !defined(GL_ARB_shading_language_packing)\n"
             "    float fromSnorm(uint x)\n"
             "    {\n"
             "        int xi = (int(x) & 0x7FFF) - (int(x) & 0x8000);\n"
             "        return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
             "    }\n"
             "#endif\n"
             "\n"
@@ -184,17 +165,17 @@ void InitBuiltInFunctionEmulatorForGLSLM
             "    #else\n"
             "        uint y = (u >> 16);\n"
             "        uint x = u;\n"
             "        return vec2(fromSnorm(x), fromSnorm(y));\n"
             "    #endif\n"
             "}\n");
         // Functions uint f32tof16(float val) and float f16tof32(uint val) are
         // based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL".
-        emu->addEmulatedFunction(EOpPackHalf2x16, float2,
+        emu->addEmulatedFunction(BuiltInId::packHalf2x16_Float2,
             "#if !defined(GL_ARB_shading_language_packing)\n"
             "    uint f32tof16(float val)\n"
             "    {\n"
             "        uint f32 = floatBitsToUint(val);\n"
             "        uint f16 = 0u;\n"
             "        uint sign = (f32 >> 16) & 0x8000u;\n"
             "        int exponent = int((f32 >> 23) & 0xFFu) - 127;\n"
             "        uint mantissa = f32 & 0x007FFFFFu;\n"
@@ -231,17 +212,17 @@ void InitBuiltInFunctionEmulatorForGLSLM
             "    #if defined(GL_ARB_shading_language_packing)\n"
             "        return packHalf2x16(v);\n"
             "    #else\n"
             "        uint x = f32tof16(v.x);\n"
             "        uint y = f32tof16(v.y);\n"
             "        return (y << 16) | x;\n"
             "    #endif\n"
             "}\n");
-        emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1,
+        emu->addEmulatedFunction(BuiltInId::unpackHalf2x16_UInt1,
             "#if !defined(GL_ARB_shading_language_packing)\n"
             "    float f16tof32(uint val)\n"
             "    {\n"
             "        uint sign = (val & 0x8000u) << 16;\n"
             "        int exponent = int((val & 0x7C00u) >> 10);\n"
             "        uint mantissa = val & 0x03FFu;\n"
             "        float f32 = 0.0;\n"
             "        if(exponent == 0)\n"
--- a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -1,142 +1,131 @@
 //
 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
+#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
 #include "angle_gl.h"
 #include "compiler/translator/BuiltInFunctionEmulator.h"
-#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
-#include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.h"
 
 namespace sh
 {
 
 // Defined in emulated_builtin_functions_hlsl_autogen.cpp.
-const char *FindHLSLFunction(const FunctionId &functionID);
+const char *FindHLSLFunction(int uniqueId);
 
 void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
                                                         int targetGLSLVersion)
 {
     if (targetGLSLVersion < GLSL_VERSION_130)
         return;
 
-    TType *float1 = new TType(EbtFloat);
-    TType *float2 = new TType(EbtFloat, 2);
-    TType *float3 = new TType(EbtFloat, 3);
-    TType *float4 = new TType(EbtFloat, 4);
-
-    emu->addEmulatedFunction(EOpIsnan, float1,
+    emu->addEmulatedFunction(BuiltInId::isnan_Float1,
                              "bool isnan_emu(float x)\n"
                              "{\n"
                              "    return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
                              "}\n"
                              "\n");
 
     emu->addEmulatedFunction(
-        EOpIsnan, float2,
+        BuiltInId::isnan_Float2,
         "bool2 isnan_emu(float2 x)\n"
         "{\n"
         "    bool2 isnan;\n"
         "    for (int i = 0; i < 2; i++)\n"
         "    {\n"
         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
         "    }\n"
         "    return isnan;\n"
         "}\n");
 
     emu->addEmulatedFunction(
-        EOpIsnan, float3,
+        BuiltInId::isnan_Float3,
         "bool3 isnan_emu(float3 x)\n"
         "{\n"
         "    bool3 isnan;\n"
         "    for (int i = 0; i < 3; i++)\n"
         "    {\n"
         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
         "    }\n"
         "    return isnan;\n"
         "}\n");
 
     emu->addEmulatedFunction(
-        EOpIsnan, float4,
+        BuiltInId::isnan_Float4,
         "bool4 isnan_emu(float4 x)\n"
         "{\n"
         "    bool4 isnan;\n"
         "    for (int i = 0; i < 4; i++)\n"
         "    {\n"
         "        isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
         "    }\n"
         "    return isnan;\n"
         "}\n");
 }
 
 void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
 {
-    TType *int1   = new TType(EbtInt);
-    TType *int2   = new TType(EbtInt, 2);
-    TType *int3   = new TType(EbtInt, 3);
-    TType *int4   = new TType(EbtInt, 4);
-    TType *uint1  = new TType(EbtUInt);
-    TType *uint2  = new TType(EbtUInt, 2);
-    TType *uint3  = new TType(EbtUInt, 3);
-    TType *uint4  = new TType(EbtUInt, 4);
-
     emu->addFunctionMap(FindHLSLFunction);
 
     // (a + b2^16) * (c + d2^16) = ac + (ad + bc) * 2^16 + bd * 2^32
     // Also note that below, a * d + ((a * c) >> 16) is guaranteed not to overflow, because:
     // a <= 0xffff, d <= 0xffff, ((a * c) >> 16) <= 0xffff and 0xffff * 0xffff + 0xffff = 0xffff0000
-    FunctionId umulExtendedUint1 = emu->addEmulatedFunction(
-        EOpUmulExtended, uint1, uint1, uint1, uint1,
-        "void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n"
-        "{\n"
-        "    lsb = x * y;\n"
-        "    uint a = (x & 0xffffu);\n"
-        "    uint b = (x >> 16);\n"
-        "    uint c = (y & 0xffffu);\n"
-        "    uint d = (y >> 16);\n"
-        "    uint ad = a * d + ((a * c) >> 16);\n"
-        "    uint bc = b * c;\n"
-        "    uint carry = uint(ad > (0xffffffffu - bc));\n"
-        "    msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n"
-        "}\n");
+    emu->addEmulatedFunction(BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+                             "void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n"
+                             "{\n"
+                             "    lsb = x * y;\n"
+                             "    uint a = (x & 0xffffu);\n"
+                             "    uint b = (x >> 16);\n"
+                             "    uint c = (y & 0xffffu);\n"
+                             "    uint d = (y >> 16);\n"
+                             "    uint ad = a * d + ((a * c) >> 16);\n"
+                             "    uint bc = b * c;\n"
+                             "    uint carry = uint(ad > (0xffffffffu - bc));\n"
+                             "    msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n"
+                             "}\n");
     emu->addEmulatedFunctionWithDependency(
-        umulExtendedUint1, EOpUmulExtended, uint2, uint2, uint2, uint2,
+        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+        BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
         "void umulExtended_emu(uint2 x, uint2 y, out uint2 msb, out uint2 lsb)\n"
         "{\n"
         "    umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
         "    umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
         "}\n");
     emu->addEmulatedFunctionWithDependency(
-        umulExtendedUint1, EOpUmulExtended, uint3, uint3, uint3, uint3,
+        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+        BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
         "void umulExtended_emu(uint3 x, uint3 y, out uint3 msb, out uint3 lsb)\n"
         "{\n"
         "    umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
         "    umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
         "    umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
         "}\n");
     emu->addEmulatedFunctionWithDependency(
-        umulExtendedUint1, EOpUmulExtended, uint4, uint4, uint4, uint4,
+        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+        BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
         "void umulExtended_emu(uint4 x, uint4 y, out uint4 msb, out uint4 lsb)\n"
         "{\n"
         "    umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
         "    umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
         "    umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
         "    umulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
         "}\n");
 
     // The imul emulation does two's complement negation on the lsb and msb manually in case the
     // result needs to be negative.
     // TODO(oetuaho): Note that this code doesn't take one edge case into account, where x or y is
     // -2^31. abs(-2^31) is undefined.
-    FunctionId imulExtendedInt1 = emu->addEmulatedFunctionWithDependency(
-        umulExtendedUint1, EOpImulExtended, int1, int1, int1, int1,
+    emu->addEmulatedFunctionWithDependency(
+        BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+        BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
         "void imulExtended_emu(int x, int y, out int msb, out int lsb)\n"
         "{\n"
         "    uint unsignedMsb;\n"
         "    uint unsignedLsb;\n"
         "    bool negative = (x < 0) != (y < 0);\n"
         "    umulExtended_emu(uint(abs(x)), uint(abs(y)), unsignedMsb, unsignedLsb);\n"
         "    lsb = asint(unsignedLsb);\n"
         "    msb = asint(unsignedMsb);\n"
@@ -151,32 +140,32 @@ void InitBuiltInFunctionEmulatorForHLSL(
         "        }\n"
         "        else\n"
         "        {\n"
         "            lsb += 1;\n"
         "        }\n"
         "    }\n"
         "}\n");
     emu->addEmulatedFunctionWithDependency(
-        imulExtendedInt1, EOpImulExtended, int2, int2, int2, int2,
+        BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
         "void imulExtended_emu(int2 x, int2 y, out int2 msb, out int2 lsb)\n"
         "{\n"
         "    imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
         "    imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
         "}\n");
     emu->addEmulatedFunctionWithDependency(
-        imulExtendedInt1, EOpImulExtended, int3, int3, int3, int3,
+        BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
         "void imulExtended_emu(int3 x, int3 y, out int3 msb, out int3 lsb)\n"
         "{\n"
         "    imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
         "    imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
         "    imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
         "}\n");
     emu->addEmulatedFunctionWithDependency(
-        imulExtendedInt1, EOpImulExtended, int4, int4, int4, int4,
+        BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
         "void imulExtended_emu(int4 x, int4 y, out int4 msb, out int4 lsb)\n"
         "{\n"
         "    imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
         "    imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
         "    imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
         "    imulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
         "}\n");
 }
--- a/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
@@ -6,18 +6,18 @@
 
 // CallDAG.h: Implements a call graph DAG of functions to be re-used accross
 // analyses, allows to efficiently traverse the functions in topological
 // order.
 
 #include "compiler/translator/CallDAG.h"
 
 #include "compiler/translator/Diagnostics.h"
-#include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 
 namespace sh
 {
 
 // The CallDAGCreator does all the processing required to create the CallDAG
 // structure so that the latter contains only the necessary variables.
 class CallDAG::CallDAGCreator : public TIntermTraverser
 {
@@ -111,26 +111,23 @@ class CallDAG::CallDAGCreator : public T
         mCurrentFunction->name           = node->getFunction()->name();
         mCurrentFunction->definitionNode = node;
 
         node->getBody()->traverse(this);
         mCurrentFunction = nullptr;
         return false;
     }
 
-    bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override
+    void visitFunctionPrototype(TIntermFunctionPrototype *node) override
     {
         ASSERT(mCurrentFunction == nullptr);
 
         // Function declaration, create an empty record.
         auto &record = mFunctions[node->getFunction()->uniqueId().get()];
         record.name  = node->getFunction()->name();
-
-        // No need to traverse the parameters.
-        return false;
     }
 
     // Track functions called from another function.
     bool visitAggregate(Visit visit, TIntermAggregate *node) override
     {
         if (node->getOp() == EOpCallFunctionInAST)
         {
             // Function call, add the callees
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampFragDepth.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// ClampFragDepth.cpp: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0].
-// The clamping is run at the very end of shader execution, and is only performed if the shader
-// statically accesses gl_FragDepth.
-//
-
-#include "compiler/translator/ClampFragDepth.h"
-
-#include "compiler/translator/FindSymbolNode.h"
-#include "compiler/translator/ImmutableString.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/RunAtTheEndOfShader.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable)
-{
-    // Only clamp gl_FragDepth if it's used in the shader.
-    if (!FindSymbolNode(root, ImmutableString("gl_FragDepth")))
-    {
-        return;
-    }
-
-    TIntermSymbol *fragDepthNode =
-        ReferenceBuiltInVariable(ImmutableString("gl_FragDepth"), *symbolTable, 300);
-
-    TIntermTyped *minFragDepthNode = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
-
-    TConstantUnion *maxFragDepthConstant = new TConstantUnion();
-    maxFragDepthConstant->setFConst(1.0);
-    TIntermConstantUnion *maxFragDepthNode =
-        new TIntermConstantUnion(maxFragDepthConstant, TType(EbtFloat, EbpHigh, EvqConst));
-
-    // clamp(gl_FragDepth, 0.0, 1.0)
-    TIntermSequence *clampArguments = new TIntermSequence();
-    clampArguments->push_back(fragDepthNode->deepCopy());
-    clampArguments->push_back(minFragDepthNode);
-    clampArguments->push_back(maxFragDepthNode);
-    TIntermTyped *clampedFragDepth =
-        CreateBuiltInFunctionCallNode("clamp", clampArguments, *symbolTable, 100);
-
-    // gl_FragDepth = clamp(gl_FragDepth, 0.0, 1.0)
-    TIntermBinary *assignFragDepth = new TIntermBinary(EOpAssign, fragDepthNode, clampedFragDepth);
-
-    RunAtTheEndOfShader(root, assignFragDepth, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampFragDepth.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// ClampFragDepth.h: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0].
-// The clamping is run at the very end of shader execution, and is only performed if the shader
-// statically accesses gl_FragDepth.
-//
-
-#ifndef COMPILER_TRANSLATOR_CLAMPFRAGDEPTH_H_
-#define COMPILER_TRANSLATOR_CLAMPFRAGDEPTH_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_CLAMPFRAGDEPTH_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampPointSize.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// ClampPointSize.cpp: Limit the value that is written to gl_PointSize.
-//
-
-#include "compiler/translator/ClampPointSize.h"
-
-#include "compiler/translator/FindSymbolNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/RunAtTheEndOfShader.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable)
-{
-    // Only clamp gl_PointSize if it's used in the shader.
-    if (!FindSymbolNode(root, ImmutableString("gl_PointSize")))
-    {
-        return;
-    }
-
-    TIntermSymbol *pointSizeNode =
-        ReferenceBuiltInVariable(ImmutableString("gl_PointSize"), *symbolTable, 100);
-
-    TConstantUnion *maxPointSizeConstant = new TConstantUnion();
-    maxPointSizeConstant->setFConst(maxPointSize);
-    TIntermConstantUnion *maxPointSizeNode =
-        new TIntermConstantUnion(maxPointSizeConstant, TType(EbtFloat, EbpHigh, EvqConst));
-
-    // min(gl_PointSize, maxPointSize)
-    TIntermSequence *minArguments = new TIntermSequence();
-    minArguments->push_back(pointSizeNode->deepCopy());
-    minArguments->push_back(maxPointSizeNode);
-    TIntermTyped *clampedPointSize =
-        CreateBuiltInFunctionCallNode("min", minArguments, *symbolTable, 100);
-
-    // gl_PointSize = min(gl_PointSize, maxPointSize)
-    TIntermBinary *assignPointSize = new TIntermBinary(EOpAssign, pointSizeNode, clampedPointSize);
-
-    RunAtTheEndOfShader(root, assignPointSize, symbolTable);
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/ClampPointSize.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// ClampPointSize.h: Limit the value that is written to gl_PointSize.
-//
-
-#ifndef COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_
-#define COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_
--- a/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
@@ -5,18 +5,18 @@
 //
 // CollectVariables.cpp: Collect lists of shader interface variables based on the AST.
 
 #include "compiler/translator/CollectVariables.h"
 
 #include "angle_gl.h"
 #include "common/utilities.h"
 #include "compiler/translator/HashNames.h"
-#include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
 #include "compiler/translator/util.h"
 
 namespace sh
 {
 
 namespace
 {
 
@@ -63,44 +63,46 @@ VarT *FindVariable(const ImmutableString
     {
         if (name == (*infoList)[ii].name)
             return &((*infoList)[ii]);
     }
 
     return nullptr;
 }
 
-// Note that this shouldn't be called for interface blocks - static use information is collected for
+// Note that this shouldn't be called for interface blocks - active information is collected for
 // individual fields in case of interface blocks.
-void MarkStaticallyUsed(ShaderVariable *variable)
+void MarkActive(ShaderVariable *variable)
 {
-    if (!variable->staticUse)
+    if (!variable->active)
     {
         if (variable->isStruct())
         {
             // Conservatively assume all fields are statically used as well.
             for (auto &field : variable->fields)
             {
-                MarkStaticallyUsed(&field);
+                MarkActive(&field);
             }
         }
-        variable->staticUse = true;
+        ASSERT(variable->staticUse);
+        variable->active    = true;
     }
 }
 
 ShaderVariable *FindVariableInInterfaceBlock(const ImmutableString &name,
                                              const TInterfaceBlock *interfaceBlock,
                                              std::vector<InterfaceBlock> *infoList)
 {
     ASSERT(interfaceBlock);
     InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), infoList);
     ASSERT(namedBlock);
 
     // Set static use on the parent interface block here
     namedBlock->staticUse = true;
+    namedBlock->active    = true;
     return FindVariable(name, &namedBlock->fields);
 }
 
 // Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
 // and interface blocks.
 class CollectVariablesTraverser : public TIntermTraverser
 {
   public:
@@ -109,50 +111,53 @@ class CollectVariablesTraverser : public
                               std::vector<Uniform> *uniforms,
                               std::vector<Varying> *inputVaryings,
                               std::vector<Varying> *outputVaryings,
                               std::vector<InterfaceBlock> *uniformBlocks,
                               std::vector<InterfaceBlock> *shaderStorageBlocks,
                               std::vector<InterfaceBlock> *inBlocks,
                               ShHashFunction64 hashFunction,
                               TSymbolTable *symbolTable,
-                              int shaderVersion,
                               GLenum shaderType,
                               const TExtensionBehavior &extensionBehavior);
 
+    bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override;
     void visitSymbol(TIntermSymbol *symbol) override;
     bool visitDeclaration(Visit, TIntermDeclaration *node) override;
     bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
 
   private:
     std::string getMappedName(const TSymbol *symbol) const;
 
-    void setFieldOrVariableProperties(const TType &type, ShaderVariable *variableOut) const;
+    void setFieldOrVariableProperties(const TType &type,
+                                      bool staticUse,
+                                      ShaderVariable *variableOut) const;
     void setFieldProperties(const TType &type,
                             const ImmutableString &name,
+                            bool staticUse,
                             ShaderVariable *variableOut) const;
     void setCommonVariableProperties(const TType &type,
                                      const TVariable &variable,
                                      ShaderVariable *variableOut) const;
 
     Attribute recordAttribute(const TIntermSymbol &variable) const;
     OutputVariable recordOutputVariable(const TIntermSymbol &variable) const;
     Varying recordVarying(const TIntermSymbol &variable) const;
     void recordInterfaceBlock(const char *instanceName,
                               const TType &interfaceBlockType,
                               InterfaceBlock *interfaceBlock) const;
     Uniform recordUniform(const TIntermSymbol &variable) const;
 
-    void setBuiltInInfoFromSymbolTable(const ImmutableString &name, ShaderVariable *info);
+    void setBuiltInInfoFromSymbol(const TVariable &variable, ShaderVariable *info);
 
-    void recordBuiltInVaryingUsed(const ImmutableString &name,
+    void recordBuiltInVaryingUsed(const TVariable &variable,
                                   bool *addedFlag,
                                   std::vector<Varying> *varyings);
-    void recordBuiltInFragmentOutputUsed(const ImmutableString &name, bool *addedFlag);
-    void recordBuiltInAttributeUsed(const ImmutableString &name, bool *addedFlag);
+    void recordBuiltInFragmentOutputUsed(const TVariable &variable, bool *addedFlag);
+    void recordBuiltInAttributeUsed(const TVariable &variable, bool *addedFlag);
     InterfaceBlock *recordGLInUsed(const TType &glInType);
     InterfaceBlock *findNamedInterfaceBlock(const ImmutableString &name) const;
 
     std::vector<Attribute> *mAttribs;
     std::vector<OutputVariable> *mOutputVariables;
     std::vector<Uniform> *mUniforms;
     std::vector<Varying> *mInputVaryings;
     std::vector<Varying> *mOutputVaryings;
@@ -191,33 +196,31 @@ class CollectVariablesTraverser : public
     bool mInvocationIDAdded;
 
     // Geometry Shader and Fragment Shader builtins
     bool mPrimitiveIDAdded;
     bool mLayerAdded;
 
     ShHashFunction64 mHashFunction;
 
-    int mShaderVersion;
     GLenum mShaderType;
     const TExtensionBehavior &mExtensionBehavior;
 };
 
 CollectVariablesTraverser::CollectVariablesTraverser(
     std::vector<sh::Attribute> *attribs,
     std::vector<sh::OutputVariable> *outputVariables,
     std::vector<sh::Uniform> *uniforms,
     std::vector<sh::Varying> *inputVaryings,
     std::vector<sh::Varying> *outputVaryings,
     std::vector<sh::InterfaceBlock> *uniformBlocks,
     std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
     std::vector<sh::InterfaceBlock> *inBlocks,
     ShHashFunction64 hashFunction,
     TSymbolTable *symbolTable,
-    int shaderVersion,
     GLenum shaderType,
     const TExtensionBehavior &extensionBehavior)
     : TIntermTraverser(true, false, false, symbolTable),
       mAttribs(attribs),
       mOutputVariables(outputVariables),
       mUniforms(uniforms),
       mInputVaryings(inputVaryings),
       mOutputVaryings(outputVaryings),
@@ -240,112 +243,116 @@ CollectVariablesTraverser::CollectVariab
       mSecondaryFragColorEXTAdded(false),
       mSecondaryFragDataEXTAdded(false),
       mPerVertexInAdded(false),
       mPrimitiveIDInAdded(false),
       mInvocationIDAdded(false),
       mPrimitiveIDAdded(false),
       mLayerAdded(false),
       mHashFunction(hashFunction),
-      mShaderVersion(shaderVersion),
       mShaderType(shaderType),
       mExtensionBehavior(extensionBehavior)
 {
 }
 
 std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
 {
     return HashName(symbol, mHashFunction, nullptr).data();
 }
 
-void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const ImmutableString &name,
-                                                              ShaderVariable *info)
+void CollectVariablesTraverser::setBuiltInInfoFromSymbol(const TVariable &variable,
+                                                         ShaderVariable *info)
 {
-    const TVariable *symbolTableVar =
-        reinterpret_cast<const TVariable *>(mSymbolTable->findBuiltIn(name, mShaderVersion));
-    ASSERT(symbolTableVar);
-    const TType &type = symbolTableVar->getType();
+    const TType &type = variable.getType();
 
-    info->name       = name.data();
-    info->mappedName = name.data();
+    info->name       = variable.name().data();
+    info->mappedName = variable.name().data();
     info->type       = GLVariableType(type);
     info->precision = GLVariablePrecision(type);
     if (auto *arraySizes = type.getArraySizes())
     {
         info->arraySizes.assign(arraySizes->begin(), arraySizes->end());
     }
 }
 
-void CollectVariablesTraverser::recordBuiltInVaryingUsed(const ImmutableString &name,
+void CollectVariablesTraverser::recordBuiltInVaryingUsed(const TVariable &variable,
                                                          bool *addedFlag,
                                                          std::vector<Varying> *varyings)
 {
     ASSERT(varyings);
     if (!(*addedFlag))
     {
         Varying info;
-        setBuiltInInfoFromSymbolTable(name, &info);
+        setBuiltInInfoFromSymbol(variable, &info);
         info.staticUse   = true;
-        info.isInvariant = mSymbolTable->isVaryingInvariant(name);
+        info.active      = true;
+        info.isInvariant = mSymbolTable->isVaryingInvariant(variable.name());
         varyings->push_back(info);
         (*addedFlag) = true;
     }
 }
 
-void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const ImmutableString &name,
+void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const TVariable &variable,
                                                                 bool *addedFlag)
 {
     if (!(*addedFlag))
     {
         OutputVariable info;
-        setBuiltInInfoFromSymbolTable(name, &info);
+        setBuiltInInfoFromSymbol(variable, &info);
         info.staticUse = true;
+        info.active    = true;
         mOutputVariables->push_back(info);
         (*addedFlag) = true;
     }
 }
 
-void CollectVariablesTraverser::recordBuiltInAttributeUsed(const ImmutableString &name,
+void CollectVariablesTraverser::recordBuiltInAttributeUsed(const TVariable &variable,
                                                            bool *addedFlag)
 {
     if (!(*addedFlag))
     {
         Attribute info;
-        setBuiltInInfoFromSymbolTable(name, &info);
+        setBuiltInInfoFromSymbol(variable, &info);
         info.staticUse = true;
+        info.active    = true;
         info.location  = -1;
         mAttribs->push_back(info);
         (*addedFlag) = true;
     }
 }
 
 InterfaceBlock *CollectVariablesTraverser::recordGLInUsed(const TType &glInType)
 {
     if (!mPerVertexInAdded)
     {
         ASSERT(glInType.getQualifier() == EvqPerVertexIn);
         InterfaceBlock info;
         recordInterfaceBlock("gl_in", glInType, &info);
-        info.staticUse = true;
 
         mPerVertexInAdded = true;
         mInBlocks->push_back(info);
         return &mInBlocks->back();
     }
     else
     {
         return FindVariable(ImmutableString("gl_PerVertex"), mInBlocks);
     }
 }
 
-// We want to check whether a uniform/varying is statically used
-// because we only count the used ones in packing computing.
-// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
-// toward varying counting if they are statically used in a fragment
-// shader.
+bool CollectVariablesTraverser::visitInvariantDeclaration(Visit visit,
+                                                          TIntermInvariantDeclaration *node)
+{
+    // We should not mark variables as active just based on an invariant declaration, so we don't
+    // traverse the symbols declared invariant.
+    return false;
+}
+
+// We want to check whether a uniform/varying is active because we need to skip updating inactive
+// ones. We also only count the active ones in packing computing. Also, gl_FragCoord, gl_PointCoord,
+// and gl_FrontFacing count toward varying counting if they are active in a fragment shader.
 void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
 {
     ASSERT(symbol != nullptr);
 
     if (symbol->variable().symbolType() == SymbolType::AngleInternal ||
         symbol->variable().symbolType() == SymbolType::Empty)
     {
         // Internal variables or nameless variables are not collected.
@@ -380,37 +387,41 @@ void CollectVariablesTraverser::visitSym
         {
             Uniform info;
             const char kName[] = "gl_DepthRange";
             info.name          = kName;
             info.mappedName    = kName;
             info.type          = GL_NONE;
             info.precision     = GL_NONE;
             info.staticUse     = true;
+            info.active        = true;
 
             ShaderVariable nearInfo(GL_FLOAT);
             const char kNearName[] = "near";
             nearInfo.name          = kNearName;
             nearInfo.mappedName    = kNearName;
             nearInfo.precision     = GL_HIGH_FLOAT;
             nearInfo.staticUse     = true;
+            nearInfo.active        = true;
 
             ShaderVariable farInfo(GL_FLOAT);
             const char kFarName[] = "far";
             farInfo.name          = kFarName;
             farInfo.mappedName    = kFarName;
             farInfo.precision     = GL_HIGH_FLOAT;
             farInfo.staticUse     = true;
+            farInfo.active        = true;
 
             ShaderVariable diffInfo(GL_FLOAT);
             const char kDiffName[] = "diff";
             diffInfo.name          = kDiffName;
             diffInfo.mappedName    = kDiffName;
             diffInfo.precision     = GL_HIGH_FLOAT;
             diffInfo.staticUse     = true;
+            diffInfo.active        = true;
 
             info.fields.push_back(nearInfo);
             info.fields.push_back(farInfo);
             info.fields.push_back(diffInfo);
 
             mUniforms->push_back(info);
             mDepthRangeAdded = true;
         }
@@ -445,148 +456,126 @@ void CollectVariablesTraverser::visitSym
             case EvqBuffer:
             {
                 const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
                 var =
                     FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
             }
             break;
             case EvqFragCoord:
-                recordBuiltInVaryingUsed(ImmutableString("gl_FragCoord"), &mFragCoordAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mFragCoordAdded, mInputVaryings);
                 return;
             case EvqFrontFacing:
-                recordBuiltInVaryingUsed(ImmutableString("gl_FrontFacing"), &mFrontFacingAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mFrontFacingAdded, mInputVaryings);
                 return;
             case EvqPointCoord:
-                recordBuiltInVaryingUsed(ImmutableString("gl_PointCoord"), &mPointCoordAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPointCoordAdded, mInputVaryings);
                 return;
             case EvqInstanceID:
                 // Whenever the SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set,
                 // gl_InstanceID is added inside expressions to initialize ViewID_OVR and
-                // InstanceID. gl_InstanceID is not added to the symbol table for ESSL1 shaders
-                // which makes it necessary to populate the type information explicitly instead of
-                // extracting it from the symbol table.
-                if (!mInstanceIDAdded)
-                {
-                    Attribute info;
-                    const char kName[] = "gl_InstanceID";
-                    info.name          = kName;
-                    info.mappedName    = kName;
-                    info.type          = GL_INT;
-                    info.precision     = GL_HIGH_INT;  // Defined by spec.
-                    info.staticUse     = true;
-                    info.location      = -1;
-                    mAttribs->push_back(info);
-                    mInstanceIDAdded = true;
-                }
+                // InstanceID. Note that gl_InstanceID is not added to the symbol table for ESSL1
+                // shaders.
+                recordBuiltInAttributeUsed(symbol->variable(), &mInstanceIDAdded);
                 return;
             case EvqVertexID:
-                recordBuiltInAttributeUsed(ImmutableString("gl_VertexID"), &mVertexIDAdded);
+                recordBuiltInAttributeUsed(symbol->variable(), &mVertexIDAdded);
                 return;
             case EvqPosition:
-                recordBuiltInVaryingUsed(ImmutableString("gl_Position"), &mPositionAdded,
-                                         mOutputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPositionAdded, mOutputVaryings);
                 return;
             case EvqPointSize:
-                recordBuiltInVaryingUsed(ImmutableString("gl_PointSize"), &mPointSizeAdded,
-                                         mOutputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPointSizeAdded, mOutputVaryings);
                 return;
             case EvqLastFragData:
-                recordBuiltInVaryingUsed(ImmutableString("gl_LastFragData"), &mLastFragDataAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mLastFragDataAdded, mInputVaryings);
                 return;
             case EvqFragColor:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragColor"), &mFragColorAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragColorAdded);
                 return;
             case EvqFragData:
                 if (!mFragDataAdded)
                 {
                     OutputVariable info;
-                    setBuiltInInfoFromSymbolTable(ImmutableString("gl_FragData"), &info);
+                    setBuiltInInfoFromSymbol(symbol->variable(), &info);
                     if (!IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
                     {
                         ASSERT(info.arraySizes.size() == 1u);
                         info.arraySizes.back() = 1u;
                     }
                     info.staticUse = true;
+                    info.active    = true;
                     mOutputVariables->push_back(info);
                     mFragDataAdded = true;
                 }
                 return;
             case EvqFragDepthEXT:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragDepthEXT"),
-                                                &mFragDepthEXTAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDepthEXTAdded);
                 return;
             case EvqFragDepth:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_FragDepth"), &mFragDepthAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDepthAdded);
                 return;
             case EvqSecondaryFragColorEXT:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_SecondaryFragColorEXT"),
-                                                &mSecondaryFragColorEXTAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragColorEXTAdded);
                 return;
             case EvqSecondaryFragDataEXT:
-                recordBuiltInFragmentOutputUsed(ImmutableString("gl_SecondaryFragDataEXT"),
-                                                &mSecondaryFragDataEXTAdded);
+                recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragDataEXTAdded);
                 return;
             case EvqInvocationID:
-                recordBuiltInVaryingUsed(ImmutableString("gl_InvocationID"), &mInvocationIDAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mInvocationIDAdded, mInputVaryings);
                 break;
             case EvqPrimitiveIDIn:
-                recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveIDIn"), &mPrimitiveIDInAdded,
-                                         mInputVaryings);
+                recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDInAdded, mInputVaryings);
                 break;
             case EvqPrimitiveID:
                 if (mShaderType == GL_GEOMETRY_SHADER_EXT)
                 {
-                    recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveID"), &mPrimitiveIDAdded,
+                    recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
                                              mOutputVaryings);
                 }
                 else
                 {
                     ASSERT(mShaderType == GL_FRAGMENT_SHADER);
-                    recordBuiltInVaryingUsed(ImmutableString("gl_PrimitiveID"), &mPrimitiveIDAdded,
+                    recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
                                              mInputVaryings);
                 }
                 break;
             case EvqLayer:
                 if (mShaderType == GL_GEOMETRY_SHADER_EXT)
                 {
-                    recordBuiltInVaryingUsed(ImmutableString("gl_Layer"), &mLayerAdded,
-                                             mOutputVaryings);
+                    recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mOutputVaryings);
                 }
                 else if (mShaderType == GL_FRAGMENT_SHADER)
                 {
-                    recordBuiltInVaryingUsed(ImmutableString("gl_Layer"), &mLayerAdded,
-                                             mInputVaryings);
+                    recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mInputVaryings);
                 }
                 else
                 {
                     ASSERT(mShaderType == GL_VERTEX_SHADER &&
                            IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview));
                 }
                 break;
             default:
                 break;
         }
     }
     if (var)
     {
-        MarkStaticallyUsed(var);
+        MarkActive(var);
     }
 }
 
 void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
+                                                             bool staticUse,
                                                              ShaderVariable *variableOut) const
 {
     ASSERT(variableOut);
 
+    variableOut->staticUse = staticUse;
+
     const TStructure *structure = type.getStruct();
     if (!structure)
     {
         variableOut->type      = GLVariableType(type);
         variableOut->precision = GLVariablePrecision(type);
     }
     else
     {
@@ -599,43 +588,45 @@ void CollectVariablesTraverser::setField
 
         const TFieldList &fields = structure->fields();
 
         for (const TField *field : fields)
         {
             // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
             // ShaderVariable objects.
             ShaderVariable fieldVariable;
-            setFieldProperties(*field->type(), field->name(), &fieldVariable);
+            setFieldProperties(*field->type(), field->name(), staticUse, &fieldVariable);
             variableOut->fields.push_back(fieldVariable);
         }
     }
     if (auto *arraySizes = type.getArraySizes())
     {
         variableOut->arraySizes.assign(arraySizes->begin(), arraySizes->end());
     }
 }
 
 void CollectVariablesTraverser::setFieldProperties(const TType &type,
                                                    const ImmutableString &name,
+                                                   bool staticUse,
                                                    ShaderVariable *variableOut) const
 {
     ASSERT(variableOut);
-    setFieldOrVariableProperties(type, variableOut);
+    setFieldOrVariableProperties(type, staticUse, variableOut);
     variableOut->name.assign(name.data(), name.length());
     variableOut->mappedName = HashName(name, mHashFunction, nullptr).data();
 }
 
 void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
                                                             const TVariable &variable,
                                                             ShaderVariable *variableOut) const
 {
     ASSERT(variableOut);
 
-    setFieldOrVariableProperties(type, variableOut);
+    variableOut->staticUse = mSymbolTable->isStaticallyUsed(variable);
+    setFieldOrVariableProperties(type, variableOut->staticUse, variableOut);
     ASSERT(variable.symbolType() != SymbolType::Empty);
     variableOut->name.assign(variable.name().data(), variable.name().length());
     variableOut->mappedName = getMappedName(&variable);
 }
 
 Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
 {
     const TType &type = variable.getType();
@@ -701,41 +692,73 @@ void CollectVariablesTraverser::recordIn
     const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
     ASSERT(blockType);
 
     interfaceBlock->name       = blockType->name().data();
     interfaceBlock->mappedName = getMappedName(blockType);
     if (instanceName != nullptr)
     {
         interfaceBlock->instanceName = instanceName;
+        const TSymbol *blockSymbol   = nullptr;
+        if (strncmp(instanceName, "gl_in", 5u) == 0)
+        {
+            blockSymbol = mSymbolTable->getGlInVariableWithArraySize();
+        }
+        else
+        {
+            blockSymbol = mSymbolTable->findGlobal(ImmutableString(instanceName));
+        }
+        ASSERT(blockSymbol && blockSymbol->isVariable());
+        interfaceBlock->staticUse =
+            mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(blockSymbol));
     }
     ASSERT(!interfaceBlockType.isArrayOfArrays());  // Disallowed by GLSL ES 3.10 section 4.3.9
     interfaceBlock->arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
 
     interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier());
     if (interfaceBlock->blockType == BlockType::BLOCK_UNIFORM ||
         interfaceBlock->blockType == BlockType::BLOCK_BUFFER)
     {
         // TODO(oetuaho): Remove setting isRowMajorLayout.
         interfaceBlock->isRowMajorLayout = false;
         interfaceBlock->binding          = blockType->blockBinding();
         interfaceBlock->layout           = GetBlockLayoutType(blockType->blockStorage());
     }
 
     // Gather field information
+    bool anyFieldStaticallyUsed = false;
     for (const TField *field : blockType->fields())
     {
         const TType &fieldType = *field->type();
 
+        bool staticUse = false;
+        if (instanceName == nullptr)
+        {
+            // Static use of individual fields has been recorded, since they are present in the
+            // symbol table as variables.
+            const TSymbol *fieldSymbol = mSymbolTable->findGlobal(field->name());
+            ASSERT(fieldSymbol && fieldSymbol->isVariable());
+            staticUse =
+                mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(fieldSymbol));
+            if (staticUse)
+            {
+                anyFieldStaticallyUsed = true;
+            }
+        }
+
         InterfaceBlockField fieldVariable;
-        setFieldProperties(fieldType, field->name(), &fieldVariable);
+        setFieldProperties(fieldType, field->name(), staticUse, &fieldVariable);
         fieldVariable.isRowMajorLayout =
             (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
         interfaceBlock->fields.push_back(fieldVariable);
     }
+    if (anyFieldStaticallyUsed)
+    {
+        interfaceBlock->staticUse = true;
+    }
 }
 
 Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
 {
     Uniform uniform;
     setCommonVariableProperties(variable.getType(), variable.variable(), &uniform);
     uniform.binding  = variable.getType().getLayoutQualifier().binding;
     uniform.location = variable.getType().getLayoutQualifier().location;
@@ -843,17 +866,17 @@ InterfaceBlock *CollectVariablesTraverse
     }
     return namedBlock;
 }
 
 bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
 {
     if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
     {
-        // NOTE: we do not determine static use for individual blocks of an array
+        // NOTE: we do not determine static use / activeness for individual blocks of an array.
         TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
         ASSERT(blockNode);
 
         TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
         ASSERT(constantUnion);
 
         InterfaceBlock *namedBlock = nullptr;
 
@@ -877,20 +900,25 @@ bool CollectVariablesTraverser::visitBin
         }
 
         const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
         if (!namedBlock)
         {
             namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
         }
         ASSERT(namedBlock);
-        namedBlock->staticUse   = true;
+        ASSERT(namedBlock->staticUse);
+        namedBlock->active      = true;
         unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
         ASSERT(fieldIndex < namedBlock->fields.size());
+        // TODO(oetuaho): Would be nicer to record static use of fields of named interface blocks
+        // more accurately at parse time - now we only mark the fields statically used if they are
+        // active. http://anglebug.com/2440
         namedBlock->fields[fieldIndex].staticUse = true;
+        namedBlock->fields[fieldIndex].active    = true;
 
         if (traverseIndexExpression)
         {
             ASSERT(interfaceIndexingNode);
             interfaceIndexingNode->getRight()->traverse(this);
         }
         return false;
     }
@@ -906,20 +934,18 @@ void CollectVariables(TIntermBlock *root
                       std::vector<Uniform> *uniforms,
                       std::vector<Varying> *inputVaryings,
                       std::vector<Varying> *outputVaryings,
                       std::vector<InterfaceBlock> *uniformBlocks,
                       std::vector<InterfaceBlock> *shaderStorageBlocks,
                       std::vector<InterfaceBlock> *inBlocks,
                       ShHashFunction64 hashFunction,
                       TSymbolTable *symbolTable,
-                      int shaderVersion,
                       GLenum shaderType,
                       const TExtensionBehavior &extensionBehavior)
 {
     CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
                                       outputVaryings, uniformBlocks, shaderStorageBlocks, inBlocks,
-                                      hashFunction, symbolTable, shaderVersion, shaderType,
-                                      extensionBehavior);
+                                      hashFunction, symbolTable, shaderType, extensionBehavior);
     root->traverse(&collect);
 }
 
 }  // namespace sh
--- a/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
@@ -24,14 +24,13 @@ void CollectVariables(TIntermBlock *root
                       std::vector<Uniform> *uniforms,
                       std::vector<Varying> *inputVaryings,
                       std::vector<Varying> *outputVaryings,
                       std::vector<InterfaceBlock> *uniformBlocks,
                       std::vector<InterfaceBlock> *shaderStorageBlocks,
                       std::vector<InterfaceBlock> *inBlocks,
                       ShHashFunction64 hashFunction,
                       TSymbolTable *symbolTable,
-                      int shaderVersion,
                       GLenum shaderType,
                       const TExtensionBehavior &extensionBehavior);
 }
 
 #endif  // COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
--- a/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
@@ -5,53 +5,53 @@
 //
 
 #include "compiler/translator/Compiler.h"
 
 #include <sstream>
 
 #include "angle_gl.h"
 #include "common/utilities.h"
-#include "compiler/translator/AddAndTrueToLoopCondition.h"
 #include "compiler/translator/CallDAG.h"
-#include "compiler/translator/ClampFragDepth.h"
-#include "compiler/translator/ClampPointSize.h"
 #include "compiler/translator/CollectVariables.h"
-#include "compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h"
-#include "compiler/translator/DeferGlobalInitializers.h"
-#include "compiler/translator/EmulateGLFragColorBroadcast.h"
-#include "compiler/translator/EmulatePrecision.h"
-#include "compiler/translator/FoldExpressions.h"
 #include "compiler/translator/Initialize.h"
-#include "compiler/translator/InitializeVariables.h"
-#include "compiler/translator/IntermNodePatternMatcher.h"
 #include "compiler/translator/IsASTDepthBelowLimit.h"
 #include "compiler/translator/OutputTree.h"
 #include "compiler/translator/ParseContext.h"
-#include "compiler/translator/PruneNoOps.h"
-#include "compiler/translator/RegenerateStructNames.h"
-#include "compiler/translator/RemoveArrayLengthMethod.h"
-#include "compiler/translator/RemoveEmptySwitchStatements.h"
-#include "compiler/translator/RemoveInvariantDeclaration.h"
-#include "compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h"
-#include "compiler/translator/RemovePow.h"
-#include "compiler/translator/RemoveUnreferencedVariables.h"
-#include "compiler/translator/RewriteDoWhile.h"
-#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
-#include "compiler/translator/SeparateDeclarations.h"
-#include "compiler/translator/SimplifyLoopConditions.h"
-#include "compiler/translator/SplitSequenceOperator.h"
-#include "compiler/translator/UnfoldShortCircuitAST.h"
-#include "compiler/translator/UseInterfaceBlockFields.h"
 #include "compiler/translator/ValidateLimitations.h"
 #include "compiler/translator/ValidateMaxParameters.h"
 #include "compiler/translator/ValidateOutputs.h"
 #include "compiler/translator/ValidateVaryingLocations.h"
 #include "compiler/translator/VariablePacker.h"
-#include "compiler/translator/VectorizeVectorScalarArithmetic.h"
+#include "compiler/translator/tree_ops/AddAndTrueToLoopCondition.h"
+#include "compiler/translator/tree_ops/ClampFragDepth.h"
+#include "compiler/translator/tree_ops/ClampPointSize.h"
+#include "compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h"
+#include "compiler/translator/tree_ops/DeferGlobalInitializers.h"
+#include "compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h"
+#include "compiler/translator/tree_ops/EmulatePrecision.h"
+#include "compiler/translator/tree_ops/FoldExpressions.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_ops/PruneEmptyCases.h"
+#include "compiler/translator/tree_ops/PruneNoOps.h"
+#include "compiler/translator/tree_ops/RegenerateStructNames.h"
+#include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
+#include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
+#include "compiler/translator/tree_ops/RemovePow.h"
+#include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
+#include "compiler/translator/tree_ops/RewriteDoWhile.h"
+#include "compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h"
+#include "compiler/translator/tree_ops/SeparateDeclarations.h"
+#include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
+#include "compiler/translator/tree_ops/SplitSequenceOperator.h"
+#include "compiler/translator/tree_ops/UnfoldShortCircuitAST.h"
+#include "compiler/translator/tree_ops/UseInterfaceBlockFields.h"
+#include "compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h"
+#include "compiler/translator/tree_util/BuiltIn_autogen.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
 #include "compiler/translator/util.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 
 namespace sh
 {
 
 namespace
 {
@@ -188,22 +188,22 @@ class TScopedPoolAllocator
     TPoolAllocator *mAllocator;
 };
 
 class TScopedSymbolTableLevel
 {
   public:
     TScopedSymbolTableLevel(TSymbolTable *table) : mTable(table)
     {
-        ASSERT(mTable->atBuiltInLevel());
+        ASSERT(mTable->isEmpty());
         mTable->push();
     }
     ~TScopedSymbolTableLevel()
     {
-        while (!mTable->atBuiltInLevel())
+        while (!mTable->isEmpty())
             mTable->pop();
     }
 
   private:
     TSymbolTable *mTable;
 };
 
 int MapSpecToShaderVersion(ShShaderSpec spec)
@@ -220,16 +220,61 @@ int MapSpecToShaderVersion(ShShaderSpec 
         case SH_WEBGL3_SPEC:
             return 310;
         default:
             UNREACHABLE();
             return 0;
     }
 }
 
+bool ValidateFragColorAndFragData(GLenum shaderType,
+                                  int shaderVersion,
+                                  const TSymbolTable &symbolTable,
+                                  TDiagnostics *diagnostics)
+{
+    if (shaderVersion > 100 || shaderType != GL_FRAGMENT_SHADER)
+    {
+        return true;
+    }
+
+    bool usesFragColor = false;
+    bool usesFragData  = false;
+    // This validation is a bit stricter than the spec - it's only an error to write to
+    // both FragData and FragColor. But because it's better not to have reads from undefined
+    // variables, we always return an error if they are both referenced, rather than only if they
+    // are written.
+    if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_FragColor()) ||
+        symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()))
+    {
+        usesFragColor = true;
+    }
+    // Extension variables may not always be initialized (saves some time at symbol table init).
+    bool secondaryFragDataUsed =
+        symbolTable.gl_SecondaryFragDataEXT() != nullptr &&
+        symbolTable.isStaticallyUsed(*symbolTable.gl_SecondaryFragDataEXT());
+    if (symbolTable.isStaticallyUsed(*symbolTable.gl_FragData()) || secondaryFragDataUsed)
+    {
+        usesFragData = true;
+    }
+    if (usesFragColor && usesFragData)
+    {
+        const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
+        if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()) ||
+            secondaryFragDataUsed)
+        {
+            errorMessage =
+                "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
+                " and (gl_FragColor, gl_SecondaryFragColorEXT)";
+        }
+        diagnostics->globalError(errorMessage);
+        return false;
+    }
+    return true;
+}
+
 }  // namespace
 
 TShHandleBase::TShHandleBase()
 {
     allocator.push();
     SetGlobalPoolAllocator(&allocator);
 }
 
@@ -446,41 +491,36 @@ bool TCompiler::checkAndSimplifyAST(TInt
     }
 
     if (shouldRunLoopAndIndexingValidation(compileOptions) &&
         !ValidateLimitations(root, shaderType, &symbolTable, &mDiagnostics))
     {
         return false;
     }
 
+    if (!ValidateFragColorAndFragData(shaderType, shaderVersion, symbolTable, &mDiagnostics))
+    {
+        return false;
+    }
+
     // Fold expressions that could not be folded before validation that was done as a part of
     // parsing.
     FoldExpressions(root, &mDiagnostics);
     // Folding should only be able to generate warnings.
     ASSERT(mDiagnostics.numErrors() == 0);
 
     // We prune no-ops to work around driver bugs and to keep AST processing and output simple.
     // The following kinds of no-ops are pruned:
     //   1. Empty declarations "int;".
     //   2. Literal statements: "1.0;". The ESSL output doesn't define a default precision
     //      for float, so float literal statements would end up with no precision which is
     //      invalid ESSL.
     // After this empty declarations are not allowed in the AST.
     PruneNoOps(root, &symbolTable);
 
-    // In case the last case inside a switch statement is a certain type of no-op, GLSL
-    // compilers in drivers may not accept it. In this case we clean up the dead code from the
-    // end of switch statements. This is also required because PruneNoOps may have left switch
-    // statements that only contained an empty declaration inside the final case in an invalid
-    // state. Relies on that PruneNoOps has already been run.
-    RemoveNoOpCasesFromEndOfSwitchStatements(root, &symbolTable);
-
-    // Remove empty switch statements - this makes output simpler.
-    RemoveEmptySwitchStatements(root);
-
     // Create the function DAG and check there is no recursion
     if (!initCallDag(root))
     {
         return false;
     }
 
     if ((compileOptions & SH_LIMIT_CALL_STACK_DEPTH) && !checkCallDepth())
     {
@@ -543,17 +583,17 @@ bool TCompiler::checkAndSimplifyAST(TInt
 
     if (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)
     {
         UnfoldShortCircuitAST(root);
     }
 
     if (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)
     {
-        RemovePow(root);
+        RemovePow(root, &symbolTable);
     }
 
     if (compileOptions & SH_REGENERATE_STRUCT_NAMES)
     {
         RegenerateStructNames gen(&symbolTable);
         root->traverse(&gen);
     }
 
@@ -583,16 +623,24 @@ bool TCompiler::checkAndSimplifyAST(TInt
 
     SplitSequenceOperator(root, IntermNodePatternMatcher::kArrayLengthMethod | simplifyScalarized,
                           &getSymbolTable());
 
     RemoveArrayLengthMethod(root);
 
     RemoveUnreferencedVariables(root, &symbolTable);
 
+    // In case the last case inside a switch statement is a certain type of no-op, GLSL compilers in
+    // drivers may not accept it. In this case we clean up the dead code from the end of switch
+    // statements. This is also required because PruneNoOps or RemoveUnreferencedVariables may have
+    // left switch statements that only contained an empty declaration inside the final case in an
+    // invalid state. Relies on that PruneNoOps and RemoveUnreferencedVariables have already been
+    // run.
+    PruneEmptyCases(root);
+
     // Built-in function emulation needs to happen after validateLimitations pass.
     // TODO(jmadill): Remove global pool allocator.
     GetGlobalPoolAllocator()->lock();
     initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions);
     GetGlobalPoolAllocator()->unlock();
     builtInFunctionEmulator.markBuiltInFunctionsForEmulation(root);
 
     if (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)
@@ -600,17 +648,17 @@ bool TCompiler::checkAndSimplifyAST(TInt
         ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh, &symbolTable);
     }
 
     if (shouldCollectVariables(compileOptions))
     {
         ASSERT(!variablesCollected);
         CollectVariables(root, &attributes, &outputVariables, &uniforms, &inputVaryings,
                          &outputVaryings, &uniformBlocks, &shaderStorageBlocks, &inBlocks,
-                         hashFunction, &symbolTable, shaderVersion, shaderType, extensionBehavior);
+                         hashFunction, &symbolTable, shaderType, extensionBehavior);
         collectInterfaceBlocks();
         variablesCollected = true;
         if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
         {
             useAllMembersInUnusedStandardAndSharedBlocks(root);
         }
         if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
         {
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Applies the necessary AST transformations to support multiview rendering through instancing.
-// Check the header file For more information.
-//
-
-#include "compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h"
-
-#include "compiler/translator/FindMain.h"
-#include "compiler/translator/InitializeVariables.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/ReplaceVariable.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/util.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kGlLayerString("gl_Layer");
-constexpr const ImmutableString kGlViewportIndexString("gl_ViewportIndex");
-constexpr const ImmutableString kGlViewIdOVRString("gl_ViewID_OVR");
-constexpr const ImmutableString kGlInstanceIdString("gl_InstanceID");
-constexpr const ImmutableString kViewIDVariableName("ViewID_OVR");
-constexpr const ImmutableString kInstanceIDVariableName("InstanceID");
-constexpr const ImmutableString kMultiviewBaseViewLayerIndexVariableName(
-    "multiviewBaseViewLayerIndex");
-
-TIntermSymbol *CreateGLInstanceIDSymbol(const TSymbolTable &symbolTable)
-{
-    return ReferenceBuiltInVariable(kGlInstanceIdString, symbolTable, 300);
-}
-
-// Adds the InstanceID and ViewID_OVR initializers to the end of the initializers' sequence.
-void InitializeViewIDAndInstanceID(const TVariable *viewID,
-                                   const TVariable *instanceID,
-                                   unsigned numberOfViews,
-                                   const TSymbolTable &symbolTable,
-                                   TIntermSequence *initializers)
-{
-    // Create an unsigned numberOfViews node.
-    TConstantUnion *numberOfViewsUnsignedConstant = new TConstantUnion();
-    numberOfViewsUnsignedConstant->setUConst(numberOfViews);
-    TIntermConstantUnion *numberOfViewsUint =
-        new TIntermConstantUnion(numberOfViewsUnsignedConstant, TType(EbtUInt, EbpHigh, EvqConst));
-
-    // Create a uint(gl_InstanceID) node.
-    TIntermSequence *glInstanceIDSymbolCastArguments = new TIntermSequence();
-    glInstanceIDSymbolCastArguments->push_back(CreateGLInstanceIDSymbol(symbolTable));
-    TIntermAggregate *glInstanceIDAsUint = TIntermAggregate::CreateConstructor(
-        TType(EbtUInt, EbpHigh, EvqTemporary), glInstanceIDSymbolCastArguments);
-
-    // Create a uint(gl_InstanceID) / numberOfViews node.
-    TIntermBinary *normalizedInstanceID =
-        new TIntermBinary(EOpDiv, glInstanceIDAsUint, numberOfViewsUint);
-
-    // Create an int(uint(gl_InstanceID) / numberOfViews) node.
-    TIntermSequence *normalizedInstanceIDCastArguments = new TIntermSequence();
-    normalizedInstanceIDCastArguments->push_back(normalizedInstanceID);
-    TIntermAggregate *normalizedInstanceIDAsInt = TIntermAggregate::CreateConstructor(
-        TType(EbtInt, EbpHigh, EvqTemporary), normalizedInstanceIDCastArguments);
-
-    // Create an InstanceID = int(uint(gl_InstanceID) / numberOfViews) node.
-    TIntermBinary *instanceIDInitializer =
-        new TIntermBinary(EOpAssign, new TIntermSymbol(instanceID), normalizedInstanceIDAsInt);
-    initializers->push_back(instanceIDInitializer);
-
-    // Create a uint(gl_InstanceID) % numberOfViews node.
-    TIntermBinary *normalizedViewID =
-        new TIntermBinary(EOpIMod, glInstanceIDAsUint->deepCopy(), numberOfViewsUint->deepCopy());
-
-    // Create a ViewID_OVR = uint(gl_InstanceID) % numberOfViews node.
-    TIntermBinary *viewIDInitializer =
-        new TIntermBinary(EOpAssign, new TIntermSymbol(viewID), normalizedViewID);
-    initializers->push_back(viewIDInitializer);
-}
-
-void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
-{
-    TIntermDeclaration *declaration = new TIntermDeclaration();
-    declaration->appendDeclarator(new TIntermSymbol(variable));
-
-    TIntermSequence *globalSequence = root->getSequence();
-    globalSequence->insert(globalSequence->begin(), declaration);
-}
-
-// Adds a branch to write int(ViewID_OVR) to either gl_ViewportIndex or gl_Layer. The branch is
-// added to the end of the initializers' sequence.
-void SelectViewIndexInVertexShader(const TVariable *viewID,
-                                   const TVariable *multiviewBaseViewLayerIndex,
-                                   TIntermSequence *initializers,
-                                   const TSymbolTable &symbolTable)
-{
-    // Create an int(ViewID_OVR) node.
-    TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence();
-    viewIDSymbolCastArguments->push_back(new TIntermSymbol(viewID));
-    TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor(
-        TType(EbtInt, EbpHigh, EvqTemporary), viewIDSymbolCastArguments);
-
-    // Create a gl_ViewportIndex node.
-    TIntermSymbol *viewportIndexSymbol =
-        ReferenceBuiltInVariable(kGlViewportIndexString, symbolTable, 0);
-
-    // Create a { gl_ViewportIndex = int(ViewID_OVR) } node.
-    TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock();
-    viewportIndexInitializerInBlock->appendStatement(
-        new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt));
-
-    // Create a gl_Layer node.
-    TIntermSymbol *layerSymbol = ReferenceBuiltInVariable(kGlLayerString, symbolTable, 0);
-
-    // Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
-    TIntermBinary *sumOfViewIDAndBaseViewIndex = new TIntermBinary(
-        EOpAdd, viewIDAsInt->deepCopy(), new TIntermSymbol(multiviewBaseViewLayerIndex));
-
-    // Create a { gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex } node.
-    TIntermBlock *layerInitializerInBlock = new TIntermBlock();
-    layerInitializerInBlock->appendStatement(
-        new TIntermBinary(EOpAssign, layerSymbol, sumOfViewIDAndBaseViewIndex));
-
-    // Create a node to compare whether the base view index uniform is less than zero.
-    TIntermBinary *multiviewBaseViewLayerIndexZeroComparison =
-        new TIntermBinary(EOpLessThan, new TIntermSymbol(multiviewBaseViewLayerIndex),
-                          CreateZeroNode(TType(EbtInt, EbpHigh, EvqConst)));
-
-    // Create an if-else statement to select the code path.
-    TIntermIfElse *multiviewBranch =
-        new TIntermIfElse(multiviewBaseViewLayerIndexZeroComparison,
-                          viewportIndexInitializerInBlock, layerInitializerInBlock);
-
-    initializers->push_back(multiviewBranch);
-}
-
-}  // namespace
-
-void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
-                                                 unsigned numberOfViews,
-                                                 GLenum shaderType,
-                                                 ShCompileOptions compileOptions,
-                                                 ShShaderOutput shaderOutput,
-                                                 TSymbolTable *symbolTable)
-{
-    ASSERT(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER);
-
-    TQualifier viewIDQualifier  = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
-    const TVariable *viewID =
-        new TVariable(symbolTable, kViewIDVariableName,
-                      new TType(EbtUInt, EbpHigh, viewIDQualifier), SymbolType::AngleInternal);
-
-    DeclareGlobalVariable(root, viewID);
-    ReplaceVariable(
-        root,
-        static_cast<const TVariable *>(symbolTable->findBuiltIn(kGlViewIdOVRString, 300, true)),
-        viewID);
-    if (shaderType == GL_VERTEX_SHADER)
-    {
-        // Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
-        // InstanceID and ViewID.
-        const TType *instanceIDVariableType   = StaticType::Get<EbtInt, EbpHigh, EvqGlobal, 1, 1>();
-        const TVariable *instanceID =
-            new TVariable(symbolTable, kInstanceIDVariableName, instanceIDVariableType,
-                          SymbolType::AngleInternal);
-        DeclareGlobalVariable(root, instanceID);
-        ReplaceVariable(root,
-                        static_cast<const TVariable *>(
-                            symbolTable->findBuiltIn(kGlInstanceIdString, 300, true)),
-                        instanceID);
-
-        TIntermSequence *initializers = new TIntermSequence();
-        InitializeViewIDAndInstanceID(viewID, instanceID, numberOfViews, *symbolTable,
-                                      initializers);
-
-        // The AST transformation which adds the expression to select the viewport index should
-        // be done only for the GLSL and ESSL output.
-        const bool selectView = (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u;
-        // Assert that if the view is selected in the vertex shader, then the output is
-        // either GLSL or ESSL.
-        ASSERT(!selectView || IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput));
-        if (selectView)
-        {
-            // Add a uniform to switch between side-by-side and layered rendering.
-            const TType *baseLayerIndexVariableType =
-                StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
-            const TVariable *multiviewBaseViewLayerIndex =
-                new TVariable(symbolTable, kMultiviewBaseViewLayerIndexVariableName,
-                              baseLayerIndexVariableType, SymbolType::AngleInternal);
-            DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
-
-            // Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
-            // initialization.
-            SelectViewIndexInVertexShader(viewID, multiviewBaseViewLayerIndex, initializers,
-                                          *symbolTable);
-        }
-
-        // Insert initializers at the beginning of main().
-        TIntermBlock *initializersBlock = new TIntermBlock();
-        initializersBlock->getSequence()->swap(*initializers);
-        TIntermBlock *mainBody = FindMainBody(root);
-        mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initializersBlock);
-    }
-}
-
-}  // namespace sh
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Regardless of the shader type, the following AST transformations are applied:
-// - Add declaration of View_ID_OVR.
-// - Replace every occurrence of gl_ViewID_OVR with ViewID_OVR, mark ViewID_OVR as internal and
-// declare it as a flat varying.
-//
-// If the shader type is a vertex shader, the following AST transformations are applied:
-// - Replace every occurrence of gl_InstanceID with InstanceID, mark InstanceID as internal and set
-// its qualifier to EvqTemporary.
-// - Add initializers of ViewID_OVR and InstanceID to the beginning of the body of main. The pass
-// should be executed before any variables get collected so that usage of gl_InstanceID is recorded.
-// - If the output is ESSL or GLSL and the SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is
-// enabled, the expression
-// "if (multiviewBaseViewLayerIndex < 0) {
-//      gl_ViewportIndex = int(ViewID_OVR);
-//  } else {
-//      gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex;
-//  }"
-// is added after ViewID and InstanceID are initialized. Also, MultiviewRenderPath is added as a
-// uniform.
-//
-
-#ifndef COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
-#define COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
-
-#include "GLSLANG/ShaderLang.h"
-#include "angle_gl.h"
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
-                                                 unsigned numberOfViews,
-                                                 GLenum shaderType,
-                                                 ShCompileOptions compileOptions,
-                                                 ShShaderOutput shaderOutput,
-                                                 TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
\ No newline at end of file
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate
-// function that is called in the beginning of main(). This enables initialization of globals with
-// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing
-// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be
-// done after DeferGlobalInitializers is run. Note that it's important that the function definition
-// is at the end of the shader, as some globals may be declared after main().
-//
-// It can also initialize all uninitialized globals.
-//
-
-#include "compiler/translator/DeferGlobalInitializers.h"
-
-#include <vector>
-
-#include "compiler/translator/FindMain.h"
-#include "compiler/translator/InitializeVariables.h"
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/ReplaceVariable.h"
-#include "compiler/translator/StaticType.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kInitGlobalsString("initGlobals");
-
-void GetDeferredInitializers(TIntermDeclaration *declaration,
-                             bool initializeUninitializedGlobals,
-                             bool canUseLoopsToInitialize,
-                             bool highPrecisionSupported,
-                             TIntermSequence *deferredInitializersOut,
-                             std::vector<const TVariable *> *variablesToReplaceOut,
-                             TSymbolTable *symbolTable)
-{
-    // SeparateDeclarations should have already been run.
-    ASSERT(declaration->getSequence()->size() == 1);
-
-    TIntermNode *declarator = declaration->getSequence()->back();
-    TIntermBinary *init     = declarator->getAsBinaryNode();
-    if (init)
-    {
-        TIntermSymbol *symbolNode = init->getLeft()->getAsSymbolNode();
-        ASSERT(symbolNode);
-        TIntermTyped *expression = init->getRight();
-
-        if (expression->getQualifier() != EvqConst || !expression->hasConstantValue())
-        {
-            // For variables which are not constant, defer their real initialization until
-            // after we initialize uniforms.
-            // Deferral is done also in any cases where the variable can not be converted to a
-            // constant union, since otherwise there's a chance that HLSL output will generate extra
-            // statements from the initializer expression.
-
-            // Change const global to a regular global if its initialization is deferred.
-            // This can happen if ANGLE has not been able to fold the constant expression used
-            // as an initializer.
-            ASSERT(symbolNode->getQualifier() == EvqConst ||
-                   symbolNode->getQualifier() == EvqGlobal);
-            if (symbolNode->getQualifier() == EvqConst)
-            {
-                variablesToReplaceOut->push_back(&symbolNode->variable());
-            }
-
-            TIntermBinary *deferredInit =
-                new TIntermBinary(EOpAssign, symbolNode->deepCopy(), init->getRight());
-            deferredInitializersOut->push_back(deferredInit);
-
-            // Remove the initializer from the global scope and just declare the global instead.
-            declaration->replaceChildNode(init, symbolNode);
-        }
-    }
-    else if (initializeUninitializedGlobals)
-    {
-        TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
-        ASSERT(symbolNode);
-
-        // Ignore ANGLE internal variables and nameless declarations.
-        if (symbolNode->variable().symbolType() == SymbolType::AngleInternal ||
-            symbolNode->variable().symbolType() == SymbolType::Empty)
-            return;
-
-        if (symbolNode->getQualifier() == EvqGlobal)
-        {
-            TIntermSequence *initCode = CreateInitCode(symbolNode, canUseLoopsToInitialize,
-                                                       highPrecisionSupported, symbolTable);
-            deferredInitializersOut->insert(deferredInitializersOut->end(), initCode->begin(),
-                                            initCode->end());
-        }
-    }
-}
-
-void InsertInitCallToMain(TIntermBlock *root,
-                          TIntermSequence *deferredInitializers,
-                          TSymbolTable *symbolTable)
-{
-    TIntermBlock *initGlobalsBlock = new TIntermBlock();
-    initGlobalsBlock->getSequence()->swap(*deferredInitializers);
-
-    TFunction *initGlobalsFunction =
-        new TFunction(symbolTable, kInitGlobalsString, SymbolType::AngleInternal,
-                      StaticType::GetBasic<EbtVoid>(), false);
-
-    TIntermFunctionPrototype *initGlobalsFunctionPrototype =
-        CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
-    root->getSequence()->insert(root->getSequence()->begin(), initGlobalsFunctionPrototype);
-    TIntermFunctionDefinition *initGlobalsFunctionDefinition =
-        CreateInternalFunctionDefinitionNode(*initGlobalsFunction, initGlobalsBlock);
-    root->appendStatement(initGlobalsFunctionDefinition);
-
-    TIntermAggregate *initGlobalsCall =
-        TIntermAggregate::CreateFunctionCall(*initGlobalsFunction, new TIntermSequence());
-
-    TIntermBlock *mainBody = FindMainBody(root);
-    mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initGlobalsCall);
-}
-
-}  // namespace
-
-void DeferGlobalInitializers(TIntermBlock *root,
-                             bool initializeUninitializedGlobals,
-                             bool canUseLoopsToInitialize,
-                             bool highPrecisionSupported,
-                             TSymbolTable *symbolTable)
-{
-    TIntermSequence *deferredInitializers = new TIntermSequence();
-    std::vector<const TVariable *> variablesToReplace;
-
-    // Loop over all global statements and process the declarations. This is simpler than using a
-    // traverser.
-    for (TIntermNode *statement : *root->getSequence())
-    {
-        TIntermDeclaration *declaration = statement->getAsDeclarationNode();
-        if (declaration)
-        {
-            GetDeferredInitializers(declaration, initializeUninitializedGlobals,
-                                    canUseLoopsToInitialize, highPrecisionSupported,
-                                    deferredInitializers, &variablesToReplace, symbolTable);
-        }
-    }
-
-    // Add the function with initialization and the call to that.
-    if (!deferredInitializers->empty())
-    {
-        InsertInitCallToMain(root, deferredInitializers, symbolTable);
-    }
-
-    // Replace constant variables with non-constant global variables.
-    for (const TVariable *var : variablesToReplace)
-    {
-        TType *replacementType = new TType(var->getType());
-        replacementType->setQualifier(EvqGlobal);
-        TVariable *replacement =
-            new TVariable(symbolTable, var->name(), replacementType, var->symbolType());
-        ReplaceVariable(root, var, replacement);
-    }
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/DeferGlobalInitializers.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate
-// function that is called in the beginning of main(). This enables initialization of globals with
-// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing
-// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be
-// done after DeferGlobalInitializers is run. Note that it's important that the function definition
-// is at the end of the shader, as some globals may be declared after main().
-//
-// It can also initialize all uninitialized globals.
-//
-
-#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
-#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
-
-namespace sh
-{
-
-class TIntermBlock;
-class TSymbolTable;
-
-void DeferGlobalInitializers(TIntermBlock *root,
-                             bool initializeUninitializedGlobals,
-                             bool canUseLoopsToInitialize,
-                             bool highPrecisionSupported,
-                             TSymbolTable *symbolTable);
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-//
-// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// gl_FragColor needs to broadcast to all color buffers in ES2 if
-// GL_EXT_draw_buffers is explicitly enabled in a fragment shader.
-//
-// We emulate this by replacing all gl_FragColor with gl_FragData[0], and in the end
-// of main() function, assigning gl_FragData[1], ..., gl_FragData[maxDrawBuffers-1]
-// with gl_FragData[0].
-//
-
-#include "compiler/translator/EmulateGLFragColorBroadcast.h"
-
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-#include "compiler/translator/RunAtTheEndOfShader.h"
-#include "compiler/translator/Symbol.h"
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kGlFragDataString("gl_FragData");
-
-class GLFragColorBroadcastTraverser : public TIntermTraverser
-{
-  public:
-    GLFragColorBroadcastTraverser(int maxDrawBuffers, TSymbolTable *symbolTable, int shaderVersion)
-        : TIntermTraverser(true, false, false, symbolTable),
-          mGLFragColorUsed(false),
-          mMaxDrawBuffers(maxDrawBuffers),
-          mShaderVersion(shaderVersion)
-    {
-    }
-
-    void broadcastGLFragColor(TIntermBlock *root);
-
-    bool isGLFragColorUsed() const { return mGLFragColorUsed; }
-
-  protected:
-    void visitSymbol(TIntermSymbol *node) override;
-
-    TIntermBinary *constructGLFragDataNode(int index) const;
-    TIntermBinary *constructGLFragDataAssignNode(int index) const;
-
-  private:
-    bool mGLFragColorUsed;
-    int mMaxDrawBuffers;
-    const int mShaderVersion;
-};
-
-TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
-{
-    TIntermSymbol *symbol =
-        ReferenceBuiltInVariable(kGlFragDataString, *mSymbolTable, mShaderVersion);
-    TIntermTyped *indexNode = CreateIndexNode(index);
-
-    TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
-    return binary;
-}
-
-TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int index) const
-{
-    TIntermTyped *fragDataIndex = constructGLFragDataNode(index);
-    TIntermTyped *fragDataZero  = constructGLFragDataNode(0);
-
-    return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero);
-}
-
-void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
-{
-    if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_FragColor")
-    {
-        queueReplacement(constructGLFragDataNode(0), OriginalNode::IS_DROPPED);
-        mGLFragColorUsed = true;
-    }
-}
-
-void GLFragColorBroadcastTraverser::broadcastGLFragColor(TIntermBlock *root)
-{
-    ASSERT(mMaxDrawBuffers > 1);
-    if (!mGLFragColorUsed)
-    {
-        return;
-    }
-
-    TIntermBlock *broadcastBlock = new TIntermBlock();
-    // Now insert statements
-    //   gl_FragData[1] = gl_FragData[0];
-    //   ...
-    //   gl_FragData[maxDrawBuffers - 1] = gl_FragData[0];
-    for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex)
-    {
-        broadcastBlock->appendStatement(constructGLFragDataAssignNode(colorIndex));
-    }
-    RunAtTheEndOfShader(root, broadcastBlock, mSymbolTable);
-}
-
-}  // namespace anonymous
-
-void EmulateGLFragColorBroadcast(TIntermBlock *root,
-                                 int maxDrawBuffers,
-                                 std::vector<sh::OutputVariable> *outputVariables,
-                                 TSymbolTable *symbolTable,
-                                 int shaderVersion)
-{
-    ASSERT(maxDrawBuffers > 1);
-    GLFragColorBroadcastTraverser traverser(maxDrawBuffers, symbolTable, shaderVersion);
-    root->traverse(&traverser);
-    if (traverser.isGLFragColorUsed())
-    {
-        traverser.updateTree();
-        traverser.broadcastGLFragColor(root);
-        for (auto &var : *outputVariables)
-        {
-            if (var.name == "gl_FragColor")
-            {
-                // TODO(zmo): Find a way to keep the original variable information.
-                var.name       = "gl_FragData";
-                var.mappedName = "gl_FragData";
-                var.arraySizes.push_back(maxDrawBuffers);
-                ASSERT(var.arraySizes.size() == 1u);
-            }
-        }
-    }
-}
-
-}  // namespace sh
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/EmulateGLFragColorBroadcast.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Emulate gl_FragColor broadcast behaviors in ES2 where
-// GL_EXT_draw_buffers is explicitly enabled in a fragment shader.
-//
-
-#ifndef COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
-#define COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
-
-#include <vector>
-
-namespace sh
-{
-struct OutputVariable;
-class TIntermBlock;
-class TSymbolTable;
-
-// Replace all gl_FragColor with gl_FragData[0], and in the end of main() function,
-// assign gl_FragData[1] ... gl_FragData[maxDrawBuffers - 1] with gl_FragData[0].
-// If gl_FragColor is in outputVariables, it is replaced by gl_FragData.
-void EmulateGLFragColorBroadcast(TIntermBlock *root,
-                                 int maxDrawBuffers,
-                                 std::vector<OutputVariable> *outputVariables,
-                                 TSymbolTable *symbolTable,
-                                 int shaderVersion);
-}
-
-#endif  // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
deleted file mode 100644
--- a/gfx/angle/checkout/src/compiler/translator/EmulatePrecision.cpp
+++ /dev/null
@@ -1,779 +0,0 @@
-//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/EmulatePrecision.h"
-
-#include "compiler/translator/FunctionLookup.h"
-
-#include <memory>
-
-namespace sh
-{
-
-namespace
-{
-
-constexpr const ImmutableString kParamXName("x");
-constexpr const ImmutableString kParamYName("y");
-constexpr const ImmutableString kAngleFrmString("angle_frm");
-constexpr const ImmutableString kAngleFrlString("angle_frl");
-
-class RoundingHelperWriter : angle::NonCopyable
-{
-  public:
-    static RoundingHelperWriter *createHelperWriter(const ShShaderOutput outputLanguage);
-
-    void writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion);
-    void writeCompoundAssignmentHelper(TInfoSinkBase &sink,
-                                       const char *lType,
-                                       const char *rType,
-                                       const char *opStr,
-                                       const char *opNameStr);
-
-    virtual ~RoundingHelperWriter() {}
-
-  protected:
-    RoundingHelperWriter(const ShShaderOutput outputLanguage) : mOutputLanguage(outputLanguage) {}
-    RoundingHelperWriter() = delete;
-
-    const ShShaderOutput mOutputLanguage;
-
-  private:
-    virtual std::string getTypeString(const char *glslType)     = 0;
-    virtual void writeFloatRoundingHelpers(TInfoSinkBase &sink) = 0;
-    virtual void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) = 0;
-    virtual void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                           const unsigned int columns,
-                                           const unsigned int rows,
-                                           const char *functionName) = 0;
-};
-
-class RoundingHelperWriterGLSL : public RoundingHelperWriter
-{
-  public:
-    RoundingHelperWriterGLSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriter(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
-    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
-    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                   const unsigned int columns,
-                                   const unsigned int rows,
-                                   const char *functionName) override;
-};
-
-class RoundingHelperWriterESSL : public RoundingHelperWriterGLSL
-{
-  public:
-    RoundingHelperWriterESSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriterGLSL(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-};
-
-class RoundingHelperWriterHLSL : public RoundingHelperWriter
-{
-  public:
-    RoundingHelperWriterHLSL(const ShShaderOutput outputLanguage)
-        : RoundingHelperWriter(outputLanguage)
-    {
-    }
-
-  private:
-    std::string getTypeString(const char *glslType) override;
-    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
-    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
-    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                   const unsigned int columns,
-                                   const unsigned int rows,
-                                   const char *functionName) override;
-};
-
-RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
-{
-    ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
-    switch (outputLanguage)
-    {
-        case SH_HLSL_4_1_OUTPUT:
-            return new RoundingHelperWriterHLSL(outputLanguage);
-        case SH_ESSL_OUTPUT:
-            return new RoundingHelperWriterESSL(outputLanguage);
-        default:
-            return new RoundingHelperWriterGLSL(outputLanguage);
-    }
-}
-
-void RoundingHelperWriter::writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion)
-{
-    // Write the angle_frm functions that round floating point numbers to
-    // half precision, and angle_frl functions that round them to minimum lowp
-    // precision.
-
-    writeFloatRoundingHelpers(sink);
-    writeVectorRoundingHelpers(sink, 2);
-    writeVectorRoundingHelpers(sink, 3);
-    writeVectorRoundingHelpers(sink, 4);
-    if (shaderVersion > 100)
-    {
-        for (unsigned int columns = 2; columns <= 4; ++columns)
-        {
-            for (unsigned int rows = 2; rows <= 4; ++rows)
-            {
-                writeMatrixRoundingHelper(sink, columns, rows, "angle_frm");
-                writeMatrixRoundingHelper(sink, columns, rows, "angle_frl");
-            }
-        }
-    }
-    else
-    {
-        for (unsigned int size = 2; size <= 4; ++size)
-        {
-            writeMatrixRoundingHelper(sink, size, size, "angle_frm");
-            writeMatrixRoundingHelper(sink, size, size, "angle_frl");
-        }
-    }
-}
-
-void RoundingHelperWriter::writeCompoundAssignmentHelper(TInfoSinkBase &sink,
-                                                         const char *lType,
-                                                         const char *rType,
-                                                         const char *opStr,
-                                                         const char *opNameStr)
-{
-    std::string lTypeStr = getTypeString(lType);
-    std::string rTypeStr = getTypeString(rType);
-
-    // Note that y should be passed through angle_frm at the function call site,
-    // but x can't be passed through angle_frm there since it is an inout parameter.
-    // So only pass x and the result through angle_frm here.
-    // clang-format off
-    sink <<
-        lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
-        "    x = angle_frm(angle_frm(x) " << opStr << " y);\n"
-        "    return x;\n"
-        "}\n";
-    sink <<
-        lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
-        "    x = angle_frl(angle_frl(x) " << opStr << " y);\n"
-        "    return x;\n"
-        "}\n";
-    // clang-format on
-}
-
-std::string RoundingHelperWriterGLSL::getTypeString(const char *glslType)
-{
-    return glslType;
-}
-
-std::string RoundingHelperWriterESSL::getTypeString(const char *glslType)
-{
-    std::stringstream typeStrStr;
-    typeStrStr << "highp " << glslType;
-    return typeStrStr.str();
-}
-
-void RoundingHelperWriterGLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
-{
-    // Unoptimized version of angle_frm for single floats:
-    //
-    // int webgl_maxNormalExponent(in int exponentBits)
-    // {
-    //     int possibleExponents = int(exp2(float(exponentBits)));
-    //     int exponentBias = possibleExponents / 2 - 1;
-    //     int allExponentBitsOne = possibleExponents - 1;
-    //     return (allExponentBitsOne - 1) - exponentBias;
-    // }
-    //
-    // float angle_frm(in float x)
-    // {
-    //     int mantissaBits = 10;
-    //     int exponentBits = 5;
-    //     float possibleMantissas = exp2(float(mantissaBits));
-    //     float mantissaMax = 2.0 - 1.0 / possibleMantissas;
-    //     int maxNE = webgl_maxNormalExponent(exponentBits);
-    //     float max = exp2(float(maxNE)) * mantissaMax;
-    //     if (x > max)
-    //     {
-    //         return max;
-    //     }
-    //     if (x < -max)
-    //     {
-    //         return -max;
-    //     }
-    //     float exponent = floor(log2(abs(x)));
-    //     if (abs(x) == 0.0 || exponent < -float(maxNE))
-    //     {
-    //         return 0.0 * sign(x)
-    //     }
-    //     x = x * exp2(-(exponent - float(mantissaBits)));
-    //     x = sign(x) * floor(abs(x));
-    //     return x * exp2(exponent - float(mantissaBits));
-    // }
-
-    // All numbers with a magnitude less than 2^-15 are subnormal, and are
-    // flushed to zero.
-
-    // Note the constant numbers below:
-    // a) 65504 is the maximum possible mantissa (1.1111111111 in binary) times
-    //    2^15, the maximum normal exponent.
-    // b) 10.0 is the number of mantissa bits.
-    // c) -25.0 is the minimum normal half-float exponent -15.0 minus the number
-    //    of mantissa bits.
-    // d) + 1e-30 is to make sure the argument of log2() won't be zero. It can
-    //    only affect the result of log2 on x where abs(x) < 1e-22. Since these
-    //    numbers will be flushed to zero either way (2^-15 is the smallest
-    //    normal positive number), this does not introduce any error.
-
-    std::string floatType = getTypeString("float");
-
-    // clang-format off
-    sink <<
-        floatType << " angle_frm(in " << floatType << " x) {\n"
-        "    x = clamp(x, -65504.0, 65504.0);\n"
-        "    " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
-        "    bool isNonZero = (exponent >= -25.0);\n"
-        "    x = x * exp2(-exponent);\n"
-        "    x = sign(x) * floor(abs(x));\n"
-        "    return x * exp2(exponent) * float(isNonZero);\n"
-        "}\n";
-
-    sink <<
-        floatType << " angle_frl(in " << floatType << " x) {\n"
-        "    x = clamp(x, -2.0, 2.0);\n"
-        "    x = x * 256.0;\n"
-        "    x = sign(x) * floor(abs(x));\n"
-        "    return x * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
-                                                          const unsigned int size)
-{
-    std::stringstream vecTypeStrStr;
-    vecTypeStrStr << "vec" << size;
-    std::string vecType = getTypeString(vecTypeStrStr.str().c_str());
-
-    // clang-format off
-    sink <<
-        vecType << " angle_frm(in " << vecType << " v) {\n"
-        "    v = clamp(v, -65504.0, 65504.0);\n"
-        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
-        "    bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
-        "    v = v * exp2(-exponent);\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
-        "}\n";
-
-    sink <<
-        vecType << " angle_frl(in " << vecType << " v) {\n"
-        "    v = clamp(v, -2.0, 2.0);\n"
-        "    v = v * 256.0;\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterGLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                                         const unsigned int columns,
-                                                         const unsigned int rows,
-                                                         const char *functionName)
-{
-    std::stringstream matTypeStrStr;
-    matTypeStrStr << "mat" << columns;
-    if (rows != columns)
-    {
-        matTypeStrStr << "x" << rows;
-    }
-    std::string matType = getTypeString(matTypeStrStr.str().c_str());
-
-    sink << matType << " " << functionName << "(in " << matType << " m) {\n"
-         << "    " << matType << " rounded;\n";
-
-    for (unsigned int i = 0; i < columns; ++i)
-    {
-        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
-    }
-
-    sink << "    return rounded;\n"
-            "}\n";
-}
-
-static const char *GetHLSLTypeStr(const char *floatTypeStr)
-{
-    if (strcmp(floatTypeStr, "float") == 0)
-    {
-        return "float";
-    }
-    if (strcmp(floatTypeStr, "vec2") == 0)
-    {
-        return "float2";
-    }
-    if (strcmp(floatTypeStr, "vec3") == 0)
-    {
-        return "float3";
-    }
-    if (strcmp(floatTypeStr, "vec4") == 0)
-    {
-        return "float4";
-    }
-    if (strcmp(floatTypeStr, "mat2") == 0)
-    {
-        return "float2x2";
-    }
-    if (strcmp(floatTypeStr, "mat3") == 0)
-    {
-        return "float3x3";
-    }
-    if (strcmp(floatTypeStr, "mat4") == 0)
-    {
-        return "float4x4";
-    }
-    if (strcmp(floatTypeStr, "mat2x3") == 0)
-    {
-        return "float2x3";
-    }
-    if (strcmp(floatTypeStr, "mat2x4") == 0)
-    {
-        return "float2x4";
-    }
-    if (strcmp(floatTypeStr, "mat3x2") == 0)
-    {
-        return "float3x2";
-    }
-    if (strcmp(floatTypeStr, "mat3x4") == 0)
-    {
-        return "float3x4";
-    }
-    if (strcmp(floatTypeStr, "mat4x2") == 0)
-    {
-        return "float4x2";
-    }
-    if (strcmp(floatTypeStr, "mat4x3") == 0)
-    {
-        return "float4x3";
-    }
-    UNREACHABLE();
-    return nullptr;
-}
-
-std::string RoundingHelperWriterHLSL::getTypeString(const char *glslType)
-{
-    return GetHLSLTypeStr(glslType);
-}
-
-void RoundingHelperWriterHLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
-{
-    // In HLSL scalars are the same as 1-vectors.
-    writeVectorRoundingHelpers(sink, 1);
-}
-
-void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
-                                                          const unsigned int size)
-{
-    std::stringstream vecTypeStrStr;
-    vecTypeStrStr << "float" << size;
-    std::string vecType = vecTypeStrStr.str();
-
-    // clang-format off
-    sink <<
-        vecType << " angle_frm(" << vecType << " v) {\n"
-        "    v = clamp(v, -65504.0, 65504.0);\n"
-        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
-        "    bool" << size << " isNonZero = exponent < -25.0;\n"
-        "    v = v * exp2(-exponent);\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * exp2(exponent) * (float" << size << ")(isNonZero);\n"
-        "}\n";
-
-    sink <<
-        vecType << " angle_frl(" << vecType << " v) {\n"
-        "    v = clamp(v, -2.0, 2.0);\n"
-        "    v = v * 256.0;\n"
-        "    v = sign(v) * floor(abs(v));\n"
-        "    return v * 0.00390625;\n"
-        "}\n";
-    // clang-format on
-}
-
-void RoundingHelperWriterHLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
-                                                         const unsigned int columns,
-                                                         const unsigned int rows,
-                                                         const char *functionName)
-{
-    std::stringstream matTypeStrStr;
-    matTypeStrStr << "float" << columns << "x" << rows;
-    std::string matType = matTypeStrStr.str();
-
-    sink << matType << " " << functionName << "(" << matType << " m) {\n"
-         << "    " << matType << " rounded;\n";
-
-    for (unsigned int i = 0; i < columns; ++i)
-    {
-        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
-    }
-
-    sink << "    return rounded;\n"
-            "}\n";
-}
-
-bool canRoundFloat(const TType &type)
-{