|
|
1.1 root 1: /* Expands front end tree to back end RTL for GNU C-Compiler 1.1.1.7 ! root 2: Copyright (C) 1987, 88, 89, 92, 93, 1994 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU CC. 5: 6: GNU CC is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU CC is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU CC; see the file COPYING. If not, write to 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19: 20: 21: /* This file handles the generation of rtl code from tree structure 22: above the level of expressions, using subroutines in exp*.c and emit-rtl.c. 23: It also creates the rtl expressions for parameters and auto variables 24: and has full responsibility for allocating stack slots. 25: 26: The functions whose names start with `expand_' are called by the 27: parser to generate RTL instructions for various kinds of constructs. 28: 29: Some control and binding constructs require calling several such 30: functions at different times. For example, a simple if-then 31: is expanded by calling `expand_start_cond' (with the condition-expression 32: as argument) before parsing the then-clause and calling `expand_end_cond' 33: after parsing the then-clause. */ 34: 35: #include "config.h" 36: 37: #include <stdio.h> 38: #include <ctype.h> 39: 40: #include "rtl.h" 41: #include "tree.h" 42: #include "flags.h" 43: #include "function.h" 44: #include "insn-flags.h" 45: #include "insn-config.h" 46: #include "insn-codes.h" 47: #include "expr.h" 48: #include "hard-reg-set.h" 49: #include "obstack.h" 50: #include "loop.h" 51: #include "recog.h" 1.1.1.6 root 52: #include "machmode.h" 53: 54: #include "bytecode.h" 55: #include "bc-typecd.h" 56: #include "bc-opcode.h" 57: #include "bc-optab.h" 58: #include "bc-emit.h" 1.1 root 59: 60: #define obstack_chunk_alloc xmalloc 61: #define obstack_chunk_free free 62: struct obstack stmt_obstack; 63: 64: /* Filename and line number of last line-number note, 65: whether we actually emitted it or not. */ 66: char *emit_filename; 67: int emit_lineno; 68: 69: /* Nonzero if within a ({...}) grouping, in which case we must 70: always compute a value for each expr-stmt in case it is the last one. */ 71: 72: int expr_stmts_for_value; 73: 74: /* Each time we expand an expression-statement, 75: record the expr's type and its RTL value here. */ 76: 77: static tree last_expr_type; 78: static rtx last_expr_value; 79: 1.1.1.4 root 80: /* Each time we expand the end of a binding contour (in `expand_end_bindings') 81: and we emit a new NOTE_INSN_BLOCK_END note, we save a pointer to it here. 82: This is used by the `remember_end_note' function to record the endpoint 83: of each generated block in its associated BLOCK node. */ 84: 85: static rtx last_block_end_note; 86: 1.1 root 87: /* Number of binding contours started so far in this function. */ 88: 89: int block_start_count; 90: 91: /* Nonzero if function being compiled needs to 92: return the address of where it has put a structure value. */ 93: 94: extern int current_function_returns_pcc_struct; 95: 96: /* Label that will go on parm cleanup code, if any. 97: Jumping to this label runs cleanup code for parameters, if 98: such code must be run. Following this code is the logical return label. */ 99: 100: extern rtx cleanup_label; 101: 102: /* Label that will go on function epilogue. 103: Jumping to this label serves as a "return" instruction 104: on machines which require execution of the epilogue on all returns. */ 105: 106: extern rtx return_label; 107: 108: /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs. 109: So we can mark them all live at the end of the function, if nonopt. */ 110: extern rtx save_expr_regs; 111: 112: /* Offset to end of allocated area of stack frame. 113: If stack grows down, this is the address of the last stack slot allocated. 114: If stack grows up, this is the address for the next slot. */ 115: extern int frame_offset; 116: 117: /* Label to jump back to for tail recursion, or 0 if we have 118: not yet needed one for this function. */ 119: extern rtx tail_recursion_label; 120: 121: /* Place after which to insert the tail_recursion_label if we need one. */ 122: extern rtx tail_recursion_reentry; 123: 124: /* Location at which to save the argument pointer if it will need to be 125: referenced. There are two cases where this is done: if nonlocal gotos 126: exist, or if vars whose is an offset from the argument pointer will be 127: needed by inner routines. */ 128: 129: extern rtx arg_pointer_save_area; 130: 131: /* Chain of all RTL_EXPRs that have insns in them. */ 132: extern tree rtl_expr_chain; 133: 134: #if 0 /* Turned off because 0 seems to work just as well. */ 135: /* Cleanup lists are required for binding levels regardless of whether 136: that binding level has cleanups or not. This node serves as the 137: cleanup list whenever an empty list is required. */ 138: static tree empty_cleanup_list; 139: #endif 1.1.1.7 ! root 140: ! 141: extern void (*interim_eh_hook) PROTO((tree)); 1.1 root 142: 143: /* Functions and data structures for expanding case statements. */ 144: 145: /* Case label structure, used to hold info on labels within case 146: statements. We handle "range" labels; for a single-value label 147: as in C, the high and low limits are the same. 148: 149: A chain of case nodes is initially maintained via the RIGHT fields 150: in the nodes. Nodes with higher case values are later in the list. 151: 152: Switch statements can be output in one of two forms. A branch table 153: is used if there are more than a few labels and the labels are dense 154: within the range between the smallest and largest case value. If a 155: branch table is used, no further manipulations are done with the case 156: node chain. 157: 158: The alternative to the use of a branch table is to generate a series 159: of compare and jump insns. When that is done, we use the LEFT, RIGHT, 160: and PARENT fields to hold a binary tree. Initially the tree is 161: totally unbalanced, with everything on the right. We balance the tree 162: with nodes on the left having lower case values than the parent 163: and nodes on the right having higher values. We then output the tree 164: in order. */ 165: 166: struct case_node 167: { 168: struct case_node *left; /* Left son in binary tree */ 169: struct case_node *right; /* Right son in binary tree; also node chain */ 170: struct case_node *parent; /* Parent of node in binary tree */ 171: tree low; /* Lowest index value for this label */ 172: tree high; /* Highest index value for this label */ 173: tree code_label; /* Label to jump to when node matches */ 174: }; 175: 176: typedef struct case_node case_node; 177: typedef struct case_node *case_node_ptr; 178: 179: /* These are used by estimate_case_costs and balance_case_nodes. */ 180: 181: /* This must be a signed type, and non-ANSI compilers lack signed char. */ 182: static short *cost_table; 183: static int use_cost_table; 184: 185: /* Stack of control and binding constructs we are currently inside. 186: 187: These constructs begin when you call `expand_start_WHATEVER' 188: and end when you call `expand_end_WHATEVER'. This stack records 189: info about how the construct began that tells the end-function 190: what to do. It also may provide information about the construct 191: to alter the behavior of other constructs within the body. 192: For example, they may affect the behavior of C `break' and `continue'. 193: 194: Each construct gets one `struct nesting' object. 195: All of these objects are chained through the `all' field. 196: `nesting_stack' points to the first object (innermost construct). 197: The position of an entry on `nesting_stack' is in its `depth' field. 198: 199: Each type of construct has its own individual stack. 200: For example, loops have `loop_stack'. Each object points to the 201: next object of the same type through the `next' field. 202: 203: Some constructs are visible to `break' exit-statements and others 204: are not. Which constructs are visible depends on the language. 205: Therefore, the data structure allows each construct to be visible 206: or not, according to the args given when the construct is started. 207: The construct is visible if the `exit_label' field is non-null. 208: In that case, the value should be a CODE_LABEL rtx. */ 209: 210: struct nesting 211: { 212: struct nesting *all; 213: struct nesting *next; 214: int depth; 215: rtx exit_label; 216: union 217: { 218: /* For conds (if-then and if-then-else statements). */ 219: struct 220: { 221: /* Label for the end of the if construct. 222: There is none if EXITFLAG was not set 223: and no `else' has been seen yet. */ 224: rtx endif_label; 225: /* Label for the end of this alternative. 226: This may be the end of the if or the next else/elseif. */ 227: rtx next_label; 228: } cond; 229: /* For loops. */ 230: struct 231: { 232: /* Label at the top of the loop; place to loop back to. */ 233: rtx start_label; 234: /* Label at the end of the whole construct. */ 235: rtx end_label; 1.1.1.7 ! root 236: /* Label before a jump that branches to the end of the whole ! 237: construct. This is where destructors go if any. */ ! 238: rtx alt_end_label; 1.1 root 239: /* Label for `continue' statement to jump to; 240: this is in front of the stepper of the loop. */ 241: rtx continue_label; 242: } loop; 243: /* For variable binding contours. */ 244: struct 245: { 246: /* Sequence number of this binding contour within the function, 247: in order of entry. */ 248: int block_start_count; 1.1.1.6 root 249: /* Nonzero => value to restore stack to on exit. Complemented by 250: bc_stack_level (see below) when generating bytecodes. */ 1.1 root 251: rtx stack_level; 252: /* The NOTE that starts this contour. 253: Used by expand_goto to check whether the destination 254: is within each contour or not. */ 255: rtx first_insn; 256: /* Innermost containing binding contour that has a stack level. */ 257: struct nesting *innermost_stack_block; 258: /* List of cleanups to be run on exit from this contour. 259: This is a list of expressions to be evaluated. 260: The TREE_PURPOSE of each link is the ..._DECL node 261: which the cleanup pertains to. */ 262: tree cleanups; 263: /* List of cleanup-lists of blocks containing this block, 264: as they were at the locus where this block appears. 265: There is an element for each containing block, 266: ordered innermost containing block first. 267: The tail of this list can be 0 (was empty_cleanup_list), 268: if all remaining elements would be empty lists. 269: The element's TREE_VALUE is the cleanup-list of that block, 270: which may be null. */ 271: tree outer_cleanups; 272: /* Chain of labels defined inside this binding contour. 273: For contours that have stack levels or cleanups. */ 274: struct label_chain *label_chain; 275: /* Number of function calls seen, as of start of this block. */ 276: int function_call_count; 1.1.1.6 root 277: /* Bytecode specific: stack level to restore stack to on exit. */ 278: int bc_stack_level; 1.1 root 279: } block; 280: /* For switch (C) or case (Pascal) statements, 281: and also for dummies (see `expand_start_case_dummy'). */ 282: struct 283: { 284: /* The insn after which the case dispatch should finally 285: be emitted. Zero for a dummy. */ 286: rtx start; 1.1.1.6 root 287: /* For bytecodes, the case table is in-lined right in the code. 288: A label is needed for skipping over this block. It is only 289: used when generating bytecodes. */ 290: rtx skip_label; 1.1 root 291: /* A list of case labels, kept in ascending order by value 292: as the list is built. 293: During expand_end_case, this list may be rearranged into a 294: nearly balanced binary tree. */ 295: struct case_node *case_list; 296: /* Label to jump to if no case matches. */ 297: tree default_label; 298: /* The expression to be dispatched on. */ 299: tree index_expr; 300: /* Type that INDEX_EXPR should be converted to. */ 301: tree nominal_type; 302: /* Number of range exprs in case statement. */ 303: int num_ranges; 304: /* Name of this kind of statement, for warnings. */ 305: char *printname; 306: /* Nonzero if a case label has been seen in this case stmt. */ 307: char seenlabel; 308: } case_stmt; 309: } data; 310: }; 311: 312: /* Chain of all pending binding contours. */ 313: struct nesting *block_stack; 314: 1.1.1.4 root 315: /* If any new stacks are added here, add them to POPSTACKS too. */ 316: 1.1 root 317: /* Chain of all pending binding contours that restore stack levels 318: or have cleanups. */ 319: struct nesting *stack_block_stack; 320: 321: /* Chain of all pending conditional statements. */ 322: struct nesting *cond_stack; 323: 324: /* Chain of all pending loops. */ 325: struct nesting *loop_stack; 326: 327: /* Chain of all pending case or switch statements. */ 328: struct nesting *case_stack; 329: 330: /* Separate chain including all of the above, 331: chained through the `all' field. */ 332: struct nesting *nesting_stack; 333: 334: /* Number of entries on nesting_stack now. */ 335: int nesting_depth; 336: 337: /* Allocate and return a new `struct nesting'. */ 338: 339: #define ALLOC_NESTING() \ 340: (struct nesting *) obstack_alloc (&stmt_obstack, sizeof (struct nesting)) 341: 1.1.1.4 root 342: /* Pop the nesting stack element by element until we pop off 343: the element which is at the top of STACK. 344: Update all the other stacks, popping off elements from them 345: as we pop them from nesting_stack. */ 1.1 root 346: 347: #define POPSTACK(STACK) \ 1.1.1.4 root 348: do { struct nesting *target = STACK; \ 349: struct nesting *this; \ 350: do { this = nesting_stack; \ 351: if (loop_stack == this) \ 352: loop_stack = loop_stack->next; \ 353: if (cond_stack == this) \ 354: cond_stack = cond_stack->next; \ 355: if (block_stack == this) \ 356: block_stack = block_stack->next; \ 357: if (stack_block_stack == this) \ 358: stack_block_stack = stack_block_stack->next; \ 359: if (case_stack == this) \ 360: case_stack = case_stack->next; \ 361: nesting_depth = nesting_stack->depth - 1; \ 1.1 root 362: nesting_stack = this->all; \ 363: obstack_free (&stmt_obstack, this); } \ 1.1.1.4 root 364: while (this != target); } while (0) 1.1 root 365: 366: /* In some cases it is impossible to generate code for a forward goto 367: until the label definition is seen. This happens when it may be necessary 368: for the goto to reset the stack pointer: we don't yet know how to do that. 369: So expand_goto puts an entry on this fixup list. 370: Each time a binding contour that resets the stack is exited, 371: we check each fixup. 372: If the target label has now been defined, we can insert the proper code. */ 373: 374: struct goto_fixup 375: { 376: /* Points to following fixup. */ 377: struct goto_fixup *next; 378: /* Points to the insn before the jump insn. 379: If more code must be inserted, it goes after this insn. */ 380: rtx before_jump; 381: /* The LABEL_DECL that this jump is jumping to, or 0 382: for break, continue or return. */ 383: tree target; 1.1.1.4 root 384: /* The BLOCK for the place where this goto was found. */ 385: tree context; 1.1 root 386: /* The CODE_LABEL rtx that this is jumping to. */ 387: rtx target_rtl; 388: /* Number of binding contours started in current function 389: before the label reference. */ 390: int block_start_count; 391: /* The outermost stack level that should be restored for this jump. 392: Each time a binding contour that resets the stack is exited, 393: if the target label is *not* yet defined, this slot is updated. */ 394: rtx stack_level; 395: /* List of lists of cleanup expressions to be run by this goto. 396: There is one element for each block that this goto is within. 397: The tail of this list can be 0 (was empty_cleanup_list), 398: if all remaining elements would be empty. 399: The TREE_VALUE contains the cleanup list of that block as of the 400: time this goto was seen. 401: The TREE_ADDRESSABLE flag is 1 for a block that has been exited. */ 402: tree cleanup_list_list; 1.1.1.6 root 403: 404: /* Bytecode specific members follow */ 405: 406: /* The label that this jump is jumping to, or 0 for break, continue 407: or return. */ 408: struct bc_label *bc_target; 409: 410: /* The label we use for the fixup patch */ 411: struct bc_label *label; 412: 413: /* True (non-0) if fixup has been handled */ 414: int bc_handled:1; 415: 416: /* Like stack_level above, except refers to the interpreter stack */ 417: int bc_stack_level; 1.1 root 418: }; 419: 420: static struct goto_fixup *goto_fixup_chain; 421: 422: /* Within any binding contour that must restore a stack level, 423: all labels are recorded with a chain of these structures. */ 424: 425: struct label_chain 426: { 427: /* Points to following fixup. */ 428: struct label_chain *next; 429: tree label; 430: }; 1.1.1.7 ! root 431: static void expand_goto_internal PROTO((tree, rtx, rtx)); ! 432: static void bc_expand_goto_internal PROTO((enum bytecode_opcode, ! 433: struct bc_label *, tree)); ! 434: static int expand_fixup PROTO((tree, rtx, rtx)); ! 435: static void bc_expand_fixup PROTO((enum bytecode_opcode, ! 436: struct bc_label *, int)); ! 437: static void fixup_gotos PROTO((struct nesting *, rtx, tree, ! 438: rtx, int)); ! 439: static void bc_fixup_gotos PROTO((struct nesting *, int, tree, ! 440: rtx, int)); ! 441: static int warn_if_unused_value PROTO((tree)); ! 442: static void bc_expand_start_cond PROTO((tree, int)); ! 443: static void bc_expand_end_cond PROTO((void)); ! 444: static void bc_expand_start_else PROTO((void)); ! 445: static void bc_expand_end_loop PROTO((void)); ! 446: static void bc_expand_end_bindings PROTO((tree, int, int)); ! 447: static void bc_expand_decl PROTO((tree, tree)); ! 448: static void bc_expand_variable_local_init PROTO((tree)); ! 449: static void bc_expand_decl_init PROTO((tree)); ! 450: static void expand_null_return_1 PROTO((rtx, int)); ! 451: static int tail_recursion_args PROTO((tree, tree)); ! 452: static void expand_cleanups PROTO((tree, tree)); ! 453: static void bc_expand_start_case PROTO((struct nesting *, tree, ! 454: tree, char *)); ! 455: static int bc_pushcase PROTO((tree, tree)); ! 456: static void bc_check_for_full_enumeration_handling PROTO((tree)); ! 457: static void bc_expand_end_case PROTO((tree)); ! 458: static void do_jump_if_equal PROTO((rtx, rtx, rtx, int)); ! 459: static int estimate_case_costs PROTO((case_node_ptr)); ! 460: static void group_case_nodes PROTO((case_node_ptr)); ! 461: static void balance_case_nodes PROTO((case_node_ptr *, ! 462: case_node_ptr)); ! 463: static int node_has_low_bound PROTO((case_node_ptr, tree)); ! 464: static int node_has_high_bound PROTO((case_node_ptr, tree)); ! 465: static int node_is_bounded PROTO((case_node_ptr, tree)); ! 466: static void emit_jump_if_reachable PROTO((rtx)); ! 467: static void emit_case_nodes PROTO((rtx, case_node_ptr, rtx, tree)); ! 468: ! 469: int bc_expand_exit_loop_if_false (); ! 470: void bc_expand_start_cond (); ! 471: void bc_expand_end_cond (); ! 472: void bc_expand_start_else (); ! 473: void bc_expand_end_bindings (); ! 474: void bc_expand_start_case (); ! 475: void bc_check_for_full_enumeration_handling (); ! 476: void bc_expand_end_case (); ! 477: void bc_expand_decl (); ! 478: ! 479: extern rtx bc_allocate_local (); ! 480: extern rtx bc_allocate_variable_array (); 1.1 root 481: 482: void 483: init_stmt () 484: { 485: gcc_obstack_init (&stmt_obstack); 486: #if 0 487: empty_cleanup_list = build_tree_list (NULL_TREE, NULL_TREE); 488: #endif 489: } 490: 491: void 492: init_stmt_for_function () 493: { 494: /* We are not currently within any block, conditional, loop or case. */ 495: block_stack = 0; 1.1.1.7 ! root 496: stack_block_stack = 0; 1.1 root 497: loop_stack = 0; 498: case_stack = 0; 499: cond_stack = 0; 500: nesting_stack = 0; 501: nesting_depth = 0; 502: 503: block_start_count = 0; 504: 505: /* No gotos have been expanded yet. */ 506: goto_fixup_chain = 0; 507: 508: /* We are not processing a ({...}) grouping. */ 509: expr_stmts_for_value = 0; 510: last_expr_type = 0; 511: } 512: 513: void 514: save_stmt_status (p) 515: struct function *p; 516: { 517: p->block_stack = block_stack; 518: p->stack_block_stack = stack_block_stack; 519: p->cond_stack = cond_stack; 520: p->loop_stack = loop_stack; 521: p->case_stack = case_stack; 522: p->nesting_stack = nesting_stack; 523: p->nesting_depth = nesting_depth; 524: p->block_start_count = block_start_count; 525: p->last_expr_type = last_expr_type; 526: p->last_expr_value = last_expr_value; 527: p->expr_stmts_for_value = expr_stmts_for_value; 528: p->emit_filename = emit_filename; 529: p->emit_lineno = emit_lineno; 530: p->goto_fixup_chain = goto_fixup_chain; 531: } 532: 533: void 534: restore_stmt_status (p) 535: struct function *p; 536: { 537: block_stack = p->block_stack; 538: stack_block_stack = p->stack_block_stack; 539: cond_stack = p->cond_stack; 540: loop_stack = p->loop_stack; 541: case_stack = p->case_stack; 542: nesting_stack = p->nesting_stack; 543: nesting_depth = p->nesting_depth; 544: block_start_count = p->block_start_count; 545: last_expr_type = p->last_expr_type; 546: last_expr_value = p->last_expr_value; 547: expr_stmts_for_value = p->expr_stmts_for_value; 548: emit_filename = p->emit_filename; 549: emit_lineno = p->emit_lineno; 550: goto_fixup_chain = p->goto_fixup_chain; 551: } 552: 553: /* Emit a no-op instruction. */ 554: 555: void 556: emit_nop () 557: { 1.1.1.6 root 558: rtx last_insn; 559: 560: if (!output_bytecode) 561: { 562: last_insn = get_last_insn (); 563: if (!optimize 564: && (GET_CODE (last_insn) == CODE_LABEL 565: || prev_real_insn (last_insn) == 0)) 566: emit_insn (gen_nop ()); 567: } 1.1 root 568: } 569: 570: /* Return the rtx-label that corresponds to a LABEL_DECL, 571: creating it if necessary. */ 572: 573: rtx 574: label_rtx (label) 575: tree label; 576: { 577: if (TREE_CODE (label) != LABEL_DECL) 578: abort (); 579: 580: if (DECL_RTL (label)) 581: return DECL_RTL (label); 582: 583: return DECL_RTL (label) = gen_label_rtx (); 584: } 585: 586: /* Add an unconditional jump to LABEL as the next sequential instruction. */ 587: 588: void 589: emit_jump (label) 590: rtx label; 591: { 592: do_pending_stack_adjust (); 593: emit_jump_insn (gen_jump (label)); 594: emit_barrier (); 595: } 596: 597: /* Emit code to jump to the address 598: specified by the pointer expression EXP. */ 599: 600: void 601: expand_computed_goto (exp) 602: tree exp; 603: { 1.1.1.6 root 604: if (output_bytecode) 605: { 606: bc_expand_expr (exp); 607: bc_emit_instruction (jumpP); 608: } 609: else 610: { 611: rtx x = expand_expr (exp, NULL_RTX, VOIDmode, 0); 612: emit_queue (); 613: emit_indirect_jump (x); 614: } 1.1 root 615: } 616: 617: /* Handle goto statements and the labels that they can go to. */ 618: 619: /* Specify the location in the RTL code of a label LABEL, 620: which is a LABEL_DECL tree node. 621: 622: This is used for the kind of label that the user can jump to with a 623: goto statement, and for alternatives of a switch or case statement. 624: RTL labels generated for loops and conditionals don't go through here; 625: they are generated directly at the RTL level, by other functions below. 626: 627: Note that this has nothing to do with defining label *names*. 628: Languages vary in how they do that and what that even means. */ 629: 630: void 631: expand_label (label) 632: tree label; 633: { 634: struct label_chain *p; 635: 1.1.1.6 root 636: if (output_bytecode) 637: { 638: if (! DECL_RTL (label)) 639: DECL_RTL (label) = bc_gen_rtx ((char *) 0, 0, bc_get_bytecode_label ()); 640: if (! bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (DECL_RTL (label)))) 641: error ("multiply defined label"); 642: return; 643: } 644: 1.1 root 645: do_pending_stack_adjust (); 646: emit_label (label_rtx (label)); 647: if (DECL_NAME (label)) 648: LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label)); 649: 650: if (stack_block_stack != 0) 651: { 652: p = (struct label_chain *) oballoc (sizeof (struct label_chain)); 653: p->next = stack_block_stack->data.block.label_chain; 654: stack_block_stack->data.block.label_chain = p; 655: p->label = label; 656: } 657: } 658: 659: /* Declare that LABEL (a LABEL_DECL) may be used for nonlocal gotos 660: from nested functions. */ 661: 662: void 663: declare_nonlocal_label (label) 664: tree label; 665: { 666: nonlocal_labels = tree_cons (NULL_TREE, label, nonlocal_labels); 667: LABEL_PRESERVE_P (label_rtx (label)) = 1; 668: if (nonlocal_goto_handler_slot == 0) 669: { 670: nonlocal_goto_handler_slot 671: = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0); 1.1.1.3 root 672: emit_stack_save (SAVE_NONLOCAL, 673: &nonlocal_goto_stack_level, 674: PREV_INSN (tail_recursion_reentry)); 1.1 root 675: } 676: } 677: 678: /* Generate RTL code for a `goto' statement with target label LABEL. 679: LABEL should be a LABEL_DECL tree node that was or will later be 680: defined with `expand_label'. */ 681: 682: void 683: expand_goto (label) 684: tree label; 685: { 1.1.1.6 root 686: tree context; 687: 688: if (output_bytecode) 689: { 690: expand_goto_internal (label, label_rtx (label), NULL_RTX); 691: return; 692: } 693: 1.1 root 694: /* Check for a nonlocal goto to a containing function. */ 1.1.1.6 root 695: context = decl_function_context (label); 1.1 root 696: if (context != 0 && context != current_function_decl) 697: { 698: struct function *p = find_function_data (context); 1.1.1.4 root 699: rtx label_ref = gen_rtx (LABEL_REF, Pmode, label_rtx (label)); 1.1 root 700: rtx temp; 1.1.1.4 root 701: 1.1 root 702: p->has_nonlocal_label = 1; 1.1.1.6 root 703: current_function_has_nonlocal_goto = 1; 1.1.1.4 root 704: LABEL_REF_NONLOCAL_P (label_ref) = 1; 1.1.1.3 root 705: 706: /* Copy the rtl for the slots so that they won't be shared in 707: case the virtual stack vars register gets instantiated differently 708: in the parent than in the child. */ 709: 1.1 root 710: #if HAVE_nonlocal_goto 711: if (HAVE_nonlocal_goto) 712: emit_insn (gen_nonlocal_goto (lookup_static_chain (label), 1.1.1.3 root 713: copy_rtx (p->nonlocal_goto_handler_slot), 714: copy_rtx (p->nonlocal_goto_stack_level), 1.1.1.4 root 715: label_ref)); 1.1 root 716: else 717: #endif 718: { 1.1.1.3 root 719: rtx addr; 720: 1.1 root 721: /* Restore frame pointer for containing function. 722: This sets the actual hard register used for the frame pointer 723: to the location of the function's incoming static chain info. 724: The non-local goto handler will then adjust it to contain the 725: proper value and reload the argument pointer, if needed. */ 1.1.1.6 root 726: emit_move_insn (hard_frame_pointer_rtx, lookup_static_chain (label)); 1.1.1.3 root 727: 728: /* We have now loaded the frame pointer hardware register with 729: the address of that corresponds to the start of the virtual 730: stack vars. So replace virtual_stack_vars_rtx in all 731: addresses we use with stack_pointer_rtx. */ 732: 1.1 root 733: /* Get addr of containing function's current nonlocal goto handler, 734: which will do any cleanups and then jump to the label. */ 1.1.1.3 root 735: addr = copy_rtx (p->nonlocal_goto_handler_slot); 736: temp = copy_to_reg (replace_rtx (addr, virtual_stack_vars_rtx, 1.1.1.6 root 737: hard_frame_pointer_rtx)); 1.1.1.3 root 738: 1.1 root 739: /* Restore the stack pointer. Note this uses fp just restored. */ 1.1.1.3 root 740: addr = p->nonlocal_goto_stack_level; 741: if (addr) 742: addr = replace_rtx (copy_rtx (addr), 1.1.1.6 root 743: virtual_stack_vars_rtx, 744: hard_frame_pointer_rtx); 1.1.1.3 root 745: 1.1.1.4 root 746: emit_stack_restore (SAVE_NONLOCAL, addr, NULL_RTX); 1.1.1.3 root 747: 1.1 root 748: /* Put in the static chain register the nonlocal label address. */ 1.1.1.4 root 749: emit_move_insn (static_chain_rtx, label_ref); 1.1.1.6 root 750: /* USE of hard_frame_pointer_rtx added for consistency; not clear if 1.1 root 751: really needed. */ 1.1.1.6 root 752: emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx)); 1.1 root 753: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); 754: emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx)); 755: emit_indirect_jump (temp); 756: } 757: } 758: else 1.1.1.4 root 759: expand_goto_internal (label, label_rtx (label), NULL_RTX); 1.1 root 760: } 761: 762: /* Generate RTL code for a `goto' statement with target label BODY. 763: LABEL should be a LABEL_REF. 764: LAST_INSN, if non-0, is the rtx we should consider as the last 765: insn emitted (for the purposes of cleaning up a return). */ 766: 767: static void 768: expand_goto_internal (body, label, last_insn) 769: tree body; 770: rtx label; 771: rtx last_insn; 772: { 773: struct nesting *block; 774: rtx stack_level = 0; 775: 1.1.1.6 root 776: /* NOTICE! If a bytecode instruction other than `jump' is needed, 777: then the caller has to call bc_expand_goto_internal() 778: directly. This is rather an exceptional case, and there aren't 779: that many places where this is necessary. */ 780: if (output_bytecode) 781: { 782: expand_goto_internal (body, label, last_insn); 783: return; 784: } 785: 1.1 root 786: if (GET_CODE (label) != CODE_LABEL) 787: abort (); 788: 789: /* If label has already been defined, we can tell now 790: whether and how we must alter the stack level. */ 791: 792: if (PREV_INSN (label) != 0) 793: { 794: /* Find the innermost pending block that contains the label. 795: (Check containment by comparing insn-uids.) 796: Then restore the outermost stack level within that block, 797: and do cleanups of all blocks contained in it. */ 798: for (block = block_stack; block; block = block->next) 799: { 800: if (INSN_UID (block->data.block.first_insn) < INSN_UID (label)) 801: break; 802: if (block->data.block.stack_level != 0) 803: stack_level = block->data.block.stack_level; 804: /* Execute the cleanups for blocks we are exiting. */ 805: if (block->data.block.cleanups != 0) 806: { 1.1.1.4 root 807: expand_cleanups (block->data.block.cleanups, NULL_TREE); 1.1 root 808: do_pending_stack_adjust (); 809: } 810: } 811: 812: if (stack_level) 813: { 814: /* Ensure stack adjust isn't done by emit_jump, as this would clobber 815: the stack pointer. This one should be deleted as dead by flow. */ 816: clear_pending_stack_adjust (); 817: do_pending_stack_adjust (); 1.1.1.4 root 818: emit_stack_restore (SAVE_BLOCK, stack_level, NULL_RTX); 1.1 root 819: } 820: 821: if (body != 0 && DECL_TOO_LATE (body)) 822: error ("jump to `%s' invalidly jumps into binding contour", 823: IDENTIFIER_POINTER (DECL_NAME (body))); 824: } 825: /* Label not yet defined: may need to put this goto 826: on the fixup list. */ 827: else if (! expand_fixup (body, label, last_insn)) 828: { 829: /* No fixup needed. Record that the label is the target 830: of at least one goto that has no fixup. */ 831: if (body != 0) 832: TREE_ADDRESSABLE (body) = 1; 833: } 834: 835: emit_jump (label); 836: } 837: 1.1.1.6 root 838: /* Generate a jump with OPCODE to the given bytecode LABEL which is 839: found within BODY. */ 1.1.1.7 ! root 840: 1.1.1.6 root 841: static void 842: bc_expand_goto_internal (opcode, label, body) 843: enum bytecode_opcode opcode; 844: struct bc_label *label; 845: tree body; 846: { 847: struct nesting *block; 848: int stack_level = -1; 849: 850: /* If the label is defined, adjust the stack as necessary. 851: If it's not defined, we have to push the reference on the 852: fixup list. */ 853: 854: if (label->defined) 855: { 856: 857: /* Find the innermost pending block that contains the label. 858: (Check containment by comparing bytecode uids.) Then restore the 859: outermost stack level within that block. */ 860: 861: for (block = block_stack; block; block = block->next) 862: { 863: if (BYTECODE_BC_LABEL (block->data.block.first_insn)->uid < label->uid) 864: break; 865: if (block->data.block.bc_stack_level) 866: stack_level = block->data.block.bc_stack_level; 867: 868: /* Execute the cleanups for blocks we are exiting. */ 869: if (block->data.block.cleanups != 0) 870: { 871: expand_cleanups (block->data.block.cleanups, NULL_TREE); 872: do_pending_stack_adjust (); 873: } 874: } 875: 876: /* Restore the stack level. If we need to adjust the stack, we 877: must do so after the jump, since the jump may depend on 878: what's on the stack. Thus, any stack-modifying conditional 879: jumps (these are the only ones that rely on what's on the 880: stack) go into the fixup list. */ 881: 882: if (stack_level >= 0 883: && stack_depth != stack_level 884: && opcode != jump) 885: 886: bc_expand_fixup (opcode, label, stack_level); 887: else 888: { 889: if (stack_level >= 0) 890: bc_adjust_stack (stack_depth - stack_level); 891: 892: if (body && DECL_BIT_FIELD (body)) 893: error ("jump to `%s' invalidly jumps into binding contour", 894: IDENTIFIER_POINTER (DECL_NAME (body))); 895: 896: /* Emit immediate jump */ 897: bc_emit_bytecode (opcode); 898: bc_emit_bytecode_labelref (label); 899: 900: #ifdef DEBUG_PRINT_CODE 901: fputc ('\n', stderr); 902: #endif 903: } 904: } 905: else 906: /* Put goto in the fixup list */ 907: bc_expand_fixup (opcode, label, stack_level); 908: } 909: 1.1 root 910: /* Generate if necessary a fixup for a goto 911: whose target label in tree structure (if any) is TREE_LABEL 912: and whose target in rtl is RTL_LABEL. 913: 914: If LAST_INSN is nonzero, we pretend that the jump appears 915: after insn LAST_INSN instead of at the current point in the insn stream. 916: 1.1.1.4 root 917: The fixup will be used later to insert insns just before the goto. 918: Those insns will restore the stack level as appropriate for the 919: target label, and will (in the case of C++) also invoke any object 920: destructors which have to be invoked when we exit the scopes which 921: are exited by the goto. 1.1 root 922: 923: Value is nonzero if a fixup is made. */ 924: 925: static int 926: expand_fixup (tree_label, rtl_label, last_insn) 927: tree tree_label; 928: rtx rtl_label; 929: rtx last_insn; 930: { 931: struct nesting *block, *end_block; 932: 933: /* See if we can recognize which block the label will be output in. 934: This is possible in some very common cases. 935: If we succeed, set END_BLOCK to that block. 936: Otherwise, set it to 0. */ 937: 938: if (cond_stack 939: && (rtl_label == cond_stack->data.cond.endif_label 940: || rtl_label == cond_stack->data.cond.next_label)) 941: end_block = cond_stack; 942: /* If we are in a loop, recognize certain labels which 943: are likely targets. This reduces the number of fixups 944: we need to create. */ 945: else if (loop_stack 946: && (rtl_label == loop_stack->data.loop.start_label 947: || rtl_label == loop_stack->data.loop.end_label 948: || rtl_label == loop_stack->data.loop.continue_label)) 949: end_block = loop_stack; 950: else 951: end_block = 0; 952: 953: /* Now set END_BLOCK to the binding level to which we will return. */ 954: 955: if (end_block) 956: { 957: struct nesting *next_block = end_block->all; 958: block = block_stack; 959: 960: /* First see if the END_BLOCK is inside the innermost binding level. 961: If so, then no cleanups or stack levels are relevant. */ 962: while (next_block && next_block != block) 963: next_block = next_block->all; 964: 965: if (next_block) 966: return 0; 967: 968: /* Otherwise, set END_BLOCK to the innermost binding level 969: which is outside the relevant control-structure nesting. */ 970: next_block = block_stack->next; 971: for (block = block_stack; block != end_block; block = block->all) 972: if (block == next_block) 973: next_block = next_block->next; 974: end_block = next_block; 975: } 976: 977: /* Does any containing block have a stack level or cleanups? 978: If not, no fixup is needed, and that is the normal case 979: (the only case, for standard C). */ 980: for (block = block_stack; block != end_block; block = block->next) 981: if (block->data.block.stack_level != 0 982: || block->data.block.cleanups != 0) 983: break; 984: 985: if (block != end_block) 986: { 987: /* Ok, a fixup is needed. Add a fixup to the list of such. */ 988: struct goto_fixup *fixup 989: = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup)); 990: /* In case an old stack level is restored, make sure that comes 991: after any pending stack adjust. */ 992: /* ?? If the fixup isn't to come at the present position, 993: doing the stack adjust here isn't useful. Doing it with our 994: settings at that location isn't useful either. Let's hope 995: someone does it! */ 996: if (last_insn == 0) 997: do_pending_stack_adjust (); 998: fixup->target = tree_label; 999: fixup->target_rtl = rtl_label; 1.1.1.4 root 1000: 1001: /* Create a BLOCK node and a corresponding matched set of 1002: NOTE_INSN_BEGIN_BLOCK and NOTE_INSN_END_BLOCK notes at 1003: this point. The notes will encapsulate any and all fixup 1004: code which we might later insert at this point in the insn 1005: stream. Also, the BLOCK node will be the parent (i.e. the 1006: `SUPERBLOCK') of any other BLOCK nodes which we might create 1007: later on when we are expanding the fixup code. */ 1008: 1009: { 1010: register rtx original_before_jump 1011: = last_insn ? last_insn : get_last_insn (); 1012: 1013: start_sequence (); 1014: pushlevel (0); 1015: fixup->before_jump = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG); 1016: last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END); 1017: fixup->context = poplevel (1, 0, 0); /* Create the BLOCK node now! */ 1018: end_sequence (); 1019: emit_insns_after (fixup->before_jump, original_before_jump); 1020: } 1021: 1.1 root 1022: fixup->block_start_count = block_start_count; 1023: fixup->stack_level = 0; 1024: fixup->cleanup_list_list 1025: = (((block->data.block.outer_cleanups 1026: #if 0 1027: && block->data.block.outer_cleanups != empty_cleanup_list 1028: #endif 1029: ) 1030: || block->data.block.cleanups) 1.1.1.4 root 1031: ? tree_cons (NULL_TREE, block->data.block.cleanups, 1.1 root 1032: block->data.block.outer_cleanups) 1033: : 0); 1034: fixup->next = goto_fixup_chain; 1035: goto_fixup_chain = fixup; 1036: } 1037: 1038: return block != 0; 1039: } 1040: 1.1.1.6 root 1041: 1042: /* Generate bytecode jump with OPCODE to a fixup routine that links to LABEL. 1043: Make the fixup restore the stack level to STACK_LEVEL. */ 1044: 1045: static void 1046: bc_expand_fixup (opcode, label, stack_level) 1047: enum bytecode_opcode opcode; 1048: struct bc_label *label; 1049: int stack_level; 1050: { 1051: struct goto_fixup *fixup 1052: = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup)); 1053: 1054: fixup->label = bc_get_bytecode_label (); 1055: fixup->bc_target = label; 1056: fixup->bc_stack_level = stack_level; 1057: fixup->bc_handled = FALSE; 1058: 1059: fixup->next = goto_fixup_chain; 1060: goto_fixup_chain = fixup; 1061: 1062: /* Insert a jump to the fixup code */ 1063: bc_emit_bytecode (opcode); 1064: bc_emit_bytecode_labelref (fixup->label); 1065: 1066: #ifdef DEBUG_PRINT_CODE 1067: fputc ('\n', stderr); 1068: #endif 1069: } 1.1.1.7 ! root 1070: ! 1071: /* Expand any needed fixups in the outputmost binding level of the ! 1072: function. FIRST_INSN is the first insn in the function. */ 1.1.1.6 root 1073: 1.1.1.7 ! root 1074: void ! 1075: expand_fixups (first_insn) ! 1076: rtx first_insn; ! 1077: { ! 1078: fixup_gotos (NULL_PTR, NULL_RTX, NULL_TREE, first_insn, 0); ! 1079: } 1.1.1.6 root 1080: 1.1 root 1081: /* When exiting a binding contour, process all pending gotos requiring fixups. 1082: THISBLOCK is the structure that describes the block being exited. 1083: STACK_LEVEL is the rtx for the stack level to restore exiting this contour. 1084: CLEANUP_LIST is a list of expressions to evaluate on exiting this contour. 1085: FIRST_INSN is the insn that began this contour. 1086: 1087: Gotos that jump out of this contour must restore the 1088: stack level and do the cleanups before actually jumping. 1089: 1090: DONT_JUMP_IN nonzero means report error there is a jump into this 1091: contour from before the beginning of the contour. 1092: This is also done if STACK_LEVEL is nonzero. */ 1093: 1.1.1.7 ! root 1094: static void 1.1 root 1095: fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in) 1096: struct nesting *thisblock; 1097: rtx stack_level; 1098: tree cleanup_list; 1099: rtx first_insn; 1100: int dont_jump_in; 1101: { 1102: register struct goto_fixup *f, *prev; 1103: 1.1.1.6 root 1104: if (output_bytecode) 1105: { 1.1.1.7 ! root 1106: /* ??? The second arg is the bc stack level, which is not the same ! 1107: as STACK_LEVEL. I have no idea what should go here, so I'll ! 1108: just pass 0. */ ! 1109: bc_fixup_gotos (thisblock, 0, cleanup_list, first_insn, dont_jump_in); 1.1.1.6 root 1110: return; 1111: } 1112: 1.1 root 1113: /* F is the fixup we are considering; PREV is the previous one. */ 1114: /* We run this loop in two passes so that cleanups of exited blocks 1115: are run first, and blocks that are exited are marked so 1116: afterwards. */ 1117: 1118: for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next) 1119: { 1120: /* Test for a fixup that is inactive because it is already handled. */ 1121: if (f->before_jump == 0) 1122: { 1123: /* Delete inactive fixup from the chain, if that is easy to do. */ 1124: if (prev != 0) 1125: prev->next = f->next; 1126: } 1127: /* Has this fixup's target label been defined? 1128: If so, we can finalize it. */ 1129: else if (PREV_INSN (f->target_rtl) != 0) 1130: { 1.1.1.4 root 1131: register rtx cleanup_insns; 1132: 1.1 root 1133: /* Get the first non-label after the label 1134: this goto jumps to. If that's before this scope begins, 1135: we don't have a jump into the scope. */ 1136: rtx after_label = f->target_rtl; 1137: while (after_label != 0 && GET_CODE (after_label) == CODE_LABEL) 1138: after_label = NEXT_INSN (after_label); 1139: 1140: /* If this fixup jumped into this contour from before the beginning 1141: of this contour, report an error. */ 1142: /* ??? Bug: this does not detect jumping in through intermediate 1143: blocks that have stack levels or cleanups. 1144: It detects only a problem with the innermost block 1145: around the label. */ 1146: if (f->target != 0 1147: && (dont_jump_in || stack_level || cleanup_list) 1148: /* If AFTER_LABEL is 0, it means the jump goes to the end 1149: of the rtl, which means it jumps into this scope. */ 1150: && (after_label == 0 1151: || INSN_UID (first_insn) < INSN_UID (after_label)) 1152: && INSN_UID (first_insn) > INSN_UID (f->before_jump) 1.1.1.4 root 1153: && ! DECL_REGISTER (f->target)) 1.1 root 1154: { 1155: error_with_decl (f->target, 1156: "label `%s' used before containing binding contour"); 1157: /* Prevent multiple errors for one label. */ 1.1.1.4 root 1158: DECL_REGISTER (f->target) = 1; 1.1 root 1159: } 1160: 1.1.1.4 root 1161: /* We will expand the cleanups into a sequence of their own and 1162: then later on we will attach this new sequence to the insn 1163: stream just ahead of the actual jump insn. */ 1164: 1165: start_sequence (); 1166: 1167: /* Temporarily restore the lexical context where we will 1168: logically be inserting the fixup code. We do this for the 1169: sake of getting the debugging information right. */ 1170: 1171: pushlevel (0); 1172: set_block (f->context); 1173: 1174: /* Expand the cleanups for blocks this jump exits. */ 1.1 root 1175: if (f->cleanup_list_list) 1176: { 1177: tree lists; 1178: for (lists = f->cleanup_list_list; lists; lists = TREE_CHAIN (lists)) 1179: /* Marked elements correspond to blocks that have been closed. 1180: Do their cleanups. */ 1181: if (TREE_ADDRESSABLE (lists) 1182: && TREE_VALUE (lists) != 0) 1.1.1.4 root 1183: { 1184: expand_cleanups (TREE_VALUE (lists), 0); 1185: /* Pop any pushes done in the cleanups, 1186: in case function is about to return. */ 1187: do_pending_stack_adjust (); 1188: } 1.1 root 1189: } 1190: 1191: /* Restore stack level for the biggest contour that this 1192: jump jumps out of. */ 1193: if (f->stack_level) 1.1.1.3 root 1194: emit_stack_restore (SAVE_BLOCK, f->stack_level, f->before_jump); 1.1.1.4 root 1195: 1196: /* Finish up the sequence containing the insns which implement the 1197: necessary cleanups, and then attach that whole sequence to the 1198: insn stream just ahead of the actual jump insn. Attaching it 1199: at that point insures that any cleanups which are in fact 1200: implicit C++ object destructions (which must be executed upon 1201: leaving the block) appear (to the debugger) to be taking place 1202: in an area of the generated code where the object(s) being 1203: destructed are still "in scope". */ 1204: 1205: cleanup_insns = get_insns (); 1206: poplevel (1, 0, 0); 1207: 1208: end_sequence (); 1209: emit_insns_after (cleanup_insns, f->before_jump); 1210: 1211: 1.1 root 1212: f->before_jump = 0; 1213: } 1214: } 1215: 1216: /* Mark the cleanups of exited blocks so that they are executed 1217: by the code above. */ 1218: for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next) 1219: if (f->before_jump != 0 1220: && PREV_INSN (f->target_rtl) == 0 1221: /* Label has still not appeared. If we are exiting a block with 1222: a stack level to restore, that started before the fixup, 1223: mark this stack level as needing restoration 1224: when the fixup is later finalized. 1225: Also mark the cleanup_list_list element for F 1226: that corresponds to this block, so that ultimately 1227: this block's cleanups will be executed by the code above. */ 1228: && thisblock != 0 1229: /* Note: if THISBLOCK == 0 and we have a label that hasn't appeared, 1230: it means the label is undefined. That's erroneous, but possible. */ 1231: && (thisblock->data.block.block_start_count 1232: <= f->block_start_count)) 1233: { 1234: tree lists = f->cleanup_list_list; 1235: for (; lists; lists = TREE_CHAIN (lists)) 1236: /* If the following elt. corresponds to our containing block 1237: then the elt. must be for this block. */ 1238: if (TREE_CHAIN (lists) == thisblock->data.block.outer_cleanups) 1239: TREE_ADDRESSABLE (lists) = 1; 1240: 1241: if (stack_level) 1242: f->stack_level = stack_level; 1243: } 1244: } 1.1.1.6 root 1245: 1246: 1247: /* When exiting a binding contour, process all pending gotos requiring fixups. 1248: Note: STACK_DEPTH is not altered. 1249: 1.1.1.7 ! root 1250: The arguments are currently not used in the bytecode compiler, but we may ! 1251: need them one day for languages other than C. 1.1.1.6 root 1252: 1253: THISBLOCK is the structure that describes the block being exited. 1254: STACK_LEVEL is the rtx for the stack level to restore exiting this contour. 1255: CLEANUP_LIST is a list of expressions to evaluate on exiting this contour. 1256: FIRST_INSN is the insn that began this contour. 1257: 1258: Gotos that jump out of this contour must restore the 1259: stack level and do the cleanups before actually jumping. 1260: 1261: DONT_JUMP_IN nonzero means report error there is a jump into this 1262: contour from before the beginning of the contour. 1263: This is also done if STACK_LEVEL is nonzero. */ 1264: 1265: static void 1266: bc_fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in) 1267: struct nesting *thisblock; 1268: int stack_level; 1269: tree cleanup_list; 1270: rtx first_insn; 1271: int dont_jump_in; 1272: { 1273: register struct goto_fixup *f, *prev; 1274: int saved_stack_depth; 1275: 1276: /* F is the fixup we are considering; PREV is the previous one. */ 1277: 1278: for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next) 1279: { 1280: /* Test for a fixup that is inactive because it is already handled. */ 1281: if (f->before_jump == 0) 1282: { 1283: /* Delete inactive fixup from the chain, if that is easy to do. */ 1284: if (prev) 1285: prev->next = f->next; 1286: } 1287: 1288: /* Emit code to restore the stack and continue */ 1289: bc_emit_bytecode_labeldef (f->label); 1290: 1291: /* Save stack_depth across call, since bc_adjust_stack () will alter 1292: the perceived stack depth via the instructions generated. */ 1293: 1294: if (f->bc_stack_level >= 0) 1295: { 1296: saved_stack_depth = stack_depth; 1297: bc_adjust_stack (stack_depth - f->bc_stack_level); 1298: stack_depth = saved_stack_depth; 1299: } 1300: 1301: bc_emit_bytecode (jump); 1302: bc_emit_bytecode_labelref (f->bc_target); 1303: 1304: #ifdef DEBUG_PRINT_CODE 1305: fputc ('\n', stderr); 1306: #endif 1307: } 1308: 1309: goto_fixup_chain = NULL; 1310: } 1.1 root 1311: 1312: /* Generate RTL for an asm statement (explicit assembler code). 1313: BODY is a STRING_CST node containing the assembler code text, 1314: or an ADDR_EXPR containing a STRING_CST. */ 1315: 1316: void 1317: expand_asm (body) 1318: tree body; 1319: { 1.1.1.6 root 1320: if (output_bytecode) 1321: { 1322: error ("`asm' is illegal when generating bytecode"); 1323: return; 1324: } 1325: 1.1 root 1326: if (TREE_CODE (body) == ADDR_EXPR) 1327: body = TREE_OPERAND (body, 0); 1328: 1329: emit_insn (gen_rtx (ASM_INPUT, VOIDmode, 1330: TREE_STRING_POINTER (body))); 1331: last_expr_type = 0; 1332: } 1333: 1334: /* Generate RTL for an asm statement with arguments. 1335: STRING is the instruction template. 1336: OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs. 1337: Each output or input has an expression in the TREE_VALUE and 1338: a constraint-string in the TREE_PURPOSE. 1339: CLOBBERS is a list of STRING_CST nodes each naming a hard register 1340: that is clobbered by this insn. 1341: 1342: Not all kinds of lvalue that may appear in OUTPUTS can be stored directly. 1343: Some elements of OUTPUTS may be replaced with trees representing temporary 1344: values. The caller should copy those temporary values to the originally 1345: specified lvalues. 1346: 1347: VOL nonzero means the insn is volatile; don't optimize it. */ 1348: 1349: void 1350: expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) 1351: tree string, outputs, inputs, clobbers; 1352: int vol; 1353: char *filename; 1354: int line; 1355: { 1356: rtvec argvec, constraints; 1357: rtx body; 1358: int ninputs = list_length (inputs); 1359: int noutputs = list_length (outputs); 1.1.1.3 root 1360: int nclobbers; 1.1 root 1361: tree tail; 1362: register int i; 1363: /* Vector of RTX's of evaluated output operands. */ 1364: rtx *output_rtx = (rtx *) alloca (noutputs * sizeof (rtx)); 1365: /* The insn we have emitted. */ 1366: rtx insn; 1367: 1.1.1.6 root 1368: if (output_bytecode) 1369: { 1370: error ("`asm' is illegal when generating bytecode"); 1371: return; 1372: } 1373: 1.1.1.3 root 1374: /* Count the number of meaningful clobbered registers, ignoring what 1375: we would ignore later. */ 1376: nclobbers = 0; 1377: for (tail = clobbers; tail; tail = TREE_CHAIN (tail)) 1378: { 1379: char *regname = TREE_STRING_POINTER (TREE_VALUE (tail)); 1.1.1.4 root 1380: i = decode_reg_name (regname); 1381: if (i >= 0 || i == -4) 1.1.1.3 root 1382: ++nclobbers; 1.1.1.7 ! root 1383: else if (i == -2) ! 1384: error ("unknown register name `%s' in `asm'", regname); 1.1.1.3 root 1385: } 1386: 1.1 root 1387: last_expr_type = 0; 1388: 1389: for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) 1390: { 1391: tree val = TREE_VALUE (tail); 1392: tree val1; 1393: int j; 1394: int found_equal; 1395: 1396: /* If there's an erroneous arg, emit no insn. */ 1397: if (TREE_TYPE (val) == error_mark_node) 1398: return; 1399: 1400: /* Make sure constraint has `=' and does not have `+'. */ 1401: 1402: found_equal = 0; 1403: for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++) 1404: { 1405: if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+') 1406: { 1407: error ("output operand constraint contains `+'"); 1408: return; 1409: } 1410: if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '=') 1411: found_equal = 1; 1412: } 1413: if (! found_equal) 1414: { 1415: error ("output operand constraint lacks `='"); 1416: return; 1417: } 1418: 1419: /* If an output operand is not a variable or indirect ref, 1420: or a part of one, 1421: create a SAVE_EXPR which is a pseudo-reg 1422: to act as an intermediate temporary. 1423: Make the asm insn write into that, then copy it to 1424: the real output operand. */ 1425: 1426: while (TREE_CODE (val) == COMPONENT_REF 1427: || TREE_CODE (val) == ARRAY_REF) 1428: val = TREE_OPERAND (val, 0); 1429: 1430: if (TREE_CODE (val) != VAR_DECL 1431: && TREE_CODE (val) != PARM_DECL 1432: && TREE_CODE (val) != INDIRECT_REF) 1.1.1.5 root 1433: { 1434: TREE_VALUE (tail) = save_expr (TREE_VALUE (tail)); 1435: /* If it's a constant, print error now so don't crash later. */ 1436: if (TREE_CODE (TREE_VALUE (tail)) != SAVE_EXPR) 1437: { 1438: error ("invalid output in `asm'"); 1439: return; 1440: } 1441: } 1.1 root 1442: 1.1.1.4 root 1443: output_rtx[i] = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0); 1.1 root 1444: } 1445: 1446: if (ninputs + noutputs > MAX_RECOG_OPERANDS) 1447: { 1448: error ("more than %d operands in `asm'", MAX_RECOG_OPERANDS); 1449: return; 1450: } 1451: 1452: /* Make vectors for the expression-rtx and constraint strings. */ 1453: 1454: argvec = rtvec_alloc (ninputs); 1455: constraints = rtvec_alloc (ninputs); 1456: 1457: body = gen_rtx (ASM_OPERANDS, VOIDmode, 1458: TREE_STRING_POINTER (string), "", 0, argvec, constraints, 1459: filename, line); 1460: MEM_VOLATILE_P (body) = vol; 1461: 1462: /* Eval the inputs and put them into ARGVEC. 1463: Put their constraints into ASM_INPUTs and store in CONSTRAINTS. */ 1464: 1465: i = 0; 1466: for (tail = inputs; tail; tail = TREE_CHAIN (tail)) 1467: { 1468: int j; 1469: 1470: /* If there's an erroneous arg, emit no insn, 1471: because the ASM_INPUT would get VOIDmode 1472: and that could cause a crash in reload. */ 1473: if (TREE_TYPE (TREE_VALUE (tail)) == error_mark_node) 1474: return; 1475: if (TREE_PURPOSE (tail) == NULL_TREE) 1476: { 1477: error ("hard register `%s' listed as input operand to `asm'", 1478: TREE_STRING_POINTER (TREE_VALUE (tail)) ); 1479: return; 1480: } 1481: 1482: /* Make sure constraint has neither `=' nor `+'. */ 1483: 1484: for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++) 1485: if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '=' 1486: || TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+') 1487: { 1488: error ("input operand constraint contains `%c'", 1489: TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]); 1490: return; 1491: } 1492: 1493: XVECEXP (body, 3, i) /* argvec */ 1.1.1.4 root 1494: = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0); 1.1 root 1495: XVECEXP (body, 4, i) /* constraints */ 1496: = gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), 1497: TREE_STRING_POINTER (TREE_PURPOSE (tail))); 1498: i++; 1499: } 1500: 1501: /* Protect all the operands from the queue, 1502: now that they have all been evaluated. */ 1503: 1504: for (i = 0; i < ninputs; i++) 1505: XVECEXP (body, 3, i) = protect_from_queue (XVECEXP (body, 3, i), 0); 1506: 1507: for (i = 0; i < noutputs; i++) 1508: output_rtx[i] = protect_from_queue (output_rtx[i], 1); 1509: 1510: /* Now, for each output, construct an rtx 1511: (set OUTPUT (asm_operands INSN OUTPUTNUMBER OUTPUTCONSTRAINT 1512: ARGVEC CONSTRAINTS)) 1513: If there is more than one, put them inside a PARALLEL. */ 1514: 1515: if (noutputs == 1 && nclobbers == 0) 1516: { 1517: XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs)); 1518: insn = emit_insn (gen_rtx (SET, VOIDmode, output_rtx[0], body)); 1519: } 1520: else if (noutputs == 0 && nclobbers == 0) 1521: { 1522: /* No output operands: put in a raw ASM_OPERANDS rtx. */ 1523: insn = emit_insn (body); 1524: } 1525: else 1526: { 1527: rtx obody = body; 1528: int num = noutputs; 1529: if (num == 0) num = 1; 1530: body = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num + nclobbers)); 1531: 1532: /* For each output operand, store a SET. */ 1533: 1534: for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) 1535: { 1536: XVECEXP (body, 0, i) 1537: = gen_rtx (SET, VOIDmode, 1538: output_rtx[i], 1539: gen_rtx (ASM_OPERANDS, VOIDmode, 1540: TREE_STRING_POINTER (string), 1541: TREE_STRING_POINTER (TREE_PURPOSE (tail)), 1542: i, argvec, constraints, 1543: filename, line)); 1544: MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol; 1545: } 1546: 1547: /* If there are no outputs (but there are some clobbers) 1548: store the bare ASM_OPERANDS into the PARALLEL. */ 1549: 1550: if (i == 0) 1551: XVECEXP (body, 0, i++) = obody; 1552: 1553: /* Store (clobber REG) for each clobbered register specified. */ 1554: 1.1.1.3 root 1555: for (tail = clobbers; tail; tail = TREE_CHAIN (tail)) 1.1 root 1556: { 1557: char *regname = TREE_STRING_POINTER (TREE_VALUE (tail)); 1.1.1.2 root 1558: int j = decode_reg_name (regname); 1.1 root 1559: 1.1.1.2 root 1560: if (j < 0) 1.1 root 1561: { 1.1.1.4 root 1562: if (j == -3) /* `cc', which is not a register */ 1.1.1.3 root 1563: continue; 1564: 1.1.1.4 root 1565: if (j == -4) /* `memory', don't cache memory across asm */ 1566: { 1.1.1.5 root 1567: XVECEXP (body, 0, i++) 1568: = gen_rtx (CLOBBER, VOIDmode, 1.1.1.7 ! root 1569: gen_rtx (MEM, BLKmode, 1.1.1.5 root 1570: gen_rtx (SCRATCH, VOIDmode, 0))); 1.1.1.4 root 1571: continue; 1572: } 1573: 1.1.1.7 ! root 1574: /* Ignore unknown register, error already signalled. */ 1.1 root 1575: } 1576: 1577: /* Use QImode since that's guaranteed to clobber just one reg. */ 1.1.1.3 root 1578: XVECEXP (body, 0, i++) 1.1 root 1579: = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, QImode, j)); 1580: } 1581: 1582: insn = emit_insn (body); 1583: } 1584: 1585: free_temp_slots (); 1586: } 1587: 1588: /* Generate RTL to evaluate the expression EXP 1589: and remember it in case this is the VALUE in a ({... VALUE; }) constr. */ 1590: 1591: void 1592: expand_expr_stmt (exp) 1593: tree exp; 1594: { 1.1.1.6 root 1595: if (output_bytecode) 1596: { 1597: int org_stack_depth = stack_depth; 1598: 1599: bc_expand_expr (exp); 1600: 1601: /* Restore stack depth */ 1602: if (stack_depth < org_stack_depth) 1603: abort (); 1604: 1605: bc_emit_instruction (drop); 1606: 1607: last_expr_type = TREE_TYPE (exp); 1608: return; 1609: } 1610: 1.1 root 1611: /* If -W, warn about statements with no side effects, 1612: except for an explicit cast to void (e.g. for assert()), and 1613: except inside a ({...}) where they may be useful. */ 1614: if (expr_stmts_for_value == 0 && exp != error_mark_node) 1615: { 1616: if (! TREE_SIDE_EFFECTS (exp) && (extra_warnings || warn_unused) 1617: && !(TREE_CODE (exp) == CONVERT_EXPR 1618: && TREE_TYPE (exp) == void_type_node)) 1619: warning_with_file_and_line (emit_filename, emit_lineno, 1620: "statement with no effect"); 1621: else if (warn_unused) 1622: warn_if_unused_value (exp); 1623: } 1624: last_expr_type = TREE_TYPE (exp); 1625: if (! flag_syntax_only) 1.1.1.4 root 1626: last_expr_value = expand_expr (exp, 1627: (expr_stmts_for_value 1628: ? NULL_RTX : const0_rtx), 1.1 root 1629: VOIDmode, 0); 1630: 1631: /* If all we do is reference a volatile value in memory, 1632: copy it to a register to be sure it is actually touched. */ 1633: if (last_expr_value != 0 && GET_CODE (last_expr_value) == MEM 1634: && TREE_THIS_VOLATILE (exp)) 1635: { 1.1.1.5 root 1636: if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode) 1637: ; 1638: else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode) 1.1 root 1639: copy_to_reg (last_expr_value); 1640: else 1.1.1.3 root 1641: { 1642: rtx lab = gen_label_rtx (); 1643: 1644: /* Compare the value with itself to reference it. */ 1645: emit_cmp_insn (last_expr_value, last_expr_value, EQ, 1646: expand_expr (TYPE_SIZE (last_expr_type), 1.1.1.4 root 1647: NULL_RTX, VOIDmode, 0), 1.1.1.3 root 1648: BLKmode, 0, 1649: TYPE_ALIGN (last_expr_type) / BITS_PER_UNIT); 1650: emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (lab)); 1651: emit_label (lab); 1652: } 1.1 root 1653: } 1654: 1655: /* If this expression is part of a ({...}) and is in memory, we may have 1656: to preserve temporaries. */ 1657: preserve_temp_slots (last_expr_value); 1658: 1659: /* Free any temporaries used to evaluate this expression. Any temporary 1660: used as a result of this expression will already have been preserved 1661: above. */ 1662: free_temp_slots (); 1663: 1664: emit_queue (); 1665: } 1666: 1667: /* Warn if EXP contains any computations whose results are not used. 1668: Return 1 if a warning is printed; 0 otherwise. */ 1669: 1670: static int 1671: warn_if_unused_value (exp) 1672: tree exp; 1673: { 1674: if (TREE_USED (exp)) 1675: return 0; 1676: 1677: switch (TREE_CODE (exp)) 1678: { 1679: case PREINCREMENT_EXPR: 1680: case POSTINCREMENT_EXPR: 1681: case PREDECREMENT_EXPR: 1682: case POSTDECREMENT_EXPR: 1683: case MODIFY_EXPR: 1684: case INIT_EXPR: 1685: case TARGET_EXPR: 1686: case CALL_EXPR: 1687: case METHOD_CALL_EXPR: 1688: case RTL_EXPR: 1689: case WITH_CLEANUP_EXPR: 1690: case EXIT_EXPR: 1691: /* We don't warn about COND_EXPR because it may be a useful 1692: construct if either arm contains a side effect. */ 1693: case COND_EXPR: 1694: return 0; 1695: 1696: case BIND_EXPR: 1697: /* For a binding, warn if no side effect within it. */ 1698: return warn_if_unused_value (TREE_OPERAND (exp, 1)); 1699: 1700: case TRUTH_ORIF_EXPR: 1701: case TRUTH_ANDIF_EXPR: 1702: /* In && or ||, warn if 2nd operand has no side effect. */ 1703: return warn_if_unused_value (TREE_OPERAND (exp, 1)); 1704: 1705: case COMPOUND_EXPR: 1.1.1.7 ! root 1706: if (TREE_NO_UNUSED_WARNING (exp)) ! 1707: return 0; 1.1 root 1708: if (warn_if_unused_value (TREE_OPERAND (exp, 0))) 1709: return 1; 1.1.1.3 root 1710: /* Let people do `(foo (), 0)' without a warning. */ 1711: if (TREE_CONSTANT (TREE_OPERAND (exp, 1))) 1712: return 0; 1.1 root 1713: return warn_if_unused_value (TREE_OPERAND (exp, 1)); 1714: 1715: case NOP_EXPR: 1716: case CONVERT_EXPR: 1.1.1.2 root 1717: case NON_LVALUE_EXPR: 1.1 root 1718: /* Don't warn about values cast to void. */ 1719: if (TREE_TYPE (exp) == void_type_node) 1720: return 0; 1721: /* Don't warn about conversions not explicit in the user's program. */ 1722: if (TREE_NO_UNUSED_WARNING (exp)) 1723: return 0; 1724: /* Assignment to a cast usually results in a cast of a modify. 1.1.1.6 root 1725: Don't complain about that. There can be an arbitrary number of 1726: casts before the modify, so we must loop until we find the first 1727: non-cast expression and then test to see if that is a modify. */ 1728: { 1729: tree tem = TREE_OPERAND (exp, 0); 1730: 1731: while (TREE_CODE (tem) == CONVERT_EXPR || TREE_CODE (tem) == NOP_EXPR) 1732: tem = TREE_OPERAND (tem, 0); 1733: 1.1.1.7 ! root 1734: if (TREE_CODE (tem) == MODIFY_EXPR || TREE_CODE (tem) == INIT_EXPR) 1.1.1.6 root 1735: return 0; 1736: } 1737: /* ... fall through ... */ 1.1 root 1738: 1739: default: 1.1.1.3 root 1740: /* Referencing a volatile value is a side effect, so don't warn. */ 1741: if ((TREE_CODE_CLASS (TREE_CODE (exp)) == 'd' 1742: || TREE_CODE_CLASS (TREE_CODE (exp)) == 'r') 1743: && TREE_THIS_VOLATILE (exp)) 1744: return 0; 1.1 root 1745: warning_with_file_and_line (emit_filename, emit_lineno, 1746: "value computed is not used"); 1747: return 1; 1748: } 1749: } 1750: 1751: /* Clear out the memory of the last expression evaluated. */ 1752: 1753: void 1754: clear_last_expr () 1755: { 1756: last_expr_type = 0; 1757: } 1758: 1759: /* Begin a statement which will return a value. 1760: Return the RTL_EXPR for this statement expr. 1761: The caller must save that value and pass it to expand_end_stmt_expr. */ 1762: 1763: tree 1764: expand_start_stmt_expr () 1765: { 1.1.1.6 root 1766: int momentary; 1767: tree t; 1768: 1769: /* When generating bytecode just note down the stack depth */ 1770: if (output_bytecode) 1771: return (build_int_2 (stack_depth, 0)); 1772: 1.1 root 1773: /* Make the RTL_EXPR node temporary, not momentary, 1774: so that rtl_expr_chain doesn't become garbage. */ 1.1.1.6 root 1775: momentary = suspend_momentary (); 1776: t = make_node (RTL_EXPR); 1.1 root 1777: resume_momentary (momentary); 1.1.1.6 root 1778: start_sequence_for_rtl_expr (t); 1.1 root 1779: NO_DEFER_POP; 1780: expr_stmts_for_value++; 1781: return t; 1782: } 1783: 1784: /* Restore the previous state at the end of a statement that returns a value. 1785: Returns a tree node representing the statement's value and the 1786: insns to compute the value. 1787: 1788: The nodes of that expression have been freed by now, so we cannot use them. 1789: But we don't want to do that anyway; the expression has already been 1790: evaluated and now we just want to use the value. So generate a RTL_EXPR 1791: with the proper type and RTL value. 1792: 1793: If the last substatement was not an expression, 1794: return something with type `void'. */ 1795: 1796: tree 1797: expand_end_stmt_expr (t) 1798: tree t; 1799: { 1.1.1.6 root 1800: if (output_bytecode) 1801: { 1802: int i; 1803: tree t; 1804: 1805: 1806: /* At this point, all expressions have been evaluated in order. 1807: However, all expression values have been popped when evaluated, 1808: which means we have to recover the last expression value. This is 1809: the last value removed by means of a `drop' instruction. Instead 1810: of adding code to inhibit dropping the last expression value, it 1811: is here recovered by undoing the `drop'. Since `drop' is 1812: equivalent to `adjustackSI [1]', it can be undone with `adjstackSI 1813: [-1]'. */ 1814: 1815: bc_adjust_stack (-1); 1816: 1817: if (!last_expr_type) 1818: last_expr_type = void_type_node; 1819: 1820: t = make_node (RTL_EXPR); 1821: TREE_TYPE (t) = last_expr_type; 1822: RTL_EXPR_RTL (t) = NULL; 1823: RTL_EXPR_SEQUENCE (t) = NULL; 1824: 1825: /* Don't consider deleting this expr or containing exprs at tree level. */ 1826: TREE_THIS_VOLATILE (t) = 1; 1827: 1828: last_expr_type = 0; 1829: return t; 1830: } 1831: 1.1 root 1832: OK_DEFER_POP; 1833: 1834: if (last_expr_type == 0) 1835: { 1836: last_expr_type = void_type_node; 1837: last_expr_value = const0_rtx; 1838: } 1839: else if (last_expr_value == 0) 1840: /* There are some cases where this can happen, such as when the 1841: statement is void type. */ 1842: last_expr_value = const0_rtx; 1843: else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value)) 1844: /* Remove any possible QUEUED. */ 1845: last_expr_value = protect_from_queue (last_expr_value, 0); 1846: 1847: emit_queue (); 1848: 1849: TREE_TYPE (t) = last_expr_type; 1850: RTL_EXPR_RTL (t) = last_expr_value; 1851: RTL_EXPR_SEQUENCE (t) = get_insns (); 1852: 1853: rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain); 1854: 1855: end_sequence (); 1856: 1857: /* Don't consider deleting this expr or containing exprs at tree level. */ 1858: TREE_SIDE_EFFECTS (t) = 1; 1859: /* Propagate volatility of the actual RTL expr. */ 1860: TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value); 1861: 1862: last_expr_type = 0; 1863: expr_stmts_for_value--; 1864: 1865: return t; 1866: } 1867: 1868: /* Generate RTL for the start of an if-then. COND is the expression 1869: whose truth should be tested. 1870: 1871: If EXITFLAG is nonzero, this conditional is visible to 1872: `exit_something'. */ 1873: 1874: void 1875: expand_start_cond (cond, exitflag) 1876: tree cond; 1877: int exitflag; 1878: { 1879: struct nesting *thiscond = ALLOC_NESTING (); 1880: 1881: /* Make an entry on cond_stack for the cond we are entering. */ 1882: 1883: thiscond->next = cond_stack; 1884: thiscond->all = nesting_stack; 1885: thiscond->depth = ++nesting_depth; 1886: thiscond->data.cond.next_label = gen_label_rtx (); 1887: /* Before we encounter an `else', we don't need a separate exit label 1888: unless there are supposed to be exit statements 1889: to exit this conditional. */ 1890: thiscond->exit_label = exitflag ? gen_label_rtx () : 0; 1891: thiscond->data.cond.endif_label = thiscond->exit_label; 1892: cond_stack = thiscond; 1893: nesting_stack = thiscond; 1894: 1.1.1.6 root 1895: if (output_bytecode) 1896: bc_expand_start_cond (cond, exitflag); 1897: else 1898: do_jump (cond, thiscond->data.cond.next_label, NULL_RTX); 1.1 root 1899: } 1900: 1901: /* Generate RTL between then-clause and the elseif-clause 1902: of an if-then-elseif-.... */ 1903: 1904: void 1905: expand_start_elseif (cond) 1906: tree cond; 1907: { 1908: if (cond_stack->data.cond.endif_label == 0) 1909: cond_stack->data.cond.endif_label = gen_label_rtx (); 1910: emit_jump (cond_stack->data.cond.endif_label); 1911: emit_label (cond_stack->data.cond.next_label); 1912: cond_stack->data.cond.next_label = gen_label_rtx (); 1.1.1.4 root 1913: do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX); 1.1 root 1914: } 1915: 1916: /* Generate RTL between the then-clause and the else-clause 1917: of an if-then-else. */ 1918: 1919: void 1920: expand_start_else () 1921: { 1922: if (cond_stack->data.cond.endif_label == 0) 1923: cond_stack->data.cond.endif_label = gen_label_rtx (); 1.1.1.6 root 1924: 1925: if (output_bytecode) 1926: { 1927: bc_expand_start_else (); 1928: return; 1929: } 1930: 1.1 root 1931: emit_jump (cond_stack->data.cond.endif_label); 1932: emit_label (cond_stack->data.cond.next_label); 1933: cond_stack->data.cond.next_label = 0; /* No more _else or _elseif calls. */ 1934: } 1935: 1.1.1.7 ! root 1936: /* After calling expand_start_else, turn this "else" into an "else if" ! 1937: by providing another condition. */ ! 1938: ! 1939: void ! 1940: expand_elseif (cond) ! 1941: tree cond; ! 1942: { ! 1943: cond_stack->data.cond.next_label = gen_label_rtx (); ! 1944: do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX); ! 1945: } ! 1946: 1.1 root 1947: /* Generate RTL for the end of an if-then. 1948: Pop the record for it off of cond_stack. */ 1949: 1950: void 1951: expand_end_cond () 1952: { 1953: struct nesting *thiscond = cond_stack; 1954: 1.1.1.6 root 1955: if (output_bytecode) 1956: bc_expand_end_cond (); 1957: else 1958: { 1959: do_pending_stack_adjust (); 1960: if (thiscond->data.cond.next_label) 1961: emit_label (thiscond->data.cond.next_label); 1962: if (thiscond->data.cond.endif_label) 1963: emit_label (thiscond->data.cond.endif_label); 1964: } 1.1 root 1965: 1966: POPSTACK (cond_stack); 1967: last_expr_type = 0; 1968: } 1.1.1.6 root 1969: 1970: 1971: /* Generate code for the start of an if-then. COND is the expression 1972: whose truth is to be tested; if EXITFLAG is nonzero this conditional 1973: is to be visible to exit_something. It is assumed that the caller 1974: has pushed the previous context on the cond stack. */ 1.1.1.7 ! root 1975: ! 1976: static void 1.1.1.6 root 1977: bc_expand_start_cond (cond, exitflag) 1978: tree cond; 1979: int exitflag; 1980: { 1981: struct nesting *thiscond = cond_stack; 1982: 1983: thiscond->data.case_stmt.nominal_type = cond; 1.1.1.7 ! root 1984: if (! exitflag) ! 1985: thiscond->exit_label = gen_label_rtx (); 1.1.1.6 root 1986: bc_expand_expr (cond); 1987: bc_emit_bytecode (xjumpifnot); 1988: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscond->exit_label)); 1989: 1990: #ifdef DEBUG_PRINT_CODE 1991: fputc ('\n', stderr); 1992: #endif 1993: } 1994: 1995: /* Generate the label for the end of an if with 1996: no else- clause. */ 1.1.1.7 ! root 1997: ! 1998: static void 1.1.1.6 root 1999: bc_expand_end_cond () 2000: { 2001: struct nesting *thiscond = cond_stack; 2002: 2003: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscond->exit_label)); 2004: } 2005: 2006: /* Generate code for the start of the else- clause of 2007: an if-then-else. */ 1.1.1.7 ! root 2008: ! 2009: static void 1.1.1.6 root 2010: bc_expand_start_else () 2011: { 2012: struct nesting *thiscond = cond_stack; 2013: 2014: thiscond->data.cond.endif_label = thiscond->exit_label; 2015: thiscond->exit_label = gen_label_rtx (); 2016: bc_emit_bytecode (jump); 2017: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscond->exit_label)); 2018: 2019: #ifdef DEBUG_PRINT_CODE 2020: fputc ('\n', stderr); 2021: #endif 2022: 2023: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscond->data.cond.endif_label)); 2024: } 1.1 root 2025: 2026: /* Generate RTL for the start of a loop. EXIT_FLAG is nonzero if this 2027: loop should be exited by `exit_something'. This is a loop for which 2028: `expand_continue' will jump to the top of the loop. 2029: 2030: Make an entry on loop_stack to record the labels associated with 2031: this loop. */ 2032: 2033: struct nesting * 2034: expand_start_loop (exit_flag) 2035: int exit_flag; 2036: { 2037: register struct nesting *thisloop = ALLOC_NESTING (); 2038: 2039: /* Make an entry on loop_stack for the loop we are entering. */ 2040: 2041: thisloop->next = loop_stack; 2042: thisloop->all = nesting_stack; 2043: thisloop->depth = ++nesting_depth; 2044: thisloop->data.loop.start_label = gen_label_rtx (); 2045: thisloop->data.loop.end_label = gen_label_rtx (); 1.1.1.7 ! root 2046: thisloop->data.loop.alt_end_label = 0; 1.1 root 2047: thisloop->data.loop.continue_label = thisloop->data.loop.start_label; 2048: thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0; 2049: loop_stack = thisloop; 2050: nesting_stack = thisloop; 2051: 1.1.1.6 root 2052: if (output_bytecode) 2053: { 2054: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisloop->data.loop.start_label)); 2055: return thisloop; 2056: } 2057: 1.1 root 2058: do_pending_stack_adjust (); 2059: emit_queue (); 1.1.1.4 root 2060: emit_note (NULL_PTR, NOTE_INSN_LOOP_BEG); 1.1 root 2061: emit_label (thisloop->data.loop.start_label); 2062: 2063: return thisloop; 2064: } 2065: 2066: /* Like expand_start_loop but for a loop where the continuation point 2067: (for expand_continue_loop) will be specified explicitly. */ 2068: 2069: struct nesting * 2070: expand_start_loop_continue_elsewhere (exit_flag) 2071: int exit_flag; 2072: { 2073: struct nesting *thisloop = expand_start_loop (exit_flag); 2074: loop_stack->data.loop.continue_label = gen_label_rtx (); 2075: return thisloop; 2076: } 2077: 2078: /* Specify the continuation point for a loop started with 2079: expand_start_loop_continue_elsewhere. 2080: Use this at the point in the code to which a continue statement 2081: should jump. */ 2082: 2083: void 2084: expand_loop_continue_here () 2085: { 1.1.1.6 root 2086: if (output_bytecode) 2087: { 2088: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (loop_stack->data.loop.continue_label)); 2089: return; 2090: } 1.1 root 2091: do_pending_stack_adjust (); 1.1.1.4 root 2092: emit_note (NULL_PTR, NOTE_INSN_LOOP_CONT); 1.1 root 2093: emit_label (loop_stack->data.loop.continue_label); 2094: } 2095: 1.1.1.6 root 2096: /* End a loop. */ 1.1.1.7 ! root 2097: 1.1.1.6 root 2098: static void 2099: bc_expand_end_loop () 2100: { 2101: struct nesting *thisloop = loop_stack; 2102: 2103: bc_emit_bytecode (jump); 2104: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thisloop->data.loop.start_label)); 2105: 2106: #ifdef DEBUG_PRINT_CODE 2107: fputc ('\n', stderr); 2108: #endif 2109: 2110: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisloop->exit_label)); 2111: POPSTACK (loop_stack); 2112: last_expr_type = 0; 2113: } 2114: 2115: 1.1 root 2116: /* Finish a loop. Generate a jump back to the top and the loop-exit label. 2117: Pop the block off of loop_stack. */ 2118: 2119: void 2120: expand_end_loop () 2121: { 1.1.1.6 root 2122: register rtx insn; 2123: register rtx start_label; 1.1 root 2124: rtx last_test_insn = 0; 2125: int num_insns = 0; 1.1.1.6 root 2126: 2127: if (output_bytecode) 2128: { 2129: bc_expand_end_loop (); 2130: return; 2131: } 2132: 2133: insn = get_last_insn (); 2134: start_label = loop_stack->data.loop.start_label; 1.1 root 2135: 2136: /* Mark the continue-point at the top of the loop if none elsewhere. */ 2137: if (start_label == loop_stack->data.loop.continue_label) 2138: emit_note_before (NOTE_INSN_LOOP_CONT, start_label); 2139: 2140: do_pending_stack_adjust (); 2141: 2142: /* If optimizing, perhaps reorder the loop. If the loop 2143: starts with a conditional exit, roll that to the end 2144: where it will optimize together with the jump back. 2145: 2146: We look for the last conditional branch to the exit that we encounter 2147: before hitting 30 insns or a CALL_INSN. If we see an unconditional 2148: branch to the exit first, use it. 2149: 2150: We must also stop at NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes 2151: because moving them is not valid. */ 2152: 2153: if (optimize 2154: && 2155: ! (GET_CODE (insn) == JUMP_INSN 2156: && GET_CODE (PATTERN (insn)) == SET 2157: && SET_DEST (PATTERN (insn)) == pc_rtx 2158: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)) 2159: { 2160: /* Scan insns from the top of the loop looking for a qualified 2161: conditional exit. */ 2162: for (insn = NEXT_INSN (loop_stack->data.loop.start_label); insn; 2163: insn = NEXT_INSN (insn)) 2164: { 2165: if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CODE_LABEL) 2166: break; 2167: 2168: if (GET_CODE (insn) == NOTE 2169: && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG 2170: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)) 2171: break; 2172: 2173: if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == INSN) 2174: num_insns++; 2175: 2176: if (last_test_insn && num_insns > 30) 2177: break; 2178: 2179: if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET 2180: && SET_DEST (PATTERN (insn)) == pc_rtx 2181: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE 2182: && ((GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == LABEL_REF 1.1.1.7 ! root 2183: && ((XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0) ! 2184: == loop_stack->data.loop.end_label) ! 2185: || (XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0) ! 2186: == loop_stack->data.loop.alt_end_label))) 1.1 root 2187: || (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF 1.1.1.7 ! root 2188: && ((XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0) ! 2189: == loop_stack->data.loop.end_label) ! 2190: || (XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0) ! 2191: == loop_stack->data.loop.alt_end_label))))) 1.1 root 2192: last_test_insn = insn; 2193: 2194: if (last_test_insn == 0 && GET_CODE (insn) == JUMP_INSN 2195: && GET_CODE (PATTERN (insn)) == SET 2196: && SET_DEST (PATTERN (insn)) == pc_rtx 2197: && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF 1.1.1.7 ! root 2198: && ((XEXP (SET_SRC (PATTERN (insn)), 0) ! 2199: == loop_stack->data.loop.end_label) ! 2200: || (XEXP (SET_SRC (PATTERN (insn)), 0) ! 2201: == loop_stack->data.loop.alt_end_label))) 1.1 root 2202: /* Include BARRIER. */ 2203: last_test_insn = NEXT_INSN (insn); 2204: } 2205: 2206: if (last_test_insn != 0 && last_test_insn != get_last_insn ()) 2207: { 2208: /* We found one. Move everything from there up 2209: to the end of the loop, and add a jump into the loop 2210: to jump to there. */ 2211: register rtx newstart_label = gen_label_rtx (); 2212: register rtx start_move = start_label; 2213: 1.1.1.2 root 2214: /* If the start label is preceded by a NOTE_INSN_LOOP_CONT note, 1.1 root 2215: then we want to move this note also. */ 2216: if (GET_CODE (PREV_INSN (start_move)) == NOTE 2217: && (NOTE_LINE_NUMBER (PREV_INSN (start_move)) 2218: == NOTE_INSN_LOOP_CONT)) 2219: start_move = PREV_INSN (start_move); 2220: 2221: emit_label_after (newstart_label, PREV_INSN (start_move)); 2222: reorder_insns (start_move, last_test_insn, get_last_insn ()); 2223: emit_jump_insn_after (gen_jump (start_label), 2224: PREV_INSN (newstart_label)); 2225: emit_barrier_after (PREV_INSN (newstart_label)); 2226: start_label = newstart_label; 2227: } 2228: } 2229: 2230: emit_jump (start_label); 1.1.1.4 root 2231: emit_note (NULL_PTR, NOTE_INSN_LOOP_END); 1.1 root 2232: emit_label (loop_stack->data.loop.end_label); 2233: 2234: POPSTACK (loop_stack); 2235: 2236: last_expr_type = 0; 2237: } 2238: 2239: /* Generate a jump to the current loop's continue-point. 2240: This is usually the top of the loop, but may be specified 2241: explicitly elsewhere. If not currently inside a loop, 2242: return 0 and do nothing; caller will print an error message. */ 2243: 2244: int 2245: expand_continue_loop (whichloop) 2246: struct nesting *whichloop; 2247: { 2248: last_expr_type = 0; 2249: if (whichloop == 0) 2250: whichloop = loop_stack; 2251: if (whichloop == 0) 2252: return 0; 1.1.1.4 root 2253: expand_goto_internal (NULL_TREE, whichloop->data.loop.continue_label, 2254: NULL_RTX); 1.1 root 2255: return 1; 2256: } 2257: 2258: /* Generate a jump to exit the current loop. If not currently inside a loop, 2259: return 0 and do nothing; caller will print an error message. */ 2260: 2261: int 2262: expand_exit_loop (whichloop) 2263: struct nesting *whichloop; 2264: { 2265: last_expr_type = 0; 2266: if (whichloop == 0) 2267: whichloop = loop_stack; 2268: if (whichloop == 0) 2269: return 0; 1.1.1.4 root 2270: expand_goto_internal (NULL_TREE, whichloop->data.loop.end_label, NULL_RTX); 1.1 root 2271: return 1; 2272: } 2273: 2274: /* Generate a conditional jump to exit the current loop if COND 2275: evaluates to zero. If not currently inside a loop, 2276: return 0 and do nothing; caller will print an error message. */ 2277: 2278: int 2279: expand_exit_loop_if_false (whichloop, cond) 2280: struct nesting *whichloop; 2281: tree cond; 2282: { 2283: last_expr_type = 0; 2284: if (whichloop == 0) 2285: whichloop = loop_stack; 2286: if (whichloop == 0) 2287: return 0; 1.1.1.6 root 2288: if (output_bytecode) 2289: { 2290: bc_expand_expr (cond); 2291: bc_expand_goto_internal (xjumpifnot, 2292: BYTECODE_BC_LABEL (whichloop->exit_label), 1.1.1.7 ! root 2293: NULL_TREE); 1.1.1.6 root 2294: } 2295: else 1.1.1.7 ! root 2296: { ! 2297: /* In order to handle fixups, we actually create a conditional jump ! 2298: around a unconditional branch to exit the loop. If fixups are ! 2299: necessary, they go before the unconditional branch. */ ! 2300: ! 2301: rtx label = gen_label_rtx (); ! 2302: rtx last_insn; ! 2303: ! 2304: do_jump (cond, NULL_RTX, label); ! 2305: last_insn = get_last_insn (); ! 2306: if (GET_CODE (last_insn) == CODE_LABEL) ! 2307: whichloop->data.loop.alt_end_label = last_insn; ! 2308: expand_goto_internal (NULL_TREE, whichloop->data.loop.end_label, ! 2309: NULL_RTX); ! 2310: emit_label (label); ! 2311: } 1.1.1.6 root 2312: 1.1 root 2313: return 1; 2314: } 2315: 2316: /* Return non-zero if we should preserve sub-expressions as separate 2317: pseudos. We never do so if we aren't optimizing. We always do so 2318: if -fexpensive-optimizations. 2319: 2320: Otherwise, we only do so if we are in the "early" part of a loop. I.e., 2321: the loop may still be a small one. */ 2322: 2323: int 2324: preserve_subexpressions_p () 2325: { 2326: rtx insn; 2327: 2328: if (flag_expensive_optimizations) 2329: return 1; 2330: 2331: if (optimize == 0 || loop_stack == 0) 2332: return 0; 2333: 2334: insn = get_last_insn_anywhere (); 2335: 2336: return (insn 2337: && (INSN_UID (insn) - INSN_UID (loop_stack->data.loop.start_label) 2338: < n_non_fixed_regs * 3)); 2339: 2340: } 2341: 2342: /* Generate a jump to exit the current loop, conditional, binding contour 2343: or case statement. Not all such constructs are visible to this function, 2344: only those started with EXIT_FLAG nonzero. Individual languages use 2345: the EXIT_FLAG parameter to control which kinds of constructs you can 2346: exit this way. 2347: 2348: If not currently inside anything that can be exited, 2349: return 0 and do nothing; caller will print an error message. */ 2350: 2351: int 2352: expand_exit_something () 2353: { 2354: struct nesting *n; 2355: last_expr_type = 0; 2356: for (n = nesting_stack; n; n = n->all) 2357: if (n->exit_label != 0) 2358: { 1.1.1.4 root 2359: expand_goto_internal (NULL_TREE, n->exit_label, NULL_RTX); 1.1 root 2360: return 1; 2361: } 2362: 2363: return 0; 2364: } 2365: 2366: /* Generate RTL to return from the current function, with no value. 2367: (That is, we do not do anything about returning any value.) */ 2368: 2369: void 2370: expand_null_return () 2371: { 2372: struct nesting *block = block_stack; 2373: rtx last_insn = 0; 2374: 1.1.1.6 root 2375: if (output_bytecode) 2376: { 2377: bc_emit_instruction (ret); 2378: return; 2379: } 2380: 1.1 root 2381: /* Does any pending block have cleanups? */ 2382: 2383: while (block && block->data.block.cleanups == 0) 2384: block = block->next; 2385: 2386: /* If yes, use a goto to return, since that runs cleanups. */ 2387: 2388: expand_null_return_1 (last_insn, block != 0); 2389: } 2390: 2391: /* Generate RTL to return from the current function, with value VAL. */ 2392: 2393: void 2394: expand_value_return (val) 2395: rtx val; 2396: { 2397: struct nesting *block = block_stack; 2398: rtx last_insn = get_last_insn (); 2399: rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl)); 2400: 2401: /* Copy the value to the return location 2402: unless it's already there. */ 2403: 2404: if (return_reg != val) 1.1.1.4 root 2405: { 2406: #ifdef PROMOTE_FUNCTION_RETURN 2407: tree type = TREE_TYPE (DECL_RESULT (current_function_decl)); 2408: int unsignedp = TREE_UNSIGNED (type); 1.1.1.7 ! root 2409: enum machine_mode mode ! 2410: = promote_mode (type, DECL_MODE (DECL_RESULT (current_function_decl)), ! 2411: &unsignedp, 1); 1.1.1.4 root 2412: 2413: if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode) 1.1.1.5 root 2414: convert_move (return_reg, val, unsignedp); 1.1.1.4 root 2415: else 2416: #endif 2417: emit_move_insn (return_reg, val); 2418: } 1.1 root 2419: if (GET_CODE (return_reg) == REG 2420: && REGNO (return_reg) < FIRST_PSEUDO_REGISTER) 2421: emit_insn (gen_rtx (USE, VOIDmode, return_reg)); 2422: 2423: /* Does any pending block have cleanups? */ 2424: 2425: while (block && block->data.block.cleanups == 0) 2426: block = block->next; 2427: 2428: /* If yes, use a goto to return, since that runs cleanups. 2429: Use LAST_INSN to put cleanups *before* the move insn emitted above. */ 2430: 2431: expand_null_return_1 (last_insn, block != 0); 2432: } 2433: 2434: /* Output a return with no value. If LAST_INSN is nonzero, 2435: pretend that the return takes place after LAST_INSN. 2436: If USE_GOTO is nonzero then don't use a return instruction; 2437: go to the return label instead. This causes any cleanups 2438: of pending blocks to be executed normally. */ 2439: 2440: static void 2441: expand_null_return_1 (last_insn, use_goto) 2442: rtx last_insn; 2443: int use_goto; 2444: { 2445: rtx end_label = cleanup_label ? cleanup_label : return_label; 2446: 2447: clear_pending_stack_adjust (); 2448: do_pending_stack_adjust (); 2449: last_expr_type = 0; 2450: 2451: /* PCC-struct return always uses an epilogue. */ 2452: if (current_function_returns_pcc_struct || use_goto) 2453: { 2454: if (end_label == 0) 2455: end_label = return_label = gen_label_rtx (); 1.1.1.4 root 2456: expand_goto_internal (NULL_TREE, end_label, last_insn); 1.1 root 2457: return; 2458: } 2459: 2460: /* Otherwise output a simple return-insn if one is available, 2461: unless it won't do the job. */ 2462: #ifdef HAVE_return 2463: if (HAVE_return && use_goto == 0 && cleanup_label == 0) 2464: { 2465: emit_jump_insn (gen_return ()); 2466: emit_barrier (); 2467: return; 2468: } 2469: #endif 2470: 2471: /* Otherwise jump to the epilogue. */ 1.1.1.4 root 2472: expand_goto_internal (NULL_TREE, end_label, last_insn); 1.1 root 2473: } 2474: 2475: /* Generate RTL to evaluate the expression RETVAL and return it 2476: from the current function. */ 2477: 2478: void 2479: expand_return (retval) 2480: tree retval; 2481: { 2482: /* If there are any cleanups to be performed, then they will 2483: be inserted following LAST_INSN. It is desirable 2484: that the last_insn, for such purposes, should be the 2485: last insn before computing the return value. Otherwise, cleanups 2486: which call functions can clobber the return value. */ 2487: /* ??? rms: I think that is erroneous, because in C++ it would 2488: run destructors on variables that might be used in the subsequent 2489: computation of the return value. */ 2490: rtx last_insn = 0; 2491: register rtx val = 0; 2492: register rtx op0; 2493: tree retval_rhs; 2494: int cleanups; 2495: struct nesting *block; 2496: 1.1.1.6 root 2497: /* Bytecode returns are quite simple, just leave the result on the 2498: arithmetic stack. */ 2499: if (output_bytecode) 2500: { 2501: bc_expand_expr (retval); 2502: bc_emit_instruction (ret); 2503: return; 2504: } 2505: 1.1 root 2506: /* If function wants no value, give it none. */ 2507: if (TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl))) == VOID_TYPE) 2508: { 1.1.1.4 root 2509: expand_expr (retval, NULL_RTX, VOIDmode, 0); 2510: emit_queue (); 1.1 root 2511: expand_null_return (); 2512: return; 2513: } 2514: 2515: /* Are any cleanups needed? E.g. C++ destructors to be run? */ 1.1.1.7 ! root 2516: /* This is not sufficient. We also need to watch for cleanups of the ! 2517: expression we are about to expand. Unfortunately, we cannot know ! 2518: if it has cleanups until we expand it, and we want to change how we ! 2519: expand it depending upon if we need cleanups. We can't win. */ ! 2520: #if 0 1.1 root 2521: cleanups = any_pending_cleanups (1); 1.1.1.7 ! root 2522: #else ! 2523: cleanups = 1; ! 2524: #endif 1.1 root 2525: 2526: if (TREE_CODE (retval) == RESULT_DECL) 2527: retval_rhs = retval; 2528: else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR) 2529: && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL) 2530: retval_rhs = TREE_OPERAND (retval, 1); 2531: else if (TREE_TYPE (retval) == void_type_node) 2532: /* Recognize tail-recursive call to void function. */ 2533: retval_rhs = retval; 2534: else 2535: retval_rhs = NULL_TREE; 2536: 2537: /* Only use `last_insn' if there are cleanups which must be run. */ 2538: if (cleanups || cleanup_label != 0) 2539: last_insn = get_last_insn (); 2540: 2541: /* Distribute return down conditional expr if either of the sides 2542: may involve tail recursion (see test below). This enhances the number 2543: of tail recursions we see. Don't do this always since it can produce 2544: sub-optimal code in some cases and we distribute assignments into 2545: conditional expressions when it would help. */ 2546: 2547: if (optimize && retval_rhs != 0 2548: && frame_offset == 0 2549: && TREE_CODE (retval_rhs) == COND_EXPR 2550: && (TREE_CODE (TREE_OPERAND (retval_rhs, 1)) == CALL_EXPR 2551: || TREE_CODE (TREE_OPERAND (retval_rhs, 2)) == CALL_EXPR)) 2552: { 2553: rtx label = gen_label_rtx (); 1.1.1.6 root 2554: tree expr; 2555: 1.1.1.4 root 2556: do_jump (TREE_OPERAND (retval_rhs, 0), label, NULL_RTX); 1.1.1.6 root 2557: expr = build (MODIFY_EXPR, TREE_TYPE (current_function_decl), 2558: DECL_RESULT (current_function_decl), 2559: TREE_OPERAND (retval_rhs, 1)); 2560: TREE_SIDE_EFFECTS (expr) = 1; 2561: expand_return (expr); 1.1 root 2562: emit_label (label); 1.1.1.6 root 2563: 2564: expr = build (MODIFY_EXPR, TREE_TYPE (current_function_decl), 2565: DECL_RESULT (current_function_decl), 2566: TREE_OPERAND (retval_rhs, 2)); 2567: TREE_SIDE_EFFECTS (expr) = 1; 2568: expand_return (expr); 1.1 root 2569: return; 2570: } 2571: 2572: /* For tail-recursive call to current function, 2573: just jump back to the beginning. 2574: It's unsafe if any auto variable in this function 2575: has its address taken; for simplicity, 2576: require stack frame to be empty. */ 2577: if (optimize && retval_rhs != 0 2578: && frame_offset == 0 2579: && TREE_CODE (retval_rhs) == CALL_EXPR 2580: && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR 2581: && TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0) == current_function_decl 2582: /* Finish checking validity, and if valid emit code 2583: to set the argument variables for the new call. */ 2584: && tail_recursion_args (TREE_OPERAND (retval_rhs, 1), 2585: DECL_ARGUMENTS (current_function_decl))) 2586: { 2587: if (tail_recursion_label == 0) 2588: { 2589: tail_recursion_label = gen_label_rtx (); 2590: emit_label_after (tail_recursion_label, 2591: tail_recursion_reentry); 2592: } 1.1.1.4 root 2593: emit_queue (); 2594: expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn); 1.1 root 2595: emit_barrier (); 2596: return; 2597: } 2598: #ifdef HAVE_return 2599: /* This optimization is safe if there are local cleanups 2600: because expand_null_return takes care of them. 2601: ??? I think it should also be safe when there is a cleanup label, 2602: because expand_null_return takes care of them, too. 2603: Any reason why not? */ 2604: if (HAVE_return && cleanup_label == 0 1.1.1.6 root 2605: && ! current_function_returns_pcc_struct 2606: && BRANCH_COST <= 1) 1.1 root 2607: { 2608: /* If this is return x == y; then generate 2609: if (x == y) return 1; else return 0; 1.1.1.6 root 2610: if we can do it with explicit return insns and 2611: branches are cheap. */ 1.1 root 2612: if (retval_rhs) 2613: switch (TREE_CODE (retval_rhs)) 2614: { 2615: case EQ_EXPR: 2616: case NE_EXPR: 2617: case GT_EXPR: 2618: case GE_EXPR: 2619: case LT_EXPR: 2620: case LE_EXPR: 2621: case TRUTH_ANDIF_EXPR: 2622: case TRUTH_ORIF_EXPR: 2623: case TRUTH_AND_EXPR: 2624: case TRUTH_OR_EXPR: 2625: case TRUTH_NOT_EXPR: 1.1.1.5 root 2626: case TRUTH_XOR_EXPR: 1.1 root 2627: op0 = gen_label_rtx (); 2628: jumpifnot (retval_rhs, op0); 2629: expand_value_return (const1_rtx); 2630: emit_label (op0); 2631: expand_value_return (const0_rtx); 2632: return; 2633: } 2634: } 2635: #endif /* HAVE_return */ 2636: 2637: if (cleanups 2638: && retval_rhs != 0 2639: && TREE_TYPE (retval_rhs) != void_type_node 2640: && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG) 2641: { 2642: /* Calculate the return value into a pseudo reg. */ 1.1.1.4 root 2643: val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0); 1.1 root 2644: emit_queue (); 2645: /* All temporaries have now been used. */ 2646: free_temp_slots (); 2647: /* Return the calculated value, doing cleanups first. */ 2648: expand_value_return (val); 2649: } 2650: else 2651: { 2652: /* No cleanups or no hard reg used; 2653: calculate value into hard return reg. */ 1.1.1.6 root 2654: expand_expr (retval, const0_rtx, VOIDmode, 0); 1.1 root 2655: emit_queue (); 2656: free_temp_slots (); 2657: expand_value_return (DECL_RTL (DECL_RESULT (current_function_decl))); 2658: } 2659: } 2660: 2661: /* Return 1 if the end of the generated RTX is not a barrier. 2662: This means code already compiled can drop through. */ 2663: 2664: int 2665: drop_through_at_end_p () 2666: { 2667: rtx insn = get_last_insn (); 2668: while (insn && GET_CODE (insn) == NOTE) 2669: insn = PREV_INSN (insn); 2670: return insn && GET_CODE (insn) != BARRIER; 2671: } 2672: 2673: /* Emit code to alter this function's formal parms for a tail-recursive call. 2674: ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs). 2675: FORMALS is the chain of decls of formals. 2676: Return 1 if this can be done; 2677: otherwise return 0 and do not emit any code. */ 2678: 2679: static int 2680: tail_recursion_args (actuals, formals) 2681: tree actuals, formals; 2682: { 2683: register tree a = actuals, f = formals; 2684: register int i; 2685: register rtx *argvec; 2686: 2687: /* Check that number and types of actuals are compatible 2688: with the formals. This is not always true in valid C code. 2689: Also check that no formal needs to be addressable 2690: and that all formals are scalars. */ 2691: 2692: /* Also count the args. */ 2693: 2694: for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++) 2695: { 2696: if (TREE_TYPE (TREE_VALUE (a)) != TREE_TYPE (f)) 2697: return 0; 2698: if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode) 2699: return 0; 2700: } 2701: if (a != 0 || f != 0) 2702: return 0; 2703: 2704: /* Compute all the actuals. */ 2705: 2706: argvec = (rtx *) alloca (i * sizeof (rtx)); 2707: 2708: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++) 1.1.1.4 root 2709: argvec[i] = expand_expr (TREE_VALUE (a), NULL_RTX, VOIDmode, 0); 1.1 root 2710: 2711: /* Find which actual values refer to current values of previous formals. 2712: Copy each of them now, before any formal is changed. */ 2713: 2714: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++) 2715: { 2716: int copy = 0; 2717: register int j; 2718: for (f = formals, j = 0; j < i; f = TREE_CHAIN (f), j++) 2719: if (reg_mentioned_p (DECL_RTL (f), argvec[i])) 2720: { copy = 1; break; } 2721: if (copy) 2722: argvec[i] = copy_to_reg (argvec[i]); 2723: } 2724: 2725: /* Store the values of the actuals into the formals. */ 2726: 2727: for (f = formals, a = actuals, i = 0; f; 2728: f = TREE_CHAIN (f), a = TREE_CHAIN (a), i++) 2729: { 1.1.1.4 root 2730: if (GET_MODE (DECL_RTL (f)) == GET_MODE (argvec[i])) 1.1 root 2731: emit_move_insn (DECL_RTL (f), argvec[i]); 2732: else 2733: convert_move (DECL_RTL (f), argvec[i], 2734: TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a)))); 2735: } 2736: 2737: free_temp_slots (); 2738: return 1; 2739: } 2740: 2741: /* Generate the RTL code for entering a binding contour. 2742: The variables are declared one by one, by calls to `expand_decl'. 2743: 2744: EXIT_FLAG is nonzero if this construct should be visible to 2745: `exit_something'. */ 2746: 2747: void 2748: expand_start_bindings (exit_flag) 2749: int exit_flag; 2750: { 2751: struct nesting *thisblock = ALLOC_NESTING (); 1.1.1.7 ! root 2752: rtx note = output_bytecode ? 0 : emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG); 1.1 root 2753: 2754: /* Make an entry on block_stack for the block we are entering. */ 2755: 2756: thisblock->next = block_stack; 2757: thisblock->all = nesting_stack; 2758: thisblock->depth = ++nesting_depth; 2759: thisblock->data.block.stack_level = 0; 2760: thisblock->data.block.cleanups = 0; 2761: thisblock->data.block.function_call_count = 0; 2762: #if 0 2763: if (block_stack) 2764: { 2765: if (block_stack->data.block.cleanups == NULL_TREE 2766: && (block_stack->data.block.outer_cleanups == NULL_TREE 2767: || block_stack->data.block.outer_cleanups == empty_cleanup_list)) 2768: thisblock->data.block.outer_cleanups = empty_cleanup_list; 2769: else 2770: thisblock->data.block.outer_cleanups 2771: = tree_cons (NULL_TREE, block_stack->data.block.cleanups, 2772: block_stack->data.block.outer_cleanups); 2773: } 2774: else 2775: thisblock->data.block.outer_cleanups = 0; 2776: #endif 2777: #if 1 2778: if (block_stack 2779: && !(block_stack->data.block.cleanups == NULL_TREE 2780: && block_stack->data.block.outer_cleanups == NULL_TREE)) 2781: thisblock->data.block.outer_cleanups 2782: = tree_cons (NULL_TREE, block_stack->data.block.cleanups, 2783: block_stack->data.block.outer_cleanups); 2784: else 2785: thisblock->data.block.outer_cleanups = 0; 2786: #endif 2787: thisblock->data.block.label_chain = 0; 2788: thisblock->data.block.innermost_stack_block = stack_block_stack; 2789: thisblock->data.block.first_insn = note; 2790: thisblock->data.block.block_start_count = ++block_start_count; 2791: thisblock->exit_label = exit_flag ? gen_label_rtx () : 0; 2792: block_stack = thisblock; 2793: nesting_stack = thisblock; 2794: 1.1.1.6 root 2795: if (!output_bytecode) 2796: { 2797: /* Make a new level for allocating stack slots. */ 2798: push_temp_slots (); 2799: } 1.1 root 2800: } 2801: 1.1.1.4 root 2802: /* Given a pointer to a BLOCK node, save a pointer to the most recently 2803: generated NOTE_INSN_BLOCK_END in the BLOCK_END_NOTE field of the given 2804: BLOCK node. */ 2805: 2806: void 2807: remember_end_note (block) 2808: register tree block; 2809: { 2810: BLOCK_END_NOTE (block) = last_block_end_note; 2811: last_block_end_note = NULL_RTX; 2812: } 2813: 1.1 root 2814: /* Generate RTL code to terminate a binding contour. 2815: VARS is the chain of VAR_DECL nodes 2816: for the variables bound in this contour. 2817: MARK_ENDS is nonzero if we should put a note at the beginning 2818: and end of this binding contour. 2819: 2820: DONT_JUMP_IN is nonzero if it is not valid to jump into this contour. 2821: (That is true automatically if the contour has a saved stack level.) */ 2822: 2823: void 2824: expand_end_bindings (vars, mark_ends, dont_jump_in) 2825: tree vars; 2826: int mark_ends; 2827: int dont_jump_in; 2828: { 2829: register struct nesting *thisblock = block_stack; 2830: register tree decl; 2831: 1.1.1.6 root 2832: if (output_bytecode) 2833: { 2834: bc_expand_end_bindings (vars, mark_ends, dont_jump_in); 2835: return; 2836: } 2837: 1.1 root 2838: if (warn_unused) 2839: for (decl = vars; decl; decl = TREE_CHAIN (decl)) 1.1.1.4 root 2840: if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL 2841: && ! DECL_IN_SYSTEM_HEADER (decl)) 1.1 root 2842: warning_with_decl (decl, "unused variable `%s'"); 2843: 2844: if (thisblock->exit_label) 2845: { 2846: do_pending_stack_adjust (); 2847: emit_label (thisblock->exit_label); 2848: } 2849: 2850: /* If necessary, make a handler for nonlocal gotos taking 2851: place in the function calls in this block. */ 2852: if (function_call_count != thisblock->data.block.function_call_count 2853: && nonlocal_labels 2854: /* Make handler for outermost block 2855: if there were any nonlocal gotos to this function. */ 2856: && (thisblock->next == 0 ? current_function_has_nonlocal_label 2857: /* Make handler for inner block if it has something 2858: special to do when you jump out of it. */ 2859: : (thisblock->data.block.cleanups != 0 2860: || thisblock->data.block.stack_level != 0))) 2861: { 2862: tree link; 2863: rtx afterward = gen_label_rtx (); 2864: rtx handler_label = gen_label_rtx (); 2865: rtx save_receiver = gen_reg_rtx (Pmode); 1.1.1.6 root 2866: rtx insns; 1.1 root 2867: 2868: /* Don't let jump_optimize delete the handler. */ 2869: LABEL_PRESERVE_P (handler_label) = 1; 2870: 2871: /* Record the handler address in the stack slot for that purpose, 2872: during this block, saving and restoring the outer value. */ 2873: if (thisblock->next != 0) 2874: { 2875: emit_move_insn (nonlocal_goto_handler_slot, save_receiver); 1.1.1.6 root 2876: 2877: start_sequence (); 2878: emit_move_insn (save_receiver, nonlocal_goto_handler_slot); 2879: insns = get_insns (); 2880: end_sequence (); 2881: emit_insns_before (insns, thisblock->data.block.first_insn); 2882: } 2883: 2884: start_sequence (); 2885: emit_move_insn (nonlocal_goto_handler_slot, 2886: gen_rtx (LABEL_REF, Pmode, handler_label)); 2887: insns = get_insns (); 2888: end_sequence (); 2889: emit_insns_before (insns, thisblock->data.block.first_insn); 1.1 root 2890: 2891: /* Jump around the handler; it runs only when specially invoked. */ 2892: emit_jump (afterward); 2893: emit_label (handler_label); 2894: 2895: #ifdef HAVE_nonlocal_goto 2896: if (! HAVE_nonlocal_goto) 2897: #endif 2898: /* First adjust our frame pointer to its actual value. It was 2899: previously set to the start of the virtual area corresponding to 2900: the stacked variables when we branched here and now needs to be 2901: adjusted to the actual hardware fp value. 2902: 2903: Assignments are to virtual registers are converted by 2904: instantiate_virtual_regs into the corresponding assignment 2905: to the underlying register (fp in this case) that makes 2906: the original assignment true. 2907: So the following insn will actually be 2908: decrementing fp by STARTING_FRAME_OFFSET. */ 1.1.1.7 ! root 2909: emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); 1.1 root 2910: 1.1.1.6 root 2911: #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM 1.1 root 2912: if (fixed_regs[ARG_POINTER_REGNUM]) 2913: { 1.1.1.4 root 2914: #ifdef ELIMINABLE_REGS 2915: /* If the argument pointer can be eliminated in favor of the 2916: frame pointer, we don't need to restore it. We assume here 2917: that if such an elimination is present, it can always be used. 2918: This is the case on all known machines; if we don't make this 2919: assumption, we do unnecessary saving on many machines. */ 2920: static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS; 2921: int i; 2922: 2923: for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++) 2924: if (elim_regs[i].from == ARG_POINTER_REGNUM 1.1.1.6 root 2925: && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM) 1.1.1.4 root 2926: break; 2927: 2928: if (i == sizeof elim_regs / sizeof elim_regs [0]) 2929: #endif 2930: { 2931: /* Now restore our arg pointer from the address at which it 2932: was saved in our stack frame. 2933: If there hasn't be space allocated for it yet, make 2934: some now. */ 2935: if (arg_pointer_save_area == 0) 2936: arg_pointer_save_area 2937: = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0); 2938: emit_move_insn (virtual_incoming_args_rtx, 2939: /* We need a pseudo here, or else 2940: instantiate_virtual_regs_1 complains. */ 2941: copy_to_reg (arg_pointer_save_area)); 2942: } 1.1 root 2943: } 2944: #endif 2945: 2946: /* The handler expects the desired label address in the static chain 2947: register. It tests the address and does an appropriate jump 2948: to whatever label is desired. */ 2949: for (link = nonlocal_labels; link; link = TREE_CHAIN (link)) 2950: /* Skip any labels we shouldn't be able to jump to from here. */ 2951: if (! DECL_TOO_LATE (TREE_VALUE (link))) 2952: { 2953: rtx not_this = gen_label_rtx (); 2954: rtx this = gen_label_rtx (); 2955: do_jump_if_equal (static_chain_rtx, 2956: gen_rtx (LABEL_REF, Pmode, DECL_RTL (TREE_VALUE (link))), 2957: this, 0); 2958: emit_jump (not_this); 2959: emit_label (this); 2960: expand_goto (TREE_VALUE (link)); 2961: emit_label (not_this); 2962: } 2963: /* If label is not recognized, abort. */ 2964: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "abort"), 0, 2965: VOIDmode, 0); 2966: emit_label (afterward); 2967: } 2968: 2969: /* Don't allow jumping into a block that has cleanups or a stack level. */ 2970: if (dont_jump_in 2971: || thisblock->data.block.stack_level != 0 2972: || thisblock->data.block.cleanups != 0) 2973: { 2974: struct label_chain *chain; 2975: 2976: /* Any labels in this block are no longer valid to go to. 2977: Mark them to cause an error message. */ 2978: for (chain = thisblock->data.block.label_chain; chain; chain = chain->next) 2979: { 2980: DECL_TOO_LATE (chain->label) = 1; 2981: /* If any goto without a fixup came to this label, 2982: that must be an error, because gotos without fixups 2983: come from outside all saved stack-levels and all cleanups. */ 2984: if (TREE_ADDRESSABLE (chain->label)) 2985: error_with_decl (chain->label, 2986: "label `%s' used before containing binding contour"); 2987: } 2988: } 2989: 2990: /* Restore stack level in effect before the block 2991: (only if variable-size objects allocated). */ 2992: /* Perform any cleanups associated with the block. */ 2993: 2994: if (thisblock->data.block.stack_level != 0 2995: || thisblock->data.block.cleanups != 0) 2996: { 1.1.1.7 ! root 2997: /* Only clean up here if this point can actually be reached. */ ! 2998: if (GET_CODE (get_last_insn ()) != BARRIER) ! 2999: { ! 3000: /* Don't let cleanups affect ({...}) constructs. */ ! 3001: int old_expr_stmts_for_value = expr_stmts_for_value; ! 3002: rtx old_last_expr_value = last_expr_value; ! 3003: tree old_last_expr_type = last_expr_type; ! 3004: expr_stmts_for_value = 0; 1.1 root 3005: 1.1.1.7 ! root 3006: /* Do the cleanups. */ ! 3007: expand_cleanups (thisblock->data.block.cleanups, NULL_TREE); ! 3008: do_pending_stack_adjust (); ! 3009: ! 3010: expr_stmts_for_value = old_expr_stmts_for_value; ! 3011: last_expr_value = old_last_expr_value; ! 3012: last_expr_type = old_last_expr_type; 1.1 root 3013: 1.1.1.7 ! root 3014: /* Restore the stack level. */ ! 3015: ! 3016: if (thisblock->data.block.stack_level != 0) ! 3017: { ! 3018: emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION, ! 3019: thisblock->data.block.stack_level, NULL_RTX); ! 3020: if (nonlocal_goto_handler_slot != 0) ! 3021: emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, ! 3022: NULL_RTX); ! 3023: } 1.1 root 3024: } 3025: 3026: /* Any gotos out of this block must also do these things. 1.1.1.3 root 3027: Also report any gotos with fixups that came to labels in this 3028: level. */ 1.1 root 3029: fixup_gotos (thisblock, 3030: thisblock->data.block.stack_level, 3031: thisblock->data.block.cleanups, 3032: thisblock->data.block.first_insn, 3033: dont_jump_in); 3034: } 3035: 1.1.1.4 root 3036: /* Mark the beginning and end of the scope if requested. 3037: We do this now, after running cleanups on the variables 3038: just going out of scope, so they are in scope for their cleanups. */ 3039: 3040: if (mark_ends) 3041: last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END); 3042: else 3043: /* Get rid of the beginning-mark if we don't make an end-mark. */ 3044: NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED; 3045: 1.1 root 3046: /* If doing stupid register allocation, make sure lives of all 3047: register variables declared here extend thru end of scope. */ 3048: 3049: if (obey_regdecls) 3050: for (decl = vars; decl; decl = TREE_CHAIN (decl)) 3051: { 3052: rtx rtl = DECL_RTL (decl); 3053: if (TREE_CODE (decl) == VAR_DECL && rtl != 0) 3054: use_variable (rtl); 3055: } 3056: 3057: /* Restore block_stack level for containing block. */ 3058: 3059: stack_block_stack = thisblock->data.block.innermost_stack_block; 3060: POPSTACK (block_stack); 3061: 3062: /* Pop the stack slot nesting and free any slots at this level. */ 3063: pop_temp_slots (); 3064: } 1.1.1.6 root 3065: 3066: 3067: /* End a binding contour. 3068: VARS is the chain of VAR_DECL nodes for the variables bound 3069: in this contour. MARK_ENDS is nonzer if we should put a note 3070: at the beginning and end of this binding contour. 3071: DONT_JUMP_IN is nonzero if it is not valid to jump into this 3072: contour. */ 3073: 1.1.1.7 ! root 3074: static void 1.1.1.6 root 3075: bc_expand_end_bindings (vars, mark_ends, dont_jump_in) 3076: tree vars; 3077: int mark_ends; 3078: int dont_jump_in; 3079: { 3080: struct nesting *thisbind = nesting_stack; 3081: tree decl; 3082: 3083: if (warn_unused) 3084: for (decl = vars; decl; decl = TREE_CHAIN (decl)) 3085: if (! TREE_USED (TREE_VALUE (decl)) && TREE_CODE (TREE_VALUE (decl)) == VAR_DECL) 3086: warning_with_decl (decl, "unused variable `%s'"); 3087: 1.1.1.7 ! root 3088: if (thisbind->exit_label) ! 3089: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisbind->exit_label)); 1.1.1.6 root 3090: 3091: /* Pop block/bindings off stack */ 3092: POPSTACK (block_stack); 3093: } 1.1 root 3094: 3095: /* Generate RTL for the automatic variable declaration DECL. 3096: (Other kinds of declarations are simply ignored if seen here.) 3097: CLEANUP is an expression to be executed at exit from this binding contour; 3098: for example, in C++, it might call the destructor for this variable. 3099: 3100: If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them 3101: either before or after calling `expand_decl' but before compiling 3102: any subsequent expressions. This is because CLEANUP may be expanded 3103: more than once, on different branches of execution. 3104: For the same reason, CLEANUP may not contain a CALL_EXPR 3105: except as its topmost node--else `preexpand_calls' would get confused. 3106: 3107: If CLEANUP is nonzero and DECL is zero, we record a cleanup 3108: that is not associated with any particular variable. 3109: 3110: There is no special support here for C++ constructors. 3111: They should be handled by the proper code in DECL_INITIAL. */ 3112: 3113: void 3114: expand_decl (decl) 3115: register tree decl; 3116: { 3117: struct nesting *thisblock = block_stack; 1.1.1.6 root 3118: tree type; 3119: 3120: if (output_bytecode) 3121: { 3122: bc_expand_decl (decl, 0); 3123: return; 3124: } 3125: 3126: type = TREE_TYPE (decl); 1.1 root 3127: 3128: /* Only automatic variables need any expansion done. 3129: Static and external variables, and external functions, 3130: will be handled by `assemble_variable' (called from finish_decl). 3131: TYPE_DECL and CONST_DECL require nothing. 3132: PARM_DECLs are handled in `assign_parms'. */ 3133: 3134: if (TREE_CODE (decl) != VAR_DECL) 3135: return; 1.1.1.4 root 3136: if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) 1.1 root 3137: return; 3138: 3139: /* Create the RTL representation for the variable. */ 3140: 3141: if (type == error_mark_node) 3142: DECL_RTL (decl) = gen_rtx (MEM, BLKmode, const0_rtx); 3143: else if (DECL_SIZE (decl) == 0) 3144: /* Variable with incomplete type. */ 3145: { 3146: if (DECL_INITIAL (decl) == 0) 3147: /* Error message was already done; now avoid a crash. */ 3148: DECL_RTL (decl) = assign_stack_temp (DECL_MODE (decl), 0, 1); 3149: else 3150: /* An initializer is going to decide the size of this array. 3151: Until we know the size, represent its address with a reg. */ 3152: DECL_RTL (decl) = gen_rtx (MEM, BLKmode, gen_reg_rtx (Pmode)); 3153: } 3154: else if (DECL_MODE (decl) != BLKmode 3155: /* If -ffloat-store, don't put explicit float vars 3156: into regs. */ 3157: && !(flag_float_store 3158: && TREE_CODE (type) == REAL_TYPE) 3159: && ! TREE_THIS_VOLATILE (decl) 3160: && ! TREE_ADDRESSABLE (decl) 1.1.1.4 root 3161: && (DECL_REGISTER (decl) || ! obey_regdecls)) 1.1 root 3162: { 3163: /* Automatic variable that can go in a register. */ 1.1.1.4 root 3164: int unsignedp = TREE_UNSIGNED (type); 1.1.1.7 ! root 3165: enum machine_mode reg_mode ! 3166: = promote_mode (type, DECL_MODE (decl), &unsignedp, 0); 1.1.1.4 root 3167: 1.1.1.6 root 3168: if (TREE_CODE (type) == COMPLEX_TYPE) 3169: { 3170: rtx realpart, imagpart; 3171: enum machine_mode partmode = TYPE_MODE (TREE_TYPE (type)); 3172: 3173: /* For a complex type variable, make a CONCAT of two pseudos 3174: so that the real and imaginary parts 3175: can be allocated separately. */ 3176: realpart = gen_reg_rtx (partmode); 3177: REG_USERVAR_P (realpart) = 1; 3178: imagpart = gen_reg_rtx (partmode); 3179: REG_USERVAR_P (imagpart) = 1; 3180: DECL_RTL (decl) = gen_rtx (CONCAT, reg_mode, realpart, imagpart); 3181: } 3182: else 3183: { 3184: DECL_RTL (decl) = gen_reg_rtx (reg_mode); 3185: if (TREE_CODE (type) == POINTER_TYPE) 3186: mark_reg_pointer (DECL_RTL (decl)); 3187: REG_USERVAR_P (DECL_RTL (decl)) = 1; 3188: } 1.1 root 3189: } 3190: else if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) 3191: { 3192: /* Variable of fixed size that goes on the stack. */ 3193: rtx oldaddr = 0; 3194: rtx addr; 3195: 3196: /* If we previously made RTL for this decl, it must be an array 3197: whose size was determined by the initializer. 3198: The old address was a register; set that register now 3199: to the proper address. */ 3200: if (DECL_RTL (decl) != 0) 3201: { 3202: if (GET_CODE (DECL_RTL (decl)) != MEM 3203: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != REG) 3204: abort (); 3205: oldaddr = XEXP (DECL_RTL (decl), 0); 3206: } 3207: 3208: DECL_RTL (decl) 3209: = assign_stack_temp (DECL_MODE (decl), 3210: ((TREE_INT_CST_LOW (DECL_SIZE (decl)) 3211: + BITS_PER_UNIT - 1) 3212: / BITS_PER_UNIT), 3213: 1); 3214: 3215: /* Set alignment we actually gave this decl. */ 3216: DECL_ALIGN (decl) = (DECL_MODE (decl) == BLKmode ? BIGGEST_ALIGNMENT 3217: : GET_MODE_BITSIZE (DECL_MODE (decl))); 3218: 3219: if (oldaddr) 3220: { 3221: addr = force_operand (XEXP (DECL_RTL (decl), 0), oldaddr); 3222: if (addr != oldaddr) 3223: emit_move_insn (oldaddr, addr); 3224: } 3225: 3226: /* If this is a memory ref that contains aggregate components, 3227: mark it as such for cse and loop optimize. */ 1.1.1.7 ! root 3228: MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl)); 1.1 root 3229: #if 0 3230: /* If this is in memory because of -ffloat-store, 3231: set the volatile bit, to prevent optimizations from 3232: undoing the effects. */ 3233: if (flag_float_store && TREE_CODE (type) == REAL_TYPE) 3234: MEM_VOLATILE_P (DECL_RTL (decl)) = 1; 3235: #endif 3236: } 3237: else 3238: /* Dynamic-size object: must push space on the stack. */ 3239: { 3240: rtx address, size; 3241: 3242: /* Record the stack pointer on entry to block, if have 3243: not already done so. */ 3244: if (thisblock->data.block.stack_level == 0) 3245: { 3246: do_pending_stack_adjust (); 1.1.1.3 root 3247: emit_stack_save (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION, 3248: &thisblock->data.block.stack_level, 3249: thisblock->data.block.first_insn); 1.1 root 3250: stack_block_stack = thisblock; 3251: } 3252: 3253: /* Compute the variable's size, in bytes. */ 3254: size = expand_expr (size_binop (CEIL_DIV_EXPR, 3255: DECL_SIZE (decl), 3256: size_int (BITS_PER_UNIT)), 1.1.1.4 root 3257: NULL_RTX, VOIDmode, 0); 1.1 root 3258: free_temp_slots (); 3259: 3260: /* Allocate space on the stack for the variable. */ 1.1.1.4 root 3261: address = allocate_dynamic_stack_space (size, NULL_RTX, 3262: DECL_ALIGN (decl)); 1.1 root 3263: 3264: /* Reference the variable indirect through that rtx. */ 3265: DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address); 3266: 1.1.1.3 root 3267: /* If this is a memory ref that contains aggregate components, 3268: mark it as such for cse and loop optimize. */ 1.1.1.7 ! root 3269: MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl)); 1.1.1.3 root 3270: 1.1 root 3271: /* Indicate the alignment we actually gave this variable. */ 3272: #ifdef STACK_BOUNDARY 3273: DECL_ALIGN (decl) = STACK_BOUNDARY; 3274: #else 3275: DECL_ALIGN (decl) = BIGGEST_ALIGNMENT; 3276: #endif 3277: } 3278: 3279: if (TREE_THIS_VOLATILE (decl)) 3280: MEM_VOLATILE_P (DECL_RTL (decl)) = 1; 1.1.1.5 root 3281: #if 0 /* A variable is not necessarily unchanging 3282: just because it is const. RTX_UNCHANGING_P 3283: means no change in the function, 3284: not merely no change in the variable's scope. 3285: It is correct to set RTX_UNCHANGING_P if the variable's scope 3286: is the whole function. There's no convenient way to test that. */ 1.1 root 3287: if (TREE_READONLY (decl)) 3288: RTX_UNCHANGING_P (DECL_RTL (decl)) = 1; 1.1.1.5 root 3289: #endif 1.1 root 3290: 3291: /* If doing stupid register allocation, make sure life of any 3292: register variable starts here, at the start of its scope. */ 3293: 3294: if (obey_regdecls) 3295: use_variable (DECL_RTL (decl)); 3296: } 1.1.1.6 root 3297: 3298: 3299: /* Generate code for the automatic variable declaration DECL. For 3300: most variables this just means we give it a stack offset. The 3301: compiler sometimes emits cleanups without variables and we will 3302: have to deal with those too. */ 3303: 1.1.1.7 ! root 3304: static void 1.1.1.6 root 3305: bc_expand_decl (decl, cleanup) 3306: tree decl; 3307: tree cleanup; 3308: { 3309: tree type; 3310: 3311: if (!decl) 3312: { 3313: /* A cleanup with no variable. */ 3314: if (!cleanup) 3315: abort (); 3316: 3317: return; 3318: } 3319: 3320: /* Only auto variables need any work. */ 3321: if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl) || DECL_EXTERNAL (decl)) 3322: return; 3323: 3324: type = TREE_TYPE (decl); 3325: 3326: if (type == error_mark_node) 3327: DECL_RTL (decl) = bc_gen_rtx ((char *) 0, 0, (struct bc_label *) 0); 3328: 3329: else if (DECL_SIZE (decl) == 0) 3330: 3331: /* Variable with incomplete type. The stack offset herein will be 3332: fixed later in expand_decl_init (). */ 3333: DECL_RTL (decl) = bc_gen_rtx ((char *) 0, 0, (struct bc_label *) 0); 3334: 3335: else if (TREE_CONSTANT (DECL_SIZE (decl))) 3336: { 3337: DECL_RTL (decl) = bc_allocate_local (TREE_INT_CST_LOW (DECL_SIZE (decl)) / BITS_PER_UNIT, 3338: DECL_ALIGN (decl)); 3339: } 3340: else 3341: DECL_RTL (decl) = bc_allocate_variable_array (DECL_SIZE (decl)); 3342: } 1.1 root 3343: 3344: /* Emit code to perform the initialization of a declaration DECL. */ 3345: 3346: void 3347: expand_decl_init (decl) 3348: tree decl; 3349: { 1.1.1.2 root 3350: int was_used = TREE_USED (decl); 3351: 1.1.1.7 ! root 3352: if (output_bytecode) ! 3353: { ! 3354: bc_expand_decl_init (decl); ! 3355: return; ! 3356: } ! 3357: 1.1.1.6 root 3358: /* If this is a CONST_DECL, we don't have to generate any code, but 3359: if DECL_INITIAL is a constant, call expand_expr to force TREE_CST_RTL 3360: to be set while in the obstack containing the constant. If we don't 3361: do this, we can lose if we have functions nested three deep and the middle 3362: function makes a CONST_DECL whose DECL_INITIAL is a STRING_CST while 3363: the innermost function is the first to expand that STRING_CST. */ 3364: if (TREE_CODE (decl) == CONST_DECL) 3365: { 3366: if (DECL_INITIAL (decl) && TREE_CONSTANT (DECL_INITIAL (decl))) 3367: expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode, 3368: EXPAND_INITIALIZER); 3369: return; 3370: } 3371: 1.1 root 3372: if (TREE_STATIC (decl)) 3373: return; 3374: 3375: /* Compute and store the initial value now. */ 3376: 3377: if (DECL_INITIAL (decl) == error_mark_node) 3378: { 3379: enum tree_code code = TREE_CODE (TREE_TYPE (decl)); 3380: if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE 3381: || code == POINTER_TYPE) 3382: expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node), 3383: 0, 0); 3384: emit_queue (); 3385: } 3386: else if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) != TREE_LIST) 3387: { 3388: emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); 3389: expand_assignment (decl, DECL_INITIAL (decl), 0, 0); 3390: emit_queue (); 3391: } 3392: 1.1.1.2 root 3393: /* Don't let the initialization count as "using" the variable. */ 3394: TREE_USED (decl) = was_used; 3395: 1.1 root 3396: /* Free any temporaries we made while initializing the decl. */ 3397: free_temp_slots (); 3398: } 3399: 1.1.1.6 root 3400: /* Expand initialization for variable-sized types. Allocate array 3401: using newlocalSI and set local variable, which is a pointer to the 3402: storage. */ 3403: 1.1.1.7 ! root 3404: static void 1.1.1.6 root 3405: bc_expand_variable_local_init (decl) 3406: tree decl; 3407: { 3408: /* Evaluate size expression and coerce to SI */ 3409: bc_expand_expr (DECL_SIZE (decl)); 3410: 3411: /* Type sizes are always (?) of TREE_CODE INTEGER_CST, so 3412: no coercion is necessary (?) */ 3413: 3414: /* emit_typecode_conversion (preferred_typecode (TYPE_MODE (DECL_SIZE (decl)), 3415: TREE_UNSIGNED (DECL_SIZE (decl))), SIcode); */ 3416: 3417: /* Emit code to allocate array */ 3418: bc_emit_instruction (newlocalSI); 3419: 3420: /* Store array pointer in local variable. This is the only instance 3421: where we actually want the address of the pointer to the 3422: variable-size block, rather than the pointer itself. We avoid 3423: using expand_address() since that would cause the pointer to be 3424: pushed rather than its address. Hence the hard-coded reference; 3425: notice also that the variable is always local (no global 3426: variable-size type variables). */ 3427: 3428: bc_load_localaddr (DECL_RTL (decl)); 3429: bc_emit_instruction (storeP); 3430: } 3431: 3432: 3433: /* Emit code to initialize a declaration. */ 1.1.1.7 ! root 3434: ! 3435: static void 1.1.1.6 root 3436: bc_expand_decl_init (decl) 3437: tree decl; 3438: { 3439: int org_stack_depth; 3440: 3441: /* Statical initializers are handled elsewhere */ 3442: 3443: if (TREE_STATIC (decl)) 3444: return; 3445: 3446: /* Memory original stack depth */ 3447: org_stack_depth = stack_depth; 3448: 3449: /* If the type is variable-size, we first create its space (we ASSUME 3450: it CAN'T be static). We do this regardless of whether there's an 3451: initializer assignment or not. */ 3452: 3453: if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 3454: bc_expand_variable_local_init (decl); 3455: 3456: /* Expand initializer assignment */ 3457: if (DECL_INITIAL (decl) == error_mark_node) 3458: { 3459: enum tree_code code = TREE_CODE (TREE_TYPE (decl)); 3460: 3461: if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE 3462: || code == POINTER_TYPE) 3463: 3464: expand_assignment (TREE_TYPE (decl), decl, 0, 0); 3465: } 3466: else if (DECL_INITIAL (decl)) 3467: expand_assignment (TREE_TYPE (decl), decl, 0, 0); 3468: 3469: /* Restore stack depth */ 3470: if (org_stack_depth > stack_depth) 3471: abort (); 3472: 3473: bc_adjust_stack (stack_depth - org_stack_depth); 3474: } 3475: 3476: 1.1 root 3477: /* CLEANUP is an expression to be executed at exit from this binding contour; 3478: for example, in C++, it might call the destructor for this variable. 3479: 3480: If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them 3481: either before or after calling `expand_decl' but before compiling 3482: any subsequent expressions. This is because CLEANUP may be expanded 3483: more than once, on different branches of execution. 3484: For the same reason, CLEANUP may not contain a CALL_EXPR 3485: except as its topmost node--else `preexpand_calls' would get confused. 3486: 3487: If CLEANUP is nonzero and DECL is zero, we record a cleanup 3488: that is not associated with any particular variable. */ 3489: 3490: int 3491: expand_decl_cleanup (decl, cleanup) 3492: tree decl, cleanup; 3493: { 3494: struct nesting *thisblock = block_stack; 3495: 3496: /* Error if we are not in any block. */ 3497: if (thisblock == 0) 3498: return 0; 3499: 3500: /* Record the cleanup if there is one. */ 3501: 3502: if (cleanup != 0) 3503: { 3504: thisblock->data.block.cleanups 3505: = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups); 3506: /* If this block has a cleanup, it belongs in stack_block_stack. */ 3507: stack_block_stack = thisblock; 1.1.1.7 ! root 3508: (*interim_eh_hook) (NULL_TREE); 1.1 root 3509: } 3510: return 1; 3511: } 3512: 3513: /* DECL is an anonymous union. CLEANUP is a cleanup for DECL. 3514: DECL_ELTS is the list of elements that belong to DECL's type. 3515: In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup. */ 3516: 3517: void 3518: expand_anon_union_decl (decl, cleanup, decl_elts) 3519: tree decl, cleanup, decl_elts; 3520: { 3521: struct nesting *thisblock = block_stack; 3522: rtx x; 3523: 3524: expand_decl (decl, cleanup); 3525: x = DECL_RTL (decl); 3526: 3527: while (decl_elts) 3528: { 3529: tree decl_elt = TREE_VALUE (decl_elts); 3530: tree cleanup_elt = TREE_PURPOSE (decl_elts); 3531: enum machine_mode mode = TYPE_MODE (TREE_TYPE (decl_elt)); 3532: 1.1.1.7 ! root 3533: /* Propagate the union's alignment to the elements. */ ! 3534: DECL_ALIGN (decl_elt) = DECL_ALIGN (decl); ! 3535: ! 3536: /* If the element has BLKmode and the union doesn't, the union is ! 3537: aligned such that the element doesn't need to have BLKmode, so ! 3538: change the element's mode to the appropriate one for its size. */ ! 3539: if (mode == BLKmode && DECL_MODE (decl) != BLKmode) ! 3540: DECL_MODE (decl_elt) = mode ! 3541: = mode_for_size (TREE_INT_CST_LOW (DECL_SIZE (decl_elt)), ! 3542: MODE_INT, 1); ! 3543: 1.1 root 3544: /* (SUBREG (MEM ...)) at RTL generation time is invalid, so we 3545: instead create a new MEM rtx with the proper mode. */ 3546: if (GET_CODE (x) == MEM) 3547: { 3548: if (mode == GET_MODE (x)) 3549: DECL_RTL (decl_elt) = x; 3550: else 3551: { 3552: DECL_RTL (decl_elt) = gen_rtx (MEM, mode, copy_rtx (XEXP (x, 0))); 3553: MEM_IN_STRUCT_P (DECL_RTL (decl_elt)) = MEM_IN_STRUCT_P (x); 3554: RTX_UNCHANGING_P (DECL_RTL (decl_elt)) = RTX_UNCHANGING_P (x); 3555: } 3556: } 3557: else if (GET_CODE (x) == REG) 3558: { 3559: if (mode == GET_MODE (x)) 3560: DECL_RTL (decl_elt) = x; 3561: else 3562: DECL_RTL (decl_elt) = gen_rtx (SUBREG, mode, x, 0); 3563: } 3564: else 3565: abort (); 3566: 3567: /* Record the cleanup if there is one. */ 3568: 3569: if (cleanup != 0) 3570: thisblock->data.block.cleanups 3571: = temp_tree_cons (decl_elt, cleanup_elt, 3572: thisblock->data.block.cleanups); 3573: 3574: decl_elts = TREE_CHAIN (decl_elts); 3575: } 3576: } 3577: 3578: /* Expand a list of cleanups LIST. 3579: Elements may be expressions or may be nested lists. 3580: 3581: If DONT_DO is nonnull, then any list-element 3582: whose TREE_PURPOSE matches DONT_DO is omitted. 3583: This is sometimes used to avoid a cleanup associated with 3584: a value that is being returned out of the scope. */ 3585: 3586: static void 3587: expand_cleanups (list, dont_do) 3588: tree list; 3589: tree dont_do; 3590: { 3591: tree tail; 3592: for (tail = list; tail; tail = TREE_CHAIN (tail)) 3593: if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do) 3594: { 3595: if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST) 3596: expand_cleanups (TREE_VALUE (tail), dont_do); 3597: else 3598: { 1.1.1.7 ! root 3599: (*interim_eh_hook) (TREE_VALUE (tail)); ! 3600: 1.1 root 3601: /* Cleanups may be run multiple times. For example, 3602: when exiting a binding contour, we expand the 3603: cleanups associated with that contour. When a goto 3604: within that binding contour has a target outside that 3605: contour, it will expand all cleanups from its scope to 3606: the target. Though the cleanups are expanded multiple 3607: times, the control paths are non-overlapping so the 3608: cleanups will not be executed twice. */ 3609: expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); 3610: free_temp_slots (); 3611: } 3612: } 3613: } 3614: 3615: /* Move all cleanups from the current block_stack 3616: to the containing block_stack, where they are assumed to 3617: have been created. If anything can cause a temporary to 3618: be created, but not expanded for more than one level of 3619: block_stacks, then this code will have to change. */ 3620: 3621: void 3622: move_cleanups_up () 3623: { 3624: struct nesting *block = block_stack; 3625: struct nesting *outer = block->next; 3626: 3627: outer->data.block.cleanups 3628: = chainon (block->data.block.cleanups, 3629: outer->data.block.cleanups); 3630: block->data.block.cleanups = 0; 3631: } 3632: 3633: tree 3634: last_cleanup_this_contour () 3635: { 3636: if (block_stack == 0) 3637: return 0; 3638: 3639: return block_stack->data.block.cleanups; 3640: } 3641: 3642: /* Return 1 if there are any pending cleanups at this point. 3643: If THIS_CONTOUR is nonzero, check the current contour as well. 3644: Otherwise, look only at the contours that enclose this one. */ 3645: 3646: int 3647: any_pending_cleanups (this_contour) 3648: int this_contour; 3649: { 3650: struct nesting *block; 3651: 3652: if (block_stack == 0) 3653: return 0; 3654: 3655: if (this_contour && block_stack->data.block.cleanups != NULL) 3656: return 1; 3657: if (block_stack->data.block.cleanups == 0 3658: && (block_stack->data.block.outer_cleanups == 0 3659: #if 0 3660: || block_stack->data.block.outer_cleanups == empty_cleanup_list 3661: #endif 3662: )) 3663: return 0; 3664: 3665: for (block = block_stack->next; block; block = block->next) 3666: if (block->data.block.cleanups != 0) 3667: return 1; 3668: 3669: return 0; 3670: } 3671: 3672: /* Enter a case (Pascal) or switch (C) statement. 3673: Push a block onto case_stack and nesting_stack 3674: to accumulate the case-labels that are seen 3675: and to record the labels generated for the statement. 3676: 3677: EXIT_FLAG is nonzero if `exit_something' should exit this case stmt. 3678: Otherwise, this construct is transparent for `exit_something'. 3679: 3680: EXPR is the index-expression to be dispatched on. 3681: TYPE is its nominal type. We could simply convert EXPR to this type, 3682: but instead we take short cuts. */ 3683: 3684: void 3685: expand_start_case (exit_flag, expr, type, printname) 3686: int exit_flag; 3687: tree expr; 3688: tree type; 3689: char *printname; 3690: { 3691: register struct nesting *thiscase = ALLOC_NESTING (); 3692: 3693: /* Make an entry on case_stack for the case we are entering. */ 3694: 3695: thiscase->next = case_stack; 3696: thiscase->all = nesting_stack; 3697: thiscase->depth = ++nesting_depth; 3698: thiscase->exit_label = exit_flag ? gen_label_rtx () : 0; 3699: thiscase->data.case_stmt.case_list = 0; 3700: thiscase->data.case_stmt.index_expr = expr; 3701: thiscase->data.case_stmt.nominal_type = type; 3702: thiscase->data.case_stmt.default_label = 0; 3703: thiscase->data.case_stmt.num_ranges = 0; 3704: thiscase->data.case_stmt.printname = printname; 3705: thiscase->data.case_stmt.seenlabel = 0; 3706: case_stack = thiscase; 3707: nesting_stack = thiscase; 3708: 1.1.1.6 root 3709: if (output_bytecode) 3710: { 3711: bc_expand_start_case (thiscase, expr, type, printname); 3712: return; 3713: } 3714: 1.1 root 3715: do_pending_stack_adjust (); 3716: 3717: /* Make sure case_stmt.start points to something that won't 3718: need any transformation before expand_end_case. */ 3719: if (GET_CODE (get_last_insn ()) != NOTE) 1.1.1.4 root 3720: emit_note (NULL_PTR, NOTE_INSN_DELETED); 1.1 root 3721: 3722: thiscase->data.case_stmt.start = get_last_insn (); 3723: } 3724: 1.1.1.6 root 3725: 3726: /* Enter a case statement. It is assumed that the caller has pushed 3727: the current context onto the case stack. */ 1.1.1.7 ! root 3728: ! 3729: static void 1.1.1.6 root 3730: bc_expand_start_case (thiscase, expr, type, printname) 3731: struct nesting *thiscase; 3732: tree expr; 3733: tree type; 3734: char *printname; 3735: { 3736: bc_expand_expr (expr); 3737: bc_expand_conversion (TREE_TYPE (expr), type); 3738: 3739: /* For cases, the skip is a place we jump to that's emitted after 3740: the size of the jump table is known. */ 3741: 3742: thiscase->data.case_stmt.skip_label = gen_label_rtx (); 3743: bc_emit_bytecode (jump); 3744: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->data.case_stmt.skip_label)); 3745: 3746: #ifdef DEBUG_PRINT_CODE 3747: fputc ('\n', stderr); 3748: #endif 3749: } 3750: 3751: 1.1 root 3752: /* Start a "dummy case statement" within which case labels are invalid 3753: and are not connected to any larger real case statement. 3754: This can be used if you don't want to let a case statement jump 3755: into the middle of certain kinds of constructs. */ 3756: 3757: void 3758: expand_start_case_dummy () 3759: { 3760: register struct nesting *thiscase = ALLOC_NESTING (); 3761: 3762: /* Make an entry on case_stack for the dummy. */ 3763: 3764: thiscase->next = case_stack; 3765: thiscase->all = nesting_stack; 3766: thiscase->depth = ++nesting_depth; 3767: thiscase->exit_label = 0; 3768: thiscase->data.case_stmt.case_list = 0; 3769: thiscase->data.case_stmt.start = 0; 3770: thiscase->data.case_stmt.nominal_type = 0; 3771: thiscase->data.case_stmt.default_label = 0; 3772: thiscase->data.case_stmt.num_ranges = 0; 3773: case_stack = thiscase; 3774: nesting_stack = thiscase; 3775: } 3776: 3777: /* End a dummy case statement. */ 3778: 3779: void 3780: expand_end_case_dummy () 3781: { 3782: POPSTACK (case_stack); 3783: } 3784: 3785: /* Return the data type of the index-expression 3786: of the innermost case statement, or null if none. */ 3787: 3788: tree 3789: case_index_expr_type () 3790: { 3791: if (case_stack) 3792: return TREE_TYPE (case_stack->data.case_stmt.index_expr); 3793: return 0; 3794: } 3795: 3796: /* Accumulate one case or default label inside a case or switch statement. 3797: VALUE is the value of the case (a null pointer, for a default label). 1.1.1.6 root 3798: The function CONVERTER, when applied to arguments T and V, 3799: converts the value V to the type T. 1.1 root 3800: 3801: If not currently inside a case or switch statement, return 1 and do 3802: nothing. The caller will print a language-specific error message. 3803: If VALUE is a duplicate or overlaps, return 2 and do nothing 3804: except store the (first) duplicate node in *DUPLICATE. 3805: If VALUE is out of range, return 3 and do nothing. 3806: If we are jumping into the scope of a cleaup or var-sized array, return 5. 3807: Return 0 on success. 3808: 3809: Extended to handle range statements. */ 3810: 3811: int 1.1.1.6 root 3812: pushcase (value, converter, label, duplicate) 1.1 root 3813: register tree value; 1.1.1.6 root 3814: tree (*converter) PROTO((tree, tree)); 1.1 root 3815: register tree label; 3816: tree *duplicate; 3817: { 3818: register struct case_node **l; 3819: register struct case_node *n; 3820: tree index_type; 3821: tree nominal_type; 3822: 1.1.1.6 root 3823: if (output_bytecode) 3824: return bc_pushcase (value, label); 3825: 1.1 root 3826: /* Fail if not inside a real case statement. */ 3827: if (! (case_stack && case_stack->data.case_stmt.start)) 3828: return 1; 3829: 3830: if (stack_block_stack 3831: && stack_block_stack->depth > case_stack->depth) 3832: return 5; 3833: 3834: index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr); 3835: nominal_type = case_stack->data.case_stmt.nominal_type; 3836: 3837: /* If the index is erroneous, avoid more problems: pretend to succeed. */ 3838: if (index_type == error_mark_node) 3839: return 0; 3840: 3841: /* Convert VALUE to the type in which the comparisons are nominally done. */ 3842: if (value != 0) 1.1.1.6 root 3843: value = (*converter) (nominal_type, value); 1.1 root 3844: 3845: /* If this is the first label, warn if any insns have been emitted. */ 3846: if (case_stack->data.case_stmt.seenlabel == 0) 3847: { 3848: rtx insn; 3849: for (insn = case_stack->data.case_stmt.start; 3850: insn; 3851: insn = NEXT_INSN (insn)) 3852: { 3853: if (GET_CODE (insn) == CODE_LABEL) 3854: break; 3855: if (GET_CODE (insn) != NOTE 3856: && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE)) 3857: { 3858: warning ("unreachable code at beginning of %s", 3859: case_stack->data.case_stmt.printname); 3860: break; 3861: } 3862: } 3863: } 3864: case_stack->data.case_stmt.seenlabel = 1; 3865: 3866: /* Fail if this value is out of range for the actual type of the index 3867: (which may be narrower than NOMINAL_TYPE). */ 3868: if (value != 0 && ! int_fits_type_p (value, index_type)) 3869: return 3; 3870: 3871: /* Fail if this is a duplicate or overlaps another entry. */ 3872: if (value == 0) 3873: { 3874: if (case_stack->data.case_stmt.default_label != 0) 3875: { 3876: *duplicate = case_stack->data.case_stmt.default_label; 3877: return 2; 3878: } 3879: case_stack->data.case_stmt.default_label = label; 3880: } 3881: else 3882: { 3883: /* Find the elt in the chain before which to insert the new value, 3884: to keep the chain sorted in increasing order. 3885: But report an error if this element is a duplicate. */ 3886: for (l = &case_stack->data.case_stmt.case_list; 3887: /* Keep going past elements distinctly less than VALUE. */ 3888: *l != 0 && tree_int_cst_lt ((*l)->high, value); 3889: l = &(*l)->right) 3890: ; 3891: if (*l) 3892: { 3893: /* Element we will insert before must be distinctly greater; 3894: overlap means error. */ 3895: if (! tree_int_cst_lt (value, (*l)->low)) 3896: { 3897: *duplicate = (*l)->code_label; 3898: return 2; 3899: } 3900: } 3901: 3902: /* Add this label to the chain, and succeed. 3903: Copy VALUE so it is on temporary rather than momentary 3904: obstack and will thus survive till the end of the case statement. */ 3905: n = (struct case_node *) oballoc (sizeof (struct case_node)); 3906: n->left = 0; 3907: n->right = *l; 3908: n->high = n->low = copy_node (value); 3909: n->code_label = label; 3910: *l = n; 3911: } 3912: 3913: expand_label (label); 3914: return 0; 3915: } 3916: 3917: /* Like pushcase but this case applies to all values 3918: between VALUE1 and VALUE2 (inclusive). 3919: The return value is the same as that of pushcase 3920: but there is one additional error code: 3921: 4 means the specified range was empty. */ 3922: 3923: int 1.1.1.6 root 3924: pushcase_range (value1, value2, converter, label, duplicate) 1.1 root 3925: register tree value1, value2; 1.1.1.6 root 3926: tree (*converter) PROTO((tree, tree)); 1.1 root 3927: register tree label; 3928: tree *duplicate; 3929: { 3930: register struct case_node **l; 3931: register struct case_node *n; 3932: tree index_type; 3933: tree nominal_type; 3934: 3935: /* Fail if not inside a real case statement. */ 3936: if (! (case_stack && case_stack->data.case_stmt.start)) 3937: return 1; 3938: 3939: if (stack_block_stack 3940: && stack_block_stack->depth > case_stack->depth) 3941: return 5; 3942: 3943: index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr); 3944: nominal_type = case_stack->data.case_stmt.nominal_type; 3945: 3946: /* If the index is erroneous, avoid more problems: pretend to succeed. */ 3947: if (index_type == error_mark_node) 3948: return 0; 3949: 3950: /* If this is the first label, warn if any insns have been emitted. */ 3951: if (case_stack->data.case_stmt.seenlabel == 0) 3952: { 3953: rtx insn; 3954: for (insn = case_stack->data.case_stmt.start; 3955: insn; 3956: insn = NEXT_INSN (insn)) 3957: { 3958: if (GET_CODE (insn) == CODE_LABEL) 3959: break; 3960: if (GET_CODE (insn) != NOTE 3961: && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE)) 3962: { 3963: warning ("unreachable code at beginning of %s", 3964: case_stack->data.case_stmt.printname); 3965: break; 3966: } 3967: } 3968: } 3969: case_stack->data.case_stmt.seenlabel = 1; 3970: 3971: /* Convert VALUEs to type in which the comparisons are nominally done. */ 3972: if (value1 == 0) /* Negative infinity. */ 3973: value1 = TYPE_MIN_VALUE(index_type); 1.1.1.6 root 3974: value1 = (*converter) (nominal_type, value1); 1.1 root 3975: 3976: if (value2 == 0) /* Positive infinity. */ 3977: value2 = TYPE_MAX_VALUE(index_type); 1.1.1.6 root 3978: value2 = (*converter) (nominal_type, value2); 1.1 root 3979: 3980: /* Fail if these values are out of range. */ 3981: if (! int_fits_type_p (value1, index_type)) 3982: return 3; 3983: 3984: if (! int_fits_type_p (value2, index_type)) 3985: return 3; 3986: 3987: /* Fail if the range is empty. */ 3988: if (tree_int_cst_lt (value2, value1)) 3989: return 4; 3990: 3991: /* If the bounds are equal, turn this into the one-value case. */ 3992: if (tree_int_cst_equal (value1, value2)) 1.1.1.6 root 3993: return pushcase (value1, converter, label, duplicate); 1.1 root 3994: 3995: /* Find the elt in the chain before which to insert the new value, 3996: to keep the chain sorted in increasing order. 3997: But report an error if this element is a duplicate. */ 3998: for (l = &case_stack->data.case_stmt.case_list; 3999: /* Keep going past elements distinctly less than this range. */ 4000: *l != 0 && tree_int_cst_lt ((*l)->high, value1); 4001: l = &(*l)->right) 4002: ; 4003: if (*l) 4004: { 4005: /* Element we will insert before must be distinctly greater; 4006: overlap means error. */ 4007: if (! tree_int_cst_lt (value2, (*l)->low)) 4008: { 4009: *duplicate = (*l)->code_label; 4010: return 2; 4011: } 4012: } 4013: 4014: /* Add this label to the chain, and succeed. 4015: Copy VALUE1, VALUE2 so they are on temporary rather than momentary 4016: obstack and will thus survive till the end of the case statement. */ 4017: 4018: n = (struct case_node *) oballoc (sizeof (struct case_node)); 4019: n->left = 0; 4020: n->right = *l; 4021: n->low = copy_node (value1); 4022: n->high = copy_node (value2); 4023: n->code_label = label; 4024: *l = n; 4025: 4026: expand_label (label); 4027: 4028: case_stack->data.case_stmt.num_ranges++; 4029: 4030: return 0; 4031: } 1.1.1.6 root 4032: 4033: 4034: /* Accumulate one case or default label; VALUE is the value of the 4035: case, or nil for a default label. If not currently inside a case, 4036: return 1 and do nothing. If VALUE is a duplicate or overlaps, return 4037: 2 and do nothing. If VALUE is out of range, return 3 and do nothing. 4038: Return 0 on success. This function is a leftover from the earlier 4039: bytecode compiler, which was based on gcc 1.37. It should be 4040: merged into pushcase. */ 4041: 1.1.1.7 ! root 4042: static int 1.1.1.6 root 4043: bc_pushcase (value, label) 4044: tree value; 4045: tree label; 4046: { 4047: struct nesting *thiscase = case_stack; 4048: struct case_node *case_label, *new_label; 4049: 4050: if (! thiscase) 4051: return 1; 4052: 4053: /* Fail if duplicate, overlap, or out of type range. */ 4054: if (value) 4055: { 4056: value = convert (thiscase->data.case_stmt.nominal_type, value); 4057: if (! int_fits_type_p (value, thiscase->data.case_stmt.nominal_type)) 4058: return 3; 4059: 4060: for (case_label = thiscase->data.case_stmt.case_list; 4061: case_label->left; case_label = case_label->left) 4062: if (! tree_int_cst_lt (case_label->left->high, value)) 4063: break; 4064: 4065: if (case_label != thiscase->data.case_stmt.case_list 4066: && ! tree_int_cst_lt (case_label->high, value) 4067: || case_label->left && ! tree_int_cst_lt (value, case_label->left->low)) 4068: return 2; 4069: 4070: new_label = (struct case_node *) oballoc (sizeof (struct case_node)); 4071: new_label->low = new_label->high = copy_node (value); 4072: new_label->code_label = label; 4073: new_label->left = case_label->left; 4074: 4075: case_label->left = new_label; 4076: thiscase->data.case_stmt.num_ranges++; 4077: } 4078: else 4079: { 4080: if (thiscase->data.case_stmt.default_label) 4081: return 2; 4082: thiscase->data.case_stmt.default_label = label; 4083: } 4084: 4085: expand_label (label); 4086: return 0; 4087: } 1.1 root 4088: 1.1.1.7 ! root 4089: /* Returns the number of possible values of TYPE. ! 4090: Returns -1 if the number is unknown or variable. ! 4091: Returns -2 if the number does not fit in a HOST_WIDE_INT. ! 4092: Sets *SPARENESS to 2 if TYPE is an ENUMERAL_TYPE whose values ! 4093: do not increase monotonically (there may be duplicates); ! 4094: to 1 if the values increase monotonically, but not always by 1; ! 4095: otherwise sets it to 0. */ ! 4096: ! 4097: HOST_WIDE_INT ! 4098: all_cases_count (type, spareness) ! 4099: tree type; ! 4100: int *spareness; ! 4101: { ! 4102: HOST_WIDE_INT count, count_high = 0; ! 4103: *spareness = 0; ! 4104: ! 4105: switch (TREE_CODE (type)) ! 4106: { ! 4107: tree t; ! 4108: case BOOLEAN_TYPE: ! 4109: count = 2; ! 4110: break; ! 4111: case CHAR_TYPE: ! 4112: count = 1 << BITS_PER_UNIT; ! 4113: break; ! 4114: default: ! 4115: case INTEGER_TYPE: ! 4116: if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST ! 4117: || TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST) ! 4118: return -1; ! 4119: else ! 4120: { ! 4121: /* count ! 4122: = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) ! 4123: - TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + 1 ! 4124: but with overflow checking. */ ! 4125: tree mint = TYPE_MIN_VALUE (type); ! 4126: tree maxt = TYPE_MAX_VALUE (type); ! 4127: HOST_WIDE_INT lo, hi; ! 4128: neg_double(TREE_INT_CST_LOW (mint), TREE_INT_CST_HIGH (mint), ! 4129: &lo, &hi); ! 4130: add_double(TREE_INT_CST_LOW (maxt), TREE_INT_CST_HIGH (maxt), ! 4131: lo, hi, &lo, &hi); ! 4132: add_double (lo, hi, 1, 0, &lo, &hi); ! 4133: if (hi != 0 || lo < 0) ! 4134: return -2; ! 4135: count = lo; ! 4136: } ! 4137: break; ! 4138: case ENUMERAL_TYPE: ! 4139: count = 0; ! 4140: for (t = TYPE_VALUES (type); t != NULL_TREE; t = TREE_CHAIN (t)) ! 4141: { ! 4142: if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST ! 4143: || TREE_CODE (TREE_VALUE (t)) != INTEGER_CST ! 4144: || TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + count ! 4145: != TREE_INT_CST_LOW (TREE_VALUE (t))) ! 4146: *spareness = 1; ! 4147: count++; ! 4148: } ! 4149: if (*spareness == 1) ! 4150: { ! 4151: tree prev = TREE_VALUE (TYPE_VALUES (type)); ! 4152: for (t = TYPE_VALUES (type); t = TREE_CHAIN (t), t != NULL_TREE; ) ! 4153: { ! 4154: if (! tree_int_cst_lt (prev, TREE_VALUE (t))) ! 4155: { ! 4156: *spareness = 2; ! 4157: break; ! 4158: } ! 4159: prev = TREE_VALUE (t); ! 4160: } ! 4161: ! 4162: } ! 4163: } ! 4164: return count; ! 4165: } ! 4166: ! 4167: ! 4168: #define BITARRAY_TEST(ARRAY, INDEX) \ ! 4169: ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\ ! 4170: & (1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR))) ! 4171: #define BITARRAY_SET(ARRAY, INDEX) \ ! 4172: ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\ ! 4173: |= 1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR)) ! 4174: ! 4175: /* Set the elements of the bitstring CASES_SEEN (which has length COUNT), ! 4176: with the case values we have seen, assuming the case expression ! 4177: has the given TYPE. ! 4178: SPARSENESS is as determined by all_cases_count. ! 4179: ! 4180: The time needed is propotional to COUNT, unless ! 4181: SPARSENESS is 2, in which case quadratic time is needed. */ ! 4182: ! 4183: void ! 4184: mark_seen_cases (type, cases_seen, count, sparseness) ! 4185: tree type; ! 4186: unsigned char *cases_seen; ! 4187: long count; ! 4188: int sparseness; ! 4189: { ! 4190: long i; ! 4191: ! 4192: tree next_node_to_try = NULL_TREE; ! 4193: long next_node_offset = 0; ! 4194: ! 4195: register struct case_node *n; ! 4196: tree val = make_node (INTEGER_CST); ! 4197: TREE_TYPE (val) = type; ! 4198: for (n = case_stack->data.case_stmt.case_list; n; ! 4199: n = n->right) ! 4200: { ! 4201: TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (n->low); ! 4202: TREE_INT_CST_HIGH (val) = TREE_INT_CST_HIGH (n->low); ! 4203: while ( ! tree_int_cst_lt (n->high, val)) ! 4204: { ! 4205: /* Calculate (into xlo) the "offset" of the integer (val). ! 4206: The element with lowest value has offset 0, the next smallest ! 4207: element has offset 1, etc. */ ! 4208: ! 4209: HOST_WIDE_INT xlo, xhi; ! 4210: tree t; ! 4211: if (sparseness == 2) ! 4212: { ! 4213: /* This less efficient loop is only needed to handle ! 4214: duplicate case values (multiple enum constants ! 4215: with the same value). */ ! 4216: for (t = TYPE_VALUES (type), xlo = 0; t != NULL_TREE; ! 4217: t = TREE_CHAIN (t), xlo++) ! 4218: { ! 4219: if (tree_int_cst_equal (val, TREE_VALUE (t))) ! 4220: BITARRAY_SET (cases_seen, xlo); ! 4221: } ! 4222: } ! 4223: else ! 4224: { ! 4225: if (sparseness && TYPE_VALUES (type) != NULL_TREE) ! 4226: { ! 4227: /* The TYPE_VALUES will be in increasing order, so ! 4228: starting searching where we last ended. */ ! 4229: t = next_node_to_try; ! 4230: xlo = next_node_offset; ! 4231: xhi = 0; ! 4232: for (;;) ! 4233: { ! 4234: if (t == NULL_TREE) ! 4235: { ! 4236: t = TYPE_VALUES (type); ! 4237: xlo = 0; ! 4238: } ! 4239: if (tree_int_cst_equal (val, TREE_VALUE (t))) ! 4240: { ! 4241: next_node_to_try = TREE_CHAIN (t); ! 4242: next_node_offset = xlo + 1; ! 4243: break; ! 4244: } ! 4245: xlo++; ! 4246: t = TREE_CHAIN (t); ! 4247: if (t == next_node_to_try) ! 4248: break; ! 4249: } ! 4250: } ! 4251: else ! 4252: { ! 4253: t = TYPE_MIN_VALUE (type); ! 4254: if (t) ! 4255: neg_double (TREE_INT_CST_LOW (t), TREE_INT_CST_HIGH (t), ! 4256: &xlo, &xhi); ! 4257: else ! 4258: xlo = xhi = 0; ! 4259: add_double (xlo, xhi, ! 4260: TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val), ! 4261: &xlo, &xhi); ! 4262: } ! 4263: ! 4264: if (xhi == 0 && xlo >= 0 && xlo < count) ! 4265: BITARRAY_SET (cases_seen, xlo); ! 4266: } ! 4267: add_double (TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val), ! 4268: 1, 0, ! 4269: &TREE_INT_CST_LOW (val), &TREE_INT_CST_HIGH (val)); ! 4270: } ! 4271: } ! 4272: } ! 4273: 1.1 root 4274: /* Called when the index of a switch statement is an enumerated type 4275: and there is no default label. 4276: 4277: Checks that all enumeration literals are covered by the case 4278: expressions of a switch. Also, warn if there are any extra 4279: switch cases that are *not* elements of the enumerated type. 4280: 4281: If all enumeration literals were covered by the case expressions, 4282: turn one of the expressions into the default expression since it should 4283: not be possible to fall through such a switch. */ 4284: 4285: void 4286: check_for_full_enumeration_handling (type) 4287: tree type; 4288: { 4289: register struct case_node *n; 4290: register struct case_node **l; 4291: register tree chain; 4292: int all_values = 1; 4293: 1.1.1.7 ! root 4294: /* True iff the selector type is a numbered set mode. */ ! 4295: int sparseness = 0; ! 4296: ! 4297: /* The number of possible selector values. */ ! 4298: HOST_WIDE_INT size; ! 4299: ! 4300: /* For each possible selector value. a one iff it has been matched ! 4301: by a case value alternative. */ ! 4302: unsigned char *cases_seen; ! 4303: ! 4304: /* The allocated size of cases_seen, in chars. */ ! 4305: long bytes_needed; ! 4306: tree t; ! 4307: 1.1.1.6 root 4308: if (output_bytecode) 4309: { 4310: bc_check_for_full_enumeration_handling (type); 4311: return; 4312: } 4313: 1.1.1.7 ! root 4314: if (! warn_switch) ! 4315: return; ! 4316: ! 4317: size = all_cases_count (type, &sparseness); ! 4318: bytes_needed = (size + HOST_BITS_PER_CHAR) / HOST_BITS_PER_CHAR; ! 4319: ! 4320: if (size > 0 && size < 600000 ! 4321: /* We deliberately use malloc here - not xmalloc. */ ! 4322: && (cases_seen = (unsigned char *) malloc (bytes_needed)) != NULL) ! 4323: { ! 4324: long i; ! 4325: tree v = TYPE_VALUES (type); ! 4326: bzero (cases_seen, bytes_needed); ! 4327: ! 4328: /* The time complexity of this code is normally O(N), where ! 4329: N being the number of members in the enumerated type. ! 4330: However, if type is a ENUMERAL_TYPE whose values do not ! 4331: increase monotonically, quadratic time may be needed. */ ! 4332: ! 4333: mark_seen_cases (type, cases_seen, size, sparseness); 1.1 root 4334: 1.1.1.7 ! root 4335: for (i = 0; v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v)) 1.1 root 4336: { 1.1.1.7 ! root 4337: if (BITARRAY_TEST(cases_seen, i) == 0) 1.1.1.4 root 4338: warning ("enumeration value `%s' not handled in switch", 1.1.1.7 ! root 4339: IDENTIFIER_POINTER (TREE_PURPOSE (v))); 1.1 root 4340: } 1.1.1.7 ! root 4341: ! 4342: free (cases_seen); 1.1 root 4343: } 4344: 4345: /* Now we go the other way around; we warn if there are case 1.1.1.5 root 4346: expressions that don't correspond to enumerators. This can 1.1 root 4347: occur since C and C++ don't enforce type-checking of 4348: assignments to enumeration variables. */ 4349: 4350: if (warn_switch) 4351: for (n = case_stack->data.case_stmt.case_list; n; n = n->right) 4352: { 4353: for (chain = TYPE_VALUES (type); 4354: chain && !tree_int_cst_equal (n->low, TREE_VALUE (chain)); 4355: chain = TREE_CHAIN (chain)) 4356: ; 4357: 4358: if (!chain) 1.1.1.5 root 4359: { 4360: if (TYPE_NAME (type) == 0) 4361: warning ("case value `%d' not in enumerated type", 4362: TREE_INT_CST_LOW (n->low)); 4363: else 4364: warning ("case value `%d' not in enumerated type `%s'", 4365: TREE_INT_CST_LOW (n->low), 4366: IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type)) 4367: == IDENTIFIER_NODE) 4368: ? TYPE_NAME (type) 4369: : DECL_NAME (TYPE_NAME (type)))); 4370: } 1.1.1.4 root 4371: if (!tree_int_cst_equal (n->low, n->high)) 4372: { 4373: for (chain = TYPE_VALUES (type); 4374: chain && !tree_int_cst_equal (n->high, TREE_VALUE (chain)); 4375: chain = TREE_CHAIN (chain)) 4376: ; 4377: 4378: if (!chain) 1.1.1.5 root 4379: { 4380: if (TYPE_NAME (type) == 0) 4381: warning ("case value `%d' not in enumerated type", 4382: TREE_INT_CST_LOW (n->high)); 4383: else 4384: warning ("case value `%d' not in enumerated type `%s'", 4385: TREE_INT_CST_LOW (n->high), 4386: IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type)) 4387: == IDENTIFIER_NODE) 4388: ? TYPE_NAME (type) 4389: : DECL_NAME (TYPE_NAME (type)))); 4390: } 1.1.1.4 root 4391: } 1.1 root 4392: } 4393: 1.1.1.5 root 4394: #if 0 4395: /* ??? This optimization is disabled because it causes valid programs to 4396: fail. ANSI C does not guarantee that an expression with enum type 4397: will have a value that is the same as one of the enumation literals. */ 4398: 1.1 root 4399: /* If all values were found as case labels, make one of them the default 4400: label. Thus, this switch will never fall through. We arbitrarily pick 4401: the last one to make the default since this is likely the most 4402: efficient choice. */ 4403: 4404: if (all_values) 4405: { 4406: for (l = &case_stack->data.case_stmt.case_list; 4407: (*l)->right != 0; 4408: l = &(*l)->right) 4409: ; 4410: 4411: case_stack->data.case_stmt.default_label = (*l)->code_label; 4412: *l = 0; 4413: } 1.1.1.5 root 4414: #endif /* 0 */ 1.1 root 4415: } 1.1.1.6 root 4416: 4417: 4418: /* Check that all enumeration literals are covered by the case 4419: expressions of a switch. Also warn if there are any cases 4420: that are not elements of the enumerated type. */ 1.1.1.7 ! root 4421: ! 4422: static void 1.1.1.6 root 4423: bc_check_for_full_enumeration_handling (type) 4424: tree type; 4425: { 4426: struct nesting *thiscase = case_stack; 4427: struct case_node *c; 4428: tree e; 4429: 4430: /* Check for enums not handled. */ 4431: for (e = TYPE_VALUES (type); e; e = TREE_CHAIN (e)) 4432: { 4433: for (c = thiscase->data.case_stmt.case_list->left; 4434: c && tree_int_cst_lt (c->high, TREE_VALUE (e)); 4435: c = c->left) 4436: ; 4437: if (! (c && tree_int_cst_equal (c->low, TREE_VALUE (e)))) 4438: warning ("enumerated value `%s' not handled in switch", 4439: IDENTIFIER_POINTER (TREE_PURPOSE (e))); 4440: } 4441: 4442: /* Check for cases not in the enumeration. */ 4443: for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left) 4444: { 4445: for (e = TYPE_VALUES (type); 4446: e && !tree_int_cst_equal (c->low, TREE_VALUE (e)); 4447: e = TREE_CHAIN (e)) 4448: ; 4449: if (! e) 4450: warning ("case value `%d' not in enumerated type `%s'", 4451: TREE_INT_CST_LOW (c->low), 4452: IDENTIFIER_POINTER (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE 4453: ? TYPE_NAME (type) 4454: : DECL_NAME (TYPE_NAME (type)))); 4455: } 4456: } 1.1 root 4457: 4458: /* Terminate a case (Pascal) or switch (C) statement 1.1.1.4 root 4459: in which ORIG_INDEX is the expression to be tested. 1.1 root 4460: Generate the code to test it and jump to the right place. */ 4461: 4462: void 4463: expand_end_case (orig_index) 4464: tree orig_index; 4465: { 1.1.1.6 root 4466: tree minval, maxval, range, orig_minval; 1.1 root 4467: rtx default_label = 0; 4468: register struct case_node *n; 4469: int count; 4470: rtx index; 1.1.1.6 root 4471: rtx table_label; 1.1 root 4472: int ncases; 4473: rtx *labelvec; 4474: register int i; 4475: rtx before_case; 4476: register struct nesting *thiscase = case_stack; 1.1.1.7 ! root 4477: tree index_expr, index_type; 1.1.1.6 root 4478: int unsignedp; 4479: 4480: if (output_bytecode) 4481: { 4482: bc_expand_end_case (orig_index); 4483: return; 4484: } 4485: 4486: table_label = gen_label_rtx (); 4487: index_expr = thiscase->data.case_stmt.index_expr; 1.1.1.7 ! root 4488: index_type = TREE_TYPE (index_expr); ! 4489: unsignedp = TREE_UNSIGNED (index_type); 1.1 root 4490: 4491: do_pending_stack_adjust (); 4492: 4493: /* An ERROR_MARK occurs for various reasons including invalid data type. */ 1.1.1.7 ! root 4494: if (index_type != error_mark_node) 1.1 root 4495: { 4496: /* If switch expression was an enumerated type, check that all 4497: enumeration literals are covered by the cases. 4498: No sense trying this if there's a default case, however. */ 4499: 4500: if (!thiscase->data.case_stmt.default_label 4501: && TREE_CODE (TREE_TYPE (orig_index)) == ENUMERAL_TYPE 4502: && TREE_CODE (index_expr) != INTEGER_CST) 4503: check_for_full_enumeration_handling (TREE_TYPE (orig_index)); 4504: 4505: /* If this is the first label, warn if any insns have been emitted. */ 4506: if (thiscase->data.case_stmt.seenlabel == 0) 4507: { 4508: rtx insn; 4509: for (insn = get_last_insn (); 4510: insn != case_stack->data.case_stmt.start; 4511: insn = PREV_INSN (insn)) 4512: if (GET_CODE (insn) != NOTE 4513: && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn))!= USE)) 4514: { 4515: warning ("unreachable code at beginning of %s", 4516: case_stack->data.case_stmt.printname); 4517: break; 4518: } 4519: } 4520: 4521: /* If we don't have a default-label, create one here, 4522: after the body of the switch. */ 4523: if (thiscase->data.case_stmt.default_label == 0) 4524: { 4525: thiscase->data.case_stmt.default_label 4526: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); 4527: expand_label (thiscase->data.case_stmt.default_label); 4528: } 4529: default_label = label_rtx (thiscase->data.case_stmt.default_label); 4530: 4531: before_case = get_last_insn (); 4532: 4533: /* Simplify the case-list before we count it. */ 4534: group_case_nodes (thiscase->data.case_stmt.case_list); 4535: 4536: /* Get upper and lower bounds of case values. 4537: Also convert all the case values to the index expr's data type. */ 4538: 4539: count = 0; 4540: for (n = thiscase->data.case_stmt.case_list; n; n = n->right) 4541: { 4542: /* Check low and high label values are integers. */ 4543: if (TREE_CODE (n->low) != INTEGER_CST) 4544: abort (); 4545: if (TREE_CODE (n->high) != INTEGER_CST) 4546: abort (); 4547: 1.1.1.7 ! root 4548: n->low = convert (index_type, n->low); ! 4549: n->high = convert (index_type, n->high); 1.1 root 4550: 4551: /* Count the elements and track the largest and smallest 4552: of them (treating them as signed even if they are not). */ 4553: if (count++ == 0) 4554: { 4555: minval = n->low; 4556: maxval = n->high; 4557: } 4558: else 4559: { 4560: if (INT_CST_LT (n->low, minval)) 4561: minval = n->low; 4562: if (INT_CST_LT (maxval, n->high)) 4563: maxval = n->high; 4564: } 4565: /* A range counts double, since it requires two compares. */ 4566: if (! tree_int_cst_equal (n->low, n->high)) 4567: count++; 4568: } 4569: 1.1.1.6 root 4570: orig_minval = minval; 4571: 1.1 root 4572: /* Compute span of values. */ 4573: if (count != 0) 1.1.1.7 ! root 4574: range = fold (build (MINUS_EXPR, index_type, maxval, minval)); 1.1 root 4575: 1.1.1.7 ! root 4576: if (count == 0) 1.1 root 4577: { 4578: expand_expr (index_expr, const0_rtx, VOIDmode, 0); 4579: emit_queue (); 4580: emit_jump (default_label); 4581: } 1.1.1.6 root 4582: 1.1 root 4583: /* If range of values is much bigger than number of values, 4584: make a sequence of conditional branches instead of a dispatch. 4585: If the switch-index is a constant, do it this way 4586: because we can optimize it. */ 1.1.1.4 root 4587: 4588: #ifndef CASE_VALUES_THRESHOLD 1.1 root 4589: #ifdef HAVE_casesi 1.1.1.4 root 4590: #define CASE_VALUES_THRESHOLD (HAVE_casesi ? 4 : 5) 1.1 root 4591: #else 1.1.1.4 root 4592: /* If machine does not have a case insn that compares the 4593: bounds, this means extra overhead for dispatch tables 4594: which raises the threshold for using them. */ 4595: #define CASE_VALUES_THRESHOLD 5 4596: #endif /* HAVE_casesi */ 4597: #endif /* CASE_VALUES_THRESHOLD */ 4598: 4599: else if (TREE_INT_CST_HIGH (range) != 0 4600: || count < CASE_VALUES_THRESHOLD 4601: || ((unsigned HOST_WIDE_INT) (TREE_INT_CST_LOW (range)) 4602: > 10 * count) 1.1 root 4603: || TREE_CODE (index_expr) == INTEGER_CST 1.1.1.2 root 4604: /* These will reduce to a constant. */ 1.1 root 4605: || (TREE_CODE (index_expr) == CALL_EXPR 4606: && TREE_CODE (TREE_OPERAND (index_expr, 0)) == ADDR_EXPR 4607: && TREE_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == FUNCTION_DECL 1.1.1.2 root 4608: && DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == BUILT_IN_CLASSIFY_TYPE) 4609: || (TREE_CODE (index_expr) == COMPOUND_EXPR 4610: && TREE_CODE (TREE_OPERAND (index_expr, 1)) == INTEGER_CST)) 1.1 root 4611: { 1.1.1.4 root 4612: index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0); 1.1 root 4613: 4614: /* If the index is a short or char that we do not have 4615: an insn to handle comparisons directly, convert it to 4616: a full integer now, rather than letting each comparison 4617: generate the conversion. */ 4618: 4619: if (GET_MODE_CLASS (GET_MODE (index)) == MODE_INT 4620: && (cmp_optab->handlers[(int) GET_MODE(index)].insn_code 4621: == CODE_FOR_nothing)) 4622: { 4623: enum machine_mode wider_mode; 4624: for (wider_mode = GET_MODE (index); wider_mode != VOIDmode; 4625: wider_mode = GET_MODE_WIDER_MODE (wider_mode)) 4626: if (cmp_optab->handlers[(int) wider_mode].insn_code 4627: != CODE_FOR_nothing) 4628: { 4629: index = convert_to_mode (wider_mode, index, unsignedp); 4630: break; 4631: } 4632: } 4633: 4634: emit_queue (); 4635: do_pending_stack_adjust (); 4636: 4637: index = protect_from_queue (index, 0); 4638: if (GET_CODE (index) == MEM) 4639: index = copy_to_reg (index); 4640: if (GET_CODE (index) == CONST_INT 4641: || TREE_CODE (index_expr) == INTEGER_CST) 4642: { 4643: /* Make a tree node with the proper constant value 4644: if we don't already have one. */ 4645: if (TREE_CODE (index_expr) != INTEGER_CST) 4646: { 4647: index_expr 4648: = build_int_2 (INTVAL (index), 1.1.1.7 ! root 4649: unsignedp || INTVAL (index) >= 0 ? 0 : -1); ! 4650: index_expr = convert (index_type, index_expr); 1.1 root 4651: } 4652: 4653: /* For constant index expressions we need only 4654: issue a unconditional branch to the appropriate 4655: target code. The job of removing any unreachable 4656: code is left to the optimisation phase if the 4657: "-O" option is specified. */ 1.1.1.7 ! root 4658: for (n = thiscase->data.case_stmt.case_list; n; n = n->right) ! 4659: if (! tree_int_cst_lt (index_expr, n->low) ! 4660: && ! tree_int_cst_lt (n->high, index_expr)) ! 4661: break; ! 4662: 1.1 root 4663: if (n) 4664: emit_jump (label_rtx (n->code_label)); 4665: else 4666: emit_jump (default_label); 4667: } 4668: else 4669: { 4670: /* If the index expression is not constant we generate 4671: a binary decision tree to select the appropriate 4672: target code. This is done as follows: 4673: 4674: The list of cases is rearranged into a binary tree, 4675: nearly optimal assuming equal probability for each case. 4676: 4677: The tree is transformed into RTL, eliminating 4678: redundant test conditions at the same time. 4679: 4680: If program flow could reach the end of the 4681: decision tree an unconditional jump to the 4682: default code is emitted. */ 4683: 4684: use_cost_table 4685: = (TREE_CODE (TREE_TYPE (orig_index)) != ENUMERAL_TYPE 4686: && estimate_case_costs (thiscase->data.case_stmt.case_list)); 1.1.1.4 root 4687: balance_case_nodes (&thiscase->data.case_stmt.case_list, 4688: NULL_PTR); 1.1 root 4689: emit_case_nodes (index, thiscase->data.case_stmt.case_list, 1.1.1.7 ! root 4690: default_label, index_type); 1.1 root 4691: emit_jump_if_reachable (default_label); 4692: } 4693: } 4694: else 4695: { 4696: int win = 0; 4697: #ifdef HAVE_casesi 4698: if (HAVE_casesi) 4699: { 1.1.1.3 root 4700: enum machine_mode index_mode = SImode; 4701: int index_bits = GET_MODE_BITSIZE (index_mode); 1.1.1.7 ! root 4702: rtx op1, op2; ! 4703: enum machine_mode op_mode; 1.1.1.3 root 4704: 1.1 root 4705: /* Convert the index to SImode. */ 1.1.1.7 ! root 4706: if (GET_MODE_BITSIZE (TYPE_MODE (index_type)) 1.1.1.3 root 4707: > GET_MODE_BITSIZE (index_mode)) 1.1 root 4708: { 1.1.1.7 ! root 4709: enum machine_mode omode = TYPE_MODE (index_type); 1.1.1.4 root 4710: rtx rangertx = expand_expr (range, NULL_RTX, VOIDmode, 0); 1.1.1.3 root 4711: 4712: /* We must handle the endpoints in the original mode. */ 1.1.1.7 ! root 4713: index_expr = build (MINUS_EXPR, index_type, 1.1 root 4714: index_expr, minval); 4715: minval = integer_zero_node; 1.1.1.4 root 4716: index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0); 1.1.1.6 root 4717: emit_cmp_insn (rangertx, index, LTU, NULL_RTX, omode, 1, 0); 1.1.1.3 root 4718: emit_jump_insn (gen_bltu (default_label)); 4719: /* Now we can safely truncate. */ 4720: index = convert_to_mode (index_mode, index, 0); 4721: } 4722: else 4723: { 1.1.1.7 ! root 4724: if (TYPE_MODE (index_type) != index_mode) ! 4725: { ! 4726: index_expr = convert (type_for_size (index_bits, 0), ! 4727: index_expr); ! 4728: index_type = TREE_TYPE (index_expr); ! 4729: } ! 4730: 1.1.1.4 root 4731: index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0); 1.1 root 4732: } 4733: emit_queue (); 4734: index = protect_from_queue (index, 0); 4735: do_pending_stack_adjust (); 4736: 1.1.1.7 ! root 4737: op_mode = insn_operand_mode[(int)CODE_FOR_casesi][0]; ! 4738: if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][0]) ! 4739: (index, op_mode)) ! 4740: index = copy_to_mode_reg (op_mode, index); ! 4741: ! 4742: op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0); ! 4743: ! 4744: op_mode = insn_operand_mode[(int)CODE_FOR_casesi][1]; ! 4745: if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][1]) ! 4746: (op1, op_mode)) ! 4747: op1 = copy_to_mode_reg (op_mode, op1); ! 4748: ! 4749: op2 = expand_expr (range, NULL_RTX, VOIDmode, 0); ! 4750: ! 4751: op_mode = insn_operand_mode[(int)CODE_FOR_casesi][2]; ! 4752: if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][2]) ! 4753: (op2, op_mode)) ! 4754: op2 = copy_to_mode_reg (op_mode, op2); ! 4755: ! 4756: emit_jump_insn (gen_casesi (index, op1, op2, 1.1 root 4757: table_label, default_label)); 4758: win = 1; 4759: } 4760: #endif 4761: #ifdef HAVE_tablejump 4762: if (! win && HAVE_tablejump) 4763: { 4764: index_expr = convert (thiscase->data.case_stmt.nominal_type, 1.1.1.7 ! root 4765: fold (build (MINUS_EXPR, index_type, 1.1.1.2 root 4766: index_expr, minval))); 1.1.1.7 ! root 4767: index_type = TREE_TYPE (index_expr); 1.1.1.4 root 4768: index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0); 1.1 root 4769: emit_queue (); 4770: index = protect_from_queue (index, 0); 4771: do_pending_stack_adjust (); 4772: 1.1.1.7 ! root 4773: do_tablejump (index, TYPE_MODE (index_type), 1.1.1.4 root 4774: expand_expr (range, NULL_RTX, VOIDmode, 0), 1.1 root 4775: table_label, default_label); 4776: win = 1; 4777: } 4778: #endif 4779: if (! win) 4780: abort (); 4781: 4782: /* Get table of labels to jump to, in order of case index. */ 4783: 4784: ncases = TREE_INT_CST_LOW (range) + 1; 4785: labelvec = (rtx *) alloca (ncases * sizeof (rtx)); 1.1.1.7 ! root 4786: bzero ((char *) labelvec, ncases * sizeof (rtx)); 1.1 root 4787: 4788: for (n = thiscase->data.case_stmt.case_list; n; n = n->right) 4789: { 1.1.1.4 root 4790: register HOST_WIDE_INT i 1.1.1.6 root 4791: = TREE_INT_CST_LOW (n->low) - TREE_INT_CST_LOW (orig_minval); 1.1 root 4792: 4793: while (1) 4794: { 4795: labelvec[i] 4796: = gen_rtx (LABEL_REF, Pmode, label_rtx (n->code_label)); 1.1.1.6 root 4797: if (i + TREE_INT_CST_LOW (orig_minval) 1.1 root 4798: == TREE_INT_CST_LOW (n->high)) 4799: break; 4800: i++; 4801: } 4802: } 4803: 4804: /* Fill in the gaps with the default. */ 4805: for (i = 0; i < ncases; i++) 4806: if (labelvec[i] == 0) 4807: labelvec[i] = gen_rtx (LABEL_REF, Pmode, default_label); 4808: 4809: /* Output the table */ 4810: emit_label (table_label); 4811: 4812: /* This would be a lot nicer if CASE_VECTOR_PC_RELATIVE 1.1.1.4 root 4813: were an expression, instead of an #ifdef/#ifndef. */ 1.1 root 4814: if ( 4815: #ifdef CASE_VECTOR_PC_RELATIVE 4816: 1 || 4817: #endif 4818: flag_pic) 4819: emit_jump_insn (gen_rtx (ADDR_DIFF_VEC, CASE_VECTOR_MODE, 4820: gen_rtx (LABEL_REF, Pmode, table_label), 4821: gen_rtvec_v (ncases, labelvec))); 4822: else 4823: emit_jump_insn (gen_rtx (ADDR_VEC, CASE_VECTOR_MODE, 4824: gen_rtvec_v (ncases, labelvec))); 4825: 4826: /* If the case insn drops through the table, 4827: after the table we must jump to the default-label. 4828: Otherwise record no drop-through after the table. */ 4829: #ifdef CASE_DROPS_THROUGH 4830: emit_jump (default_label); 4831: #else 4832: emit_barrier (); 4833: #endif 4834: } 4835: 1.1.1.3 root 4836: before_case = squeeze_notes (NEXT_INSN (before_case), get_last_insn ()); 4837: reorder_insns (before_case, get_last_insn (), 1.1 root 4838: thiscase->data.case_stmt.start); 4839: } 1.1.1.7 ! root 4840: 1.1 root 4841: if (thiscase->exit_label) 4842: emit_label (thiscase->exit_label); 4843: 4844: POPSTACK (case_stack); 4845: 4846: free_temp_slots (); 4847: } 4848: 1.1.1.6 root 4849: 4850: /* Terminate a case statement. EXPR is the original index 4851: expression. */ 1.1.1.7 ! root 4852: ! 4853: static void 1.1.1.6 root 4854: bc_expand_end_case (expr) 4855: tree expr; 4856: { 4857: struct nesting *thiscase = case_stack; 4858: enum bytecode_opcode opcode; 4859: struct bc_label *jump_label; 4860: struct case_node *c; 4861: 4862: bc_emit_bytecode (jump); 4863: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->exit_label)); 4864: 4865: #ifdef DEBUG_PRINT_CODE 4866: fputc ('\n', stderr); 4867: #endif 4868: 4869: /* Now that the size of the jump table is known, emit the actual 4870: indexed jump instruction. */ 4871: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscase->data.case_stmt.skip_label)); 4872: 4873: opcode = TYPE_MODE (thiscase->data.case_stmt.nominal_type) == SImode 4874: ? TREE_UNSIGNED (thiscase->data.case_stmt.nominal_type) ? caseSU : caseSI 4875: : TREE_UNSIGNED (thiscase->data.case_stmt.nominal_type) ? caseDU : caseDI; 4876: 4877: bc_emit_bytecode (opcode); 4878: 4879: /* Now emit the case instructions literal arguments, in order. 4880: In addition to the value on the stack, it uses: 4881: 1. The address of the jump table. 4882: 2. The size of the jump table. 4883: 3. The default label. */ 4884: 4885: jump_label = bc_get_bytecode_label (); 4886: bc_emit_bytecode_labelref (jump_label); 4887: bc_emit_bytecode_const ((char *) &thiscase->data.case_stmt.num_ranges, 4888: sizeof thiscase->data.case_stmt.num_ranges); 4889: 4890: if (thiscase->data.case_stmt.default_label) 4891: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (thiscase->data.case_stmt.default_label))); 4892: else 4893: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->exit_label)); 4894: 4895: /* Output the jump table. */ 4896: 4897: bc_align_bytecode (3 /* PTR_ALIGN */); 4898: bc_emit_bytecode_labeldef (jump_label); 4899: 4900: if (TYPE_MODE (thiscase->data.case_stmt.nominal_type) == SImode) 4901: for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left) 4902: { 4903: opcode = TREE_INT_CST_LOW (c->low); 4904: bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); 4905: 4906: opcode = TREE_INT_CST_LOW (c->high); 4907: bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); 4908: 4909: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (c->code_label))); 4910: } 4911: else 4912: if (TYPE_MODE (thiscase->data.case_stmt.nominal_type) == DImode) 4913: for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left) 4914: { 4915: bc_emit_bytecode_DI_const (c->low); 4916: bc_emit_bytecode_DI_const (c->high); 4917: 4918: bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (c->code_label))); 4919: } 4920: else 4921: /* Bad mode */ 4922: abort (); 4923: 4924: 4925: bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscase->exit_label)); 4926: 4927: /* Possibly issue enumeration warnings. */ 4928: 4929: if (!thiscase->data.case_stmt.default_label 4930: && TREE_CODE (TREE_TYPE (expr)) == ENUMERAL_TYPE 4931: && TREE_CODE (expr) != INTEGER_CST 4932: && warn_switch) 4933: check_for_full_enumeration_handling (TREE_TYPE (expr)); 4934: 4935: 4936: #ifdef DEBUG_PRINT_CODE 4937: fputc ('\n', stderr); 4938: #endif 4939: 4940: POPSTACK (case_stack); 4941: } 4942: 4943: 4944: /* Return unique bytecode ID. */ 1.1.1.7 ! root 4945: 1.1.1.6 root 4946: int 4947: bc_new_uid () 4948: { 4949: static int bc_uid = 0; 4950: 4951: return (++bc_uid); 4952: } 4953: 1.1 root 4954: /* Generate code to jump to LABEL if OP1 and OP2 are equal. */ 4955: 4956: static void 4957: do_jump_if_equal (op1, op2, label, unsignedp) 4958: rtx op1, op2, label; 4959: int unsignedp; 4960: { 4961: if (GET_CODE (op1) == CONST_INT 4962: && GET_CODE (op2) == CONST_INT) 4963: { 4964: if (INTVAL (op1) == INTVAL (op2)) 4965: emit_jump (label); 4966: } 4967: else 4968: { 4969: enum machine_mode mode = GET_MODE (op1); 4970: if (mode == VOIDmode) 4971: mode = GET_MODE (op2); 1.1.1.4 root 4972: emit_cmp_insn (op1, op2, EQ, NULL_RTX, mode, unsignedp, 0); 1.1 root 4973: emit_jump_insn (gen_beq (label)); 4974: } 4975: } 4976: 4977: /* Not all case values are encountered equally. This function 4978: uses a heuristic to weight case labels, in cases where that 4979: looks like a reasonable thing to do. 4980: 4981: Right now, all we try to guess is text, and we establish the 4982: following weights: 4983: 4984: chars above space: 16 4985: digits: 16 4986: default: 12 4987: space, punct: 8 4988: tab: 4 4989: newline: 2 4990: other "\" chars: 1 4991: remaining chars: 0 4992: 4993: If we find any cases in the switch that are not either -1 or in the range 4994: of valid ASCII characters, or are control characters other than those 4995: commonly used with "\", don't treat this switch scanning text. 4996: 4997: Return 1 if these nodes are suitable for cost estimation, otherwise 4998: return 0. */ 4999: 5000: static int 5001: estimate_case_costs (node) 5002: case_node_ptr node; 5003: { 5004: tree min_ascii = build_int_2 (-1, -1); 5005: tree max_ascii = convert (TREE_TYPE (node->high), build_int_2 (127, 0)); 5006: case_node_ptr n; 5007: int i; 5008: 5009: /* If we haven't already made the cost table, make it now. Note that the 5010: lower bound of the table is -1, not zero. */ 5011: 5012: if (cost_table == NULL) 5013: { 5014: cost_table = ((short *) xmalloc (129 * sizeof (short))) + 1; 1.1.1.7 ! root 5015: bzero ((char *) (cost_table - 1), 129 * sizeof (short)); 1.1 root 5016: 5017: for (i = 0; i < 128; i++) 5018: { 5019: if (isalnum (i)) 5020: cost_table[i] = 16; 5021: else if (ispunct (i)) 5022: cost_table[i] = 8; 5023: else if (iscntrl (i)) 5024: cost_table[i] = -1; 5025: } 5026: 5027: cost_table[' '] = 8; 5028: cost_table['\t'] = 4; 5029: cost_table['\0'] = 4; 5030: cost_table['\n'] = 2; 5031: cost_table['\f'] = 1; 5032: cost_table['\v'] = 1; 5033: cost_table['\b'] = 1; 5034: } 5035: 5036: /* See if all the case expressions look like text. It is text if the 5037: constant is >= -1 and the highest constant is <= 127. Do all comparisons 5038: as signed arithmetic since we don't want to ever access cost_table with a 5039: value less than -1. Also check that none of the constants in a range 5040: are strange control characters. */ 5041: 5042: for (n = node; n; n = n->right) 5043: { 5044: if ((INT_CST_LT (n->low, min_ascii)) || INT_CST_LT (max_ascii, n->high)) 5045: return 0; 5046: 5047: for (i = TREE_INT_CST_LOW (n->low); i <= TREE_INT_CST_LOW (n->high); i++) 5048: if (cost_table[i] < 0) 5049: return 0; 5050: } 5051: 5052: /* All interesting values are within the range of interesting 5053: ASCII characters. */ 5054: return 1; 5055: } 5056: 5057: /* Scan an ordered list of case nodes 5058: combining those with consecutive values or ranges. 5059: 5060: Eg. three separate entries 1: 2: 3: become one entry 1..3: */ 5061: 5062: static void 5063: group_case_nodes (head) 5064: case_node_ptr head; 5065: { 5066: case_node_ptr node = head; 5067: 5068: while (node) 5069: { 5070: rtx lb = next_real_insn (label_rtx (node->code_label)); 5071: case_node_ptr np = node; 5072: 5073: /* Try to group the successors of NODE with NODE. */ 5074: while (((np = np->right) != 0) 5075: /* Do they jump to the same place? */ 5076: && next_real_insn (label_rtx (np->code_label)) == lb 5077: /* Are their ranges consecutive? */ 5078: && tree_int_cst_equal (np->low, 5079: fold (build (PLUS_EXPR, 5080: TREE_TYPE (node->high), 5081: node->high, 5082: integer_one_node))) 5083: /* An overflow is not consecutive. */ 5084: && tree_int_cst_lt (node->high, 5085: fold (build (PLUS_EXPR, 5086: TREE_TYPE (node->high), 5087: node->high, 5088: integer_one_node)))) 5089: { 5090: node->high = np->high; 5091: } 5092: /* NP is the first node after NODE which can't be grouped with it. 5093: Delete the nodes in between, and move on to that node. */ 5094: node->right = np; 5095: node = np; 5096: } 5097: } 5098: 5099: /* Take an ordered list of case nodes 5100: and transform them into a near optimal binary tree, 1.1.1.3 root 5101: on the assumption that any target code selection value is as 1.1 root 5102: likely as any other. 5103: 5104: The transformation is performed by splitting the ordered 5105: list into two equal sections plus a pivot. The parts are 5106: then attached to the pivot as left and right branches. Each 5107: branch is is then transformed recursively. */ 5108: 5109: static void 5110: balance_case_nodes (head, parent) 5111: case_node_ptr *head; 5112: case_node_ptr parent; 5113: { 5114: register case_node_ptr np; 5115: 5116: np = *head; 5117: if (np) 5118: { 5119: int cost = 0; 5120: int i = 0; 5121: int ranges = 0; 5122: register case_node_ptr *npp; 5123: case_node_ptr left; 5124: 5125: /* Count the number of entries on branch. Also count the ranges. */ 5126: 5127: while (np) 5128: { 5129: if (!tree_int_cst_equal (np->low, np->high)) 5130: { 5131: ranges++; 5132: if (use_cost_table) 5133: cost += cost_table[TREE_INT_CST_LOW (np->high)]; 5134: } 5135: 5136: if (use_cost_table) 5137: cost += cost_table[TREE_INT_CST_LOW (np->low)]; 5138: 5139: i++; 5140: np = np->right; 5141: } 5142: 5143: if (i > 2) 5144: { 5145: /* Split this list if it is long enough for that to help. */ 5146: npp = head; 5147: left = *npp; 5148: if (use_cost_table) 5149: { 5150: /* Find the place in the list that bisects the list's total cost, 5151: Here I gets half the total cost. */ 5152: int n_moved = 0; 5153: i = (cost + 1) / 2; 5154: while (1) 5155: { 5156: /* Skip nodes while their cost does not reach that amount. */ 5157: if (!tree_int_cst_equal ((*npp)->low, (*npp)->high)) 5158: i -= cost_table[TREE_INT_CST_LOW ((*npp)->high)]; 5159: i -= cost_table[TREE_INT_CST_LOW ((*npp)->low)]; 5160: if (i <= 0) 5161: break; 5162: npp = &(*npp)->right; 5163: n_moved += 1; 5164: } 5165: if (n_moved == 0) 5166: { 5167: /* Leave this branch lopsided, but optimize left-hand 5168: side and fill in `parent' fields for right-hand side. */ 5169: np = *head; 5170: np->parent = parent; 5171: balance_case_nodes (&np->left, np); 5172: for (; np->right; np = np->right) 5173: np->right->parent = np; 5174: return; 5175: } 5176: } 5177: /* If there are just three nodes, split at the middle one. */ 5178: else if (i == 3) 5179: npp = &(*npp)->right; 5180: else 5181: { 5182: /* Find the place in the list that bisects the list's total cost, 5183: where ranges count as 2. 5184: Here I gets half the total cost. */ 5185: i = (i + ranges + 1) / 2; 5186: while (1) 5187: { 5188: /* Skip nodes while their cost does not reach that amount. */ 5189: if (!tree_int_cst_equal ((*npp)->low, (*npp)->high)) 5190: i--; 5191: i--; 5192: if (i <= 0) 5193: break; 5194: npp = &(*npp)->right; 5195: } 5196: } 5197: *head = np = *npp; 5198: *npp = 0; 5199: np->parent = parent; 5200: np->left = left; 5201: 5202: /* Optimize each of the two split parts. */ 5203: balance_case_nodes (&np->left, np); 5204: balance_case_nodes (&np->right, np); 5205: } 5206: else 5207: { 5208: /* Else leave this branch as one level, 5209: but fill in `parent' fields. */ 5210: np = *head; 5211: np->parent = parent; 5212: for (; np->right; np = np->right) 5213: np->right->parent = np; 5214: } 5215: } 5216: } 5217: 5218: /* Search the parent sections of the case node tree 5219: to see if a test for the lower bound of NODE would be redundant. 5220: INDEX_TYPE is the type of the index expression. 5221: 5222: The instructions to generate the case decision tree are 5223: output in the same order as nodes are processed so it is 5224: known that if a parent node checks the range of the current 5225: node minus one that the current node is bounded at its lower 5226: span. Thus the test would be redundant. */ 5227: 5228: static int 5229: node_has_low_bound (node, index_type) 5230: case_node_ptr node; 5231: tree index_type; 5232: { 5233: tree low_minus_one; 5234: case_node_ptr pnode; 5235: 5236: /* If the lower bound of this node is the lowest value in the index type, 5237: we need not test it. */ 5238: 5239: if (tree_int_cst_equal (node->low, TYPE_MIN_VALUE (index_type))) 5240: return 1; 5241: 5242: /* If this node has a left branch, the value at the left must be less 5243: than that at this node, so it cannot be bounded at the bottom and 5244: we need not bother testing any further. */ 5245: 5246: if (node->left) 5247: return 0; 5248: 5249: low_minus_one = fold (build (MINUS_EXPR, TREE_TYPE (node->low), 5250: node->low, integer_one_node)); 5251: 5252: /* If the subtraction above overflowed, we can't verify anything. 5253: Otherwise, look for a parent that tests our value - 1. */ 5254: 5255: if (! tree_int_cst_lt (low_minus_one, node->low)) 5256: return 0; 5257: 5258: for (pnode = node->parent; pnode; pnode = pnode->parent) 5259: if (tree_int_cst_equal (low_minus_one, pnode->high)) 5260: return 1; 5261: 5262: return 0; 5263: } 5264: 5265: /* Search the parent sections of the case node tree 5266: to see if a test for the upper bound of NODE would be redundant. 5267: INDEX_TYPE is the type of the index expression. 5268: 5269: The instructions to generate the case decision tree are 5270: output in the same order as nodes are processed so it is 5271: known that if a parent node checks the range of the current 5272: node plus one that the current node is bounded at its upper 5273: span. Thus the test would be redundant. */ 5274: 5275: static int 5276: node_has_high_bound (node, index_type) 5277: case_node_ptr node; 5278: tree index_type; 5279: { 5280: tree high_plus_one; 5281: case_node_ptr pnode; 5282: 5283: /* If the upper bound of this node is the highest value in the type 5284: of the index expression, we need not test against it. */ 5285: 5286: if (tree_int_cst_equal (node->high, TYPE_MAX_VALUE (index_type))) 5287: return 1; 5288: 5289: /* If this node has a right branch, the value at the right must be greater 5290: than that at this node, so it cannot be bounded at the top and 5291: we need not bother testing any further. */ 5292: 5293: if (node->right) 5294: return 0; 5295: 5296: high_plus_one = fold (build (PLUS_EXPR, TREE_TYPE (node->high), 5297: node->high, integer_one_node)); 5298: 5299: /* If the addition above overflowed, we can't verify anything. 5300: Otherwise, look for a parent that tests our value + 1. */ 5301: 5302: if (! tree_int_cst_lt (node->high, high_plus_one)) 5303: return 0; 5304: 5305: for (pnode = node->parent; pnode; pnode = pnode->parent) 5306: if (tree_int_cst_equal (high_plus_one, pnode->low)) 5307: return 1; 5308: 5309: return 0; 5310: } 5311: 5312: /* Search the parent sections of the 5313: case node tree to see if both tests for the upper and lower 5314: bounds of NODE would be redundant. */ 5315: 5316: static int 5317: node_is_bounded (node, index_type) 5318: case_node_ptr node; 5319: tree index_type; 5320: { 5321: return (node_has_low_bound (node, index_type) 5322: && node_has_high_bound (node, index_type)); 5323: } 5324: 5325: /* Emit an unconditional jump to LABEL unless it would be dead code. */ 5326: 5327: static void 5328: emit_jump_if_reachable (label) 5329: rtx label; 5330: { 5331: if (GET_CODE (get_last_insn ()) != BARRIER) 5332: emit_jump (label); 5333: } 5334: 5335: /* Emit step-by-step code to select a case for the value of INDEX. 5336: The thus generated decision tree follows the form of the 5337: case-node binary tree NODE, whose nodes represent test conditions. 5338: INDEX_TYPE is the type of the index of the switch. 5339: 5340: Care is taken to prune redundant tests from the decision tree 5341: by detecting any boundary conditions already checked by 5342: emitted rtx. (See node_has_high_bound, node_has_low_bound 5343: and node_is_bounded, above.) 5344: 5345: Where the test conditions can be shown to be redundant we emit 5346: an unconditional jump to the target code. As a further 5347: optimization, the subordinates of a tree node are examined to 5348: check for bounded nodes. In this case conditional and/or 5349: unconditional jumps as a result of the boundary check for the 5350: current node are arranged to target the subordinates associated 5351: code for out of bound conditions on the current node node. 5352: 1.1.1.4 root 5353: We can assume that when control reaches the code generated here, 1.1 root 5354: the index value has already been compared with the parents 5355: of this node, and determined to be on the same side of each parent 5356: as this node is. Thus, if this node tests for the value 51, 5357: and a parent tested for 52, we don't need to consider 5358: the possibility of a value greater than 51. If another parent 5359: tests for the value 50, then this node need not test anything. */ 5360: 5361: static void 5362: emit_case_nodes (index, node, default_label, index_type) 5363: rtx index; 5364: case_node_ptr node; 5365: rtx default_label; 5366: tree index_type; 5367: { 5368: /* If INDEX has an unsigned type, we must make unsigned branches. */ 5369: int unsignedp = TREE_UNSIGNED (index_type); 5370: typedef rtx rtx_function (); 5371: rtx_function *gen_bgt_pat = unsignedp ? gen_bgtu : gen_bgt; 5372: rtx_function *gen_bge_pat = unsignedp ? gen_bgeu : gen_bge; 5373: rtx_function *gen_blt_pat = unsignedp ? gen_bltu : gen_blt; 5374: rtx_function *gen_ble_pat = unsignedp ? gen_bleu : gen_ble; 5375: enum machine_mode mode = GET_MODE (index); 5376: 5377: /* See if our parents have already tested everything for us. 5378: If they have, emit an unconditional jump for this node. */ 5379: if (node_is_bounded (node, index_type)) 5380: emit_jump (label_rtx (node->code_label)); 5381: 5382: else if (tree_int_cst_equal (node->low, node->high)) 5383: { 5384: /* Node is single valued. First see if the index expression matches 5385: this node and then check our children, if any. */ 5386: 1.1.1.4 root 5387: do_jump_if_equal (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0), 1.1 root 5388: label_rtx (node->code_label), unsignedp); 5389: 5390: if (node->right != 0 && node->left != 0) 5391: { 5392: /* This node has children on both sides. 5393: Dispatch to one side or the other 5394: by comparing the index value with this node's value. 5395: If one subtree is bounded, check that one first, 5396: so we can avoid real branches in the tree. */ 5397: 5398: if (node_is_bounded (node->right, index_type)) 5399: { 1.1.1.4 root 5400: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 5401: VOIDmode, 0), 5402: GT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5403: 5404: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label))); 5405: emit_case_nodes (index, node->left, default_label, index_type); 5406: } 5407: 5408: else if (node_is_bounded (node->left, index_type)) 5409: { 1.1.1.4 root 5410: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 1.1 root 5411: VOIDmode, 0), 1.1.1.4 root 5412: LT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5413: emit_jump_insn ((*gen_blt_pat) (label_rtx (node->left->code_label))); 5414: emit_case_nodes (index, node->right, default_label, index_type); 5415: } 5416: 5417: else 5418: { 5419: /* Neither node is bounded. First distinguish the two sides; 5420: then emit the code for one side at a time. */ 5421: 5422: tree test_label 5423: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); 5424: 5425: /* See if the value is on the right. */ 1.1.1.4 root 5426: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 1.1 root 5427: VOIDmode, 0), 1.1.1.4 root 5428: GT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5429: emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label))); 5430: 5431: /* Value must be on the left. 5432: Handle the left-hand subtree. */ 5433: emit_case_nodes (index, node->left, default_label, index_type); 5434: /* If left-hand subtree does nothing, 5435: go to default. */ 5436: emit_jump_if_reachable (default_label); 5437: 5438: /* Code branches here for the right-hand subtree. */ 5439: expand_label (test_label); 5440: emit_case_nodes (index, node->right, default_label, index_type); 5441: } 5442: } 5443: 5444: else if (node->right != 0 && node->left == 0) 5445: { 5446: /* Here we have a right child but no left so we issue conditional 5447: branch to default and process the right child. 5448: 5449: Omit the conditional branch to default if we it avoid only one 5450: right child; it costs too much space to save so little time. */ 5451: 5452: if (node->right->right || node->right->left 5453: || !tree_int_cst_equal (node->right->low, node->right->high)) 5454: { 5455: if (!node_has_low_bound (node, index_type)) 5456: { 1.1.1.4 root 5457: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 5458: VOIDmode, 0), 5459: LT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5460: emit_jump_insn ((*gen_blt_pat) (default_label)); 5461: } 5462: 5463: emit_case_nodes (index, node->right, default_label, index_type); 5464: } 5465: else 5466: /* We cannot process node->right normally 5467: since we haven't ruled out the numbers less than 5468: this node's value. So handle node->right explicitly. */ 5469: do_jump_if_equal (index, 1.1.1.4 root 5470: expand_expr (node->right->low, NULL_RTX, 5471: VOIDmode, 0), 1.1 root 5472: label_rtx (node->right->code_label), unsignedp); 5473: } 5474: 5475: else if (node->right == 0 && node->left != 0) 5476: { 5477: /* Just one subtree, on the left. */ 5478: 5479: #if 0 /* The following code and comment were formerly part 5480: of the condition here, but they didn't work 5481: and I don't understand what the idea was. -- rms. */ 5482: /* If our "most probable entry" is less probable 5483: than the default label, emit a jump to 5484: the default label using condition codes 5485: already lying around. With no right branch, 5486: a branch-greater-than will get us to the default 5487: label correctly. */ 5488: if (use_cost_table 5489: && cost_table[TREE_INT_CST_LOW (node->high)] < 12) 5490: ; 5491: #endif /* 0 */ 5492: if (node->left->left || node->left->right 5493: || !tree_int_cst_equal (node->left->low, node->left->high)) 5494: { 5495: if (!node_has_high_bound (node, index_type)) 5496: { 1.1.1.4 root 5497: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 5498: VOIDmode, 0), 5499: GT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5500: emit_jump_insn ((*gen_bgt_pat) (default_label)); 5501: } 5502: 5503: emit_case_nodes (index, node->left, default_label, index_type); 5504: } 5505: else 5506: /* We cannot process node->left normally 5507: since we haven't ruled out the numbers less than 5508: this node's value. So handle node->left explicitly. */ 5509: do_jump_if_equal (index, 1.1.1.4 root 5510: expand_expr (node->left->low, NULL_RTX, 5511: VOIDmode, 0), 1.1 root 5512: label_rtx (node->left->code_label), unsignedp); 5513: } 5514: } 5515: else 5516: { 5517: /* Node is a range. These cases are very similar to those for a single 5518: value, except that we do not start by testing whether this node 5519: is the one to branch to. */ 5520: 5521: if (node->right != 0 && node->left != 0) 5522: { 5523: /* Node has subtrees on both sides. 5524: If the right-hand subtree is bounded, 5525: test for it first, since we can go straight there. 5526: Otherwise, we need to make a branch in the control structure, 5527: then handle the two subtrees. */ 5528: tree test_label = 0; 5529: 1.1.1.4 root 5530: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 5531: VOIDmode, 0), 5532: GT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5533: 5534: if (node_is_bounded (node->right, index_type)) 5535: /* Right hand node is fully bounded so we can eliminate any 5536: testing and branch directly to the target code. */ 5537: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label))); 5538: else 5539: { 5540: /* Right hand node requires testing. 5541: Branch to a label where we will handle it later. */ 5542: 5543: test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); 5544: emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label))); 5545: } 5546: 5547: /* Value belongs to this node or to the left-hand subtree. */ 5548: 1.1.1.4 root 5549: emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0), 5550: GE, NULL_RTX, mode, unsignedp, 0); 1.1 root 5551: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label))); 5552: 5553: /* Handle the left-hand subtree. */ 5554: emit_case_nodes (index, node->left, default_label, index_type); 5555: 5556: /* If right node had to be handled later, do that now. */ 5557: 5558: if (test_label) 5559: { 5560: /* If the left-hand subtree fell through, 5561: don't let it fall into the right-hand subtree. */ 5562: emit_jump_if_reachable (default_label); 5563: 5564: expand_label (test_label); 5565: emit_case_nodes (index, node->right, default_label, index_type); 5566: } 5567: } 5568: 5569: else if (node->right != 0 && node->left == 0) 5570: { 5571: /* Deal with values to the left of this node, 5572: if they are possible. */ 5573: if (!node_has_low_bound (node, index_type)) 5574: { 1.1.1.4 root 5575: emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, 5576: VOIDmode, 0), 5577: LT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5578: emit_jump_insn ((*gen_blt_pat) (default_label)); 5579: } 5580: 5581: /* Value belongs to this node or to the right-hand subtree. */ 5582: 1.1.1.4 root 5583: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 5584: VOIDmode, 0), 5585: LE, NULL_RTX, mode, unsignedp, 0); 1.1 root 5586: emit_jump_insn ((*gen_ble_pat) (label_rtx (node->code_label))); 5587: 5588: emit_case_nodes (index, node->right, default_label, index_type); 5589: } 5590: 5591: else if (node->right == 0 && node->left != 0) 5592: { 5593: /* Deal with values to the right of this node, 5594: if they are possible. */ 5595: if (!node_has_high_bound (node, index_type)) 5596: { 1.1.1.4 root 5597: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 5598: VOIDmode, 0), 5599: GT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5600: emit_jump_insn ((*gen_bgt_pat) (default_label)); 5601: } 5602: 5603: /* Value belongs to this node or to the left-hand subtree. */ 5604: 1.1.1.4 root 5605: emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0), 5606: GE, NULL_RTX, mode, unsignedp, 0); 1.1 root 5607: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label))); 5608: 5609: emit_case_nodes (index, node->left, default_label, index_type); 5610: } 5611: 5612: else 5613: { 5614: /* Node has no children so we check low and high bounds to remove 5615: redundant tests. Only one of the bounds can exist, 5616: since otherwise this node is bounded--a case tested already. */ 5617: 5618: if (!node_has_high_bound (node, index_type)) 5619: { 1.1.1.4 root 5620: emit_cmp_insn (index, expand_expr (node->high, NULL_RTX, 5621: VOIDmode, 0), 5622: GT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5623: emit_jump_insn ((*gen_bgt_pat) (default_label)); 5624: } 5625: 5626: if (!node_has_low_bound (node, index_type)) 5627: { 1.1.1.4 root 5628: emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, 5629: VOIDmode, 0), 5630: LT, NULL_RTX, mode, unsignedp, 0); 1.1 root 5631: emit_jump_insn ((*gen_blt_pat) (default_label)); 5632: } 5633: 5634: emit_jump (label_rtx (node->code_label)); 5635: } 5636: } 5637: } 5638: 5639: /* These routines are used by the loop unrolling code. They copy BLOCK trees 5640: so that the debugging info will be correct for the unrolled loop. */ 5641: 1.1.1.4 root 5642: /* Indexed by block number, contains a pointer to the N'th block node. */ 1.1 root 5643: 1.1.1.4 root 5644: static tree *block_vector; 1.1 root 5645: 5646: void 1.1.1.4 root 5647: find_loop_tree_blocks () 1.1 root 5648: { 1.1.1.4 root 5649: tree block = DECL_INITIAL (current_function_decl); 1.1 root 5650: 1.1.1.4 root 5651: /* There first block is for the function body, and does not have 5652: corresponding block notes. Don't include it in the block vector. */ 5653: block = BLOCK_SUBBLOCKS (block); 1.1 root 5654: 1.1.1.4 root 5655: block_vector = identify_blocks (block, get_insns ()); 1.1 root 5656: } 5657: 5658: void 1.1.1.4 root 5659: unroll_block_trees () 1.1 root 5660: { 1.1.1.4 root 5661: tree block = DECL_INITIAL (current_function_decl); 1.1 root 5662: 1.1.1.4 root 5663: reorder_blocks (block_vector, block, get_insns ()); 1.1 root 5664: } 1.1.1.4 root 5665:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.