Skip to content

Commit

Permalink
also search global variables assignment for live variables
Browse files Browse the repository at this point in the history
when traversing the AST to find live UBOs etc, also traverse
references to global module-level variables, incase they are
being filled in from UBOs etc.
  • Loading branch information
mbechard committed Jul 20, 2020
1 parent b481744 commit 5727fb3
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 12 deletions.
38 changes: 34 additions & 4 deletions glslang/MachineIndependent/LiveTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,33 @@ class TLiveTraverser : public TIntermTraverser {
for (unsigned int f = 0; f < globals.size(); ++f) {
TIntermAggregate* candidate = globals[f]->getAsAggregate();
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
functions.push_back(candidate);
destinations.push_back(candidate);
break;
}
}
}

typedef std::list<TIntermAggregate*> TFunctionStack;
TFunctionStack functions;
void pushGlobalReference(const TString& name)
{
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
for (unsigned int f = 0; f < globals.size(); ++f) {
TIntermAggregate* candidate = globals[f]->getAsAggregate();
if (candidate && candidate->getOp() == EOpSequence &&
candidate->getSequence().size() == 1 &&
candidate->getSequence()[0]->getAsBinaryNode()) {
TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode();
TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode();
if (symbol && symbol->getQualifier().storage == EvqGlobal &&
symbol->getName() == name) {
destinations.push_back(candidate);
break;
}
}
}
}

typedef std::list<TIntermAggregate*> TDestinationStack;
TDestinationStack destinations;

protected:
// To catch which function calls are not dead, and hence which functions must be visited.
Expand Down Expand Up @@ -117,16 +136,27 @@ class TLiveTraverser : public TIntermTraverser {
// and only visit each function once.
void addFunctionCall(TIntermAggregate* call)
{
// // just use the map to ensure we process each function at most once
// just use the map to ensure we process each function at most once
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
liveFunctions.insert(call->getName());
pushFunction(call->getName());
}
}

void addGlobalReference(const TString& name)
{
// just use the map to ensure we process each global at most once
if (liveGlobals.find(name) == liveGlobals.end()) {
liveGlobals.insert(name);
pushGlobalReference(name);
}
}

const TIntermediate& intermediate;
typedef std::unordered_set<TString> TLiveFunctions;
TLiveFunctions liveFunctions;
typedef std::unordered_set<TString> TLiveGlobals;
TLiveGlobals liveGlobals;
bool traverseAll;

private:
Expand Down
23 changes: 15 additions & 8 deletions glslang/MachineIndependent/iomapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ class TVarGatherTraverser : public TLiveTraverser {
target = &outputList;
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
target = &uniformList;
// If a global is being visited, then we should also traverse it incase it's evaluation
// ends up visiting inputs we want to tag as live
else if (base->getQualifier().storage == EvqGlobal)
addGlobalReference(base->getName());

if (target) {
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
ent.stage = intermediate.getStage();
Expand Down Expand Up @@ -1105,11 +1110,12 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
root->traverse(&iter_binding_all);
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
while (! iter_binding_live.functions.empty()) {
TIntermNode* function = iter_binding_live.functions.back();
iter_binding_live.functions.pop_back();
function->traverse(&iter_binding_live);
while (! iter_binding_live.destinations.empty()) {
TIntermNode* destination = iter_binding_live.destinations.back();
iter_binding_live.destinations.pop_back();
destination->traverse(&iter_binding_live);
}

// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
std::for_each(inVarMap.begin(), inVarMap.end(),
[&inVector](TVarLivePair p) { inVector.push_back(p); });
Expand Down Expand Up @@ -1200,11 +1206,12 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn
*uniformVarMap[stage]);
root->traverse(&iter_binding_all);
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
while (! iter_binding_live.functions.empty()) {
TIntermNode* function = iter_binding_live.functions.back();
iter_binding_live.functions.pop_back();
function->traverse(&iter_binding_live);
while (! iter_binding_live.destinations.empty()) {
TIntermNode* destination = iter_binding_live.destinations.back();
iter_binding_live.destinations.pop_back();
destination->traverse(&iter_binding_live);
}

TNotifyInOutAdaptor inOutNotify(stage, *resolver);
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
// Resolve current stage input symbol location with previous stage output here,
Expand Down

0 comments on commit 5727fb3

Please sign in to comment.