Fix issue for new unique id system. Add level bits to help verifying symbols and split symbol tables.

For intermediates rebuilding, now need manually amending level bits for redeclaring built-ins.
This commit is contained in:
Chow 2020-11-12 15:54:16 +08:00
parent 74e8f05b9f
commit 93b400f267
17 changed files with 110 additions and 71 deletions

View file

@ -48,6 +48,7 @@
#include "localintermediate.h"
#include "../Include/InfoSink.h"
#include "SymbolTable.h"
namespace glslang {
@ -304,9 +305,9 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
// Map by global name to unique ID to rationalize the same object having
// differing IDs in different trees.
TIdMaps idMaps;
int maxId;
seedIdMap(idMaps, maxId);
remapIds(idMaps, maxId + 1, unit);
long long idShift;
seedIdMap(idMaps, idShift);
remapIds(idMaps, idShift + 1, unit);
mergeBodies(infoSink, globals, unitGlobals);
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
@ -327,14 +328,14 @@ static const TString& getNameForIdMap(TIntermSymbol* symbol)
// Traverser that seeds an ID map with all built-ins, and tracks the
// maximum ID used.
// maximum ID used, currently using (maximum ID + 1) as new symbol id shift seed.
// Level id will keep same after shifting.
// (It would be nice to put this in a function, but that causes warnings
// on having no bodies for the copy-constructor/operator=.)
class TBuiltInIdTraverser : public TIntermTraverser {
public:
TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), maxId(0) { }
TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), idShift(0) { }
// If it's a built in, add it to the map.
// Track the max ID.
virtual void visitSymbol(TIntermSymbol* symbol)
{
const TQualifier& qualifier = symbol->getType().getQualifier();
@ -342,14 +343,16 @@ public:
TShaderInterface si = symbol->getType().getShaderInterface();
idMaps[si][getNameForIdMap(symbol)] = symbol->getId();
}
maxId = std::max(maxId, symbol->getId());
idShift = (symbol->getId() & ~TSymbolTable::uniqueIdMask) |
std::max(idShift & TSymbolTable::uniqueIdMask,
symbol->getId() & TSymbolTable::uniqueIdMask);
}
int getMaxId() const { return maxId; }
long long getIdShift() const { return idShift; }
protected:
TBuiltInIdTraverser(TBuiltInIdTraverser&);
TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
TIdMaps& idMaps;
int maxId;
long long idShift;
};
// Traverser that seeds an ID map with non-builtins.
@ -375,12 +378,12 @@ protected:
};
// Initialize the the ID map with what we know of 'this' AST.
void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId)
void TIntermediate::seedIdMap(TIdMaps& idMaps, long long& idShift)
{
// all built-ins everywhere need to align on IDs and contribute to the max ID
TBuiltInIdTraverser builtInIdTraverser(idMaps);
treeRoot->traverse(&builtInIdTraverser);
maxId = builtInIdTraverser.getMaxId();
idShift = builtInIdTraverser.getIdShift() & TSymbolTable::uniqueIdMask;
// user variables in the linker object list need to align on ids
TUserIdTraverser userIdTraverser(idMaps);
@ -392,7 +395,7 @@ void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId)
// on having no bodies for the copy-constructor/operator=.)
class TRemapIdTraverser : public TIntermTraverser {
public:
TRemapIdTraverser(const TIdMaps& idMaps, int idShift) : idMaps(idMaps), idShift(idShift) { }
TRemapIdTraverser(const TIdMaps& idMaps, long long idShift) : idMaps(idMaps), idShift(idShift) { }
// Do the mapping:
// - if the same symbol, adopt the 'this' ID
// - otherwise, ensure a unique ID by shifting to a new space
@ -404,7 +407,9 @@ public:
TShaderInterface si = symbol->getType().getShaderInterface();
auto it = idMaps[si].find(getNameForIdMap(symbol));
if (it != idMaps[si].end()) {
symbol->changeId(it->second);
uint64_t id = (symbol->getId() & ~TSymbolTable::uniqueIdMask) |
(it->second & TSymbolTable::uniqueIdMask);
symbol->changeId(id);
remapped = true;
}
}
@ -415,10 +420,10 @@ protected:
TRemapIdTraverser(TRemapIdTraverser&);
TRemapIdTraverser& operator=(TRemapIdTraverser&);
const TIdMaps& idMaps;
int idShift;
long long idShift;
};
void TIntermediate::remapIds(const TIdMaps& idMaps, int idShift, TIntermediate& unit)
void TIntermediate::remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate& unit)
{
// Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
TRemapIdTraverser idTraverser(idMaps, idShift);