This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFC/CFT: Patch to fix the PowerPC var-tracking.c failure
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: Richard Sandiford <rsandifo at nildram dot co dot uk>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 11 Oct 2007 16:08:53 +0200
- Subject: Re: RFC/CFT: Patch to fix the PowerPC var-tracking.c failure
- References: <876426nv78.fsf@firetop.home>
> The idea is to use PSEUDO_REGNO_MODE (ORIGINAL_REGNO ...) to detect
> cases where a register was a paradoxical subreg of a psuedo before
> reload. In that case, the REG_ATTRS of the post-reload register pretend
> that the whole register contains useful information, whereas in reality
> only the original inner register did. We can then create a
> representation of the original inner register with approriately-narrowed
> REG_ATTRS. This is the right behaviour for MO_USE, MO_SET and MO_COPY
> -- all of which are associated with locations that have trackable
> attributes -- but not for MO_USE_NO_VAR and MO_CLOBBER, which record
> attributeless uses or clobbers of the whole register.
This sounds sensible to me.
> Adjusting the rtx of a MO_SET and MO_COPY like this means that we
> need to adjust any useful SET_SRC in the same way. The current code
> goes to great lengths to try to find the original SET_SRC (sometimes
> considering COND_EXECs and sometimes not; I'm not sure if that's
> deliberate) but it's more convenient to create the new SET_SRC at the
> same time as the new SET_DEST. The patch therefore records a SET rather
> than a destination if both the SET_DEST and SET_SRC are useful.
Likewise. The authors of var-tracking.c might want to comment on this though.
> * dse.c (find_shift_sequence): Reinstate "<= UNITS_PER_WORD" condition.
> * var-tracking.c (micro_operation_def): Update comment on u.loc.
> (mode_for_reg_attrs, var_lowpart): New functions.
> (add_uses): Consider recording a lowpart of LOC for MO_USE.
> (add_stores): Likewise MO_SET and MO_COPY. If the source of a set
> or copy is known, set LOC to the SET that performs the set, instead
> of the destination.
> (find_src_status, find_src_set_src): Remove LOC parameter.
> Replace INSN with the source value.
> (compute_bb_dataflow, emit_notes_in_bb): Check for a SET u.loc when
> handling MO_SET and MO_COPY. Update the calls to find_src_status
> and find_src_set_src.
OK, modulo
> @@ -1767,16 +1824,35 @@ add_stores (rtx loc, const_rtx expr, voi
> if (GET_CODE (expr) == CLOBBER
>
> || ! REG_EXPR (loc)
> || ! track_expr_p (REG_EXPR (loc)))
>
> - mo->type = MO_CLOBBER;
> - else if (GET_CODE (expr) == SET
> - && SET_DEST (expr) == loc
> - && same_variable_part_p (SET_SRC (expr),
> - REG_EXPR (loc),
> - REG_OFFSET (loc)))
> - mo->type = MO_COPY;
> + {
> + mo->type = MO_CLOBBER;
> + mo->u.loc = loc;
> + }
> else
> - mo->type = MO_SET;
> - mo->u.loc = loc;
> + {
> + enum machine_mode mode = mode_for_reg_attrs (loc);
> + rtx src = NULL;
> +
> + if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
> + src = var_lowpart (mode, SET_SRC (expr));
> + loc = var_lowpart (mode, loc);
> +
> + if (src == NULL)
> + {
> + mo->type = MO_SET;
> + mo->u.loc = loc;
> + }
> + else
> + {
> + if (SET_SRC (expr) != src)
> + expr = gen_rtx_SET (VOIDmode, loc, src);
> + if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
> + mo->type = MO_COPY;
> + else
> + mo->type = MO_SET;
> + mo->u.loc = CONST_CAST_RTX (expr);
> + }
> + }
> mo->insn = (rtx) insn;
> }
> else if (MEM_P (loc)
> @@ -1787,49 +1863,41 @@ add_stores (rtx loc, const_rtx expr, voi
> micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
>
> if (GET_CODE (expr) == CLOBBER)
> - mo->type = MO_CLOBBER;
> + {
> + mo->type = MO_CLOBBER;
> + mo->u.loc = loc;
> + }
> else if (GET_CODE (expr) == SET
> && SET_DEST (expr) == loc
> - && same_variable_part_p (SET_SRC (expr),
> - MEM_EXPR (loc),
> - MEM_OFFSET (loc)
> - ? INTVAL (MEM_OFFSET (loc)) : 0))
> - mo->type = MO_COPY;
> + && var_lowpart (GET_MODE (loc), SET_SRC (expr)))
> + {
> + if (same_variable_part_p (SET_SRC (expr),
> + MEM_EXPR (loc),
> + MEM_OFFSET (loc)
> + ? INTVAL (MEM_OFFSET (loc)) : 0))
> + mo->type = MO_COPY;
> + else
> + mo->type = MO_SET;
> + mo->u.loc = CONST_CAST_RTX (expr);
> + }
> else
> - mo->type = MO_SET;
> - mo->u.loc = loc;
> + {
> + mo->type = MO_SET;
> + mo->u.loc = loc;
> + }
> mo->insn = (rtx) insn;
> }
> }
Please use the same structure if the MEM case as in the REG case:
else
{
rtx src = NULL;
if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
src = var_lowpart (GET_MODE (loc), SET_SRC (expr));
if (src == NULL)
{
mo->type = MO_SET;
mo->u.loc = loc;
}
else
{
if (same_variable_part_p (SET_SRC (expr),
MEM_EXPR (loc),
MEM_OFFSET (loc)
? INTVAL (MEM_OFFSET (loc)) : 0))
mo->type = MO_COPY;
else
mo->type = MO_SET;
mo->u.loc = CONST_CAST_RTX (expr);
}
--
Eric Botcazou