This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: DFA Instruction Output for VLIW


Dan Towner wrote:
> 
> Vlad,
> 
> >   The interfaces of all gcc utilities (genattrtab, genattr, gen...) are not
> > described in the documentation.  Now no one port uses queried units.  It was
> > used in an experimental patch for ia64 port.  I am still going to use it for
> > ia64 port in near future.
> >
> > The first of all you should define macro
> >
> >   #define CPU_UNITS_QUERY 1
> >
> > in <port>.h file to switch on code for querying units.
> >
> > After that you should get an internal code of queried unit with the aid of
> > function
> >
> >   int get_cpu_unit_code (char *unit_name);
> >
> > To figure out that the unit is reserved in given state, you should use the
> > function
> >
> >    int cpu_unit_reservation_p (void *state, int code);
> >
> > The function returns nonzero if the unit with given code is reserved in given
> > state.
> >
> > I put the part of the old patch for ia64 as an example.
> 
> Many thanks. However, I am not totally sure what is happening. I tried
> distilling your code down to remove the bits I thought were unnecessary.
> I've attached my attempt below.
> If my understanding of the code is correct, the code determines the
> state of the current instruction, and then updates that state from
> instruction to instruction. Some of the code uses temp_state, which
> appears to locally update the state to determine the state over the next
> few cycles, but I have removed this as I am only interested in the
> current state. When I run the code below by calling cc1 directly, the
> code works fine, and outputs the  assigned slots. However, if I run the
> scheduler using gcc, or using cc1 with -da, the code consistently
> abort's when checking:
> 
>   if (state_transition (currentState, insn) != -1)
>     abort ();
> 
> I can't see any reason why the code should behave differently.
> 

As I told, there are other optimizations after the 2nd insn scheduling. 
May be the reason of the problem is there.

At least there is a jump optimization.  On my opinion, the insn
scheduling should be the last optimization of the compiler (beside
machine dependent reorganization.  By the way this is approach of ia64
port where the machine dependent reorganization makes the 2nd insn
scheduling).  Also it is not easy to move the 2nd insn scheduling after
the last jump optimization, because it corrupts cfg information.  So you
have two solutions:

1. Switch off the last jump optimization for your port.

2. Make the 2nd insn scheduling as machine dependent reorganization (see
ia64 port).

  Today I'll try to commit a patch helping the debugging.  When
(automata_option "-v") is added to the description, genattrtab will
generate file <port>.dfa which contains automata description
(reservations, state numbers and arcs).  You can get state number from
state (see its structure in generated insn-attrtab.c.  There will be
structure member for each automaton.  The member value is the state
number) and look at the reservations and arcs in the xxx.dfa file.  It
is better to use (automata_option "-no-minimization") for debugging.

Vlad

> Thanks for your help. I am impressed with the DFA scheduler, because it
> has allowed me to quickly and easily define the pipeline/VLIW attributes
> for my port - I just need to extract them into the assembly language
> now!
> 
> 
> void
> picochip_final_prescan_insn (insn, operand, num_operands)
>      rtx insn;
>      rtx *operand;
>      int num_operands;
> {
>   static state_t currentState;
>   static int slot0Id, slot1Id, slot2Id;
>   size_t size;
>   state_t tempState;
>   int i;
>   rtx curr_insn;
> 
>   // Initialise the CPU identity codes and state.
>   if (currentState == NULL)
>     {
>       currentState = xmalloc (state_size());
>       state_reset(currentState);
>       slot0Id = get_cpu_unit_code("slot0");
>       slot1Id = get_cpu_unit_code("slot1");
>       slot2Id = get_cpu_unit_code("slot2");
> 
>       if (slot0Id < 0 || slot1Id < 0 || slot2Id < 0)
>         abort();
>     }
> 
>   printf("final_prescan for insn %d\n", INSN_UID(insn));
> 
>   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
>     abort ();
> 
>   for (i = GET_MODE (insn); i != 0; i--)
>     {


  I am not sure that this is correct.  I remember the scheduler use
TImode to mark the cycle start in the main line.  Although I tried to
use the mode as number of cycles between the insns.


> #ifdef DFA_SCHEDULER_PRE_CYCLE_INSN
>       state_transition (currentState, DFA_SCHEDULER_PRE_CYCLE_INSN);
> #endif
>       state_transition (currentState, NULL);
>     }
> 
>   if (INSN_CODE (insn) < 0)
>     return;
>   if (state_transition (currentState, insn) != -1)
>     abort ();
> 
>   if (cpu_unit_reservation_p (currentState, slot0Id))
>     printf("-> Slot 0\n");
>   if (cpu_unit_reservation_p (currentState, slot1Id))
>     printf("-> Slot 1\n");
>   if (cpu_unit_reservation_p (currentState, slot2Id))
>     printf("-> Slot 2\n");
> 
>   if (GET_CODE (insn) != JUMP_INSN)
>     for (curr_insn = insn;;)
>       {
>         curr_insn = next_nonnote_insn (curr_insn);
>         if (curr_insn == NULL || GET_RTX_CLASS (GET_CODE (curr_insn)) != 'i'
>             || GET_CODE (PATTERN (curr_insn)) != CLOBBER
>             && GET_CODE (PATTERN (curr_insn)) != USE)
>           break;
>       }
>   if (GET_CODE (insn) == JUMP_INSN || curr_insn == NULL
>       || GET_RTX_CLASS (GET_CODE (curr_insn)) != 'i'
>       || GET_CODE (PATTERN (curr_insn)) == ASM_INPUT
>       || asm_noperands (PATTERN (curr_insn)) >= 0)
>     state_reset (currentState);
> 
> }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]