Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 1 file changed
  • 0 commit comments
  • 1 contributor
Showing with 65 additions and 70 deletions.
  1. +65 −70 software/libfpvm/lnfpus.c
View
135 software/libfpvm/lnfpus.c
@@ -90,7 +90,7 @@ struct pfpu_reg {
};
-static struct sched_ctx {
+struct sched_ctx {
struct fpvm_fragment *frag;
struct insn insns[FPVM_MAXCODELEN];
struct vm_reg *regs; /* dynamically allocated */
@@ -103,7 +103,7 @@ static struct sched_ctx {
#ifdef REG_STATS
int max_regs, curr_regs; /* allocation statistics */
#endif
-} *sc;
+};
/* ----- Register initialization ------------------------------------------- */
@@ -226,13 +226,13 @@ static void list_concat(struct list *a, struct list *b)
/* ----- Register management ----------------------------------------------- */
-static int vm_reg2idx(int reg)
+static int vm_reg2idx(struct sched_ctx *sc, int reg)
{
return reg >= 0 ? reg : sc->frag->nbindings-reg;
}
-static int alloc_reg(struct insn *setter)
+static int alloc_reg(struct sched_ctx *sc, struct insn *setter)
{
struct pfpu_reg *reg;
int vm_reg, pfpu_reg, vm_idx;
@@ -258,7 +258,7 @@ static int alloc_reg(struct insn *setter)
Dprintf(" alloc reg %d -> %d\n", vm_reg, pfpu_reg);
- vm_idx = vm_reg2idx(vm_reg);
+ vm_idx = vm_reg2idx(sc, vm_reg);
sc->regs[vm_idx].setter = setter;
sc->regs[vm_idx].pfpu_reg = pfpu_reg;
sc->regs[vm_idx].refs = setter->num_dependants+1;
@@ -267,7 +267,7 @@ static int alloc_reg(struct insn *setter)
}
-static void put_reg(int vm_reg)
+static void put_reg(struct sched_ctx *sc, int vm_reg)
{
int vm_idx;
struct vm_reg *reg;
@@ -275,7 +275,7 @@ static void put_reg(int vm_reg)
if(vm_reg >= 0)
return;
- vm_idx = vm_reg2idx(vm_reg);
+ vm_idx = vm_reg2idx(sc, vm_reg);
reg = sc->regs+vm_idx;
assert(reg->refs);
@@ -301,35 +301,31 @@ static void put_reg(int vm_reg)
}
-static int lookup_pfpu_reg(int vm_reg)
+static int lookup_pfpu_reg(struct sched_ctx *sc, int vm_reg)
{
- return vm_reg >= 0 ? vm_reg : sc->regs[vm_reg2idx(vm_reg)].pfpu_reg;
+ return vm_reg >= 0 ? vm_reg :
+ sc->regs[vm_reg2idx(sc, vm_reg)].pfpu_reg;
}
-static void mark(int vm_reg)
+static void mark(struct sched_ctx *sc, int vm_reg)
{
if(vm_reg > 0)
sc->pfpu_regs[vm_reg].used = 1;
}
-static int init_registers(struct fpvm_fragment *frag,
+static int init_registers(struct sched_ctx *sc, struct fpvm_fragment *frag,
unsigned int *registers)
{
int i;
- sc->regs =
- calloc(frag->nbindings-frag->next_sur, sizeof(struct vm_reg));
- if(!sc->regs)
- return -1;
-
get_registers(frag, registers);
for(i = 0; i != frag->ninstructions; i++) {
- mark(frag->code[i].opa);
- mark(frag->code[i].opb);
- mark(frag->code[i].dest);
+ mark(sc, frag->code[i].opa);
+ mark(sc, frag->code[i].opb);
+ mark(sc, frag->code[i].dest);
}
list_init(&sc->unallocated);
@@ -344,12 +340,12 @@ static int init_registers(struct fpvm_fragment *frag,
/* ----- Instruction scheduler --------------------------------------------- */
-static struct vm_reg *add_data_ref(struct insn *insn, struct data_ref *ref,
- int reg_num)
+static struct vm_reg *add_data_ref(struct sched_ctx *sc, struct insn *insn,
+ struct data_ref *ref, int reg_num)
{
struct vm_reg *reg;
- reg = sc->regs+vm_reg2idx(reg_num);
+ reg = sc->regs+vm_reg2idx(sc, reg_num);
ref->insn = insn;
ref->dep = reg->setter;
if(insn->vm_insn->dest == reg_num)
@@ -369,7 +365,7 @@ static struct vm_reg *add_data_ref(struct insn *insn, struct data_ref *ref,
}
-static void init_scheduler(struct fpvm_fragment *frag)
+static void init_scheduler(struct sched_ctx *sc, struct fpvm_fragment *frag)
{
int i;
struct insn *insn;
@@ -389,16 +385,20 @@ static void init_scheduler(struct fpvm_fragment *frag)
list_init(&insn->dependants);
switch (insn->arity) {
case 3:
- add_data_ref(insn, &insn->cond, FPVM_REG_IFB);
+ add_data_ref(sc, insn, &insn->cond,
+ FPVM_REG_IFB);
/* fall through */
case 2:
- add_data_ref(insn, &insn->opb, frag->code[i].opb);
+ add_data_ref(sc, insn, &insn->opb,
+ frag->code[i].opb);
/* fall through */
case 1:
- add_data_ref(insn, &insn->opa, frag->code[i].opa);
+ add_data_ref(sc, insn, &insn->opa,
+ frag->code[i].opa);
/* fall through */
case 0:
- reg = sc->regs+vm_reg2idx(frag->code[i].dest);
+ reg = sc->regs+
+ vm_reg2idx(sc, frag->code[i].dest);
if(reg->setter) {
reg->setter->next_setter = insn;
foreach(ref, &reg->setter->dependants)
@@ -458,7 +458,7 @@ static void init_scheduler(struct fpvm_fragment *frag)
}
-static void unblock(struct insn *insn)
+static void unblock(struct sched_ctx *sc, struct insn *insn)
{
int slot;
@@ -474,32 +474,33 @@ static void unblock(struct insn *insn)
}
-static void put_reg_by_ref(struct data_ref *ref, int vm_reg)
+static void put_reg_by_ref(struct sched_ctx *sc, struct data_ref *ref,
+ int vm_reg)
{
struct insn *setter = ref->dep;
struct vm_reg *reg;
if(setter) {
- put_reg(setter->vm_insn->dest);
+ put_reg(sc, setter->vm_insn->dest);
if(setter->next_setter && setter->next_setter != ref->insn)
- unblock(setter->next_setter);
+ unblock(sc, setter->next_setter);
} else {
- reg = sc->regs+vm_reg2idx(vm_reg);
+ reg = sc->regs+vm_reg2idx(sc, vm_reg);
if(reg->first_setter && !reg->first_setter->rmw)
- unblock(reg->first_setter);
+ unblock(sc, reg->first_setter);
}
}
-static void unblock_after(struct insn *insn, int cycle)
+static void unblock_after(struct sched_ctx *sc, struct insn *insn, int cycle)
{
if(insn->earliest <= cycle)
insn->earliest = cycle+1;
- unblock(insn);
+ unblock(sc, insn);
}
-static int issue(struct insn *insn, unsigned *code)
+static int issue(struct sched_ctx *sc, struct insn *insn, unsigned *code)
{
struct data_ref *ref;
int end, reg;
@@ -512,15 +513,17 @@ static int issue(struct insn *insn, unsigned *code)
switch (insn->arity) {
case 3:
- put_reg_by_ref(&insn->cond, FPVM_REG_IFB);
+ put_reg_by_ref(sc, &insn->cond, FPVM_REG_IFB);
/* fall through */
case 2:
- CODE(sc->cycle).opb = lookup_pfpu_reg(insn->vm_insn->opb);
- put_reg_by_ref(&insn->opb, insn->vm_insn->opb);
+ CODE(sc->cycle).opb =
+ lookup_pfpu_reg(sc, insn->vm_insn->opb);
+ put_reg_by_ref(sc, &insn->opb, insn->vm_insn->opb);
/* fall through */
case 1:
- CODE(sc->cycle).opa = lookup_pfpu_reg(insn->vm_insn->opa);
- put_reg_by_ref(&insn->opa, insn->vm_insn->opa);
+ CODE(sc->cycle).opa =
+ lookup_pfpu_reg(sc, insn->vm_insn->opa);
+ put_reg_by_ref(sc, &insn->opa, insn->vm_insn->opa);
break;
case 0:
break;
@@ -528,16 +531,16 @@ static int issue(struct insn *insn, unsigned *code)
abort();
}
- reg = alloc_reg(insn);
+ reg = alloc_reg(sc, insn);
if(reg < 0)
return -1;
CODE(end).dest = reg;
CODE(sc->cycle).opcode = fpvm_to_pfpu(insn->vm_insn->opcode);
foreach(ref, &insn->dependants)
- unblock_after(ref->insn, end);
+ unblock_after(sc, ref->insn, end);
if(insn->next_setter && !insn->next_setter->rmw)
- unblock_after(insn->next_setter,
+ unblock_after(sc, insn->next_setter,
end-insn->next_setter->latency);
return 0;
@@ -557,7 +560,7 @@ static int count(const struct list *list)
#endif
-static int schedule(unsigned int *code)
+static int schedule(struct sched_ctx *sc, unsigned int *code)
{
int remaining;
int i, last, end;
@@ -590,13 +593,13 @@ static int schedule(unsigned int *code)
}
}
if(best) {
- if(issue(best, code) < 0)
+ if(issue(sc, best, code) < 0)
return -1;
list_del(&best->more);
remaining--;
}
if(CODE(i).dest)
- put_reg(sc->pfpu_regs[CODE(i).dest].vm_reg);
+ put_reg(sc, sc->pfpu_regs[CODE(i).dest].vm_reg);
}
/*
@@ -615,42 +618,34 @@ static int schedule(unsigned int *code)
}
-static int init_scheduler_context(struct fpvm_fragment *frag,
- unsigned int *reg)
-{
- sc = calloc(1, sizeof(*sc));
- if(!sc)
- return -1;
-
- sc->frag = frag;
-
- if(init_registers(frag, reg) < 0) {
- free(sc);
- return -1;
- }
-
- init_scheduler(frag);
- return 0;
-}
-
-
int lnfpus_schedule(struct fpvm_fragment *frag, unsigned int *code,
unsigned int *reg)
{
+ /*
+ * allocate context and registers on stack because standalone FN has no
+ * memory allocator
+ */
+ struct sched_ctx sc;
+ struct vm_reg regs[frag->nbindings-frag->next_sur];
pfpu_instruction vecout;
int res;
- if(init_scheduler_context(frag, reg) < 0)
+ memset(&sc, 0, sizeof(sc));
+ sc.frag = frag;
+ sc.regs = regs;
+ memset(regs, 0, sizeof(regs));
+
+ if(init_registers(&sc, frag, reg) < 0)
return -1;
+ init_scheduler(&sc, frag);
+
memset(code, 0, PFPU_PROGSIZE*sizeof(*code));
- res = schedule(code);
+ res = schedule(&sc, code);
#ifdef REG_STATS
printf("regs: %d/%d\n", sc->curr_regs, sc->max_regs);
#endif
- free(sc->regs);
- free(sc);
if(res < 0)
return res;
if(frag->vector_mode)

No commit comments for this range

Something went wrong with that request. Please try again.