mirror of
https://github.com/RPCS3/glslang.git
synced 2024-11-23 19:29:44 +00:00
Merge pull request #2345 from mbechard/master
also search global sequences for live variables
This commit is contained in:
commit
1c42d4ee7b
@ -74,14 +74,33 @@ public:
|
||||
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.
|
||||
@ -117,16 +136,27 @@ protected:
|
||||
// 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:
|
||||
|
@ -79,6 +79,11 @@ public:
|
||||
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();
|
||||
@ -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); });
|
||||
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user