1 /*
2  * Copyright (c) 2015-2018, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 /**
19    \file
20    \brief Functions for dealing with lexical scopes and the lifetimes
21    of scoped variables.
22 
23 
24    A lexical scope is represented by an ST_BLOCK symbol table entry. The
25    scope's ENCLFUNC field points to either the enclosing scope or the
26    containing function. Scopes have two pairs of start/end labels:
27 
28    STARTLAB / ENDLAB: These labels are only inserted when generating debug
29    info. The are tagged as volatile so they won't be removed, and they can be
30    used to generate complete DWARF lexical scope information.
31 
32    BEGINSCOPELAB / ENDSCOPELAB: These labels are inserted in-stream as ilts
33    with an IL_LABEL instruction. The corresponding ST_LABEL symbol table
34    entries are tagged with the corresponding BEGINSCOPE / ENDSCOPE flags, and
35    the ENCLFUNC field points back to the ST_BLOCK entry.
36 
37    Every local variable has a scope indicated by its ENCLFUNC field. Variables
38    with function scope point to the function's symbol table entry instead of an
39    ST_BLOCK entry.
40 */
41 
42 #include "scope.h"
43 #include "error.h"
44 #include "global.h"
45 #include "ilm.h"
46 #include "ilmtp.h"
47 #include "ili.h"
48 #include "go.h"
49 #include "scope.h"
50 #include "flang/ADT/hash.h"
51 #include "symfun.h"
52 
53 /* For addlabel(). */
54 #include "semant.h"
55 
56 #define VALIDSYM(sptr) ((sptr) > NOSYM && (sptr) < stb.stg_avail)
57 
58 /**
59    \brief Is sptr a symbol table entry that can be the root of a scope
60    tree?  For C, this is functions. For Fortran, this includes entries
61    and procedures.
62  */
63 static bool
is_scope_root(SPTR sptr)64 is_scope_root(SPTR sptr)
65 {
66   switch (STYPEG(sptr)) {
67   case ST_PROC:
68   case ST_ENTRY:
69     return true;
70   default:
71     return false;
72   }
73 }
74 
75 /**
76    \brief Return true if the scope 'outer' contains the scope 'inner'.
77 
78    Both outer and inner must be valid ST_BLOCK or ST_FUNC symbol table
79    entries.
80  */
81 bool
scope_contains(SPTR outer,SPTR inner)82 scope_contains(SPTR outer, SPTR inner)
83 {
84   ICHECK(VALIDSYM(outer) &&
85          (is_scope_root(outer) || STYPEG(outer) == ST_BLOCK));
86   ICHECK(VALIDSYM(inner) &&
87          (is_scope_root(inner) || STYPEG(inner) == ST_BLOCK));
88 
89   while (STYPEG(inner) == ST_BLOCK) {
90     if (inner == outer)
91       return true;
92     inner = ENCLFUNCG(inner);
93   }
94 
95   return inner == outer;
96 }
97 
98 /**
99    \brief Return true if label_sptr is a scope label.
100  */
101 bool
is_scope_label(int label_sptr)102 is_scope_label(int label_sptr)
103 {
104   if (!VALIDSYM(label_sptr) || STYPEG(label_sptr) != ST_LABEL)
105     return false;
106 
107   return BEGINSCOPEG(label_sptr) || ENDSCOPEG(label_sptr);
108 }
109 
110 /**
111    \brief Check if ilix is an IL_LABEL instruction referring to a
112    scope label.
113  */
114 bool
is_scope_label_ili(int ilix)115 is_scope_label_ili(int ilix)
116 {
117   return ILI_OPC(ilix) == IL_LABEL && is_scope_label(ILI_OPND(ilix, 1));
118 }
119 
120 /**
121    \brief Check if the bihx basic block contains nothing but scope
122    labels (or is empty).
123  */
124 bool
is_scope_labels_only_bih(int bihx)125 is_scope_labels_only_bih(int bihx)
126 {
127   int iltx;
128 
129   for (iltx = BIH_ILTFIRST(bihx); iltx; iltx = ILT_NEXT(iltx)) {
130     if (!is_scope_label_ili(ILT_ILIP(iltx)))
131       return false;
132   }
133   return true;
134 }
135 
136 /**
137    \brief Verify the integrity of an ST_BLOCK symbol table entry and
138    its associated labels.
139  */
140 static void
verify_block(int block_sptr)141 verify_block(int block_sptr)
142 {
143   int lab;
144 
145   ICHECK(VALIDSYM(block_sptr));
146   ICHECK(STYPEG(block_sptr) == ST_BLOCK);
147 
148   /* STARTLAB and ENDLAB are not required to be present. */
149   if (STARTLABG(block_sptr)) {
150     lab = STARTLABG(block_sptr);
151     ICHECK(VALIDSYM(lab));
152     ICHECK(STYPEG(lab) == ST_LABEL);
153     ICHECK(ENCLFUNCG(lab) == block_sptr);
154 
155     /* These flags should go on the BEGINSCOPELAB / ENDSCOPELAB
156        labels, not here. */
157     ICHECK(!BEGINSCOPEG(lab));
158     ICHECK(!ENDSCOPEG(lab));
159     /* FIXME: Check ILIBLK. */
160   }
161 
162   if (ENDLABG(block_sptr)) {
163     lab = ENDLABG(block_sptr);
164     ICHECK(VALIDSYM(lab));
165     ICHECK(STYPEG(lab) == ST_LABEL);
166     ICHECK(ENCLFUNCG(lab) == block_sptr);
167     ICHECK(!BEGINSCOPEG(lab));
168     ICHECK(!ENDSCOPEG(lab));
169     /* FIXME: Check ILIBLK. */
170   }
171 
172   /* All blocks should have delineating labels. */
173   lab = BEGINSCOPELABG(block_sptr);
174   ICHECK(VALIDSYM(lab));
175   ICHECK(STYPEG(lab) == ST_LABEL);
176   ICHECK(ENCLFUNCG(lab) == block_sptr);
177   ICHECK(BEGINSCOPEG(lab));
178   ICHECK(!ENDSCOPEG(lab));
179   /* FIXME: Check ILIBLK. */
180 
181   lab = ENDSCOPELABG(block_sptr);
182   ICHECK(VALIDSYM(lab));
183   ICHECK(STYPEG(lab) == ST_LABEL);
184   ICHECK(ENCLFUNCG(lab) == block_sptr);
185   ICHECK(!BEGINSCOPEG(lab));
186   ICHECK(ENDSCOPEG(lab));
187   /* FIXME: Check ILIBLK. */
188 }
189 
190 static bool
is_local_variable(int sptr)191 is_local_variable(int sptr)
192 {
193   switch (STYPEG(sptr)) {
194   case ST_PLIST:
195   case ST_VAR:
196   case ST_ARRAY:
197   case ST_STRUCT:
198   case ST_UNION:
199     switch (SCG(sptr)) {
200     case SC_LOCAL:
201       /* Somebody who understands Fortran should probably revisit this
202          and check DINITG, SAVEG etc. */
203       return true;
204     /* Ignore SC_DUMMY. It's going to have function scope anyway. */
205     default:
206       return false;
207     }
208   default:
209     return false;
210   }
211 }
212 
213 /**
214    \brief Collect the set of locals referenced by the ILI tree starting at ilix.
215 
216    Loads and stores to local variables are always going to use an ACON
217    to compute the address, so just find all the symbols referenced by
218    ACONs.
219  */
220 static void
collect_referenced_locals(hashset_t symbs,int ilix)221 collect_referenced_locals(hashset_t symbs, int ilix)
222 {
223   ILI_OP opc = ILI_OPC(ilix);
224 
225   if (opc == IL_ACON) {
226     /* ACON opnd 1 is an ST_CONST sptr with DT_CPTR type. */
227     int sptr = CONVAL1G(ILI_OPND(ilix, 1));
228     if (sptr && is_local_variable(sptr))
229       hashset_replace(symbs, INT2HKEY(sptr));
230   } else {
231     int i;
232     for (i = IL_OPRS(opc); i > 0; i--)
233       if (IL_ISLINK(opc, i))
234         collect_referenced_locals(symbs, ILI_OPND(ilix, i));
235   }
236 }
237 
238 /* Info about a single open scope. */
239 struct scope_info {
240   /* ST_BLOCK for scope, or ST_FUNC/ST_PROC/ST_ENTRY for the function-level
241      scope. */
242   SPTR block;
243   /* The IL_LABEL ilt that closes this scope. */
244   int closing_ilt;
245 };
246 
247 /* A stack of open scopes. */
248 struct scope_stack {
249   /* scope[0..curr] are in use. */
250   int curr;
251   /* scope[0..outer] are perfectly nested. */
252   int outer;
253   /* Allocated entries in scope. */
254   int allocated;
255   struct scope_info *scope;
256   /* scope[outer].block from before closed scopes were popped. */
257   SPTR prev_top;
258 };
259 
260 /**
261    \brief Initialize a scope stack with func as the outermost scope.
262  */
263 static void
init_scope_stack(struct scope_stack * ss,SPTR func)264 init_scope_stack(struct scope_stack *ss, SPTR func)
265 {
266   ss->curr = ss->outer = 0;
267   ss->allocated = 100;
268   NEW(ss->scope, struct scope_info, ss->allocated);
269   memset(&ss->scope[0], 0, sizeof(ss->scope[0]));
270   ss->scope[0].block = func;
271   ss->prev_top = SPTR_NULL;
272 }
273 
274 static void
push_block(struct scope_stack * ss,SPTR block)275 push_block(struct scope_stack *ss, SPTR block)
276 {
277   ++ss->curr;
278   NEED(ss->curr + 1, ss->scope, struct scope_info, ss->allocated,
279        ss->allocated + 100);
280   memset(&ss->scope[ss->curr], 0, sizeof(ss->scope[0]));
281   ss->scope[ss->curr].block = block;
282   dbgprintf("  Pushing scope %d (%s) at level %d: enclfunc=%d (%s)\n", block,
283             SYMNAME(block), ss->curr, ENCLFUNCG(block),
284             SYMNAME(ENCLFUNCG(block)));
285 }
286 
287 static void
pop_block(struct scope_stack * ss)288 pop_block(struct scope_stack *ss)
289 {
290   dbgprintf("  Popping scope %d (%s) at level %d\n", ss->scope[ss->curr].block,
291             SYMNAME(ss->scope[ss->curr].block), ss->curr);
292   ICHECK(ss->curr > 0);
293   if (--ss->curr < ss->outer)
294     ss->outer = ss->curr;
295 }
296 
297 /**
298    \brief Check labels opening scopes in bih, and collect all symbols
299    referenced in this block.
300 
301    Add opened scopes to ss.
302  */
303 static void
verify_beginscopes(int bih,hashset_t locals,struct scope_stack * ss)304 verify_beginscopes(int bih, hashset_t locals, struct scope_stack *ss)
305 {
306   int ilt;
307 
308   /* All of the scopes pushed in this block must be sub-scopes of the
309      current top. */
310   SPTR outer_scope = ss->scope[ss->curr].block;
311 
312   for (ilt = BIH_ILTFIRST(bih); ilt; ilt = ILT_NEXT(ilt)) {
313     int ilix = ILT_ILIP(ilt);
314     SPTR lab, blk;
315 
316     if (ILI_OPC(ilix) != IL_LABEL) {
317       collect_referenced_locals(locals, ilix);
318       continue;
319     }
320 
321     /* This is an IL_LABEL ilt. */
322     lab = ILI_SymOPND(ilix, 1);
323     ICHECK(VALIDSYM(lab) && STYPEG(lab) == ST_LABEL);
324     if (!BEGINSCOPEG(lab))
325       continue;
326 
327     /* This is a scope-opening label. */
328     blk = ENCLFUNCG(lab);
329     verify_block(blk);
330     ICHECK(BEGINSCOPELABG(blk) == lab);
331 
332     /* If multiple scopes are pushed in the same BIH, we'll allow any
333        order. They all have to be proper sub-scopes of outer_scope,
334        though. */
335     push_block(ss, blk);
336     ICHECK((blk != outer_scope) && "Can't open the same scope twice");
337     ICHECK(scope_contains(outer_scope, blk) &&
338            "New scope is not properly nested");
339   }
340 }
341 
342 /**
343    \brief Verify a local that was referenced in the current function.
344 
345    This function conforms to the prototype expected by hashset_iterate.
346  */
347 static void
verify_local(hash_key_t key,void * context)348 verify_local(hash_key_t key, void *context)
349 {
350   int sptr = HKEY2INT(key);
351   struct scope_stack *ss = (struct scope_stack *)context;
352   SPTR encl = ENCLFUNCG(sptr);
353   int i;
354 
355 /* The Fortran frontend doesn't bother setting ENCLFUNC on local
356    variables.  Fortran doesn't have scopes anyway, except through
357    inlining. */
358   if (!encl)
359     return;
360 
361   /* Compiler-created scalar temporaries don't always have associated
362      scopes.  They will be treated as function-scope. */
363   if (!encl && CCSYMG(sptr)) {
364     dbgprintf("  Referenced local compiler-created temporary with no "
365               "scope: %d (%s)\n",
366               sptr, SYMNAME(sptr));
367     return;
368   }
369 
370   dbgprintf("  Referenced local %d (%s) from scope %d. At block %d level "
371             "%d-%d, prev %d.\n",
372             sptr, SYMNAME(sptr), encl, ss->scope[ss->curr].block, ss->outer,
373             ss->curr, ss->prev_top);
374   ICHECK(VALIDSYM(encl) && "Local variable does not have a valid scope");
375 
376   /* Now verify that the 'encl' scope is accessible in one of the
377      active scopes in the current block.
378 
379      It is possible that multiple non-overlapping scopes were pushed
380      and popped in the current basic block. When that happens, these
381      scopes will appear on the scope stack from ss->outer to
382      ss->curr. These scopes are pushed even though they are not
383      nested. They will be popped again by verify_endscopes().
384 
385      We are satisfied if encl contains any scope from this set. */
386   for (i = ss->outer; i <= ss->curr; i++) {
387     if (scope_contains(encl, ss->scope[i].block))
388       return;
389   }
390 
391   /* Finally, it is also possible that encl overlaps one of the scopes
392      that ended in the current block. ss->prev_top records the
393      innermost active scope on entry to the block.  The assertion here
394      covers the above scope containment checks too. */
395   ICHECK(scope_contains(encl, ss->prev_top) &&
396          "Local variable referenced by code outside its scope");
397 }
398 
399 /**
400    \brief Process all the scope closing labels in bih.
401 
402    Pop the closed scopes off the stack.
403  */
404 static void
verify_endscopes(int bih,struct scope_stack * ss)405 verify_endscopes(int bih, struct scope_stack *ss)
406 {
407   int ilt, i;
408   int ilix;
409   int lab, blk;
410   bool closed_last_opened;
411 
412   for (ilt = BIH_ILTFIRST(bih); ilt; ilt = ILT_NEXT(ilt)) {
413     ilix = ILT_ILIP(ilt);
414     if (ILI_OPC(ilix) != IL_LABEL)
415       continue;
416     lab = ILI_OPND(ilix, 1);
417     if (!ENDSCOPEG(lab))
418       continue;
419 
420     /* This is a scope-closing label. */
421     blk = ENCLFUNCG(lab);
422     verify_block(blk);
423     ICHECK(ENDSCOPELABG(blk) == lab);
424 
425     /* Find the scope that is being closed. It doesn't have to be the
426        topmost one. */
427     for (i = ss->curr; i > 0; i--) {
428       if (ss->scope[i].block == blk) {
429         /* We can't have duplicate labels closing the same scope. */
430         ICHECK(ss->scope[i].closing_ilt == 0);
431         ss->scope[i].closing_ilt = ilt;
432         break;
433       }
434     }
435   }
436 
437   /* Pop all the closed scopes. */
438   while (ss->scope[ss->curr].closing_ilt != 0)
439     pop_block(ss);
440 }
441 
442 /**
443    \brief Verify all of the locals referenced in the current function
444    and check the scope labels.
445  */
446 static void
verify_all_blocks(void)447 verify_all_blocks(void)
448 {
449   hashset_t locals = hashset_alloc(hash_functions_direct);
450   struct scope_stack ss = {-1, 0, 0, 0};
451   int bih;
452 
453   dbgprintf("\nVerifying scopes\n");
454   init_scope_stack(&ss, GBL_CURRFUNC);
455 
456   /* Visit basic blocks in program order. */
457   for (bih = gbl.entbih; bih; bih = BIH_NEXT(bih)) {
458     int i, j;
459 
460     ss.prev_top = ss.scope[ss.curr].block;
461     dbgprintf("block:%d in scope %d (%s)\n", bih, ss.prev_top,
462               SYMNAME(ss.prev_top));
463 
464     /* First get rid of any open scopes that are closed in this block. */
465     verify_endscopes(bih, &ss);
466 
467     /* Check labels opening scopes, collect all symbols referenced. */
468     hashset_clear(locals);
469     verify_beginscopes(bih, locals, &ss);
470 
471     /* The scope stack is now as deep as it gets in bih.  Check that
472        all referenced locals belong to a pushed scope block. */
473     hashset_iterate(locals, verify_local, &ss);
474 
475     /* Check labels closing scopes again. This takes care of scopes
476        that were opened and closed in the same block. */
477     verify_endscopes(bih, &ss);
478 
479     /* Check that new open scope are perfectly nested with respect to
480        other open scopes. */
481     for (i = ss.curr; i > ss.outer; i--) {
482       if (ss.scope[i].closing_ilt == 0) {
483         for (j = i - 1; j > ss.outer; j--)
484           if (ss.scope[j].closing_ilt == 0)
485             break;
486         ICHECK(ENCLFUNCG(ss.scope[i].block) == ss.scope[j].block);
487       }
488     }
489     ss.outer = ss.curr;
490   }
491 
492   FREE(ss.scope);
493   hashset_free(locals);
494 }
495 
496 /**
497    \brief Verify the integrity of data structures relating to variable
498    scopes in the current function. Terminate compilation with a fatal
499    error if anything is inconsistent.
500  */
501 void
scope_verify(void)502 scope_verify(void)
503 {
504 #if DEBUG
505   if (XBIT_USE_SCOPE_LABELS) {
506     verify_all_blocks();
507   }
508 #endif
509 }
510 
511 /**
512    \brief Insert a begin-scope label ILM for the scope blksym which
513    much be an ST_BLOCK symbol table entry.
514 
515    \return the new ST_LABEL symbol table entry.
516  */
517 int
insert_begin_scope_label(int block_sptr)518 insert_begin_scope_label(int block_sptr)
519 {
520   int lab;
521 
522   ICHECK(VALIDSYM(block_sptr) && STYPEG(block_sptr) == ST_BLOCK);
523   ICHECK(BEGINSCOPELABG(block_sptr) == 0 && "Scope already has a begin label.");
524 
525   if (!XBIT_USE_SCOPE_LABELS)
526     return 0;
527 
528   lab = getlab();
529   BEGINSCOPEP(lab, 1);
530   ENCLFUNCP(lab, block_sptr);
531   BEGINSCOPELABP(block_sptr, lab);
532   addlabel(lab);
533 
534   return lab;
535 }
536 
537 /**
538    \brief Insert an end-scope label ILM for the scope blksym which
539    much be an ST_BLOCK symbol table entry.
540 
541    \return the new ST_LABEL symbol table entry.
542  */
543 int
insert_end_scope_label(int block_sptr)544 insert_end_scope_label(int block_sptr)
545 {
546   int lab;
547 
548   ICHECK(VALIDSYM(block_sptr) && STYPEG(block_sptr) == ST_BLOCK);
549   ICHECK(ENDSCOPELABG(block_sptr) == 0 && "Scope already has an end label.");
550 
551   if (!XBIT_USE_SCOPE_LABELS)
552     return 0;
553 
554   lab = getlab();
555   ENDSCOPEP(lab, 1);
556   ENCLFUNCP(lab, block_sptr);
557   ENDSCOPELABP(block_sptr, lab);
558   addlabel(lab);
559 
560   return lab;
561 }
562 
563 /*
564  * Scope tracking.
565  *
566  * During inlining, as we're scanning the current function ILMs top to bottom,
567  * call track_scope_label(label_sptr) whenever an IM_LABEL is seen in order to
568  * keep track of the current scope.
569  *
570  * The global variable current_scope points to the currently open scope.
571  */
572 int current_scope = 0;
573 
574 /**
575    \brief Reset scope tracking, start from the outer function scope.
576  */
577 void
track_scope_reset()578 track_scope_reset()
579 {
580   current_scope = GBL_CURRFUNC;
581   dbgprintf("Scope: Reset to current function %d:%s\n", current_scope,
582             SYMNAME(current_scope));
583 }
584 
585 /**
586    \brief Update curent_scope after scanning over an IM_LABEL ilmx.
587    The label sptr is the first and only ILM operand on IM_LABEL.
588  */
589 void
track_scope_label(int label)590 track_scope_label(int label)
591 {
592   assert(STYPEG(label) == ST_LABEL, "track_scope_label: Bogus label", label,
593          ERR_Severe);
594 
595   /* If scope labels are not being inserted, it is impossible to keep
596      track of the current scope. */
597   if (!XBIT_USE_SCOPE_LABELS)
598     return;
599 
600   /* Non-scope labels are simply ignored. */
601   if (!BEGINSCOPEG(label) && !ENDSCOPEG(label))
602     return;
603 
604   /* Labels left over after cancel_lexical_block() are also ignored. */
605   if (!ENCLFUNCG(label))
606     return;
607 
608   if (BEGINSCOPEG(label)) {
609     dbgprintf("Scope: Enter scope %d:%s from %d:%s. Parent %d:%s.\n",
610               ENCLFUNCG(label), SYMNAME(ENCLFUNCG(label)), current_scope,
611               SYMNAME(current_scope), ENCLFUNCG(ENCLFUNCG(label)),
612               SYMNAME(ENCLFUNCG(ENCLFUNCG(label))));
613     current_scope = ENCLFUNCG(label);
614     /* A label can't refer to a function scope. */
615     assert(STYPEG(current_scope) == ST_BLOCK,
616            "track_scope_label: Scope label does not refer to an ST_BLOCK",
617            label, ERR_Severe);
618   }
619 
620   if (ENDSCOPEG(label)) {
621     dbgprintf("Scope: Leave scope %d:%s from %d:%s. Parent %d:%s.\n",
622               ENCLFUNCG(label), SYMNAME(ENCLFUNCG(label)), current_scope,
623               SYMNAME(current_scope), ENCLFUNCG(ENCLFUNCG(label)),
624               SYMNAME(ENCLFUNCG(ENCLFUNCG(label))));
625     /* This is the scope that's ending: */
626     current_scope = ENCLFUNCG(label);
627     assert(STYPEG(current_scope) == ST_BLOCK,
628            "track_scope_label: Scope label does not refer to an ST_BLOCK",
629            label, ERR_Severe);
630     /* This is the active scope after leaving the current scope: */
631     current_scope = ENCLFUNCG(current_scope);
632   }
633 
634   if (!flg.inliner || XBIT(117, 0x10000)) {
635     assert(current_scope == GBL_CURRFUNC || STYPEG(current_scope) == ST_BLOCK,
636            "track_scope_label: Invalid scope label", label, ERR_Severe);
637   }
638 }
639 
640 /**
641    \brief Find all the scope labels in the current ILM block and pass
642    them to track_scope_label. This is used for blocks that don't
643    contain any calls.
644 
645    This function is looking at numilms ILMs in the ilmb.ilm_base
646    array. We don't have any ILM_* macros defined to access that area.
647 
648    Compare find_bpar() in inliner.c
649  */
650 void
find_scope_labels(int numilms)651 find_scope_labels(int numilms)
652 {
653   int ilmx, len;
654 
655   if (!XBIT_USE_SCOPE_LABELS)
656     return;
657 
658   for (ilmx = BOS_SIZE; ilmx < numilms; ilmx += len) {
659     int opc = ilmb.ilm_base[ilmx];
660     if (opc == IM_LABEL) {
661       int label = ilmb.ilm_base[ilmx + 1];
662       track_scope_label(label);
663     }
664 
665     len = ilms[opc].oprs + 1; /* length for opcode and fixed operands */
666     if (IM_VAR(opc))
667       len += ilmb.ilm_base[ilmx + 1]; /* include the variable opnds */
668   }
669 }
670 
671 /*
672  * Inliner support.
673  *
674  * The functions and global variables below are used by the C and Fortran
675  * inliners.
676  */
677 
678 int new_callee_scope = 0;
679 
680 /* Stack of simultaneously open callee scopes.
681  *
682  * This stack contains scopes whose begin label has been inserted, and whose
683  * end label has yet to be inserted.
684  *
685  * The stack top is equal to new_callee_scope only after calling
686  * begin_inlined_scope().
687  */
688 static int *open_callee_scope = NULL;
689 static int open_callee_scope_count = 0;
690 static int open_callee_scope_capacity = 0;
691 
692 /* Check if new_callee_scope is at the top of the open_callee_scope stack.
693  *
694  * This is false when new_callee_scope is 0 or when it hasn't been pushed yet
695  * by begin_inlined_scope().
696  */
697 #define NEW_CALLEE_SCOPE_IS_STACK_TOP \
698   (open_callee_scope_count > 0 &&     \
699    new_callee_scope == open_callee_scope[open_callee_scope_count - 1])
700 
701 /**
702    \brief The original function scope of the callee being inlined is
703    represented as a new ST_BLOCK scope, stored in new_callee_scope.
704 
705    Call create_inlined_scope() to create new_callee_scope as a subscope of the
706    currently tracked scope. Then call begin_inlined_scope() and
707    end_inlined_scope() to insert the begin/end labels.
708  */
709 void
create_inlined_scope(int callee_sptr)710 create_inlined_scope(int callee_sptr)
711 {
712   if (!XBIT_USE_SCOPE_LABELS) {
713     /* Without scope labels, we don't know the scope containing the
714        call site. Conservatively map scope to the entire function
715        scope. */
716     new_callee_scope = GBL_CURRFUNC;
717     return;
718   }
719 
720   if (!flg.inliner || XBIT(117, 0x10000)) {
721     assert(current_scope, "create_inlined_scope: No current scope?", 0,
722            ERR_Severe);
723   }
724 
725   /* An existing callee scope should have been saved or cancelled. */
726   if (new_callee_scope) {
727     assert(NEW_CALLEE_SCOPE_IS_STACK_TOP,
728            "create_inlined_scope: Previous callee scope wasn't saved",
729            new_callee_scope, ERR_Fatal);
730   }
731 
732   NEWSYM(new_callee_scope);
733   STYPEP(new_callee_scope, ST_BLOCK);
734   NMPTRP(new_callee_scope, NMPTRG(callee_sptr));
735   SCOPEP(new_callee_scope, 1);
736   ENCLFUNCP(new_callee_scope, current_scope);
737 
738   dbgprintf("Scope: Create %d:%s for inlining %d:%s.\n", new_callee_scope,
739             SYMNAME(new_callee_scope), callee_sptr, SYMNAME(callee_sptr));
740 }
741 
742 /**
743    \brief Immediately before inlining a function, create a new
744    ST_BLOCK to represent the callee's function scope in the current
745    function.
746 
747    Insert an IM_LABEL ILM to open the new scope, update the
748    new_callee_scope and current_scope variables to refer to the newly
749    created scope.
750  */
751 void
begin_inlined_scope(int func_sptr)752 begin_inlined_scope(int func_sptr)
753 {
754   int label;
755 
756   if (!XBIT_USE_SCOPE_LABELS)
757     return;
758 
759   /* Make a new scope unless create_inlined_scope() has already been called.
760    * Don't attempt to reuse an open scope that has already been pushed. */
761   if (!new_callee_scope || NEW_CALLEE_SCOPE_IS_STACK_TOP)
762     create_inlined_scope(func_sptr);
763 
764   assert(new_callee_scope && STYPEG(new_callee_scope) == ST_BLOCK,
765          "begin_inlined_scope: No inlined scope was created", new_callee_scope,
766          ERR_Severe);
767 
768   /* Push scope onto the stack of open callee scopes. */
769   NEED(open_callee_scope_count + 1, open_callee_scope, int,
770        open_callee_scope_capacity, open_callee_scope_capacity + 16);
771   open_callee_scope[open_callee_scope_count++] = new_callee_scope;
772 
773   /* Create begin label here, end label in end_inlined_scope(). */
774   label = insert_begin_scope_label(new_callee_scope);
775   dbgprintf("Scope: Label %d:%s created, nest=%d.\n", label, SYMNAME(label),
776             open_callee_scope_count);
777 
778   track_scope_label(label);
779 }
780 
781 /**
782    \brief After inlining a function, emit a scope-ending label.
783  */
784 void
end_inlined_scope(void)785 end_inlined_scope(void)
786 {
787   int label;
788 
789   if (!XBIT_USE_SCOPE_LABELS)
790     return;
791 
792   assert(new_callee_scope && STYPEG(new_callee_scope) == ST_BLOCK,
793          "end_inlined_scope: Not currently in an inlined scope",
794          new_callee_scope, ERR_Severe);
795 
796   label = insert_end_scope_label(new_callee_scope);
797   dbgprintf("Scope: Label %d:%s created, next=%d.\n", label, SYMNAME(label),
798             open_callee_scope_count);
799 
800   /* Pop this scope off the stack. Make new_callee_scope refer to the
801    * previous open callee scope. */
802   assert(NEW_CALLEE_SCOPE_IS_STACK_TOP,
803          "end_inlined_scope: Scope stack corrupted", new_callee_scope,
804          ERR_Fatal);
805   if (--open_callee_scope_count)
806     new_callee_scope = open_callee_scope[open_callee_scope_count - 1];
807   else
808     new_callee_scope = 0;
809 
810   track_scope_label(label);
811 }
812 
813 /**
814    \brief End currently open callee scopes until
815    open_callee_scope_count is new_open_count.
816  */
817 void
end_inlined_scopes(int new_open_count)818 end_inlined_scopes(int new_open_count)
819 {
820   while (open_callee_scope_count > new_open_count) {
821     new_callee_scope = open_callee_scope[open_callee_scope_count - 1];
822     end_inlined_scope();
823   }
824 }
825 
826 /**
827    \brief If create_inlined_scope() was called, but the inlining was
828    abandoned before any labels were inserted, call
829    cancel_inlined_scope() to clean up.
830  */
831 void
cancel_inlined_scope(void)832 cancel_inlined_scope(void)
833 {
834   if (!XBIT_USE_SCOPE_LABELS)
835     return;
836 
837   if (!new_callee_scope)
838     return;
839 
840   /* If the begin label was already inserted, this scope can't be cancelled. */
841   if (NEW_CALLEE_SCOPE_IS_STACK_TOP)
842     return;
843 
844   /* Go back to the scope we came from before calling
845    * begin_inlined_scope(). */
846   current_scope = ENCLFUNCG(new_callee_scope);
847   dbgprintf("Scope: Reverted to %d:%s scope.\n", current_scope,
848             SYMNAME(current_scope));
849 
850   /* Restore the old stack top into new_callee_scope. */
851   if (open_callee_scope_count)
852     new_callee_scope = open_callee_scope[open_callee_scope_count - 1];
853   else
854     new_callee_scope = 0;
855 }
856 
857 void
reset_new_callee_scope()858 reset_new_callee_scope()
859 {
860   new_callee_scope = 0;
861 }
862 
863 /**
864    \brief Remove any scope labels from all blocks.  This is done as a
865    workaround until all the phases of the compiler accept (or ignore)
866    scope labels.
867  */
868 void
remove_scope_labels(void)869 remove_scope_labels(void)
870 {
871   int bihx, iltx, nextiltx;
872   for (bihx = gbl.entbih; 1; bihx = BIH_NEXT(bihx)) {
873     rdilts(bihx);
874     for (iltx = BIH_ILTFIRST(bihx); iltx; iltx = nextiltx) {
875       nextiltx = ILT_NEXT(iltx);
876       if (is_scope_label_ili(ILT_ILIP(iltx)))
877         delilt(iltx);
878     }
879     wrilts(bihx);
880     if (BIH_LAST(bihx))
881       break;
882   }
883 } /* remove_scope_labels */
884