Coverage Report

Created: 2026-06-13 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/Zend/Optimizer/escape_analysis.c
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend OPcache, Escape Analysis                                        |
4
   +----------------------------------------------------------------------+
5
   | Copyright © The PHP Group and Contributors.                          |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to the Modified BSD License that is      |
8
   | bundled with this package in the file LICENSE, and is available      |
9
   | through the World Wide Web at <https://www.php.net/license/>.        |
10
   |                                                                      |
11
   | SPDX-License-Identifier: BSD-3-Clause                                |
12
   +----------------------------------------------------------------------+
13
   | Authors: Dmitry Stogov <dmitry@php.net>                              |
14
   +----------------------------------------------------------------------+
15
*/
16
17
#include "Optimizer/zend_optimizer.h"
18
#include "Optimizer/zend_optimizer_internal.h"
19
#include "zend_bitset.h"
20
#include "zend_cfg.h"
21
#include "zend_ssa.h"
22
#include "zend_inference.h"
23
#include "zend_dump.h"
24
25
/*
26
 * T. Kotzmann and H. Mossenbock. Escape analysis  in the context of dynamic
27
 * compilation and deoptimization. In Proceedings of the International
28
 * Conference on Virtual Execution Environments, pages 111-120, Chicago,
29
 * June 2005
30
 */
31
32
static zend_always_inline void union_find_init(int *parent, int *size, int count) /* {{{ */
33
11.3k
{
34
11.3k
  int i;
35
36
435k
  for (i = 0; i < count; i++) {
37
424k
    parent[i] = i;
38
424k
    size[i] = 1;
39
424k
  }
40
11.3k
}
41
/* }}} */
42
43
static zend_always_inline int union_find_root(int *parent, int i) /* {{{ */
44
870k
{
45
870k
  int p = parent[i];
46
47
1.20M
  while (i != p) {
48
333k
    p = parent[p];
49
333k
    parent[i] = p;
50
333k
    i = p;
51
333k
    p = parent[i];
52
333k
  }
53
870k
  return i;
54
870k
}
55
/* }}} */
56
57
static zend_always_inline void union_find_unite(int *parent, int *size, int i, int j) /* {{{ */
58
223k
{
59
223k
  int r1 = union_find_root(parent, i);
60
223k
  int r2 = union_find_root(parent, j);
61
62
223k
  if (r1 != r2) {
63
162k
    if (size[r1] < size[r2]) {
64
76.5k
      parent[r1] = r2;
65
76.5k
      size[r2] += size[r1];
66
86.2k
    } else {
67
86.2k
      parent[r2] = r1;
68
86.2k
      size[r1] += size[r2];
69
86.2k
    }
70
162k
  }
71
223k
}
72
/* }}} */
73
74
static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_array, zend_ssa *ssa) /* {{{ */
75
11.3k
{
76
11.3k
  zend_ssa_var *ssa_vars = ssa->vars;
77
11.3k
  int ssa_vars_count = ssa->vars_count;
78
11.3k
  zend_ssa_phi *p;
79
11.3k
  int i;
80
11.3k
  int *size;
81
11.3k
  ALLOCA_FLAG(use_heap)
82
83
11.3k
  size = do_alloca(sizeof(int) * ssa_vars_count, use_heap);
84
11.3k
  if (!size) {
85
0
    return FAILURE;
86
0
  }
87
11.3k
  union_find_init(parent, size, ssa_vars_count);
88
89
435k
  for (i = 0; i < ssa_vars_count; i++) {
90
424k
    if (ssa_vars[i].definition_phi) {
91
64.7k
      p = ssa_vars[i].definition_phi;
92
64.7k
      if (p->pi >= 0) {
93
17.8k
        union_find_unite(parent, size, i, p->sources[0]);
94
46.8k
      } else {
95
144k
        for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
96
97.5k
          union_find_unite(parent, size, i, p->sources[j]);
97
97.5k
        }
98
46.8k
      }
99
359k
    } else if (ssa_vars[i].definition >= 0) {
100
322k
      int def = ssa_vars[i].definition;
101
322k
      zend_ssa_op *op = ssa->ops + def;
102
322k
      zend_op *opline =  op_array->opcodes + def;
103
104
322k
      if (op->op1_def >= 0) {
105
75.8k
        if (op->op1_use >= 0) {
106
75.8k
          if (opline->opcode != ZEND_ASSIGN) {
107
38.4k
            union_find_unite(parent, size, op->op1_def, op->op1_use);
108
38.4k
          }
109
75.8k
        }
110
75.8k
        if (opline->opcode == ZEND_ASSIGN && op->op2_use >= 0) {
111
26.5k
          union_find_unite(parent, size, op->op1_def, op->op2_use);
112
26.5k
        }
113
75.8k
      }
114
322k
      if (op->op2_def >= 0) {
115
5.51k
        if (op->op2_use >= 0) {
116
5.19k
          union_find_unite(parent, size, op->op2_def, op->op2_use);
117
5.19k
        }
118
5.51k
      }
119
322k
      if (op->result_def >= 0) {
120
273k
        if (op->result_use >= 0) {
121
16.0k
          if (opline->opcode != ZEND_QM_ASSIGN) {
122
16.0k
            union_find_unite(parent, size, op->result_def, op->result_use);
123
16.0k
          }
124
16.0k
        }
125
273k
        if (opline->opcode == ZEND_QM_ASSIGN && op->op1_use >= 0) {
126
1.59k
          union_find_unite(parent, size, op->result_def, op->op1_use);
127
1.59k
        }
128
273k
        if (opline->opcode == ZEND_ASSIGN && op->op2_use >= 0) {
129
9.42k
          union_find_unite(parent, size, op->result_def, op->op2_use);
130
9.42k
        }
131
273k
        if (opline->opcode == ZEND_ASSIGN && op->op1_def >= 0) {
132
10.6k
          union_find_unite(parent, size, op->result_def, op->op1_def);
133
10.6k
        }
134
273k
      }
135
322k
    }
136
424k
  }
