Resolve comments
1. Sink adding noContraction decoration to createBinaryOperation() and createUnaryOperation(). 2. Fix comments. 3. Remove the #define of my delimiter, use global constant char.
This commit is contained in:
parent
015150e4b3
commit
25262b3fd9
2 changed files with 162 additions and 162 deletions
|
|
@ -33,8 +33,6 @@
|
|||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
//POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Author: John Kessenich, LunarG
|
||||
//
|
||||
// Visit the nodes in the glslang intermediate tree representation to
|
||||
// translate them to SPIR-V.
|
||||
|
|
@ -135,10 +133,10 @@ protected:
|
|||
spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node);
|
||||
spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
|
||||
|
||||
spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
|
||||
spv::Id createBinaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right);
|
||||
spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
|
||||
spv::Id createUnaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
|
||||
spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
|
||||
spv::Id createBinaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right);
|
||||
spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
|
||||
spv::Id createUnaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
|
||||
spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand);
|
||||
spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
|
||||
spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
|
||||
|
|
@ -621,8 +619,7 @@ bool HasNonLayoutQualifiers(const glslang::TQualifier& qualifier)
|
|||
// - struct members can inherit from a struct declaration
|
||||
// - effect decorations on the struct members (note smooth does not, and expecting something like volatile to effect the whole object)
|
||||
// - are not part of the offset/st430/etc or row/column-major layout
|
||||
return qualifier.invariant || qualifier.nopersp || qualifier.flat || qualifier.centroid || qualifier.patch || qualifier.sample || qualifier.hasLocation() ||
|
||||
qualifier.noContraction;
|
||||
return qualifier.invariant || qualifier.nopersp || qualifier.flat || qualifier.centroid || qualifier.patch || qualifier.sample || qualifier.hasLocation();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -884,12 +881,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||
|
||||
// do the operation
|
||||
rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
|
||||
TranslateNoContractionDecoration(node->getType().getQualifier()),
|
||||
convertGlslangToSpvType(node->getType()), leftRValue, rValue,
|
||||
node->getType().getBasicType());
|
||||
|
||||
// Decorate this instruction, if this node has 'noContraction' qualifier.
|
||||
addDecoration(rValue, TranslateNoContractionDecoration(node->getType().getQualifier()));
|
||||
|
||||
// these all need their counterparts in createBinaryOperation()
|
||||
assert(rValue != spv::NoResult);
|
||||
}
|
||||
|
|
@ -1005,6 +1000,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||
|
||||
// get result
|
||||
spv::Id result = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
|
||||
TranslateNoContractionDecoration(node->getType().getQualifier()),
|
||||
convertGlslangToSpvType(node->getType()), left, right,
|
||||
node->getLeft()->getType().getBasicType());
|
||||
|
||||
|
|
@ -1013,8 +1009,6 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||
logger->missingFunctionality("unknown glslang binary operation");
|
||||
return true; // pick up a child as the place-holder result
|
||||
} else {
|
||||
// Decorate this instruction, if this node has 'noContraction' qualifier.
|
||||
addDecoration(result, TranslateNoContractionDecoration(node->getType().getQualifier()));
|
||||
builder.setAccessChainRValue(result);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1073,6 +1067,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
|||
operand = accessChainLoad(node->getOperand()->getType());
|
||||
|
||||
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
|
||||
spv::Decoration noContraction = TranslateNoContractionDecoration(node->getType().getQualifier());
|
||||
|
||||
// it could be a conversion
|
||||
if (! result)
|
||||
|
|
@ -1080,11 +1075,9 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
|||
|
||||
// if not, then possibly an operation
|
||||
if (! result)
|
||||
result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, node->getOperand()->getBasicType());
|
||||
result = createUnaryOperation(node->getOp(), precision, noContraction, convertGlslangToSpvType(node->getType()), operand, node->getOperand()->getBasicType());
|
||||
|
||||
if (result) {
|
||||
// Decorate this instruction, if this node has 'noContraction' qualifier.
|
||||
addDecoration(result, TranslateNoContractionDecoration(node->getType().getQualifier()));
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainRValue(result);
|
||||
|
||||
|
|
@ -1114,11 +1107,10 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
|||
op = glslang::EOpSub;
|
||||
|
||||
spv::Id result = createBinaryOperation(op, TranslatePrecisionDecoration(node->getType()),
|
||||
TranslateNoContractionDecoration(node->getType().getQualifier()),
|
||||
convertGlslangToSpvType(node->getType()), operand, one,
|
||||
node->getType().getBasicType());
|
||||
assert(result != spv::NoResult);
|
||||
// Decorate this instruction, if this node has 'noContraction' qualifier.
|
||||
addDecoration(result, TranslateNoContractionDecoration(node->getType().getQualifier()));
|
||||
|
||||
// The result of operation is always stored, but conditionally the
|
||||
// consumed result. The consumed result is always an r-value.
|
||||
|
|
@ -1414,7 +1406,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
right->traverse(this);
|
||||
spv::Id rightId = accessChainLoad(right->getType());
|
||||
|
||||
result = createBinaryOperation(binOp, precision,
|
||||
result = createBinaryOperation(binOp, precision, TranslateNoContractionDecoration(node->getType().getQualifier()),
|
||||
convertGlslangToSpvType(node->getType()), leftId, rightId,
|
||||
left->getType().getBasicType(), reduceComparison);
|
||||
|
||||
|
|
@ -1488,7 +1480,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
result = createNoArgOperation(node->getOp());
|
||||
break;
|
||||
case 1:
|
||||
result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), glslangOperands[0]->getAsTyped()->getBasicType());
|
||||
result = createUnaryOperation(
|
||||
node->getOp(), precision,
|
||||
TranslateNoContractionDecoration(node->getType().getQualifier()),
|
||||
convertGlslangToSpvType(node->getType()), operands.front(),
|
||||
glslangOperands[0]->getAsTyped()->getBasicType());
|
||||
break;
|
||||
default:
|
||||
result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType());
|
||||
|
|
@ -2680,6 +2676,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
|||
|
||||
// Translate AST operation to SPV operation, already having SPV-based operands/types.
|
||||
spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv::Decoration precision,
|
||||
spv::Decoration noContraction,
|
||||
spv::Id typeId, spv::Id left, spv::Id right,
|
||||
glslang::TBasicType typeProxy, bool reduceComparison)
|
||||
{
|
||||
|
|
@ -2816,13 +2813,15 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
|
|||
if (binOp != spv::OpNop) {
|
||||
assert(comparison == false);
|
||||
if (builder.isMatrix(left) || builder.isMatrix(right))
|
||||
return createBinaryMatrixOperation(binOp, precision, typeId, left, right);
|
||||
return createBinaryMatrixOperation(binOp, precision, noContraction, typeId, left, right);
|
||||
|
||||
// No matrix involved; make both operands be the same number of components, if needed
|
||||
if (needMatchingVectors)
|
||||
builder.promoteScalar(precision, left, right);
|
||||
|
||||
return builder.setPrecision(builder.createBinOp(binOp, typeId, left, right), precision);
|
||||
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
||||
addDecoration(result, noContraction);
|
||||
return builder.setPrecision(result, precision);
|
||||
}
|
||||
|
||||
if (! comparison)
|
||||
|
|
@ -2891,8 +2890,11 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
|
|||
break;
|
||||
}
|
||||
|
||||
if (binOp != spv::OpNop)
|
||||
return builder.setPrecision(builder.createBinOp(binOp, typeId, left, right), precision);
|
||||
if (binOp != spv::OpNop) {
|
||||
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
||||
addDecoration(result, noContraction);
|
||||
return builder.setPrecision(result, precision);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2911,7 +2913,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
|
|||
// matrix op scalar op in {+, -, /}
|
||||
// scalar op matrix op in {+, -, /}
|
||||
//
|
||||
spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right)
|
||||
spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id left, spv::Id right)
|
||||
{
|
||||
bool firstClass = true;
|
||||
|
||||
|
|
@ -2947,8 +2949,11 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
|
|||
break;
|
||||
}
|
||||
|
||||
if (firstClass)
|
||||
return builder.setPrecision(builder.createBinOp(op, typeId, left, right), precision);
|
||||
if (firstClass) {
|
||||
spv::Id result = builder.createBinOp(op, typeId, left, right);
|
||||
addDecoration(result, noContraction);
|
||||
return builder.setPrecision(result, precision);
|
||||
}
|
||||
|
||||
// Handle component-wise +, -, *, and / for all combinations of type.
|
||||
// The result type of all of them is the same type as the (a) matrix operand.
|
||||
|
|
@ -2983,8 +2988,9 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
|
|||
indexes.push_back(c);
|
||||
spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec;
|
||||
spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
|
||||
results.push_back(builder.createBinOp(op, vecType, leftVec, rightVec));
|
||||
builder.setPrecision(results.back(), precision);
|
||||
spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
|
||||
addDecoration(result, noContraction);
|
||||
results.push_back(builder.setPrecision(result, precision));
|
||||
}
|
||||
|
||||
// put the pieces together
|
||||
|
|
@ -2996,7 +3002,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
|
|||
}
|
||||
}
|
||||
|
||||
spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy)
|
||||
spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy)
|
||||
{
|
||||
spv::Op unaryOp = spv::OpNop;
|
||||
int libCall = -1;
|
||||
|
|
@ -3008,7 +3014,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
|
|||
if (isFloat) {
|
||||
unaryOp = spv::OpFNegate;
|
||||
if (builder.isMatrixType(typeId))
|
||||
return createUnaryMatrixOperation(unaryOp, precision, typeId, operand, typeProxy);
|
||||
return createUnaryMatrixOperation(unaryOp, precision, noContraction, typeId, operand, typeProxy);
|
||||
} else
|
||||
unaryOp = spv::OpSNegate;
|
||||
break;
|
||||
|
|
@ -3290,11 +3296,12 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
|
|||
id = builder.createUnaryOp(unaryOp, typeId, operand);
|
||||
}
|
||||
|
||||
addDecoration(id, noContraction);
|
||||
return builder.setPrecision(id, precision);
|
||||
}
|
||||
|
||||
// Create a unary operation on a matrix
|
||||
spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Id typeId, spv::Id operand, glslang::TBasicType /* typeProxy */)
|
||||
spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand, glslang::TBasicType /* typeProxy */)
|
||||
{
|
||||
// Handle unary operations vector by vector.
|
||||
// The result type is the same type as the original type.
|
||||
|
|
@ -3315,8 +3322,9 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Deco
|
|||
std::vector<unsigned int> indexes;
|
||||
indexes.push_back(c);
|
||||
spv::Id vec = builder.createCompositeExtract(operand, vecType, indexes);
|
||||
results.push_back(builder.createUnaryOp(op, vecType, vec));
|
||||
builder.setPrecision(results.back(), precision);
|
||||
spv::Id vec_result = builder.createUnaryOp(op, vecType, vec);
|
||||
addDecoration(vec_result, noContraction);
|
||||
results.push_back(builder.setPrecision(vec_result, precision));
|
||||
}
|
||||
|
||||
// put the pieces together
|
||||
|
|
|
|||
|
|
@ -47,12 +47,21 @@
|
|||
#include "localintermediate.h"
|
||||
namespace {
|
||||
|
||||
// Use string to hold the accesschain information, as in most cases we the
|
||||
// accesschain is short and may contain only one element, which is the symbol ID.
|
||||
// Use string to hold the accesschain information, as in most cases the
|
||||
// accesschain is short and may contain only one element, which is the symbol
|
||||
// ID.
|
||||
// Example: struct {float a; float b;} s;
|
||||
// Object s.a will be represented with: <symbol ID of s>/0
|
||||
// Object s.b will be represented with: <symbol ID of s>/1
|
||||
// Object s will be representend with: <symbol ID of s>
|
||||
// For members of vector, matrix and arrays, they will be represented with the
|
||||
// same symbol ID of their container symbol objects. This is because their
|
||||
// precise'ness is always the same as their container symbol objects.
|
||||
using ObjectAccessChain = std::string;
|
||||
#ifndef StructAccessChainDelimiter
|
||||
#define StructAccessChainDelimiter '/'
|
||||
#endif
|
||||
|
||||
// The delimiter used in the ObjectAccessChain string to separate symbol ID and
|
||||
// different level of struct indices.
|
||||
const char OBJECT_ACCESSCHAIN_DELIMITER = '/';
|
||||
|
||||
// Mapping from Symbol IDs of symbol nodes, to their defining operation
|
||||
// nodes.
|
||||
|
|
@ -128,7 +137,8 @@ unsigned getStructIndexFromConstantUnion(glslang::TIntermTyped *node)
|
|||
// A helper function to generate symbol_label.
|
||||
ObjectAccessChain generateSymbolLabel(glslang::TIntermSymbol* node)
|
||||
{
|
||||
ObjectAccessChain symbol_id = std::to_string(node->getId()) + "(" + node->getName().c_str() + ")";
|
||||
ObjectAccessChain symbol_id =
|
||||
std::to_string(node->getId()) + "(" + node->getName().c_str() + ")";
|
||||
return symbol_id;
|
||||
}
|
||||
|
||||
|
|
@ -186,10 +196,7 @@ public:
|
|||
*state_ptr = new_state_value;
|
||||
}
|
||||
StateSettingGuard(T* state_ptr) : state_ptr_(state_ptr), previous_state_(*state_ptr) {}
|
||||
void setState(T new_state_value)
|
||||
{
|
||||
*state_ptr_ = new_state_value;
|
||||
}
|
||||
void setState(T new_state_value) { *state_ptr_ = new_state_value; }
|
||||
~StateSettingGuard() { *state_ptr_ = previous_state_; }
|
||||
|
||||
private:
|
||||
|
|
@ -200,23 +207,24 @@ private:
|
|||
// A helper function to get the front element from a given ObjectAccessChain
|
||||
ObjectAccessChain getFrontElement(const ObjectAccessChain& chain)
|
||||
{
|
||||
size_t pos_delimiter = chain.find(StructAccessChainDelimiter);
|
||||
size_t pos_delimiter = chain.find(OBJECT_ACCESSCHAIN_DELIMITER);
|
||||
return pos_delimiter == std::string::npos ? chain : chain.substr(0, pos_delimiter);
|
||||
}
|
||||
|
||||
// A helper function to get the accesschain starting from the second element.
|
||||
ObjectAccessChain subAccessChainFromSecondElement(const ObjectAccessChain& chain)
|
||||
{
|
||||
size_t pos_delimiter = chain.find(StructAccessChainDelimiter);
|
||||
size_t pos_delimiter = chain.find(OBJECT_ACCESSCHAIN_DELIMITER);
|
||||
return pos_delimiter == std::string::npos ? "" : chain.substr(pos_delimiter + 1);
|
||||
}
|
||||
|
||||
// A helper function to get the accesschain after removing a given prefix.
|
||||
ObjectAccessChain getSubAccessChainAfterPrefix(const ObjectAccessChain &chain, const ObjectAccessChain &prefix)
|
||||
ObjectAccessChain getSubAccessChainAfterPrefix(const ObjectAccessChain& chain,
|
||||
const ObjectAccessChain& prefix)
|
||||
{
|
||||
size_t pos = chain.find(prefix);
|
||||
if (pos != 0) return chain;
|
||||
return chain.substr(prefix.length() + sizeof(StructAccessChainDelimiter));
|
||||
return chain.substr(prefix.length() + sizeof(OBJECT_ACCESSCHAIN_DELIMITER));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -226,12 +234,11 @@ ObjectAccessChain getSubAccessChainAfterPrefix(const ObjectAccessChain &chain, c
|
|||
//
|
||||
class TSymbolDefinitionCollectingTraverser : public glslang::TIntermTraverser {
|
||||
public:
|
||||
TSymbolDefinitionCollectingTraverser(
|
||||
NodeMapping *symbol_definition_mapping, AccessChainMapping *accesschain_mapping,
|
||||
TSymbolDefinitionCollectingTraverser(NodeMapping* symbol_definition_mapping,
|
||||
AccessChainMapping* accesschain_mapping,
|
||||
ObjectAccesschainSet* precise_objects,
|
||||
ReturnBranchNodeSet* precise_return_nodes);
|
||||
|
||||
// bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate *) override;
|
||||
bool visitUnary(glslang::TVisit, glslang::TIntermUnary*) override;
|
||||
bool visitBinary(glslang::TVisit, glslang::TIntermBinary*) override;
|
||||
void visitSymbol(glslang::TIntermSymbol*) override;
|
||||
|
|
@ -408,7 +415,7 @@ bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit /* visit
|
|||
// object. We need to record the accesschain information of the current
|
||||
// node into its object id.
|
||||
unsigned struct_dereference_index = getStructIndexFromConstantUnion(node->getRight());
|
||||
object_to_be_defined_.push_back(StructAccessChainDelimiter);
|
||||
object_to_be_defined_.push_back(OBJECT_ACCESSCHAIN_DELIMITER);
|
||||
object_to_be_defined_.append(std::to_string(struct_dereference_index));
|
||||
accesschain_mapping_[node] = object_to_be_defined_;
|
||||
|
||||
|
|
@ -430,7 +437,8 @@ bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit /* visit
|
|||
std::tuple<NodeMapping, AccessChainMapping, ObjectAccesschainSet, ReturnBranchNodeSet>
|
||||
getSymbolToDefinitionMappingAndPreciseSymbolIDs(const glslang::TIntermediate& intermediate)
|
||||
{
|
||||
auto result_tuple = std::make_tuple(NodeMapping(), AccessChainMapping(), ObjectAccesschainSet(), ReturnBranchNodeSet());
|
||||
auto result_tuple = std::make_tuple(NodeMapping(), AccessChainMapping(), ObjectAccesschainSet(),
|
||||
ReturnBranchNodeSet());
|
||||
|
||||
TIntermNode* root = intermediate.getTreeRoot();
|
||||
if (root == 0) return result_tuple;
|
||||
|
|
@ -635,8 +643,8 @@ public:
|
|||
TNoContractionPropagator(ObjectAccesschainSet* precise_objects,
|
||||
const AccessChainMapping& accesschain_mapping)
|
||||
: TIntermTraverser(true, false, false), remained_accesschain_(),
|
||||
precise_objects_(*precise_objects),
|
||||
accesschain_mapping_(accesschain_mapping), added_precise_object_ids_() {}
|
||||
precise_objects_(*precise_objects), accesschain_mapping_(accesschain_mapping),
|
||||
added_precise_object_ids_() {}
|
||||
|
||||
// Propagates 'precise' in the right nodes of a given assignment node with
|
||||
// accesschain record from the assignee node to a 'precise' object it
|
||||
|
|
@ -662,8 +670,7 @@ public:
|
|||
}
|
||||
|
||||
// Propagates 'precise' in a given precise return node.
|
||||
void
|
||||
propagateNoContractionInReturnNode(glslang::TIntermBranch *return_node)
|
||||
void propagateNoContractionInReturnNode(glslang::TIntermBranch* return_node)
|
||||
{
|
||||
remained_accesschain_ = "";
|
||||
assert(return_node->getFlowOp() == glslang::EOpReturn && return_node->getExpression());
|
||||
|
|
@ -700,17 +707,10 @@ protected:
|
|||
&remained_accesschain_, next_level_accesschain);
|
||||
potential_precise_node->traverse(this);
|
||||
}
|
||||
|
||||
} else {
|
||||
// If this is not a struct constructor, just visit each nested node.
|
||||
glslang::TIntermSequence &seq = node->getSequence();
|
||||
for (int i = 0; i < (int)seq.size(); ++i) {
|
||||
seq[i]->traverse(this);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Visit a binary node. A binary node can be an object node, e.g. a dereference node.
|
||||
// As only the top object nodes in the right side of an assignment needs to be visited
|
||||
|
|
@ -728,8 +728,7 @@ protected:
|
|||
if (remained_accesschain_.empty()) {
|
||||
node->getWritableType().getQualifier().noContraction = true;
|
||||
} else {
|
||||
new_precise_accesschain +=
|
||||
StructAccessChainDelimiter + remained_accesschain_;
|
||||
new_precise_accesschain += OBJECT_ACCESSCHAIN_DELIMITER + remained_accesschain_;
|
||||
}
|
||||
// Cache the accesschain as added precise object, so we won't add the
|
||||
// same object to the worklist again.
|
||||
|
|
@ -746,9 +745,7 @@ protected:
|
|||
node->getWritableType().getQualifier().noContraction = true;
|
||||
}
|
||||
// As this node is not an object node, need to traverse the children nodes.
|
||||
node->getLeft()->traverse(this);
|
||||
node->getRight()->traverse(this);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Visits an unary node. An unary node can not be an object node. If the operation
|
||||
|
|
@ -759,8 +756,7 @@ protected:
|
|||
if (isArithmeticOperation(node->getOp())) {
|
||||
node->getWritableType().getQualifier().noContraction = true;
|
||||
}
|
||||
node->getOperand()->traverse(this);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Visits a symbol node. A symbol node is always an object node. So we
|
||||
|
|
@ -781,7 +777,7 @@ protected:
|
|||
if (remained_accesschain_.empty()) {
|
||||
node->getWritableType().getQualifier().noContraction = true;
|
||||
} else {
|
||||
new_precise_accesschain += StructAccessChainDelimiter + remained_accesschain_;
|
||||
new_precise_accesschain += OBJECT_ACCESSCHAIN_DELIMITER + remained_accesschain_;
|
||||
}
|
||||
// Add the new 'precise' accesschain to the worklist and make sure we
|
||||
// don't visit it again.
|
||||
|
|
@ -804,8 +800,6 @@ protected:
|
|||
// A map from node pointers to their accesschains.
|
||||
const AccessChainMapping& accesschain_mapping_;
|
||||
};
|
||||
|
||||
#undef StructAccessChainDelimiter
|
||||
}
|
||||
|
||||
namespace glslang {
|
||||
|
|
@ -828,8 +822,7 @@ void PropagateNoContraction(const glslang::TIntermediate &intermediate)
|
|||
|
||||
// The initial set of 'precise' objects which are represented as the
|
||||
// accesschain toward them.
|
||||
ObjectAccesschainSet &precise_object_accesschains =
|
||||
std::get<2>(mappings_and_precise_objects);
|
||||
ObjectAccesschainSet& precise_object_accesschains = std::get<2>(mappings_and_precise_objects);
|
||||
|
||||
// The set of 'precise' return nodes.
|
||||
ReturnBranchNodeSet& precise_return_nodes = std::get<3>(mappings_and_precise_objects);
|
||||
|
|
@ -845,10 +838,9 @@ void PropagateNoContraction(const glslang::TIntermediate &intermediate)
|
|||
// 'precise' accesschain worklist with new found object nodes.
|
||||
// Repeat above steps until the worklist is empty.
|
||||
TNoContractionAssigneeCheckingTraverser checker(accesschain_mapping);
|
||||
TNoContractionPropagator propagator(&precise_object_accesschains,
|
||||
accesschain_mapping);
|
||||
TNoContractionPropagator propagator(&precise_object_accesschains, accesschain_mapping);
|
||||
|
||||
// We have to initial precise worklist to handle:
|
||||
// We have two initial precise worklists to handle:
|
||||
// 1) precise return nodes
|
||||
// 2) precise object accesschains
|
||||
// We should process the precise return nodes first and the involved
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue