On Fri, Mar 19, 2010 at 1:06 AM, fanqifei <fanqi...@gmail.com> wrote: > On Thu, Mar 18, 2010 at 2:30 AM, Jim Wilson <wil...@codesourcery.com> 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