137
138
435k
  for (i = 0; i < ssa_vars_count; i++) {
139
424k
    parent[i] = union_find_root(parent, i);
140
424k
  }
141
142
11.3k
  free_alloca(size, use_heap);
143
144
11.3k
  return SUCCESS;
145
11.3k
}
146
/* }}} */
147
148
static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */
149
256k
{
150
256k
  zend_ssa_op *ssa_op = ssa->ops + def;
151
256k
  zend_op *opline = op_array->opcodes + def;
152
153
256k
  if (ssa_op->result_def == var) {
154
191k
    switch (opline->opcode) {
155
5.76k
      case ZEND_INIT_ARRAY:
156
5.76k
        return true;
157
24.1k
      case ZEND_NEW: {
158
          /* objects with destructors should escape */
159
24.1k
        zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
160
24.1k
          script, op_array, opline);
161
24.1k
        uint32_t forbidden_flags =
162
          /* These flags will always cause an exception */
163
24.1k
          ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
164
24.1k
          | ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT;
165
24.1k
        if (ce
166
21.3k
         && !ce->parent
167
19.5k
         && !ce->create_object
168
14.8k
         && ce->default_object_handlers->get_constructor == zend_std_get_constructor
169
14.8k
         && ce->default_object_handlers->dtor_obj == zend_objects_destroy_object
170
14.8k
         && !ce->constructor
171
12.9k
         && !ce->destructor
172
11.6k
         && !ce->__get
173
11.2k
         && !ce->__set
174
11.1k
         && !(ce->ce_flags & forbidden_flags)
175
11.1k
         && (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
176
11.0k
          return true;
177
11.0k
        }
178
13.1k
        break;
179
24.1k
      }
180
13.1k
      case ZEND_QM_ASSIGN:
181
1.08k
        if (opline->op1_type == IS_CONST
182
22
         && Z_TYPE_P(CRT_CONSTANT(opline->op1)) == IS_ARRAY) {
183
22
          return true;
184
22
        }
185
1.06k
        if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_ARRAY)) {
186
285
          return true;
187
285
        }
188
777
        break;
189
777
      case ZEND_ASSIGN:
190
591
        if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_ARRAY)) {
191
233
          return true;
192
233
        }
