/* Initialization of the RTL loop passes. */ static unsigned int rtl_loop_init (void) { gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT); if (dump_file) { dump_reg_info (dump_file); dump_flow_info (dump_file, dump_flags); } loop_optimizer_init (LOOPS_NORMAL); return 0; }
/* Return either ORIG or: (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET)) depending on MACHO_DYNAMIC_NO_PIC_P. */ rtx machopic_gen_offset (rtx orig) { if (MACHO_DYNAMIC_NO_PIC_P) return orig; else { /* Play games to avoid marking the function as needing pic if we are being called as part of the cost-estimation process. */ if (current_ir_type () != IR_GIMPLE) crtl->uses_pic_offset_table = 1; orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), UNSPEC_MACHOPIC_OFFSET); return gen_rtx_CONST (Pmode, orig); } }
static unsigned int tracer (void) { gcc_assert (current_ir_type () == IR_GIMPLE); if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1) return 0; mark_dfs_back_edges (); if (dump_file) dump_flow_info (dump_file, dump_flags); /* Trace formation is done on the fly inside tail_duplicate */ tail_duplicate (); /* FIXME: We really only need to do this when we know tail duplication has altered the CFG. */ free_dominance_info (CDI_DOMINATORS); if (dump_file) dump_flow_info (dump_file, dump_flags); return 0; }
static void mark_all_labels (rtx f) { rtx insn; if (current_ir_type () == IR_RTL_CFGLAYOUT) { basic_block bb; FOR_EACH_BB (bb) { /* In cfglayout mode, we don't bother with trivial next-insn propagation of LABEL_REFs into JUMP_LABEL. This will be handled by other optimizers using better algorithms. */ FOR_BB_INSNS (bb, insn) { gcc_assert (! INSN_DELETED_P (insn)); if (NONDEBUG_INSN_P (insn)) mark_jump_label (PATTERN (insn), insn, 0); } /* In cfglayout mode, there may be non-insns between the basic blocks. If those non-insns represent tablejump data, they contain label references that we must record. */ for (insn = BB_HEADER (bb); insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) { gcc_assert (JUMP_TABLE_DATA_P (insn)); mark_jump_label (PATTERN (insn), insn, 0); } for (insn = BB_FOOTER (bb); insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) { gcc_assert (JUMP_TABLE_DATA_P (insn)); mark_jump_label (PATTERN (insn), insn, 0); } }
static void mark_all_labels (rtx f) { rtx insn; rtx prev_nonjump_insn = NULL; for (insn = f; insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) { mark_jump_label (PATTERN (insn), insn, 0); /* If the previous non-jump insn sets something to a label, something that this jump insn uses, make that label the primary target of this insn if we don't yet have any. That previous insn must be a single_set and not refer to more than one label. The jump insn must not refer to other labels as jump targets and must be a plain (set (pc) ...), maybe in a parallel, and may refer to the item being set only directly or as one of the arms in an IF_THEN_ELSE. */ if (! INSN_DELETED_P (insn) && JUMP_P (insn) && JUMP_LABEL (insn) == NULL) { rtx label_note = NULL; rtx pc = pc_set (insn); rtx pc_src = pc != NULL ? SET_SRC (pc) : NULL; if (prev_nonjump_insn != NULL) label_note = find_reg_note (prev_nonjump_insn, REG_LABEL_OPERAND, NULL); if (label_note != NULL && pc_src != NULL) { rtx label_set = single_set (prev_nonjump_insn); rtx label_dest = label_set != NULL ? SET_DEST (label_set) : NULL; if (label_set != NULL /* The source must be the direct LABEL_REF, not a PLUS, UNSPEC, IF_THEN_ELSE etc. */ && GET_CODE (SET_SRC (label_set)) == LABEL_REF && (rtx_equal_p (label_dest, pc_src) || (GET_CODE (pc_src) == IF_THEN_ELSE && (rtx_equal_p (label_dest, XEXP (pc_src, 1)) || rtx_equal_p (label_dest, XEXP (pc_src, 2)))))) { /* The CODE_LABEL referred to in the note must be the CODE_LABEL in the LABEL_REF of the "set". We can conveniently use it for the marker function, which requires a LABEL_REF wrapping. */ gcc_assert (XEXP (label_note, 0) == XEXP (SET_SRC (label_set), 0)); mark_jump_label_1 (label_set, insn, false, true); gcc_assert (JUMP_LABEL (insn) == XEXP (SET_SRC (label_set), 0)); } } } else if (! INSN_DELETED_P (insn)) prev_nonjump_insn = insn; } else if (LABEL_P (insn)) prev_nonjump_insn = NULL; /* If we are in cfglayout mode, there may be non-insns between the basic blocks. If those non-insns represent tablejump data, they contain label references that we must record. */ if (current_ir_type () == IR_RTL_CFGLAYOUT) { basic_block bb; rtx insn; FOR_EACH_BB (bb) { for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) { gcc_assert (JUMP_TABLE_DATA_P (insn)); mark_jump_label (PATTERN (insn), insn, 0); } for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) { gcc_assert (JUMP_TABLE_DATA_P (insn)); mark_jump_label (PATTERN (insn), insn, 0); } } }