aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/link_functions.cpp
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2013-09-06 13:39:40 +0200
committermarha <marha@users.sourceforge.net>2013-09-06 13:39:40 +0200
commitd53900c52abc2402f978b72278712e4bcdbde9f2 (patch)
tree689cedc44df148a96d68ef460cff6b1756f096b6 /mesalib/src/glsl/link_functions.cpp
parent36eb733ed5aaaeaefc49c8894bf213d16b58d242 (diff)
parent2414a1de3cc17f438219f8f2a58b530d33e99a5e (diff)
downloadvcxsrv-d53900c52abc2402f978b72278712e4bcdbde9f2.tar.gz
vcxsrv-d53900c52abc2402f978b72278712e4bcdbde9f2.tar.bz2
vcxsrv-d53900c52abc2402f978b72278712e4bcdbde9f2.zip
Merge remote-tracking branch 'origin/released'
* origin/released: mesa pixman xserver xkeyboard-config Conflicts: xorg-server/dix/dispatch.c
Diffstat (limited to 'mesalib/src/glsl/link_functions.cpp')
-rw-r--r--mesalib/src/glsl/link_functions.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp
index 6b3e15448..dd6f24716 100644
--- a/mesalib/src/glsl/link_functions.cpp
+++ b/mesalib/src/glsl/link_functions.cpp
@@ -173,6 +173,38 @@ public:
return visit_continue;
}
+ virtual ir_visitor_status visit_leave(ir_call *ir)
+ {
+ /* Traverse list of function parameters, and for array parameters
+ * propagate max_array_access. Otherwise arrays that are only referenced
+ * from inside functions via function parameters will be incorrectly
+ * optimized. This will lead to incorrect code being generated (or worse).
+ * Do it when leaving the node so the children would propagate their
+ * array accesses first.
+ */
+
+ const exec_node *formal_param_node = ir->callee->parameters.get_head();
+ if (formal_param_node) {
+ const exec_node *actual_param_node = ir->actual_parameters.get_head();
+ while (!actual_param_node->is_tail_sentinel()) {
+ ir_variable *formal_param = (ir_variable *) formal_param_node;
+ ir_rvalue *actual_param = (ir_rvalue *) actual_param_node;
+
+ formal_param_node = formal_param_node->get_next();
+ actual_param_node = actual_param_node->get_next();
+
+ if (formal_param->type->is_array()) {
+ ir_dereference_variable *deref = actual_param->as_dereference_variable();
+ if (deref && deref->var && deref->var->type->is_array()) {
+ deref->var->max_array_access =
+ MAX2(formal_param->max_array_access, deref->var->max_array_access);
+ }
+ }
+ }
+ }
+ return visit_continue;
+ }
+
virtual ir_visitor_status visit(ir_dereference_variable *ir)
{
if (hash_table_find(locals, ir->var) == NULL) {