193
358
        break;
194
191k
    }
195
191k
  } else if (ssa_op->op1_def == var) {
196
62.7k
    switch (opline->opcode) {
197
37.0k
      case ZEND_ASSIGN:
198
37.0k
        if (opline->op2_type == IS_CONST
199
17.0k
         && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_ARRAY) {
200
6.89k
          return true;
201
6.89k
        }
202
30.1k
        if (opline->op2_type == IS_CV && (OP2_INFO() & MAY_BE_ARRAY)) {
203
708
          return true;
204
708
        }
205
29.4k
        break;
206
29.4k
      case ZEND_ASSIGN_DIM:
207
2.79k
        if (OP1_INFO() & (MAY_BE_UNDEF | MAY_BE_NULL | MAY_BE_FALSE)) {
208
          /* implicit object/array allocation */
209
2.72k
          return true;
210
2.72k
        }
211
68
        break;
212
62.7k
    }
213
62.7k
  }
214
215
229k
  return false;
216
256k
}
217
/* }}} */
218
219
static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */
220
122k
{
221
122k
  zend_ssa_op *op = ssa->ops + def;
222
122k
  zend_op *opline = op_array->opcodes + def;
223
224
122k
  if (op->result_def == var) {
225
91.3k
    switch (opline->opcode) {
226
3.80k
      case ZEND_INIT_ARRAY:
227
19.5k
      case ZEND_ADD_ARRAY_ELEMENT:
228
19.9k
      case ZEND_QM_ASSIGN:
229
20.4k
      case ZEND_ASSIGN:
230
20.4k
        return true;
231
10.1k
      case ZEND_NEW: {
232
        /* objects with destructors should escape */
233
10.1k
        zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
234
10.1k
          script, op_array, opline);
235
10.1k
        if (ce
236
9.26k
         && !ce->create_object
237
7.77k
         && ce->default_object_handlers->get_constructor == zend_std_get_constructor
238
7.77k
         && ce->default_object_handlers->dtor_obj == zend_objects_destroy_object
239
7.77k
         && !ce->constructor
240
7.25k
         && !ce->destructor
241
7.02k
         && !ce->__get
242
6.97k
         && !ce->__set
243
6.96k
         && !ce->parent) {
244
6.72k
          return true;
245
6.72k
        }
246
3.41k
        break;
247
10.1k
      }
248
91.3k
    }
249
91.3k
  } else if (op->op1_def == var) {
250
29.0k
    switch (opline->opcode) {
251
14.4k
      case ZEND_ASSIGN:
252
19.2k
      case ZEND_ASSIGN_DIM:
253
21.3k
      case ZEND_ASSIGN_OBJ:
254
21.3k
      case ZEND_ASSIGN_OBJ_REF:
255
21.6k
      case ZEND_ASSIGN_DIM_OP:
256
21.7k
      case ZEND_ASSIGN_OBJ_OP:
257
21.8k
      case ZEND_PRE_INC_OBJ:
258
21.8k
      case ZEND_PRE_DEC_OBJ:
259
21.8k
      case ZEND_POST_INC_OBJ:
260
21.9k
      case ZEND_POST_DEC_OBJ:
261
21.9k
        return true;
262
29.0k
    }
263
29.0k
  }
264
265
73.6k
  return false;
