Date:2011-09-21 22:44:52 (7 years 11 months ago)
Author:Werner Almesberger
Commit:8f82a0e8d4e23ab9f769e23e862936cff93fca6e
Message:m1/perf/sched.c: revamped to handle static registers correctly as well

Files: m1/perf/sched.c (12 diffs)

Change Details

m1/perf/sched.c
6262    } opa, opb, dest, cond;
6363    int arity;
6464    int latency;
65    int rmw; /* non-zero if instruction is read-modify-write */
6566    int unresolved; /* number of data refs we need before we can sched */
6667    int earliest; /* earliest cycle dependencies seen so far are met */
6768    struct list dependants; /* list of dependencies (constant) */
6869    int num_dependants; /* number of dependencies */
70    struct insn *next_setter; /* next setter of the same register */
6971#ifdef LCPF
7072    int distance; /* minimum cycles on this path until the end */
7173#endif
...... 
7476
7577struct vm_reg {
7678    struct insn *setter; /* instruction setting it; NULL if none */
79    struct insn *first_setter; /* first setter */
7780    int pfpu_reg; /* underlying PFPU register */
7881    int refs; /* usage count */
7982};
...... 
9598    struct list unscheduled; /* unscheduled insns */
9699    struct list waiting; /* insns waiting to be scheduled */
97100    struct list ready[PFPU_PROGSIZE]; /* insns ready at nth cycle */
101    int cycle; /* the current cycle */
98102#ifdef REG_STATS
99103    int max_regs, curr_regs; /* allocation statistics */
100104#endif
...... 
233237    int vm_reg, pfpu_reg, vm_idx;
234238
235239    vm_reg = setter->vm_insn->dest;
236    if (vm_reg >= 0)
237        return vm_reg;
238    reg = list_pop(&sc->unallocated);
239    if (!reg)
240        abort();
240    if (vm_reg >= 0) {
241        pfpu_reg = vm_reg;
242        sc->pfpu_regs[vm_reg].vm_reg = vm_reg; /* @@@ global init */
243    } else {
244        reg = list_pop(&sc->unallocated);
245        if (!reg)
246            abort();
241247
242#ifdef REG_STATS
243    sc->curr_regs++;
244    if (sc->curr_regs > sc->max_regs)
245        sc->max_regs = sc->curr_regs;
246#endif
248        #ifdef REG_STATS
249        sc->curr_regs++;
250        if (sc->curr_regs > sc->max_regs)
251            sc->max_regs = sc->curr_regs;
252        #endif
247253
248    reg->vm_reg = vm_reg;
249    pfpu_reg = reg-sc->pfpu_regs;
254        reg->vm_reg = vm_reg;
255        pfpu_reg = reg-sc->pfpu_regs;
256    }
250257
251258    Dprintf(" alloc reg %d -> %d\n", vm_reg, pfpu_reg);
252259
...... 
291298}
292299
293300
294static void put_reg_by_setter(struct insn *setter)
301static void unblock(struct insn *insn);
302static void put_reg_by_setter(struct insn *setter, int vm_reg)
295303{
296    if (setter)
304    struct vm_reg *reg;
305
306    if (setter) {
297307        put_reg(setter->vm_insn->dest);
308        if (setter->next_setter)
309            unblock(setter->next_setter);
310    } else {
311        reg = sc->regs+vm_reg2idx(vm_reg);
312        if (reg->first_setter && !reg->first_setter->rmw)
313            unblock(reg->first_setter);
314    }
298315}
299316
300317
...... 
347364    reg = sc->regs+vm_reg2idx(reg_num);
348365    ref->insn = insn;
349366    ref->dep = reg->setter;
350    if (ref->dep) {
367    if (insn->vm_insn->dest == reg_num)
368        insn->rmw = 1;
369    if (!ref->dep)
370        reg->refs++;
371    else {
351372        list_add_tail(&ref->dep->dependants, &ref->more);
352373        ref->dep->num_dependants++;
353374        insn->unresolved++;
...... 
364385{
365386    int i;
366387    struct insn *insn;
388    struct vm_reg *reg;
389    struct data_ref *ref;
367390
368391    list_init(&sc->unscheduled);
369392    list_init(&sc->waiting);
...... 
387410            add_data_ref(insn, &insn->opa, frag->code[i].opa);
388411            /* fall through */
389412        case 0:
390            add_data_ref(insn,
391                &insn->dest, frag->code[i].dest)->setter = insn;
413            reg = sc->regs+vm_reg2idx(frag->code[i].dest);
414            if (reg->setter) {
415                reg->setter->next_setter = insn;
416                foreach (ref, &reg->setter->dependants)
417                    if (ref->insn != insn)
418                        insn->unresolved++;
419                if (!insn->rmw)
420                    insn->unresolved++;
421            } else {
422                if (!insn->rmw)
423                    insn->unresolved += reg->refs;
424                reg->first_setter = insn;
425            }
426            reg->setter = insn;
392427            break;
393428        default:
394429            abort();
...... 
413448}
414449
415450
451static void unblock(struct insn *insn)
452{
453    int slot;
454
455    assert(insn->unresolved);
456    if (--insn->unresolved)
457        return;
458    Dprintf(" unblocked %lu -> %u\n", insn-sc->insns, insn->earliest);
459    list_del(&insn->more);
460    slot = insn->earliest;
461    if (slot <= sc->cycle)
462        slot = sc->cycle+1;
463    list_add_tail(sc->ready+slot, &insn->more);
464}
465
466
467static void unblock_after(struct insn *insn, int cycle)
468{
469    if (insn->earliest <= cycle)
470        insn->earliest = cycle+1;
471    unblock(insn);
472}
473
474
416475static void issue(struct insn *insn, int cycle, unsigned *code)
417476{
418477    struct data_ref *ref;
...... 
425484
426485    switch (insn->arity) {
427486    case 3:
487        put_reg_by_setter(insn->cond.dep, FPVM_REG_IFB);
428488        /* fall through */
429489    case 2:
430490        CODE(cycle).opb = lookup_pfpu_reg(insn->vm_insn->opb);
431        put_reg_by_setter(insn->opb.dep);
491        put_reg_by_setter(insn->opb.dep, insn->vm_insn->opb);
432492        /* fall through */
433493    case 1:
434494        CODE(cycle).opa = lookup_pfpu_reg(insn->vm_insn->opa);
435        put_reg_by_setter(insn->opa.dep);
495        put_reg_by_setter(insn->opa.dep, insn->vm_insn->opa);
436496        break;
437497    case 0:
438498        break;
...... 
443503    CODE(end).dest = alloc_reg(insn);
444504    CODE(cycle).opcode = fpvm_to_pfpu(insn->vm_insn->opcode);
445505
446    foreach (ref, &insn->dependants) {
447        if (ref->insn->earliest <= end)
448            ref->insn->earliest = end+1;
449        assert(ref->insn->unresolved);
450        if (!--ref->insn->unresolved) {
451            Dprintf(" unlocked %lu -> %u\n", ref->insn-sc->insns,
452                ref->insn->earliest);
453            list_del(&ref->insn->more);
454            list_add_tail(sc->ready+ref->insn->earliest,
455                &ref->insn->more);
456        }
457    }
506    foreach (ref, &insn->dependants)
507        unblock_after(ref->insn, end);
508    if (insn->next_setter && !insn->next_setter->rmw)
509        unblock_after(insn->next_setter,
510            end-insn->next_setter->latency);
458511}
459512
460513
...... 
485538        if (i == PFPU_PROGSIZE)
486539            return -1;
487540
541        sc->cycle = i;
488542        Dprintf("@%d --- remaining %d, waiting %d + ready %d\n",
489543            i, remaining, count(&sc->waiting), count(&sc->ready[i]));
490544

Archive Download the corresponding diff file

Branches:
master



interactive