Bug Summary

File:root/firefox-clang/third_party/rust/glslopt/glsl-optimizer/src/compiler/glsl/opt_function_inlining.cpp
Warning:line 273, column 11
Branch condition evaluates to a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name opt_function_inlining.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/third_party/rust/glslopt -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/root/firefox-clang/third_party/rust/glslopt -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I glsl-optimizer/include -I glsl-optimizer/src/mesa -I glsl-optimizer/src/mapi -I glsl-optimizer/src/compiler -I glsl-optimizer/src/compiler/glsl -I glsl-optimizer/src/gallium/auxiliary -I glsl-optimizer/src/gallium/include -I glsl-optimizer/src -I glsl-optimizer/src/util -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -D MOZILLA_CONFIG_H -D __STDC_FORMAT_MACROS -D _GNU_SOURCE -D HAVE_ENDIAN_H -D HAVE_PTHREAD -D HAVE_TIMESPEC_GET -D MOZ_INCLUDE_MOZALLOC_H -D mozilla_throw_gcc_h -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-27-100320-3286336-1 -x c++ glsl-optimizer/src/compiler/glsl/opt_function_inlining.cpp
1/*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24/**
25 * \file opt_function_inlining.cpp
26 *
27 * Replaces calls to functions with the body of the function.
28 */
29
30#include "ir.h"
31#include "ir_visitor.h"
32#include "ir_function_inlining.h"
33#include "ir_expression_flattening.h"
34#include "compiler/glsl_types.h"
35#include "util/hash_table.h"
36
37static void
38do_variable_replacement(exec_list *instructions,
39 ir_variable *orig,
40 ir_dereference *repl);
41
42namespace {
43
44class ir_function_inlining_visitor : public ir_hierarchical_visitor {
45public:
46 ir_function_inlining_visitor()
47 {
48 progress = false;
49 }
50
51 virtual ~ir_function_inlining_visitor()
52 {
53 /* empty */
54 }
55
56 virtual ir_visitor_status visit_enter(ir_expression *);
57 virtual ir_visitor_status visit_enter(ir_call *);
58 virtual ir_visitor_status visit_enter(ir_return *);
59 virtual ir_visitor_status visit_enter(ir_texture *);
60 virtual ir_visitor_status visit_enter(ir_swizzle *);
61
62 bool progress;
63};
64
65class ir_save_lvalue_visitor : public ir_hierarchical_visitor {
66public:
67 virtual ir_visitor_status visit_enter(ir_dereference_array *);
68};
69
70} /* unnamed namespace */
71
72bool
73do_function_inlining(exec_list *instructions)
74{
75 ir_function_inlining_visitor v;
76
77 v.run(instructions);
78
79 return v.progress;
80}
81
82static void
83replace_return_with_assignment(ir_instruction *ir, void *data)
84{
85 void *ctx = ralloc_parent(ir);
86 ir_dereference *orig_deref = (ir_dereference *) data;
87 ir_return *ret = ir->as_return();
88
89 if (ret) {
90 if (ret->value) {
91 ir_rvalue *lhs = orig_deref->clone(ctx, NULL__null);
92 ret->replace_with(new(ctx) ir_assignment(lhs, ret->value));
93 } else {
94 /* un-valued return has to be the last return, or we shouldn't
95 * have reached here. (see can_inline()).
96 */
97 assert(ret->next->is_tail_sentinel())(static_cast <bool> (ret->next->is_tail_sentinel(
)) ? void (0) : __assert_fail ("ret->next->is_tail_sentinel()"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
98 ret->remove();
99 }
100 }
101}
102
103/* Save the given lvalue before the given instruction.
104 *
105 * This is done by adding temporary variables into which the current value
106 * of any array indices are saved, and then modifying the dereference chain
107 * in-place to point to those temporary variables.
108 *
109 * The hierarchical visitor is only used to traverse the left-hand-side chain
110 * of derefs.
111 */
112ir_visitor_status
113ir_save_lvalue_visitor::visit_enter(ir_dereference_array *deref)
114{
115 if (deref->array_index->ir_type != ir_type_constant) {
116 void *ctx = ralloc_parent(deref);
117 ir_variable *index;
118 ir_assignment *assignment;
119
120 index = new(ctx) ir_variable(deref->array_index->type, "saved_idx", ir_var_temporary);
121 base_ir->insert_before(index);
122
123 assignment = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(index),
124 deref->array_index);
125 base_ir->insert_before(assignment);
126
127 deref->array_index = new(ctx) ir_dereference_variable(index);
128 }
129
130 deref->array->accept(this);
131 return visit_stop;
132}
133
134static bool
135should_replace_variable(ir_variable *sig_param, ir_rvalue *param) {
136 /* For opaque types, we want the inlined variable references
137 * referencing the passed in variable, since that will have
138 * the location information, which an assignment of an opaque
139 * variable wouldn't.
140 */
141 return sig_param->type->contains_opaque() &&
142 param->is_dereference() &&
143 sig_param->data.mode == ir_var_function_in;
144}
145
146void
147ir_call::generate_inline(ir_instruction *next_ir)
148{
149 void *ctx = ralloc_parent(this);
150 ir_variable **parameters;
151 unsigned num_parameters;
152 int i;
153 struct hash_table *ht;
154
155 ht = _mesa_pointer_hash_table_create(NULL__null);
156
157 num_parameters = this->callee->parameters.length();
158 parameters = new ir_variable *[num_parameters];
4
Storing uninitialized value
159
160 /* Generate the declarations for the parameters to our inlined code,
161 * and set up the mapping of real function body variables to ours.
162 */
163 i = 0;
164 foreach_two_lists(formal_node, &this->callee->parameters,for (struct exec_node * formal_node = (&this->callee->
parameters)->head_sentinel.next, * actual_node = (&this
->actual_parameters)->head_sentinel.next, * __next1 = formal_node
->next, * __next2 = actual_node->next ; __next1 != __null
&& __next2 != __null ; formal_node = __next1, actual_node
= __next2, __next1 = __next1->next, __next2 = __next2->
next)
5
Assuming the condition is true
6
Loop condition is true. Entering loop body
165 actual_node, &this->actual_parameters)for (struct exec_node * formal_node = (&this->callee->
parameters)->head_sentinel.next, * actual_node = (&this
->actual_parameters)->head_sentinel.next, * __next1 = formal_node
->next, * __next2 = actual_node->next ; __next1 != __null
&& __next2 != __null ; formal_node = __next1, actual_node
= __next2, __next1 = __next1->next, __next2 = __next2->
next)
{
166 ir_variable *sig_param = (ir_variable *) formal_node;
167 ir_rvalue *param = (ir_rvalue *) actual_node;
168
169 /* Generate a new variable for the parameter. */
170 if (should_replace_variable(sig_param, param)) {
7
Taking false branch
171 /* Actual replacement happens below */
172 parameters[i] = NULL__null;
173 } else {
174 parameters[i] = sig_param->clone(ctx, ht);
175 parameters[i]->data.mode = ir_var_temporary;
176
177 /* Remove the read-only decoration because we're going to write
178 * directly to this variable. If the cloned variable is left
179 * read-only and the inlined function is inside a loop, the loop
180 * analysis code will get confused.
181 */
182 parameters[i]->data.read_only = false;
183 next_ir->insert_before(parameters[i]);
184 }
185
186 /* Section 6.1.1 (Function Calling Conventions) of the OpenGL Shading
187 * Language 4.5 spec says:
188 *
189 * "All arguments are evaluated at call time, exactly once, in order,
190 * from left to right. [...] Evaluation of an out parameter results
191 * in an l-value that is used to copy out a value when the function
192 * returns."
193 *
194 * I.e., we have to take temporary copies of any relevant array indices
195 * before the function body is executed.
196 *
197 * This ensures that
198 * (a) if an array index expressions refers to a variable that is
199 * modified by the execution of the function body, we use the
200 * original value as intended, and
201 * (b) if an array index expression has side effects, those side effects
202 * are only executed once and at the right time.
203 */
204 if (parameters[i]) {
205 if (sig_param->data.mode == ir_var_function_in ||
8
Assuming field 'mode' is equal to ir_var_function_in
206 sig_param->data.mode == ir_var_const_in) {
207 ir_assignment *assign;
208
209 assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
210 param);
211 next_ir->insert_before(assign);
212 } else {
213 assert(sig_param->data.mode == ir_var_function_out ||(static_cast <bool> (sig_param->data.mode == ir_var_function_out
|| sig_param->data.mode == ir_var_function_inout) ? void (
0) : __assert_fail ("sig_param->data.mode == ir_var_function_out || sig_param->data.mode == ir_var_function_inout"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
214 sig_param->data.mode == ir_var_function_inout)(static_cast <bool> (sig_param->data.mode == ir_var_function_out
|| sig_param->data.mode == ir_var_function_inout) ? void (
0) : __assert_fail ("sig_param->data.mode == ir_var_function_out || sig_param->data.mode == ir_var_function_inout"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
215 assert(param->is_lvalue())(static_cast <bool> (param->is_lvalue()) ? void (0) :
__assert_fail ("param->is_lvalue()", __builtin_FILE (), __builtin_LINE
(), __extension__ __PRETTY_FUNCTION__))
;
216
217 ir_save_lvalue_visitor v;
218 v.base_ir = next_ir;
219
220 param->accept(&v);
221
222 if (sig_param->data.mode == ir_var_function_inout) {
223 ir_assignment *assign;
224
225 assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
226 param->clone(ctx, NULL__null)->as_rvalue());
227 next_ir->insert_before(assign);
228 }
229 }
230 }
231
232 ++i;
233 }
234
235 exec_list new_instructions;
236
237 /* Generate the inlined body of the function to a new list */
238 foreach_in_list(ir_instruction, ir, &callee->body)for (ir_instruction *ir = (!exec_node_is_tail_sentinel((&
callee->body)->head_sentinel.next) ? (ir_instruction *)
((&callee->body)->head_sentinel.next) : __null); (
ir) != __null; (ir) = (!exec_node_is_tail_sentinel((ir)->next
) ? (ir_instruction *) ((ir)->next) : __null))
{
9
'?' condition is false
10
Loop condition is false. Execution continues on line 248
239 ir_instruction *new_ir = ir->clone(ctx, ht);
240
241 new_instructions.push_tail(new_ir);
242 visit_tree(new_ir, replace_return_with_assignment, this->return_deref);
243 }
244
245 /* If any opaque types were passed in, replace any deref of the
246 * opaque variable with a deref of the argument.
247 */
248 foreach_two_lists(formal_node, &this->callee->parameters,for (struct exec_node * formal_node = (&this->callee->
parameters)->head_sentinel.next, * actual_node = (&this
->actual_parameters)->head_sentinel.next, * __next1 = formal_node
->next, * __next2 = actual_node->next ; __next1 != __null
&& __next2 != __null ; formal_node = __next1, actual_node
= __next2, __next1 = __next1->next, __next2 = __next2->
next)
11
Assuming the condition is true
12
Assuming the condition is true
13
Loop condition is true. Entering loop body
15
Assuming the condition is true
16
Assuming the condition is true
17
Loop condition is true. Entering loop body
19
Assuming the condition is false
249 actual_node, &this->actual_parameters)for (struct exec_node * formal_node = (&this->callee->
parameters)->head_sentinel.next, * actual_node = (&this
->actual_parameters)->head_sentinel.next, * __next1 = formal_node
->next, * __next2 = actual_node->next ; __next1 != __null
&& __next2 != __null ; formal_node = __next1, actual_node
= __next2, __next1 = __next1->next, __next2 = __next2->
next)
{
250 ir_rvalue *const param = (ir_rvalue *) actual_node;
251 ir_variable *sig_param = (ir_variable *) formal_node;
252
253 if (should_replace_variable(sig_param, param)) {
14
Taking false branch
18
Taking false branch
254 ir_dereference *deref = param->as_dereference();
255
256 do_variable_replacement(&new_instructions, sig_param, deref);
257 }
258 }
259
260 /* Now push those new instructions in. */
261 next_ir->insert_before(&new_instructions);
262
263 /* Copy back the value of any 'out' parameters from the function body
264 * variables to our own.
265 */
266 i = 0;
267 foreach_two_lists(formal_node, &this->callee->parameters,for (struct exec_node * formal_node = (&this->callee->
parameters)->head_sentinel.next, * actual_node = (&this
->actual_parameters)->head_sentinel.next, * __next1 = formal_node
->next, * __next2 = actual_node->next ; __next1 != __null
&& __next2 != __null ; formal_node = __next1, actual_node
= __next2, __next1 = __next1->next, __next2 = __next2->
next)
20
Loop condition is true. Entering loop body
25
Loop condition is true. Entering loop body
268 actual_node, &this->actual_parameters)for (struct exec_node * formal_node = (&this->callee->
parameters)->head_sentinel.next, * actual_node = (&this
->actual_parameters)->head_sentinel.next, * __next1 = formal_node
->next, * __next2 = actual_node->next ; __next1 != __null
&& __next2 != __null ; formal_node = __next1, actual_node
= __next2, __next1 = __next1->next, __next2 = __next2->
next)
{
269 ir_rvalue *const param = (ir_rvalue *) actual_node;
270 const ir_variable *const sig_param = (ir_variable *) formal_node;
271
272 /* Move our param variable into the actual param if it's an 'out' type. */
273 if (parameters[i] && (sig_param->data.mode == ir_var_function_out ||
21
Assuming field 'mode' is not equal to ir_var_function_out
23
Taking false branch
26
Branch condition evaluates to a garbage value
274 sig_param->data.mode == ir_var_function_inout)) {
22
Assuming field 'mode' is not equal to ir_var_function_inout
275 ir_assignment *assign;
276
277 assign = new(ctx) ir_assignment(param,
278 new(ctx) ir_dereference_variable(parameters[i]));
279 next_ir->insert_before(assign);
280 }
281
282 ++i;
24
The value 1 is assigned to 'i'
283 }
284
285 delete [] parameters;
286
287 _mesa_hash_table_destroy(ht, NULL__null);
288}
289
290
291ir_visitor_status
292ir_function_inlining_visitor::visit_enter(ir_expression *ir)
293{
294 (void) ir;
295 return visit_continue_with_parent;
296}
297
298
299ir_visitor_status
300ir_function_inlining_visitor::visit_enter(ir_return *ir)
301{
302 (void) ir;
303 return visit_continue_with_parent;
304}
305
306
307ir_visitor_status
308ir_function_inlining_visitor::visit_enter(ir_texture *ir)
309{
310 (void) ir;
311 return visit_continue_with_parent;
312}
313
314
315ir_visitor_status
316ir_function_inlining_visitor::visit_enter(ir_swizzle *ir)
317{
318 (void) ir;
319 return visit_continue_with_parent;
320}
321
322
323ir_visitor_status
324ir_function_inlining_visitor::visit_enter(ir_call *ir)
325{
326 if (can_inline(ir)) {
1
Assuming the condition is true
2
Taking true branch
327 ir->generate_inline(ir);
3
Calling 'ir_call::generate_inline'
328 ir->remove();
329 this->progress = true;
330 }
331
332 return visit_continue;
333}
334
335
336/**
337 * Replaces references to the "orig" variable with a clone of "repl."
338 *
339 * From the spec, opaque types can appear in the tree as function
340 * (non-out) parameters and as the result of array indexing and
341 * structure field selection. In our builtin implementation, they
342 * also appear in the sampler field of an ir_tex instruction.
343 */
344
345class ir_variable_replacement_visitor : public ir_hierarchical_visitor {
346public:
347 ir_variable_replacement_visitor(ir_variable *orig, ir_dereference *repl)
348 {
349 this->orig = orig;
350 this->repl = repl;
351 }
352
353 virtual ~ir_variable_replacement_visitor()
354 {
355 }
356
357 virtual ir_visitor_status visit_leave(ir_call *);
358 virtual ir_visitor_status visit_leave(ir_dereference_array *);
359 virtual ir_visitor_status visit_leave(ir_dereference_record *);
360 virtual ir_visitor_status visit_leave(ir_texture *);
361 virtual ir_visitor_status visit_leave(ir_assignment *);
362 virtual ir_visitor_status visit_leave(ir_expression *);
363 virtual ir_visitor_status visit_leave(ir_return *);
364
365 void replace_deref(ir_dereference **deref);
366 void replace_rvalue(ir_rvalue **rvalue);
367
368 ir_variable *orig;
369 ir_dereference *repl;
370};
371
372void
373ir_variable_replacement_visitor::replace_deref(ir_dereference **deref)
374{
375 ir_dereference_variable *deref_var = (*deref)->as_dereference_variable();
376 if (deref_var && deref_var->var == this->orig) {
377 *deref = this->repl->clone(ralloc_parent(*deref), NULL__null);
378 }
379}
380
381void
382ir_variable_replacement_visitor::replace_rvalue(ir_rvalue **rvalue)
383{
384 if (!*rvalue)
385 return;
386
387 ir_dereference *deref = (*rvalue)->as_dereference();
388
389 if (!deref)
390 return;
391
392 replace_deref(&deref);
393 *rvalue = deref;
394}
395
396ir_visitor_status
397ir_variable_replacement_visitor::visit_leave(ir_texture *ir)
398{
399 replace_deref(&ir->sampler);
400
401 return visit_continue;
402}
403
404ir_visitor_status
405ir_variable_replacement_visitor::visit_leave(ir_assignment *ir)
406{
407 replace_deref(&ir->lhs);
408 replace_rvalue(&ir->rhs);
409
410 return visit_continue;
411}
412
413ir_visitor_status
414ir_variable_replacement_visitor::visit_leave(ir_expression *ir)
415{
416 for (uint8_t i = 0; i < ir->num_operands; i++)
417 replace_rvalue(&ir->operands[i]);
418
419 return visit_continue;
420}
421
422ir_visitor_status
423ir_variable_replacement_visitor::visit_leave(ir_return *ir)
424{
425 replace_rvalue(&ir->value);
426
427 return visit_continue;
428}
429
430ir_visitor_status
431ir_variable_replacement_visitor::visit_leave(ir_dereference_array *ir)
432{
433 replace_rvalue(&ir->array);
434 return visit_continue;
435}
436
437ir_visitor_status
438ir_variable_replacement_visitor::visit_leave(ir_dereference_record *ir)
439{
440 replace_rvalue(&ir->record);
441 return visit_continue;
442}
443
444ir_visitor_status
445ir_variable_replacement_visitor::visit_leave(ir_call *ir)
446{
447 foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters)for (ir_rvalue *param = (!exec_node_is_tail_sentinel((&ir
->actual_parameters)->head_sentinel.next) ? (ir_rvalue *
) ((&ir->actual_parameters)->head_sentinel.next) : __null
), *__next = (param) ? (!exec_node_is_tail_sentinel((&ir->
actual_parameters)->head_sentinel.next->next) ? (ir_rvalue
*) ((&ir->actual_parameters)->head_sentinel.next->
next) : __null) : __null; (param) != __null; (param) = __next
, __next = __next ? (!exec_node_is_tail_sentinel(__next->next
) ? (ir_rvalue *) (__next->next) : __null) : __null)
{
448 ir_rvalue *new_param = param;
449 replace_rvalue(&new_param);
450
451 if (new_param != param) {
452 param->replace_with(new_param);
453 }
454 }
455 return visit_continue;
456}
457
458static void
459do_variable_replacement(exec_list *instructions,
460 ir_variable *orig,
461 ir_dereference *repl)
462{
463 ir_variable_replacement_visitor v(orig, repl);
464
465 visit_list_elements(&v, instructions);
466}