Skip to content

Commit 1c42d4e

Browse files
authored
Merge pull request KhronosGroup#2345 from mbechard/master
also search global sequences for live variables
2 parents c63502c + 5727fb3 commit 1c42d4e

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

glslang/MachineIndependent/LiveTraverser.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,33 @@ class TLiveTraverser : public TIntermTraverser {
7474
for (unsigned int f = 0; f < globals.size(); ++f) {
7575
TIntermAggregate* candidate = globals[f]->getAsAggregate();
7676
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
77-
functions.push_back(candidate);
77+
destinations.push_back(candidate);
7878
break;
7979
}
8080
}
8181
}
8282

83-
typedef std::list<TIntermAggregate*> TFunctionStack;
84-
TFunctionStack functions;
83+
void pushGlobalReference(const TString& name)
84+
{
85+
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
86+
for (unsigned int f = 0; f < globals.size(); ++f) {
87+
TIntermAggregate* candidate = globals[f]->getAsAggregate();
88+
if (candidate && candidate->getOp() == EOpSequence &&
89+
candidate->getSequence().size() == 1 &&
90+
candidate->getSequence()[0]->getAsBinaryNode()) {
91+
TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode();
92+
TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode();
93+
if (symbol && symbol->getQualifier().storage == EvqGlobal &&
94+
symbol->getName() == name) {
95+
destinations.push_back(candidate);
96+
break;
97+
}
98+
}
99+
}
100+
}
101+
102+
typedef std::list<TIntermAggregate*> TDestinationStack;
103+
TDestinationStack destinations;
85104

86105
protected:
87106
// To catch which function calls are not dead, and hence which functions must be visited.
@@ -117,16 +136,27 @@ class TLiveTraverser : public TIntermTraverser {
117136
// and only visit each function once.
118137
void addFunctionCall(TIntermAggregate* call)
119138
{
120-
// // just use the map to ensure we process each function at most once
139+
// just use the map to ensure we process each function at most once
121140
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
122141
liveFunctions.insert(call->getName());
123142
pushFunction(call->getName());
124143
}
125144
}
126145

146+
void addGlobalReference(const TString& name)
147+
{
148+
// just use the map to ensure we process each global at most once
149+
if (liveGlobals.find(name) == liveGlobals.end()) {
150+
liveGlobals.insert(name);
151+
pushGlobalReference(name);
152+
}
153+
}
154+
127155
const TIntermediate& intermediate;
128156
typedef std::unordered_set<TString> TLiveFunctions;
129157
TLiveFunctions liveFunctions;
158+
typedef std::unordered_set<TString> TLiveGlobals;
159+
TLiveGlobals liveGlobals;
130160
bool traverseAll;
131161

132162
private:

glslang/MachineIndependent/iomapper.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ class TVarGatherTraverser : public TLiveTraverser {
7979
target = &outputList;
8080
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
8181
target = &uniformList;
82+
// If a global is being visited, then we should also traverse it incase it's evaluation
83+
// ends up visiting inputs we want to tag as live
84+
else if (base->getQualifier().storage == EvqGlobal)
85+
addGlobalReference(base->getName());
86+
8287
if (target) {
8388
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
8489
ent.stage = intermediate.getStage();
@@ -1105,11 +1110,12 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
11051110
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
11061111
root->traverse(&iter_binding_all);
11071112
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
1108-
while (! iter_binding_live.functions.empty()) {
1109-
TIntermNode* function = iter_binding_live.functions.back();
1110-
iter_binding_live.functions.pop_back();
1111-
function->traverse(&iter_binding_live);
1113+
while (! iter_binding_live.destinations.empty()) {
1114+
TIntermNode* destination = iter_binding_live.destinations.back();
1115+
iter_binding_live.destinations.pop_back();
1116+
destination->traverse(&iter_binding_live);
11121117
}
1118+
11131119
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
11141120
std::for_each(inVarMap.begin(), inVarMap.end(),
11151121
[&inVector](TVarLivePair p) { inVector.push_back(p); });
@@ -1200,11 +1206,12 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn
12001206
*uniformVarMap[stage]);
12011207
root->traverse(&iter_binding_all);
12021208
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
1203-
while (! iter_binding_live.functions.empty()) {
1204-
TIntermNode* function = iter_binding_live.functions.back();
1205-
iter_binding_live.functions.pop_back();
1206-
function->traverse(&iter_binding_live);
1209+
while (! iter_binding_live.destinations.empty()) {
1210+
TIntermNode* destination = iter_binding_live.destinations.back();
1211+
iter_binding_live.destinations.pop_back();
1212+
destination->traverse(&iter_binding_live);
12071213
}
1214+
12081215
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
12091216
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
12101217
// Resolve current stage input symbol location with previous stage output here,

0 commit comments

Comments
 (0)