+ Construct a CFG and run life analysis. Then convert each insn one
+ by one. Run a last cleanup_cfg pass, if optimizing, to eliminate
+ code duplication created when the converter inserts pop insns on
+ the edges. */
+
+static bool
+reg_to_stack (void)
+{
+ basic_block bb;
+ int i;
+ int max_uid;
+
+ /* Clean up previous run. */
+ if (stack_regs_mentioned_data != NULL)
+ VEC_free (char, heap, stack_regs_mentioned_data);
+
+ /* See if there is something to do. Flow analysis is quite
+ expensive so we might save some compilation time. */
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ if (df_regs_ever_live_p (i))
+ break;
+ if (i > LAST_STACK_REG)
+ return false;
+
+ df_note_add_problem ();
+ df_analyze ();
+
+ mark_dfs_back_edges ();
+
+ /* Set up block info for each basic block. */
+ alloc_aux_for_blocks (sizeof (struct block_info_def));
+ FOR_EACH_BB (bb)
+ {
+ block_info bi = BLOCK_INFO (bb);
+ edge_iterator ei;
+ edge e;
+ int reg;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (!(e->flags & EDGE_DFS_BACK)
+ && e->src != ENTRY_BLOCK_PTR)
+ bi->predecessors++;
+
+ /* Set current register status at last instruction `uninitialized'. */
+ bi->stack_in.top = -2;
+
+ /* Copy live_at_end and live_at_start into temporaries. */
+ for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
+ {
+ if (REGNO_REG_SET_P (DF_LR_OUT (bb), reg))
+ SET_HARD_REG_BIT (bi->out_reg_set, reg);
+ if (REGNO_REG_SET_P (DF_LR_IN (bb), reg))
+ SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
+ }
+ }
+
+ /* Create the replacement registers up front. */
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ {
+ enum machine_mode mode;
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
+ }
+
+ ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
+
+ /* A QNaN for initializing uninitialized variables.
+
+ ??? We can't load from constant memory in PIC mode, because
+ we're inserting these instructions before the prologue and
+ the PIC register hasn't been set up. In that case, fall back
+ on zero, which we can get from `fldz'. */
+
+ if ((flag_pic && !TARGET_64BIT)
+ || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
+ not_a_num = CONST0_RTX (SFmode);
+ else
+ {
+ REAL_VALUE_TYPE r;
+
+ real_nan (&r, "", 1, SFmode);
+ not_a_num = CONST_DOUBLE_FROM_REAL_VALUE (r, SFmode);
+ not_a_num = force_const_mem (SFmode, not_a_num);
+ }
+
+ /* Allocate a cache for stack_regs_mentioned. */
+ max_uid = get_max_uid ();
+ stack_regs_mentioned_data = VEC_alloc (char, heap, max_uid + 1);
+ memset (VEC_address (char, stack_regs_mentioned_data),
+ 0, sizeof (char) * (max_uid + 1));
+
+ convert_regs ();
+
+ free_aux_for_blocks ();
+ return true;