Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
#version 450
|
|
|
|
#extension GL_EXT_tessellation_shader : require
|
|
|
|
#extension GL_EXT_gpu_shader5 : require
|
|
|
|
|
|
|
|
float minimal() {
|
|
|
|
precise float result = 5.0;
|
|
|
|
float a = 10.0;
|
|
|
|
float b = 20.0;
|
|
|
|
float c = 30.0;
|
|
|
|
float d = 40.0;
|
|
|
|
result = a * b + c * d; // c * d, a * b and rvalue1 + rvalue2 should be 'noContraction'.
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void continuous_assignment() {
|
|
|
|
precise float result = 5.0;
|
2016-05-07 01:52:28 +00:00
|
|
|
float a = 10.0;
|
|
|
|
float b = 20.0;
|
Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
result = a = b + 4; // b + 4 should be 'noContraction'.
|
|
|
|
}
|
|
|
|
|
|
|
|
void convert() {
|
2016-05-07 01:52:28 +00:00
|
|
|
precise double result;
|
|
|
|
float a = 10.0;
|
|
|
|
float b = 20.0;
|
Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
b = a + b; // a + b should be 'noContraction'.
|
2016-05-07 01:52:28 +00:00
|
|
|
result = double(b); // convert operation should not be 'noContraction'.
|
Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float loop_for() {
|
|
|
|
precise float r1 = 5.0;
|
|
|
|
precise float r2 = 10.0;
|
|
|
|
int a = 10;
|
|
|
|
int b = 20;
|
|
|
|
int c = 30;
|
|
|
|
for (int i = 0; i < a; i++) {
|
|
|
|
r1 += 3.12 + b + i; // 'noContration', this make i++ also 'noContraction'
|
|
|
|
c += 1; // 'noContration'
|
|
|
|
}
|
|
|
|
a += 1; // a + 1 should not be 'noContraction'.
|
|
|
|
r2 = c; // The calculation of c should be 'noContration'.
|
|
|
|
return float(r1 + r2); // conversion should not be 'noContration'.
|
|
|
|
}
|
|
|
|
|
|
|
|
void loop_array(void) {
|
2016-05-07 01:52:28 +00:00
|
|
|
precise float result;
|
Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
|
|
|
|
int x = 22;
|
|
|
|
int y = 33;
|
|
|
|
|
2016-05-07 01:52:28 +00:00
|
|
|
float a0[3];
|
|
|
|
result += float(x) + float(y); // x + y should be 'noContraction' also result + rvalue.
|
Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
|
|
// a's dereference + 2 should be 'noContraction'.
|
|
|
|
result += a0[i] + 2;
|
|
|
|
// result + 1 and 3 - rvalue should be 'noContraction'.
|
|
|
|
a0[i] = 3 - result++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void loop_while() {
|
|
|
|
precise float result = 5.0;
|
|
|
|
int a = 10;
|
|
|
|
int b = 20;
|
|
|
|
while (result < 10) {
|
|
|
|
result += 3.12 + b; // result + 3.12 should be 'noContraction'.
|
|
|
|
}
|
2016-05-07 01:52:28 +00:00
|
|
|
result = a + b + 5; // b + 5 should not be 'noCtraction' because all operands are integers.
|
Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
result = 11.1;
|
|
|
|
}
|
|
|
|
|
|
|
|
float fma_not_decorated() {
|
|
|
|
precise float result;
|
|
|
|
float a = 1.0;
|
|
|
|
float b = 2.0;
|
|
|
|
float c = 3.0;
|
|
|
|
b = b + c; // b + c should be decorated with 'noContraction'
|
|
|
|
result = fma(a, b, c); // fma() should not be decorated with 'noContradtion'
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
precise float precise_return_exp_func() {
|
|
|
|
float a = 1.0;
|
|
|
|
float b = 2.0;
|
|
|
|
return a + b; // the ADD operation should be 'noContraction'
|
|
|
|
}
|
|
|
|
|
|
|
|
precise float precise_return_val_func() {
|
|
|
|
float a = 1.0;
|
|
|
|
float b = 2.0;
|
|
|
|
float result = a + b; // the ADD operation should be 'noContraction'
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
float precise_func_parameter(float b, precise out float c) {
|
|
|
|
float a = 0.5;
|
|
|
|
c = a + b; // noContration
|
|
|
|
return a - b; // Not noContraction
|
|
|
|
}
|
|
|
|
|
2016-05-06 22:56:33 +00:00
|
|
|
mat3 matrix (mat2x3 a, mat3x2 b) {
|
|
|
|
mat2x3 c = mat2x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
|
|
|
|
precise mat3 result;
|
|
|
|
result = (a + c) * b; // should be noContraction
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
2016-05-04 21:34:38 +00:00
|
|
|
void main(){}
|