Hash :
c859c0ac
Author :
Date :
2020-11-24T17:21:38
Batch replace std::unordered_map with angle::HashMap in src/ There are a few places that will remain std::unordered_map due to build or run-time errors, which will need to be evaluated more closely to determine if they should remain std::unordered_map or if there is another Abseil data structure that would be more efficient while still working correctly. Bug: angleproject:4873 Change-Id: Ib04253e3ad6398e63f4cc2bfe12c0f9e57cb112b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2558873 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
//
// 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.
//
// ReplaceVariable.h: Replace all references to a specific variable in the AST with references to
// another variable.
#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
#define COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
#include "common/debug.h"
#include <stack>
#include <unordered_map>
namespace sh
{
class TCompiler;
class TFunction;
class TIntermAggregate;
class TIntermBlock;
class TIntermFunctionPrototype;
class TIntermNode;
class TIntermTyped;
class TSymbolTable;
class TVariable;
ANGLE_NO_DISCARD bool ReplaceVariable(TCompiler *compiler,
TIntermBlock *root,
const TVariable *toBeReplaced,
const TVariable *replacement);
ANGLE_NO_DISCARD bool ReplaceVariableWithTyped(TCompiler *compiler,
TIntermBlock *root,
const TVariable *toBeReplaced,
const TIntermTyped *replacement);
// A helper class to keep track of opaque variable re-typing during a pass. Unlike the above
// functions, this can be used to replace all opaque variables of a certain type with another in a
// pass that possibly does other related transformations. Only opaque variables are supported as
// replacing local variables is not supported.
//
// The class uses "old" to refer to the original type of the variable and "new" to refer to the type
// that will replace it.
//
// - replaceGlobalVariable(): Call to track a global variable that is replaced.
// - in TIntermTraverser::visitFunctionPrototype():
// * Call visitFunctionPrototype().
// * For every replaced parameter, call replaceFunctionParam().
// * call convertFunctionPrototype() to convert the prototype based on the above replacements
// and track the function with its replacement.
// * Call replaceFunction() to track the function that is replaced.
// - In PreVisit of TIntermTraverser::visitAggregate():
// * call preVisitAggregate()
// - In TIntermTraverser::visitSymbol():
// * Replace non-function-call-argument symbols that refer to a global or function param with the
// replacement (getVariableReplacement()).
// * For function call arguments, call replaceFunctionCallArg() to track the replacement.
// - In PostVisit of TIntermTraverser::visitAggregate():
// * Convert built-in functions per case. Call convertASTFunction() for non built-in functions
// for the replacement to be created.
// * Call postVisitAggregate() when done.
//
class RetypeOpaqueVariablesHelper
{
public:
RetypeOpaqueVariablesHelper() {}
~RetypeOpaqueVariablesHelper() {}
// Global variable handling:
void replaceGlobalVariable(const TVariable *oldVar, TVariable *newVar)
{
ASSERT(mReplacedGlobalVariables.count(oldVar) == 0);
mReplacedGlobalVariables[oldVar] = newVar;
}
TVariable *getVariableReplacement(const TVariable *oldVar) const
{
if (mReplacedGlobalVariables.count(oldVar) != 0)
{
return mReplacedGlobalVariables.at(oldVar);
}
else
{
// This function should only be called if the variable is expected to have been
// replaced either way (as a global variable or a function parameter).
ASSERT(mReplacedFunctionParams.count(oldVar) != 0);
return mReplacedFunctionParams.at(oldVar);
}
}
// Function parameters handling:
void visitFunctionPrototype() { mReplacedFunctionParams.clear(); }
void replaceFunctionParam(const TVariable *oldParam, TVariable *newParam)
{
ASSERT(mReplacedFunctionParams.count(oldParam) == 0);
mReplacedFunctionParams[oldParam] = newParam;
}
TVariable *getFunctionParamReplacement(const TVariable *oldParam) const
{
ASSERT(mReplacedFunctionParams.count(oldParam) != 0);
return mReplacedFunctionParams.at(oldParam);
}
// Function call arguments handling:
void preVisitAggregate() { mReplacedFunctionCallArgs.emplace(); }
bool isInAggregate() const { return !mReplacedFunctionCallArgs.empty(); }
void postVisitAggregate() { mReplacedFunctionCallArgs.pop(); }
void replaceFunctionCallArg(const TIntermNode *oldArg, TIntermTyped *newArg)
{
ASSERT(mReplacedFunctionCallArgs.top().count(oldArg) == 0);
mReplacedFunctionCallArgs.top()[oldArg] = newArg;
}
TIntermTyped *getFunctionCallArgReplacement(const TIntermNode *oldArg) const
{
ASSERT(mReplacedFunctionCallArgs.top().count(oldArg) != 0);
return mReplacedFunctionCallArgs.top().at(oldArg);
}
// Helper code conversion methods.
TIntermFunctionPrototype *convertFunctionPrototype(TSymbolTable *symbolTable,
const TFunction *oldFunction);
TIntermAggregate *convertASTFunction(TIntermAggregate *node);
private:
// A map from the old global variable to the new one.
angle::HashMap<const TVariable *, TVariable *> mReplacedGlobalVariables;
// A map from functions with old type parameters to one where that's replaced with the new type.
angle::HashMap<const TFunction *, TFunction *> mReplacedFunctions;
// A map from function old type parameters to their replacement new type parameter for the
// current function definition.
angle::HashMap<const TVariable *, TVariable *> mReplacedFunctionParams;
// A map from function call old type arguments to their replacement for the current function
// call.
std::stack<angle::HashMap<const TIntermNode *, TIntermTyped *>> mReplacedFunctionCallArgs;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_