77#include " compiler/translator/BuiltInFunctionEmulator.h"
88#include " angle_gl.h"
99#include " compiler/translator/StaticType.h"
10- #include " compiler/translator/SymbolTable .h"
10+ #include " compiler/translator/Symbol .h"
1111#include " compiler/translator/tree_util/IntermTraverse.h"
1212
1313namespace sh
@@ -23,10 +23,9 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr
2323
2424 bool visitUnary (Visit visit, TIntermUnary *node) override
2525 {
26- if (visit == PreVisit )
26+ if (node-> getFunction () )
2727 {
28- bool needToEmulate =
29- mEmulator .setFunctionCalled (node->getOp (), node->getOperand ()->getType ());
28+ bool needToEmulate = mEmulator .setFunctionCalled (node->getFunction ());
3029 if (needToEmulate)
3130 node->setUseEmulatedFunction ();
3231 }
@@ -35,56 +34,15 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr
3534
3635 bool visitAggregate (Visit visit, TIntermAggregate *node) override
3736 {
38- if (visit == PreVisit)
37+ // Here we handle all the built-in functions mapped to ops, not just the ones that are
38+ // currently identified as problematic.
39+ if (node->isConstructor () || node->isFunctionCall ())
3940 {
40- // Here we handle all the built-in functions mapped to ops, not just the ones that are
41- // currently identified as problematic.
42- if (node->isConstructor () || node->isFunctionCall ())
43- {
44- return true ;
45- }
46- const TIntermSequence &sequence = *(node->getSequence ());
47- bool needToEmulate = false ;
48- // Right now we only handle built-in functions with two to four parameters.
49- if (sequence.size () == 2 )
50- {
51- TIntermTyped *param1 = sequence[0 ]->getAsTyped ();
52- TIntermTyped *param2 = sequence[1 ]->getAsTyped ();
53- if (!param1 || !param2)
54- return true ;
55- needToEmulate = mEmulator .setFunctionCalled (node->getOp (), param1->getType (),
56- param2->getType ());
57- }
58- else if (sequence.size () == 3 )
59- {
60- TIntermTyped *param1 = sequence[0 ]->getAsTyped ();
61- TIntermTyped *param2 = sequence[1 ]->getAsTyped ();
62- TIntermTyped *param3 = sequence[2 ]->getAsTyped ();
63- if (!param1 || !param2 || !param3)
64- return true ;
65- needToEmulate = mEmulator .setFunctionCalled (node->getOp (), param1->getType (),
66- param2->getType (), param3->getType ());
67- }
68- else if (sequence.size () == 4 )
69- {
70- TIntermTyped *param1 = sequence[0 ]->getAsTyped ();
71- TIntermTyped *param2 = sequence[1 ]->getAsTyped ();
72- TIntermTyped *param3 = sequence[2 ]->getAsTyped ();
73- TIntermTyped *param4 = sequence[3 ]->getAsTyped ();
74- if (!param1 || !param2 || !param3 || !param4)
75- return true ;
76- needToEmulate =
77- mEmulator .setFunctionCalled (node->getOp (), param1->getType (), param2->getType (),
78- param3->getType (), param4->getType ());
79- }
80- else
81- {
82- return true ;
83- }
84-
85- if (needToEmulate)
86- node->setUseEmulatedFunction ();
41+ return true ;
8742 }
43+ bool needToEmulate = mEmulator .setFunctionCalled (node->getFunction ());
44+ if (needToEmulate)
45+ node->setUseEmulatedFunction ();
8846 return true ;
8947 }
9048
@@ -96,74 +54,19 @@ BuiltInFunctionEmulator::BuiltInFunctionEmulator()
9654{
9755}
9856
99- FunctionId BuiltInFunctionEmulator::addEmulatedFunction (TOperator op,
100- const TType *param,
101- const char *emulatedFunctionDefinition)
102- {
103- FunctionId id (op, param);
104- mEmulatedFunctions [id] = std::string (emulatedFunctionDefinition);
105- return id;
106- }
107-
108- FunctionId BuiltInFunctionEmulator::addEmulatedFunction (TOperator op,
109- const TType *param1,
110- const TType *param2,
111- const char *emulatedFunctionDefinition)
112- {
113- FunctionId id (op, param1, param2);
114- mEmulatedFunctions [id] = std::string (emulatedFunctionDefinition);
115- return id;
116- }
117-
118- FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency (
119- const FunctionId &dependency,
120- TOperator op,
121- const TType *param1,
122- const TType *param2,
123- const char *emulatedFunctionDefinition)
124- {
125- FunctionId id (op, param1, param2);
126- mEmulatedFunctions [id] = std::string (emulatedFunctionDefinition);
127- mFunctionDependencies [id] = dependency;
128- return id;
129- }
130-
131- FunctionId BuiltInFunctionEmulator::addEmulatedFunction (TOperator op,
132- const TType *param1,
133- const TType *param2,
134- const TType *param3,
135- const char *emulatedFunctionDefinition)
57+ void BuiltInFunctionEmulator::addEmulatedFunction (const TSymbolUniqueId &uniqueId,
58+ const char *emulatedFunctionDefinition)
13659{
137- FunctionId id (op, param1, param2, param3);
138- mEmulatedFunctions [id] = std::string (emulatedFunctionDefinition);
139- return id;
60+ mEmulatedFunctions [uniqueId.get ()] = std::string (emulatedFunctionDefinition);
14061}
14162
142- FunctionId BuiltInFunctionEmulator::addEmulatedFunction (TOperator op,
143- const TType *param1,
144- const TType *param2,
145- const TType *param3,
146- const TType *param4,
147- const char *emulatedFunctionDefinition)
148- {
149- FunctionId id (op, param1, param2, param3, param4);
150- mEmulatedFunctions [id] = std::string (emulatedFunctionDefinition);
151- return id;
152- }
153-
154- FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency (
155- const FunctionId &dependency,
156- TOperator op,
157- const TType *param1,
158- const TType *param2,
159- const TType *param3,
160- const TType *param4,
63+ void BuiltInFunctionEmulator::addEmulatedFunctionWithDependency (
64+ const TSymbolUniqueId &dependency,
65+ const TSymbolUniqueId &uniqueId,
16166 const char *emulatedFunctionDefinition)
16267{
163- FunctionId id (op, param1, param2, param3, param4);
164- mEmulatedFunctions [id] = std::string (emulatedFunctionDefinition);
165- mFunctionDependencies [id] = dependency;
166- return id;
68+ mEmulatedFunctions [uniqueId.get ()] = std::string (emulatedFunctionDefinition);
69+ mFunctionDependencies [uniqueId.get ()] = dependency.get ();
16770}
16871
16972bool BuiltInFunctionEmulator::isOutputEmpty () const
@@ -182,47 +85,18 @@ void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const
18285 }
18386}
18487
185- bool BuiltInFunctionEmulator::setFunctionCalled (TOperator op, const TType ¶m)
186- {
187- return setFunctionCalled (FunctionId (op, ¶m));
188- }
189-
190- bool BuiltInFunctionEmulator::setFunctionCalled (TOperator op,
191- const TType ¶m1,
192- const TType ¶m2)
193- {
194- return setFunctionCalled (FunctionId (op, ¶m1, ¶m2));
195- }
196-
197- bool BuiltInFunctionEmulator::setFunctionCalled (TOperator op,
198- const TType ¶m1,
199- const TType ¶m2,
200- const TType ¶m3)
201- {
202- return setFunctionCalled (FunctionId (op, ¶m1, ¶m2, ¶m3));
203- }
204-
205- bool BuiltInFunctionEmulator::setFunctionCalled (TOperator op,
206- const TType ¶m1,
207- const TType ¶m2,
208- const TType ¶m3,
209- const TType ¶m4)
210- {
211- return setFunctionCalled (FunctionId (op, ¶m1, ¶m2, ¶m3, ¶m4));
212- }
213-
214- const char *BuiltInFunctionEmulator::findEmulatedFunction (const FunctionId &functionId) const
88+ const char *BuiltInFunctionEmulator::findEmulatedFunction (int uniqueId) const
21589{
21690 for (const auto &queryFunction : mQueryFunctions )
21791 {
218- const char *result = queryFunction (functionId );
92+ const char *result = queryFunction (uniqueId );
21993 if (result)
22094 {
22195 return result;
22296 }
22397 }
22498
225- const auto &result = mEmulatedFunctions .find (functionId );
99+ const auto &result = mEmulatedFunctions .find (uniqueId );
226100 if (result != mEmulatedFunctions .end ())
227101 {
228102 return result->second .c_str ();
@@ -231,27 +105,31 @@ const char *BuiltInFunctionEmulator::findEmulatedFunction(const FunctionId &func
231105 return nullptr ;
232106}
233107
234- bool BuiltInFunctionEmulator::setFunctionCalled (const FunctionId &functionId)
108+ bool BuiltInFunctionEmulator::setFunctionCalled (const TFunction *function)
109+ {
110+ ASSERT (function != nullptr );
111+ return setFunctionCalled (function->uniqueId ().get ());
112+ }
113+
114+ bool BuiltInFunctionEmulator::setFunctionCalled (int uniqueId)
235115{
236- if (!findEmulatedFunction (functionId ))
116+ if (!findEmulatedFunction (uniqueId ))
237117 {
238118 return false ;
239119 }
240120
241121 for (size_t i = 0 ; i < mFunctions .size (); ++i)
242122 {
243- if (mFunctions [i] == functionId )
123+ if (mFunctions [i] == uniqueId )
244124 return true ;
245125 }
246126 // If the function depends on another, mark the dependency as called.
247- auto dependency = mFunctionDependencies .find (functionId );
127+ auto dependency = mFunctionDependencies .find (uniqueId );
248128 if (dependency != mFunctionDependencies .end ())
249129 {
250130 setFunctionCalled ((*dependency).second );
251131 }
252- // Copy the functionId if it needs to be stored, to make sure that the TType pointers inside
253- // remain valid and constant.
254- mFunctions .push_back (functionId.getCopy ());
132+ mFunctions .push_back (uniqueId);
255133 return true ;
256134}
257135
@@ -284,76 +162,4 @@ void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, cons
284162 out << name << " _emu" ;
285163}
286164
287- FunctionId::FunctionId ()
288- : mOp (EOpNull),
289- mParam1 (StaticType::GetBasic<EbtVoid>()),
290- mParam2(StaticType::GetBasic<EbtVoid>()),
291- mParam3(StaticType::GetBasic<EbtVoid>()),
292- mParam4(StaticType::GetBasic<EbtVoid>())
293- {
294- }
295-
296- FunctionId::FunctionId (TOperator op, const TType *param)
297- : mOp(op),
298- mParam1(param),
299- mParam2(StaticType::GetBasic<EbtVoid>()),
300- mParam3(StaticType::GetBasic<EbtVoid>()),
301- mParam4(StaticType::GetBasic<EbtVoid>())
302- {
303- }
304-
305- FunctionId::FunctionId (TOperator op, const TType *param1, const TType *param2)
306- : mOp(op),
307- mParam1(param1),
308- mParam2(param2),
309- mParam3(StaticType::GetBasic<EbtVoid>()),
310- mParam4(StaticType::GetBasic<EbtVoid>())
311- {
312- }
313-
314- FunctionId::FunctionId (TOperator op, const TType *param1, const TType *param2, const TType *param3)
315- : mOp(op),
316- mParam1(param1),
317- mParam2(param2),
318- mParam3(param3),
319- mParam4(StaticType::GetBasic<EbtVoid>())
320- {
321- }
322-
323- FunctionId::FunctionId (TOperator op,
324- const TType *param1,
325- const TType *param2,
326- const TType *param3,
327- const TType *param4)
328- : mOp(op), mParam1(param1), mParam2(param2), mParam3(param3), mParam4(param4)
329- {
330- }
331-
332- bool FunctionId::operator ==(const FunctionId &other) const
333- {
334- return (mOp == other.mOp && *mParam1 == *other.mParam1 && *mParam2 == *other.mParam2 &&
335- *mParam3 == *other.mParam3 && *mParam4 == *other.mParam4 );
336- }
337-
338- bool FunctionId::operator <(const FunctionId &other) const
339- {
340- if (mOp != other.mOp )
341- return mOp < other.mOp ;
342- if (*mParam1 != *other.mParam1 )
343- return *mParam1 < *other.mParam1 ;
344- if (*mParam2 != *other.mParam2 )
345- return *mParam2 < *other.mParam2 ;
346- if (*mParam3 != *other.mParam3 )
347- return *mParam3 < *other.mParam3 ;
348- if (*mParam4 != *other.mParam4 )
349- return *mParam4 < *other.mParam4 ;
350- return false ; // all fields are equal
351- }
352-
353- FunctionId FunctionId::getCopy () const
354- {
355- return FunctionId (mOp , new TType (*mParam1 ), new TType (*mParam2 ), new TType (*mParam3 ),
356- new TType (*mParam4 ));
357- }
358-
359165} // namespace sh
0 commit comments