On Fri, Mar 19, 2010 at 1:06 AM, fanqifei <[email protected]> wrote:
> On Thu, Mar 18, 2010 at 2:30 AM, Jim Wilson <[email protected]> wrote:
>> On Wed, 2010-03-17 at 11:27 +0800, fanqifei wrote:
>>> You are correct. The reload pass emitted the clr.w insn.
>>> However, I can see loop opt passes after reload:
>>> problem1.c.174r.loop2_invariant1
>>
>> Not unless you have a modified toolchain. We don't run loop opt after
>> register allocation. See the list of optimization passes in the FSF GCC
>> passes.c file. loop2 occurs before ira/postreload. If you do have a
>> modified toolchain, then I doubt that the current loop passes would work
>> right, since they were designed to handle pseudo-regs not hard-regs.
>>
>> Jim
>>
>>
>>
> That passes were added by me more than two months ago. I thought these
> passes could perform the optimization of hoisting constant out of
> loop.
> I just removed them. Thanks very much for your help!
> Now I am working on the movsi expander.
>
> --
> -Qifei Fan
> http://freshtime.org
>
Seems like that my change works now. The clr.w insn is now outside of
the loop. Related code is below.
There are still some questions:
1. I add movsi expander in which function foor_expand_move is used to
force the operands[1] to reg and emit the move insn.
Another change is that in the define of insn “*mov_mode_insn" in which
a condition is added to prevent a store const to mem RTL insn from
being accepted.
Are these changes necessary?
2. Is is correct to use emit_move_insn in foor_expand_move?
in mips.md, the function mips_emit_move called both emit_move_insn and
emit_move_insn_1. But I don’t quite understand the comment above the
function.
Function mips_emit_move() in mips.md:
/* Emit a move from SRC to DEST. Assume that the move expanders can
handle all moves if !can_create_pseudo_p (). The distinction is
important because, unlike emit_move_insn, the move expanders know
how to force Pmode objects into the constant pool even when the
constant pool address is not itself legitimate. */
rtx
mips_emit_move (rtx dest, rtx src)
{
return (can_create_pseudo_p ()
? emit_move_insn (dest, src)
: emit_move_insn_1 (dest, src));
}
3. My understanding of the internal flow about the issue is:
The named insn “movsi” is used to generate RTL insn list from parse
tree. The insn pattern “set mem, const” is expanded by function
foor_expand_move(). For other forms of “set” insns, the template given
in the pattern is inserted. Then the insn "*mov_mode_insn" is used to
generate assembler code. In the generation, the condition of
mov_mode_insn is checked.
I am not fully confident the understanding is correct.
----related code:
foor.md:
movsi expander:
(define_expand "movsi"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(match_operand:SI 1 "foor_move_source_operand" ""))]
""
{
if (foor_expand_move (SImode, operands))
DONE;
})
(define_insn "*mov_mode_insn"
[(set
(match_operand:BWD 0 "nonimmediate_operand" "=r,m,r,r,r,r,r,r,x,r")
(match_operand:BWD 1 "foor_move_source_operand" "Z,r,L,I,Q,P,ni,x,r,r"))]
"(!(
(memory_operand(operands[0], SImode) &&
(foor_const_operand_f(operands[1])))
||(memory_operand(operands[0], HImode) &&
(foor_const_operand_f(operands[1])))
||(memory_operand(operands[0], QImode) &&
(foor_const_operand_f(operands[1])))
))"
"@
%L1<m> %0 %1;
%S0<m> %0 %1;
…
predicates.md:
(define_predicate "foor_const_operand"
(match_test "foor_const_operand_f(op)"))
foor.c:
bool foor_expand_move(enum machine_mode mode, rtx *operands)
{
/* Handle sets of MEM first. */
if ((GET_CODE (operands[0]) == MEM)&&(GET_CODE(operands[1])==CONST_INT))
{
emit_move_insn ((operands[0]), force_reg (mode, operands[1]));
return true;
}
return false;
}
Check whether the operand is const:
bool foor_const_operand_f(rtx x)
{
if ((GET_CODE (x) == CONST_INT))
{
return true;
}
return false;
}
Thanks!
--
-Qifei Fan
http://freshtime.org