266
122k
}
267
/* }}} */
268
269
static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int var) /* {{{ */
270
25.1k
{
271
25.1k
  zend_ssa_op *ssa_op = ssa->ops + use;
272
25.1k
  zend_op *opline = op_array->opcodes + use;
273
274
25.1k
  if (ssa_op->op1_use == var) {
275
14.7k
    switch (opline->opcode) {
276
699
      case ZEND_ASSIGN:
277
        /* no_val */
278
699
        break;
279
199
      case ZEND_QM_ASSIGN:
280
199
        if (opline->op1_type == IS_CV) {
281
199
          if (OP1_INFO() & MAY_BE_OBJECT) {
282
            /* object aliasing */
283
187
            return true;
284
187
          }
285
199
        }
286
12
        break;
287
86
      case ZEND_ISSET_ISEMPTY_DIM_OBJ:
288
110
      case ZEND_ISSET_ISEMPTY_PROP_OBJ:
289
1.68k
      case ZEND_FETCH_DIM_R:
290
1.82k
      case ZEND_FETCH_OBJ_R:
291
2.29k
      case ZEND_FETCH_DIM_IS:
292
2.30k
      case ZEND_FETCH_OBJ_IS:
293
2.30k
        break;
294
0
      case ZEND_ASSIGN_OP:
295
0
        return true;
296
60
      case ZEND_ASSIGN_DIM_OP:
297
114
      case ZEND_ASSIGN_OBJ_OP:
298
114
      case ZEND_ASSIGN_STATIC_PROP_OP:
299
4.34k
      case ZEND_ASSIGN_DIM:
300
4.88k
      case ZEND_ASSIGN_OBJ:
301
4.91k
      case ZEND_ASSIGN_OBJ_REF:
302
4.91k
        break;
303
4
      case ZEND_PRE_INC_OBJ:
304
12
      case ZEND_PRE_DEC_OBJ:
305
16
      case ZEND_POST_INC_OBJ:
306
16
      case ZEND_POST_DEC_OBJ:
307
16
        break;
308
365
      case ZEND_INIT_ARRAY:
309
929
      case ZEND_ADD_ARRAY_ELEMENT:
310
929
        if (opline->extended_value & ZEND_ARRAY_ELEMENT_REF) {
311
0
          return true;
312
0
        }
313
929
        if (OP1_INFO() & MAY_BE_OBJECT) {
314
          /* object aliasing */
315
547
          return true;
316
547
        }
317
        /* reference dependencies processed separately */
318
382
        break;
319
786
      case ZEND_OP_DATA:
320
786
        if ((opline-1)->opcode != ZEND_ASSIGN_DIM
321
607
         && (opline-1)->opcode != ZEND_ASSIGN_OBJ) {
322
82
          return true;
323
82
        }
324
704
        if (OP1_INFO() & MAY_BE_OBJECT) {
325
          /* object aliasing */
326
581
          return true;
327
581
        }
328
123
        opline--;
329
123
        ssa_op--;
330
123
        if (opline->op1_type != IS_CV
331
97
         || (OP1_INFO() & MAY_BE_REF)
332
89
         || (ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].alias)) {
333
          /* assignment into escaping structure */
334
89
          return true;
335
89
        }
336
        /* reference dependencies processed separately */
337
34
        break;
338
4.86k
      default:
339
4.86k
        return true;
340
14.7k
    }
341
14.7k
  }
342
343
18.7k
  if (ssa_op->op2_use == var) {
344
4.89k
    switch (opline->opcode) {
345
4.33k
      case ZEND_ASSIGN:
346
4.33k
        if (opline->op1_type != IS_CV
347
4.29k
         || (OP1_INFO() & MAY_BE_REF)
348
3.31k
         || (ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].alias)) {
349
          /* assignment into escaping variable */
350
3.31k
          return true;
351
3.31k
        }
352
1.01k
        if (opline->op2_type == IS_CV || opline->result_type != IS_UNUSED) {
353
136
          if (OP2_INFO() & MAY_BE_OBJECT) {
354
            /* object aliasing */
355
96
            return true;
356
96
          }
357
136
        }
358
921
        break;
359
921
      default:
360
560
        return true;
361
4.89k
    }
362
4.89k
  }
363
364
14.8k
  if (ssa_op->result_use == var) {
365
5.52k
    switch (opline->opcode) {
366
0
      case ZEND_ASSIGN:
367
0
      case ZEND_QM_ASSIGN:
368
0
      case ZEND_INIT_ARRAY:
369
5.52k
      case ZEND_ADD_ARRAY_ELEMENT:
370
5.52k
        break;
371
0
      default:
372
0
        return true;
373
5.52k
    }
374
5.52k
  }
