Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 5fec7ab

Browse files
Olli EtuahoCommit Bot
authored andcommitted
Identify functions by unique id in BuiltInFunctionEmulator
Now that unique ids of all builtins are compile-time constants, we can use them to look up functions in BuiltInFunctionEmulator. This is simpler than using a custom struct with the name and parameters for identifying functions. This requires that we store a reference to a TFunction in those TIntermUnary nodes that were created based on a function. This decreases shader_translator binary size by about 6 KB on Windows. BUG=angleproject:2267 BUG=chromium:823856 TEST=angle_unittests Change-Id: Idd5a00c772c6f26dd36fdbbfbe161d22ab27c2fe Reviewed-on: https://chromium-review.googlesource.com/995372 Reviewed-by: Jamie Madill <[email protected]> Commit-Queue: Olli Etuaho <[email protected]>
1 parent f361437 commit 5fec7ab

29 files changed

+3314
-2580
lines changed

scripts/run_code_generation.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@
156156
],
157157
'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py',
158158
},
159+
'Emulated HLSL functions': {
160+
'inputs': [
161+
'src/compiler/translator/emulated_builtin_function_data_hlsl.json'
162+
],
163+
'outputs': [
164+
'src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp'
165+
],
166+
'script': 'src/compiler/translator/gen_emulated_builtin_function_tables.py'
167+
},
159168
'ESSL static builtins': {
160169
'inputs': [
161170
'src/compiler/translator/builtin_function_declarations.txt',

src/compiler.gypi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
'compiler/translator/Operator.h',
6969
'compiler/translator/OutputTree.cpp',
7070
'compiler/translator/OutputTree.h',
71-
'compiler/translator/ParamType.h',
7271
'compiler/translator/ParseContext.cpp',
7372
'compiler/translator/ParseContext.h',
7473
'compiler/translator/ParseContext_autogen.h',

src/compiler/translator/BuiltInFunctionEmulator.cpp

Lines changed: 32 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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

1313
namespace 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

16972
bool BuiltInFunctionEmulator::isOutputEmpty() const
@@ -182,47 +85,18 @@ void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const
18285
}
18386
}
18487

185-
bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, const TType &param)
186-
{
187-
return setFunctionCalled(FunctionId(op, &param));
188-
}
189-
190-
bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
191-
const TType &param1,
192-
const TType &param2)
193-
{
194-
return setFunctionCalled(FunctionId(op, &param1, &param2));
195-
}
196-
197-
bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
198-
const TType &param1,
199-
const TType &param2,
200-
const TType &param3)
201-
{
202-
return setFunctionCalled(FunctionId(op, &param1, &param2, &param3));
203-
}
204-
205-
bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op,
206-
const TType &param1,
207-
const TType &param2,
208-
const TType &param3,
209-
const TType &param4)
210-
{
211-
return setFunctionCalled(FunctionId(op, &param1, &param2, &param3, &param4));
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

Comments
 (0)