Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
9af54c33
Commit
9af54c33
authored
May 17, 2016
by
John Kessenich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Non-functional: Fix some comments English and brace formatting in recent merges.
parent
5b3f7555
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
108 additions
and
112 deletions
+108
-112
GlslangToSpv.cpp
SPIRV/GlslangToSpv.cpp
+3
-7
propagateNoContraction.cpp
glslang/MachineIndependent/propagateNoContraction.cpp
+104
-104
propagateNoContraction.h
glslang/MachineIndependent/propagateNoContraction.h
+1
-1
No files found.
SPIRV/GlslangToSpv.cpp
View file @
9af54c33
...
...
@@ -1891,8 +1891,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
addMemberDecoration
(
spvType
,
member
,
TranslateLayoutDecoration
(
glslangType
,
subQualifier
.
layoutMatrix
));
addMemberDecoration
(
spvType
,
member
,
TranslatePrecisionDecoration
(
glslangType
));
// Add interpolation decorations only to top-level members of Input and Output storage classes
if
(
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingIn
||
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingOut
)
{
if
(
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingIn
||
type
.
getQualifier
().
storage
==
glslang
::
EvqVaryingOut
)
{
addMemberDecoration
(
spvType
,
member
,
TranslateInterpolationDecoration
(
subQualifier
));
}
addMemberDecoration
(
spvType
,
member
,
TranslateInvariantDecoration
(
subQualifier
));
...
...
@@ -1909,14 +1908,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
// probably move to the linker stage of the front end proper, and just have the
// answer sitting already distributed throughout the individual member locations.
int
location
=
-
1
;
// will only decorate if present or inherited
if
(
subQualifier
.
hasLocation
())
// no inheritance, or override of inheritance
{
if
(
subQualifier
.
hasLocation
())
{
// no inheritance, or override of inheritance
// struct members should not have explicit locations
assert
(
type
.
getBasicType
()
!=
glslang
::
EbtStruct
);
location
=
subQualifier
.
layoutLocation
;
}
else
if
(
type
.
getBasicType
()
!=
glslang
::
EbtBlock
)
{
}
else
if
(
type
.
getBasicType
()
!=
glslang
::
EbtBlock
)
{
// If it is a not a Block, (...) Its members are assigned consecutive locations (...)
// The members, and their nested types, must not themselves have Location decorations.
}
...
...
glslang/MachineIndependent/propagateNoContraction.cpp
View file @
9af54c33
...
...
@@ -34,7 +34,7 @@
//
// Visit the nodes in the glslang intermediate tree representation to
// propagate 'noContraction' qualifier.
// propagate
the
'noContraction' qualifier.
//
#include "propagateNoContraction.h"
...
...
@@ -48,16 +48,16 @@
#include "localintermediate.h"
namespace
{
// Use
string to hold the access
chain information, as in most cases the
// accesschain is short and may contain only one element, which is the symbol
// Use
a string to hold the access
chain information, as in most cases the
// access
chain 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 represente
n
d with: <symbol ID of s>
// Object s will be represented 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.
// preciseness is always the same as their container symbol objects.
typedef
std
::
string
ObjectAccessChain
;
// The delimiter used in the ObjectAccessChain string to separate symbol ID and
...
...
@@ -67,7 +67,7 @@ const char ObjectAccesschainDelimiter = '/';
// Mapping from Symbol IDs of symbol nodes, to their defining operation
// nodes.
typedef
std
::
unordered_multimap
<
ObjectAccessChain
,
glslang
::
TIntermOperator
*>
NodeMapping
;
// Mapping from object nodes to their accesschain info string.
// Mapping from object nodes to their access
chain info string.
typedef
std
::
unordered_map
<
glslang
::
TIntermTyped
*
,
ObjectAccessChain
>
AccessChainMapping
;
// Set of object IDs.
...
...
@@ -127,7 +127,7 @@ bool isAssignOperation(glslang::TOperator op)
}
// A helper function to get the unsigned int from a given constant union node.
// Note the node should only hold
s
a uint scalar.
// Note the node should only hold a uint scalar.
unsigned
getStructIndexFromConstantUnion
(
glslang
::
TIntermTyped
*
node
)
{
assert
(
node
->
getAsConstantUnion
()
&&
node
->
getAsConstantUnion
()
->
isScalar
());
...
...
@@ -144,7 +144,7 @@ ObjectAccessChain generateSymbolLabel(glslang::TIntermSymbol* node)
}
// Returns true if the operation is an arithmetic operation and valid for
// 'NoContraction' decoration.
//
the
'NoContraction' decoration.
bool
isArithmeticOperation
(
glslang
::
TOperator
op
)
{
switch
(
op
)
{
...
...
@@ -184,7 +184,7 @@ bool isArithmeticOperation(glslang::TOperator op)
}
}
// A helper class to help manag
ing
populating_initial_no_contraction_ flag.
// A helper class to help manag
e the
populating_initial_no_contraction_ flag.
template
<
typename
T
>
class
StateSettingGuard
{
public
:
StateSettingGuard
(
T
*
state_ptr
,
T
new_state_value
)
...
...
@@ -208,14 +208,14 @@ ObjectAccessChain getFrontElement(const ObjectAccessChain& chain)
return
pos_delimiter
==
std
::
string
::
npos
?
chain
:
chain
.
substr
(
0
,
pos_delimiter
);
}
// A helper function to get the accesschain starting from the second element.
// A helper function to get the access
chain starting from the second element.
ObjectAccessChain
subAccessChainFromSecondElement
(
const
ObjectAccessChain
&
chain
)
{
size_t
pos_delimiter
=
chain
.
find
(
ObjectAccesschainDelimiter
);
return
pos_delimiter
==
std
::
string
::
npos
?
""
:
chain
.
substr
(
pos_delimiter
+
1
);
}
// A helper function to get the accesschain after removing a given prefix.
// A helper function to get the access
chain after removing a given prefix.
ObjectAccessChain
getSubAccessChainAfterPrefix
(
const
ObjectAccessChain
&
chain
,
const
ObjectAccessChain
&
prefix
)
{
...
...
@@ -228,7 +228,7 @@ ObjectAccessChain getSubAccessChainAfterPrefix(const ObjectAccessChain& chain,
//
// A traverser which traverses the whole AST and populates:
// 1) A mapping from symbol nodes' IDs to their defining operation nodes.
// 2) A set of accesschains of the initial precise object nodes.
// 2) A set of access
chains of the initial precise object nodes.
//
class
TSymbolDefinitionCollectingTraverser
:
public
glslang
::
TIntermTraverser
{
public
:
...
...
@@ -255,12 +255,12 @@ protected:
// A temporary cache of the symbol node whose defining node is to be found
// currently along traversing the AST.
ObjectAccessChain
current_object_
;
// A map from object node to its accesschain. This traverser stores
// the built accesschains into this map for each object node it has
// A map from object node to its access
chain. This traverser stores
// the built access
chains into this map for each object node it has
// visited.
AccessChainMapping
&
accesschain_mapping_
;
// The pointer to the Function Definition node, so we can get the
// precise
'
ness of the return expression from it when we traverse the
// preciseness of the return expression from it when we traverse the
// return branch node.
glslang
::
TIntermAggregate
*
current_function_definition_node_
;
};
...
...
@@ -288,14 +288,14 @@ void TSymbolDefinitionCollectingTraverser::visitSymbol(glslang::TIntermSymbol* n
bool
TSymbolDefinitionCollectingTraverser
::
visitAggregate
(
glslang
::
TVisit
,
glslang
::
TIntermAggregate
*
node
)
{
// This aggre
a
gate node might be a function definition node, in which case we need to
// cache this node, so we can get the precise
'
ness information of the return value
// This aggregate node might be a function definition node, in which case we need to
// cache this node, so we can get the preciseness information of the return value
// of this function later.
StateSettingGuard
<
glslang
::
TIntermAggregate
*>
current_function_definition_node_setting_guard
(
&
current_function_definition_node_
);
if
(
node
->
getOp
()
==
glslang
::
EOpFunction
)
{
// This is function definition node, we need to cache this node so that we can
// get the precise
'
ness of the return value later.
// get the preciseness of the return value later.
current_function_definition_node_setting_guard
.
setState
(
node
);
}
// Traverse the items in the sequence.
...
...
@@ -313,7 +313,7 @@ bool TSymbolDefinitionCollectingTraverser::visitBranch(glslang::TVisit,
if
(
node
->
getFlowOp
()
==
glslang
::
EOpReturn
&&
node
->
getExpression
()
&&
current_function_definition_node_
&&
current_function_definition_node_
->
getType
().
getQualifier
().
noContraction
)
{
// This node is a return node with
expression, and its function has
// This node is a return node with
an expression, and its function has a
// precise return value. We need to find the involved objects in its
// expression and add them to the set of initial precise objects.
precise_return_nodes_
.
insert
(
node
);
...
...
@@ -322,71 +322,71 @@ bool TSymbolDefinitionCollectingTraverser::visitBranch(glslang::TVisit,
return
false
;
}
// Visits a
n
unary node. This might be an implicit assignment like i++, i--. etc.
// Visits a unary node. This might be an implicit assignment like i++, i--. etc.
bool
TSymbolDefinitionCollectingTraverser
::
visitUnary
(
glslang
::
TVisit
/* visit */
,
glslang
::
TIntermUnary
*
node
)
{
current_object_
.
clear
();
node
->
getOperand
()
->
traverse
(
this
);
if
(
isAssignOperation
(
node
->
getOp
()))
{
// We should always be able to get an accesschain of the operand node.
// We should always be able to get an access
chain of the operand node.
assert
(
!
current_object_
.
empty
());
// If the operand node object is 'precise', we collect its accesschain
// If the operand node object is 'precise', we collect its access
chain
// for the initial set of 'precise' objects.
if
(
isPreciseObjectNode
(
node
->
getOperand
()))
{
// The operand node is an 'precise' object node, add its
// accesschain to the set of 'precise' objects. This is to collect
// access
chain to the set of 'precise' objects. This is to collect
// the initial set of 'precise' objects.
precise_objects_
.
insert
(
current_object_
);
}
// Gets the symbol ID from the object's accesschain.
// Gets the symbol ID from the object's access
chain.
ObjectAccessChain
id_symbol
=
getFrontElement
(
current_object_
);
// Add a mapping from the symbol ID to this assignment operation node.
symbol_definition_mapping_
.
insert
(
std
::
make_pair
(
id_symbol
,
node
));
}
//
Unary node is not a dereference node, so we clear the access
chain which
//
A unary node is not a dereference node, so we clear the access
chain which
// is under construction.
current_object_
.
clear
();
return
false
;
}
// Visits a binary node and updates the mapping from symbol IDs to the definition
// nodes. Also collects the accesschains for the initial precise objects.
// nodes. Also collects the access
chains for the initial precise objects.
bool
TSymbolDefinitionCollectingTraverser
::
visitBinary
(
glslang
::
TVisit
/* visit */
,
glslang
::
TIntermBinary
*
node
)
{
// Traverses the left node to build the accesschain info for the object.
// Traverses the left node to build the access
chain info for the object.
current_object_
.
clear
();
node
->
getLeft
()
->
traverse
(
this
);
if
(
isAssignOperation
(
node
->
getOp
()))
{
// We should always be able to get an accesschain for the left node.
// We should always be able to get an access
chain for the left node.
assert
(
!
current_object_
.
empty
());
// If the left node object is 'precise', it is an initial precise object
// specified in the shader source. Adds it to the initial worklist to
// specified in the shader source. Adds it to the initial work
list to
// process later.
if
(
isPreciseObjectNode
(
node
->
getLeft
()))
{
// The left node is an 'precise' object node, add its accesschain to
// The left node is an 'precise' object node, add its access
chain to
// the set of 'precise' objects. This is to collect the initial set
// of 'precise' objects.
precise_objects_
.
insert
(
current_object_
);
}
// Gets the symbol ID from the object accesschain, which should be the
// first element recorded in the accesschain.
// Gets the symbol ID from the object access
chain, which should be the
// first element recorded in the access
chain.
ObjectAccessChain
id_symbol
=
getFrontElement
(
current_object_
);
// Adds a mapping from the symbol ID to this assignment operation node.
symbol_definition_mapping_
.
insert
(
std
::
make_pair
(
id_symbol
,
node
));
// Traverses the right node, there may be other 'assignment'
// operat
r
ions in the right.
// operations in the right.
current_object_
.
clear
();
node
->
getRight
()
->
traverse
(
this
);
}
else
if
(
isDereferenceOperation
(
node
->
getOp
()))
{
// The left node (parent node) is a struct type object. We need to
// record the accesschain information of the current node into its
// record the access
chain information of the current node into its
// object id.
if
(
node
->
getOp
()
==
glslang
::
EOpIndexDirectStruct
)
{
unsigned
struct_dereference_index
=
getStructIndexFromConstantUnion
(
node
->
getRight
());
...
...
@@ -395,7 +395,7 @@ bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit /* visit
}
accesschain_mapping_
[
node
]
=
current_object_
;
// For dereference node, there is no need to traverse the right child
// For
a
dereference node, there is no need to traverse the right child
// node as the right node should always be an integer type object.
}
else
{
...
...
@@ -408,8 +408,8 @@ bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit /* visit
// Traverses the AST and returns a tuple of four members:
// 1) a mapping from symbol IDs to the definition nodes (aka. assignment nodes) of these symbols.
// 2) a mapping from object nodes in the AST to the accesschains of these objects.
// 3) a set of accesschains of precise objects.
// 2) a mapping from object nodes in the AST to the access
chains of these objects.
// 3) a set of access
chains of precise objects.
// 4) a set of return nodes with precise expressions.
std
::
tuple
<
NodeMapping
,
AccessChainMapping
,
ObjectAccesschainSet
,
ReturnBranchNodeSet
>
getSymbolToDefinitionMappingAndPreciseSymbolIDs
(
const
glslang
::
TIntermediate
&
intermediate
)
...
...
@@ -437,15 +437,15 @@ getSymbolToDefinitionMappingAndPreciseSymbolIDs(const glslang::TIntermediate& in
//
// A traverser that determine whether the left node (or operand node for unary
// node) of an assignment node is 'precise', containing 'precise' or not,
// according to the accesschain a given precise object which share the same
// according to the access
chain a given precise object which share the same
// symbol as the left node.
//
// Post-orderly traverses the left node subtree of an binary assignment node and:
//
// 1) Propagates the 'precise' from the left object nodes to this object node.
//
// 2) Builds object accesschain along the traversal, and also compares with
// the accesschain of the given 'precise' object along with the traversal to
// 2) Builds object access
chain along the traversal, and also compares with
// the access
chain of the given 'precise' object along with the traversal to
// tell if the node to be defined is 'precise' or not.
//
class
TNoContractionAssigneeCheckingTraverser
:
public
glslang
::
TIntermTraverser
{
...
...
@@ -464,18 +464,18 @@ public:
:
TIntermTraverser
(
true
,
false
,
false
),
accesschain_mapping_
(
accesschain_mapping
),
precise_object_
(
nullptr
)
{}
// Checks the precise
'
ness of a given assignment node with a precise object
// represented as accesschain. The precise object shares the same symbol
// Checks the preciseness of a given assignment node with a precise object
// represented as access
chain. The precise object shares the same symbol
// with the assignee of the given assignment node. Return a tuple of two:
//
// 1) The precise
'
ness of the assignee node of this assignment node. True
// 1) The preciseness of the assignee node of this assignment node. True
// if the assignee contains 'precise' objects or is 'precise', false if
// the assignee is not 'precise' according to the accesschain of the given
// the assignee is not 'precise' according to the access
chain of the given
// precise object.
//
// 2) The incremental accesschain from the assignee node to its nested
// 'precise' object, according to the accesschain of the given precise
// object. This incremental accesschain can be empty, which means the
// 2) The incremental access
chain from the assignee node to its nested
// 'precise' object, according to the access
chain of the given precise
// object. This incremental access
chain can be empty, which means the
// assignee is 'precise'. Otherwise it shows the path to the nested
// precise object.
std
::
tuple
<
bool
,
ObjectAccessChain
>
...
...
@@ -487,7 +487,7 @@ public:
ObjectAccessChain
assignee_object
;
if
(
glslang
::
TIntermBinary
*
BN
=
node
->
getAsBinaryNode
())
{
// This is a binary assignment node, we need to check the
// precise
'
ness of the left node.
// preciseness of the left node.
assert
(
accesschain_mapping_
.
count
(
BN
->
getLeft
()));
// The left node (assignee node) is an object node, traverse the
// node to let the 'precise' of nesting objects being transfered to
...
...
@@ -498,14 +498,14 @@ public:
if
(
isPreciseObjectNode
(
BN
->
getLeft
()))
{
return
make_tuple
(
true
,
ObjectAccessChain
());
}
// If the precise
'
ness of the left node (assignee node) can not
// be determined by now, we need to compare the accesschain string
// If the preciseness of the left node (assignee node) can not
// be determined by now, we need to compare the access
chain string
// of the assignee object with the given precise object.
assignee_object
=
accesschain_mapping_
.
at
(
BN
->
getLeft
());
}
else
if
(
glslang
::
TIntermUnary
*
UN
=
node
->
getAsUnaryNode
())
{
// This is a unary assignment node, we need to check the
// precise
'
ness of the operand node. For unary assignment node, the
// preciseness of the operand node. For unary assignment node, the
// operand node should always be an object node.
assert
(
accesschain_mapping_
.
count
(
UN
->
getOperand
()));
// Traverse the operand node to let the 'precise' being propagated
...
...
@@ -516,8 +516,8 @@ public:
if
(
isPreciseObjectNode
(
UN
->
getOperand
()))
{
return
make_tuple
(
true
,
ObjectAccessChain
());
}
// If the precise
'
ness of the operand node (assignee node) can not
// be determined by now, we need to compare the accesschain string
// If the preciseness of the operand node (assignee node) can not
// be determined by now, we need to compare the access
chain string
// of the assignee object with the given precise object.
assignee_object
=
accesschain_mapping_
.
at
(
UN
->
getOperand
());
}
else
{
...
...
@@ -525,23 +525,23 @@ public:
assert
(
false
);
}
// Compare the accesschain string of the assignee node with the given
// Compare the access
chain string of the assignee node with the given
// precise object to determine if this assignment should propagate
// 'precise'.
if
(
assignee_object
.
find
(
precise_object
)
==
0
)
{
// The accesschain string of the given precise object is a prefix
// of assignee's accesschain string. The assignee should be
// The access
chain string of the given precise object is a prefix
// of assignee's access
chain string. The assignee should be
// 'precise'.
return
make_tuple
(
true
,
ObjectAccessChain
());
}
else
if
(
precise_object
.
find
(
assignee_object
)
==
0
)
{
// The assignee's accesschain string is a prefix of the given
// The assignee's access
chain string is a prefix of the given
// precise object, the assignee object contains 'precise' object,
// and we need to pass the remained accesschain to the object nodes
// and we need to pass the remained access
chain to the object nodes
// in the right.
return
make_tuple
(
true
,
getSubAccessChainAfterPrefix
(
precise_object
,
assignee_object
));
}
else
{
// The accesschain strings do not match, the assignee object can
// not be label
l
ed as 'precise' according to the given precise
// The access
chain strings do not match, the assignee object can
// not be labeled as 'precise' according to the given precise
// object.
return
make_tuple
(
false
,
ObjectAccessChain
());
}
...
...
@@ -551,9 +551,9 @@ protected:
bool
visitBinary
(
glslang
::
TVisit
,
glslang
::
TIntermBinary
*
node
)
override
;
void
visitSymbol
(
glslang
::
TIntermSymbol
*
node
)
override
;
// A map from object nodes to their accesschain string (used as object ID).
// A map from object nodes to their access
chain string (used as object ID).
const
AccessChainMapping
&
accesschain_mapping_
;
// A given precise object, represented in it accesschain string. This
// A given precise object, represented in it access
chain string. This
// precise object is used to be compared with the assignee node to tell if
// the assignee node is 'precise', contains 'precise' object or not
// 'precise'.
...
...
@@ -576,7 +576,7 @@ bool TNoContractionAssigneeCheckingTraverser::visitBinary(glslang::TVisit,
assert
(
isDereferenceOperation
(
node
->
getOp
()));
// If the left node is 'precise', this node should also be precise,
// otherwise, compare with the given precise_object_. If the
// accesschain of this node matches with the given precise_object_,
// access
chain of this node matches with the given precise_object_,
// this node should be marked as 'precise'.
if
(
isPreciseObjectNode
(
node
->
getLeft
()))
{
node
->
getWritableType
().
getQualifier
().
noContraction
=
true
;
...
...
@@ -587,12 +587,12 @@ bool TNoContractionAssigneeCheckingTraverser::visitBinary(glslang::TVisit,
return
false
;
}
// Visits a symbol node, if the symbol node ID (its accesschain string) matches
// Visits a symbol node, if the symbol node ID (its access
chain string) matches
// with the given precise object, this node should be 'precise'.
void
TNoContractionAssigneeCheckingTraverser
::
visitSymbol
(
glslang
::
TIntermSymbol
*
node
)
{
// A symbol node should always be an object node, and should have been added
// to the map from object nodes to their accesschain strings.
// to the map from object nodes to their access
chain strings.
assert
(
accesschain_mapping_
.
count
(
node
));
if
(
accesschain_mapping_
.
at
(
node
)
==
*
precise_object_
)
{
node
->
getWritableType
().
getQualifier
().
noContraction
=
true
;
...
...
@@ -603,10 +603,10 @@ void TNoContractionAssigneeCheckingTraverser::visitSymbol(glslang::TIntermSymbol
// A traverser that only traverses the right side of binary assignment nodes
// and the operand node of unary assignment nodes.
//
// 1) Marks arithmetic operations 'NoContraction'.
// 1) Marks arithmetic operations
as
'NoContraction'.
//
// 2) Find the object which should be marked as 'precise' in the right and
//
update the 'precise' object work
list.
//
update the 'precise' object work
list.
//
class
TNoContractionPropagator
:
public
glslang
::
TIntermTraverser
{
public
:
...
...
@@ -617,7 +617,7 @@ public:
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
// access
chain record from the assignee node to a 'precise' object it
// contains.
void
propagateNoContractionInOneExpression
(
glslang
::
TIntermTyped
*
defining_node
,
...
...
@@ -650,26 +650,26 @@ public:
protected
:
// Visits an aggregate node. The node can be a initializer list, in which
// case we need to find the 'precise' or 'precise' containing object node
// with the accesschain record. In other cases, just need to traverse all
// with the access
chain record. In other cases, just need to traverse all
// the children nodes.
bool
visitAggregate
(
glslang
::
TVisit
,
glslang
::
TIntermAggregate
*
node
)
override
{
if
(
!
remained_accesschain_
.
empty
()
&&
node
->
getOp
()
==
glslang
::
EOpConstructStruct
)
{
// This is a struct initializer node, and the remained
// accesschain is not empty, we need to refer to the
// access
chain is not empty, we need to refer to the
// assignee_remained_access_chain_ to find the nested
// 'precise' object. And we don't need to visit other nodes in this
// aggre
a
gate node.
// aggregate node.
// Gets the struct dereference index that leads to 'precise' object.
ObjectAccessChain
precise_accesschain_index_str
=
getFrontElement
(
remained_accesschain_
);
unsigned
precise_accesschain_index
=
strtoul
(
precise_accesschain_index_str
.
c_str
(),
nullptr
,
10
);
// Gets the node pointed by the accesschain index extracted before.
// Gets the node pointed by the access
chain index extracted before.
glslang
::
TIntermTyped
*
potential_precise_node
=
node
->
getSequence
()[
precise_accesschain_index
]
->
getAsTyped
();
assert
(
potential_precise_node
);
// Pop the front accesschain index from the path, and visit the nested node.
// Pop the front access
chain index from the path, and visit the nested node.
{
ObjectAccessChain
next_level_accesschain
=
subAccessChainFromSecondElement
(
remained_accesschain_
);
...
...
@@ -684,7 +684,7 @@ protected:
// Visits 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
// and added to 'precise' worklist, this traverser won't visit the children nodes of
// and added to 'precise' work
list, this traverser won't visit the children nodes of
// an object node. If the binary node does not represent an object node, it should
// go on to traverse its children nodes and if it is an arithmetic operation node, this
// operation should be marked as 'noContraction'.
...
...
@@ -692,16 +692,16 @@ protected:
{
if
(
isDereferenceOperation
(
node
->
getOp
()))
{
// This binary node is an object node. Need to update the precise
// object set with the accesschain of this node + remained
// accesschain .
// object set with the access
chain of this node + remained
// access
chain .
ObjectAccessChain
new_precise_accesschain
=
accesschain_mapping_
.
at
(
node
);
if
(
remained_accesschain_
.
empty
())
{
node
->
getWritableType
().
getQualifier
().
noContraction
=
true
;
}
else
{
new_precise_accesschain
+=
ObjectAccesschainDelimiter
+
remained_accesschain_
;
}
// Cache the accesschain as added precise object, so we won't add the
// same object to the worklist again.
// Cache the access
chain as added precise object, so we won't add the
// same object to the work
list again.
if
(
!
added_precise_object_ids_
.
count
(
new_precise_accesschain
))
{
precise_objects_
.
insert
(
new_precise_accesschain
);
added_precise_object_ids_
.
insert
(
new_precise_accesschain
);
...
...
@@ -718,7 +718,7 @@ protected:
return
true
;
}
// Visits a
n unary node. An
unary node can not be an object node. If the operation
// Visits a
unary node. A
unary node can not be an object node. If the operation
// is an arithmetic operation, need to mark this node as 'noContraction'.
bool
visitUnary
(
glslang
::
TVisit
/* visit */
,
glslang
::
TIntermUnary
*
node
)
override
{
...
...
@@ -730,26 +730,26 @@ protected:
}
// Visits a symbol node. A symbol node is always an object node. So we
// should always be able to find its in our colected mapping from object
// nodes to accesschains. As an object node, a symbol node can be either
// should always be able to find its in our col
l
ected mapping from object
// nodes to access
chains. As an object node, a symbol node can be either
// 'precise' or containing 'precise' objects according to unused
// accesschain information we have when we visit this node.
// access
chain information we have when we visit this node.
void
visitSymbol
(
glslang
::
TIntermSymbol
*
node
)
override
{
// Symbol nodes are object nodes and should always have an
// accesschain collected before matches with it.
// access
chain collected before matches with it.
assert
(
accesschain_mapping_
.
count
(
node
));
ObjectAccessChain
new_precise_accesschain
=
accesschain_mapping_
.
at
(
node
);
// If the unused accesschain is empty, this symbol node should be
// marked as 'precise'. Otherwise, the unused accesschain should be
// appended to the symbol ID to build a new accesschain which points to
// If the unused access
chain is empty, this symbol node should be
// marked as 'precise'. Otherwise, the unused access
chain should be
// appended to the symbol ID to build a new access
chain which points to
// the nested 'precise' object in this symbol object.
if
(
remained_accesschain_
.
empty
())
{
node
->
getWritableType
().
getQualifier
().
noContraction
=
true
;
}
else
{
new_precise_accesschain
+=
ObjectAccesschainDelimiter
+
remained_accesschain_
;
}
// Add the new 'precise' access
chain to the work
list and make sure we
// Add the new 'precise' access
chain to the work
list and make sure we
// don't visit it again.
if
(
!
added_precise_object_ids_
.
count
(
new_precise_accesschain
))
{
precise_objects_
.
insert
(
new_precise_accesschain
);
...
...
@@ -757,7 +757,7 @@ protected:
}
}
// A set of precise objects, represented as accesschains.
// A set of precise objects, represented as access
chains.
ObjectAccesschainSet
&
precise_objects_
;
// Visited symbol nodes, should not revisit these nodes.
ObjectAccesschainSet
added_precise_object_ids_
;
...
...
@@ -767,7 +767,7 @@ protected:
// the right. So we need the path from the left node to its nested 'precise' node to
// tell us how to find the corresponding 'precise' node in the right.
ObjectAccessChain
remained_accesschain_
;
// A map from node pointers to their accesschains.
// A map from node pointers to their access
chains.
const
AccessChainMapping
&
accesschain_mapping_
;
};
}
...
...
@@ -787,35 +787,35 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate)
// traversing the tree again.
NodeMapping
&
symbol_definition_mapping
=
std
::
get
<
0
>
(
mappings_and_precise_objects
);
// The mapping of object nodes to their accesschains recorded.
// The mapping of object nodes to their access
chains recorded.
AccessChainMapping
&
accesschain_mapping
=
std
::
get
<
1
>
(
mappings_and_precise_objects
);
// The initial set of 'precise' objects which are represented as the
// accesschain toward them.
// access
chain toward them.
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
);
// Second, uses the initial set of precise objects as a worklist, pops an
// accesschain, extract the symbol ID from it. Then:
// Second, uses the initial set of precise objects as a work
list, pops an
// access
chain, extract the symbol ID from it. Then:
// 1) Check the assignee object, see if it is 'precise' object node or
// contains 'precise' object. Obtain the incremental accesschain from the
// contains 'precise' object. Obtain the incremental access
chain from the
// assignee node to its nested 'precise' node (if any).
// 2) If the assignee object node is 'precise' or it contains 'precise'
// objects, traverses the right side of the assignment operation
// expression to mark arithmetic operations as 'noContration' and update
// 'precise' access
chain work
list with new found object nodes.
// Repeat above steps until the worklist is empty.
// 'precise' access
chain work
list with new found object nodes.
// Repeat above steps until the work
list is empty.
TNoContractionAssigneeCheckingTraverser
checker
(
accesschain_mapping
);
TNoContractionPropagator
propagator
(
&
precise_object_accesschains
,
accesschain_mapping
);
// We have two initial precise worklists to handle:
// We have two initial precise work
lists to handle:
// 1) precise return nodes
// 2) precise object accesschains
// 2) precise object access
chains
// We should process the precise return nodes first and the involved
// objects in the return expression should be added to the precise object
// accesschain set.
// access
chain set.
while
(
!
precise_return_nodes
.
empty
())
{
glslang
::
TIntermBranch
*
precise_return_node
=
*
precise_return_nodes
.
begin
();
propagator
.
propagateNoContractionInReturnNode
(
precise_return_node
);
...
...
@@ -823,9 +823,9 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate)
}
while
(
!
precise_object_accesschains
.
empty
())
{
// Get the access
chain of a precise object from the work
list.
// Get the access
chain of a precise object from the work
list.
ObjectAccessChain
precise_object_accesschain
=
*
precise_object_accesschains
.
begin
();
// Get the symbol id from the accesschain.
// Get the symbol id from the access
chain.
ObjectAccessChain
symbol_id
=
getFrontElement
(
precise_object_accesschain
);
// Get all the defining nodes of that symbol ID.
std
::
pair
<
NodeMapping
::
iterator
,
NodeMapping
::
iterator
>
range
=
...
...
@@ -833,9 +833,9 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate)
// Visits all the assignment nodes of that symbol ID and
// 1) Check if the assignee node is 'precise' or contains 'precise'
// objects.
// 2) Propagate the 'precise' to the top layer object n
do
es
// 2) Propagate the 'precise' to the top layer object n
od
es
// in the right side of the assignment operation, update the 'precise'
// work
list with new access
chains representing the new 'precise'
// work
list with new access
chains representing the new 'precise'
// objects, and mark arithmetic operations as 'noContraction'.
for
(
NodeMapping
::
iterator
defining_node_iter
=
range
.
first
;
defining_node_iter
!=
range
.
second
;
defining_node_iter
++
)
{
...
...
@@ -852,7 +852,7 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate)
remained_accesschain
);
}
}
// Remove the last processed 'precise' object from the worklist.
// Remove the last processed 'precise' object from the work
list.
precise_object_accesschains
.
erase
(
precise_object_accesschain
);
}
}
...
...
glslang/MachineIndependent/propagateNoContraction.h
View file @
9af54c33
...
...
@@ -20,7 +20,7 @@
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment