Always create TFunctions for function call nodes
This simplifies code and ensures that nodes get consistent data.
In the future function call nodes could have a pointer to the
TFunction instead of converting the same information into a different
data structure.
BUG=angleproject:2267
TEST=angle_unittests, angle_end2end_tests
Change-Id: Ic0c24bb86b44b9bcc4a5da7f6b03701081a3af5c
Reviewed-on: https://chromium-review.googlesource.com/824606
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index 85844d6..c1bd1a8 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -427,49 +427,6 @@
(type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
}
-TIntermAggregate *createInternalFunctionCallNode(const TType &type,
- TString name,
- TIntermSequence *arguments)
-{
- TName nameObj(&name);
- nameObj.setInternal(true);
- TIntermAggregate *callNode =
- TIntermAggregate::Create(type, EOpCallInternalRawFunction, arguments);
- callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
- return callNode;
-}
-
-TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild)
-{
- TString roundFunctionName;
- if (roundedChild->getPrecision() == EbpMedium)
- roundFunctionName = "angle_frm";
- else
- roundFunctionName = "angle_frl";
- TIntermSequence *arguments = new TIntermSequence();
- arguments->push_back(roundedChild);
- TIntermAggregate *callNode =
- createInternalFunctionCallNode(roundedChild->getType(), roundFunctionName, arguments);
- callNode->getFunctionSymbolInfo()->setKnownToNotHaveSideEffects(true);
- return callNode;
-}
-
-TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
- TIntermTyped *right,
- const char *opNameStr)
-{
- std::stringstream strstr;
- if (left->getPrecision() == EbpMedium)
- strstr << "angle_compound_" << opNameStr << "_frm";
- else
- strstr << "angle_compound_" << opNameStr << "_frl";
- TString functionName = strstr.str().c_str();
- TIntermSequence *arguments = new TIntermSequence();
- arguments->push_back(left);
- arguments->push_back(right);
- return createInternalFunctionCallNode(left->getType(), functionName, arguments);
-}
-
bool ParentUsesResult(TIntermNode *parent, TIntermTyped *node)
{
if (!parent)
@@ -748,4 +705,50 @@
}
}
+TFunction *EmulatePrecision::getInternalFunction(TString *functionName,
+ const TType &returnType,
+ TIntermSequence *arguments,
+ bool knownToNotHaveSideEffects)
+{
+ TString mangledName = TFunction::GetMangledNameFromCall(*functionName, *arguments);
+ if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
+ {
+ mInternalFunctions[mangledName] =
+ new TFunction(mSymbolTable, functionName, new TType(returnType),
+ SymbolType::AngleInternal, knownToNotHaveSideEffects);
+ }
+ return mInternalFunctions[mangledName];
+}
+
+TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
+{
+ const char *roundFunctionName;
+ if (roundedChild->getPrecision() == EbpMedium)
+ roundFunctionName = "angle_frm";
+ else
+ roundFunctionName = "angle_frl";
+ TString *functionName = NewPoolTString(roundFunctionName);
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(roundedChild);
+ return TIntermAggregate::CreateRawFunctionCall(
+ *getInternalFunction(functionName, roundedChild->getType(), arguments, true), arguments);
+}
+
+TIntermAggregate *EmulatePrecision::createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
+ TIntermTyped *right,
+ const char *opNameStr)
+{
+ std::stringstream strstr;
+ if (left->getPrecision() == EbpMedium)
+ strstr << "angle_compound_" << opNameStr << "_frm";
+ else
+ strstr << "angle_compound_" << opNameStr << "_frl";
+ TString *functionName = NewPoolTString(strstr.str().c_str());
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(left);
+ arguments->push_back(right);
+ return TIntermAggregate::CreateRawFunctionCall(
+ *getInternalFunction(functionName, left->getType(), arguments, false), arguments);
+}
+
} // namespace sh