375
376
14.8k
  return false;
377
14.8k
}
378
/* }}} */
379
380
zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa) /* {{{ */
381
72.4k
{
382
72.4k
  zend_ssa_var *ssa_vars = ssa->vars;
383
72.4k
  int ssa_vars_count = ssa->vars_count;
384
72.4k
  int i, root, use;
385
72.4k
  int *ees;
386
72.4k
  bool has_allocations;
387
72.4k
  int num_non_escaped;
388
72.4k
  ALLOCA_FLAG(use_heap)
389
390
72.4k
  if (!ssa_vars) {
391
0
    return SUCCESS;
392
0
  }
393
394
72.4k
  has_allocations = false;
395
830k
  for (i = op_array->last_var; i < ssa_vars_count; i++) {
396
768k
    if (ssa_vars[i].definition >= 0
397
666k
      && (ssa->var_info[i].type & (MAY_BE_ARRAY|MAY_BE_OBJECT))
398
235k
      && is_allocation_def(op_array, ssa, ssa_vars[i].definition, i, script)) {
399
11.3k
      has_allocations = true;
400
11.3k
      break;
401
11.3k
    }
402
768k
  }
403
72.4k
  if (!has_allocations) {
404
61.1k
    return SUCCESS;
405
61.1k
  }
406
407
408
  /* 1. Build EES (Equi-Escape Sets) */
409
11.3k
  ees = do_alloca(sizeof(int) * ssa_vars_count, use_heap);
410
11.3k
  if (!ees) {
411
0
    return FAILURE;
412
0
  }
413
414
11.3k
  if (zend_build_equi_escape_sets(ees, op_array, ssa) == FAILURE) {
415
0
    free_alloca(ees, use_heap);
416
0
    return FAILURE;
417
0
  }
418
419
  /* 2. Identify Allocations */
420
11.3k
  num_non_escaped = 0;
421
398k
  for (i = op_array->last_var; i < ssa_vars_count; i++) {
422
387k
    root = ees[i];
423
387k
    if (ssa_vars[root].escape_state > ESCAPE_STATE_NO_ESCAPE) {
424
      /* already escape. skip */
425
341k
    } else if (ssa_vars[i].alias && (ssa->var_info[i].type & MAY_BE_REF)) {
426
0
      if (ssa_vars[root].escape_state == ESCAPE_STATE_NO_ESCAPE) {
427
0
        num_non_escaped--;
428
0
      }
429
0
      ssa_vars[root].escape_state = ESCAPE_STATE_GLOBAL_ESCAPE;
430
341k
    } else if (ssa_vars[i].definition >= 0
431
294k
       && (ssa->var_info[i].type & (MAY_BE_ARRAY|MAY_BE_OBJECT))) {
432
122k
      if (!is_local_def(op_array, ssa, ssa_vars[i].definition, i, script)) {
433
73.6k
        if (ssa_vars[root].escape_state == ESCAPE_STATE_NO_ESCAPE) {
434
3.34k
          num_non_escaped--;
435
3.34k
        }
436
73.6k
        ssa_vars[root].escape_state = ESCAPE_STATE_GLOBAL_ESCAPE;
437
73.6k
      } else if (ssa_vars[root].escape_state == ESCAPE_STATE_UNKNOWN
438
21.0k
       && is_allocation_def(op_array, ssa, ssa_vars[i].definition, i, script)) {
439
16.3k
        ssa_vars[root].escape_state = ESCAPE_STATE_NO_ESCAPE;
440
16.3k
        num_non_escaped++;
441
16.3k
      }
442
122k
    }
443
387k
  }
444
445
  /* 3. Mark escaped EES */
446
11.3k
  if (num_non_escaped) {
447
253k
    for (i = 0; i < ssa_vars_count; i++) {
448
244k
      if (ssa_vars[i].use_chain >= 0) {
449
200k
        root = ees[i];
450
200k
        if (ssa_vars[root].escape_state == ESCAPE_STATE_NO_ESCAPE) {
451
48.1k
          FOREACH_USE(ssa_vars + i, use) {
452
48.1k
            if (is_escape_use(op_array, ssa, use, i)) {
453
10.3k
              ssa_vars[root].escape_state = ESCAPE_STATE_GLOBAL_ESCAPE;
454
10.3k
              num_non_escaped--;
455
10.3k
              if (num_non_escaped == 0) {
456
6.50k
                i = ssa_vars_count;
457
6.50k
              }
458
10.3k
              break;
459
10.3k
            }
460
48.1k
          } FOREACH_USE_END();
461
23.0k
        }
462
200k
      }
463
244k
    }
464
8.43k
  }
465
466
  /* 4. Process referential dependencies */
467
11.3k
  if (num_non_escaped) {
468
1.92k
    bool changed;
469
470
1.95k
    do {
471
1.95k
      changed = false;
472
94.0k
      for (i = 0; i < ssa_vars_count; i++) {
473
92.1k
        if (ssa_vars[i].use_chain >= 0) {
474
73.2k
          root = ees[i];
475
73.2k
          if (ssa_vars[root].escape_state == ESCAPE_STATE_NO_ESCAPE) {
476
15.0k
            FOREACH_USE(ssa_vars + i, use) {
477
15.0k
              zend_ssa_op *op = ssa->ops + use;
478
15.0k
              zend_op *opline = op_array->opcodes + use;
479
15.0k
              int enclosing_root;
480
481
15.0k
              if (opline->opcode == ZEND_OP_DATA &&
482
28
                  ((opline-1)->opcode == ZEND_ASSIGN_DIM ||
483
20
                   (opline-1)->opcode == ZEND_ASSIGN_OBJ ||
484
0
                   (opline-1)->opcode == ZEND_ASSIGN_OBJ_REF) &&
485
28
                  op->op1_use == i &&
486
28
                  (op-1)->op1_use >= 0) {
487
28
                enclosing_root = ees[(op-1)->op1_use];
488
8.30k
              } else if ((opline->opcode == ZEND_INIT_ARRAY ||
489
8.20k
                   opline->opcode == ZEND_ADD_ARRAY_ELEMENT) &&
490
1.76k
                  op->op1_use == i &&
491
668
                  op->result_def >= 0) {
492
668
                enclosing_root = ees[op->result_def];
493
7.63k
              } else {
494
7.63k
                continue;
495
7.63k
              }
496
497
696
              if (ssa_vars[enclosing_root].escape_state == ESCAPE_STATE_UNKNOWN ||
498
692
                  ssa_vars[enclosing_root].escape_state > ssa_vars[root].escape_state) {
499
386
                  if (ssa_vars[enclosing_root].escape_state == ESCAPE_STATE_UNKNOWN) {
500
4
                  ssa_vars[root].escape_state = ESCAPE_STATE_GLOBAL_ESCAPE;
501
382
                  } else {
502
382
                  ssa_vars[root].escape_state = ssa_vars[enclosing_root].escape_state;
503
382
                }
504
386
                if (ssa_vars[root].escape_state == ESCAPE_STATE_GLOBAL_ESCAPE) {
505
386
                  num_non_escaped--;
506
386
                  if (num_non_escaped == 0) {
507
148
                    changed = false;
508
238
                  } else {
509
238
                    changed = true;
510
238
                  }
511
386
                  break;
512
386
                } else {
513
0
                  changed = true;
514
0
                }
515
386
              }
516
696
            } FOREACH_USE_END();
517
6.67k
          }
518
73.2k
        }
519
92.1k
      }
520
1.95k
    } while (changed);
521
1.92k
  }
522
523
  /* 5. Propagate values of escape sets to variables */
524
435k
  for (i = 0; i < ssa_vars_count; i++) {
525
424k
    root = ees[i];
526
424k
    if (i != root) {
527
162k
      ssa_vars[i].escape_state = ssa_vars[root].escape_state;
528
162k
    }
529
424k
  }
530
531
11.3k
  free_alloca(ees, use_heap);
532
533
11.3k
  return SUCCESS;
534
11.3k
}
535
/* }}} */