improve substantially handling of soft disjunctions.
This commit is contained in:
parent
15b86cded4
commit
afd979a246
105
C/absmi.c
105
C/absmi.c
@ -3046,6 +3046,7 @@ Yap_absmi(int inp)
|
||||
|
||||
BOp(procceed, p);
|
||||
CACHE_Y_AS_ENV(YREG);
|
||||
ALWAYS_LOOKAHEAD(CPREG->opc);
|
||||
PREG = CPREG;
|
||||
/* for profiler */
|
||||
save_pc();
|
||||
@ -3054,7 +3055,8 @@ Yap_absmi(int inp)
|
||||
DEPTH = ENV_YREG[E_DEPTH];
|
||||
#endif
|
||||
WRITEBACK_Y_AS_ENV();
|
||||
JMPNext();
|
||||
ALWAYS_GONext();
|
||||
ALWAYS_END_PREFETCH();
|
||||
ENDCACHE_Y_AS_ENV();
|
||||
ENDBOp();
|
||||
|
||||
@ -3270,6 +3272,7 @@ Yap_absmi(int inp)
|
||||
/* deref second argument */
|
||||
deref_body(d1, pt0, gvalx_nonvar_unk, gvalx_nonvar_nonvar);
|
||||
/* first argument bound, second unbound */
|
||||
PREG = NEXTOP(PREG, xx);
|
||||
BIND_AND_JUMP(pt0, d0);
|
||||
#ifdef COROUTINING
|
||||
DO_TRAIL(pt0, d0);
|
||||
@ -4372,16 +4375,16 @@ Yap_absmi(int inp)
|
||||
ENDD(d0);
|
||||
ENDOpRW();
|
||||
|
||||
OpRW(glist_valy, xy);
|
||||
OpRW(glist_valy, yx);
|
||||
BEGD(d0);
|
||||
d0 = XREG(PREG->u.xy.x);
|
||||
d0 = XREG(PREG->u.yx.x);
|
||||
deref_head(d0, glist_valy_write);
|
||||
glist_valy_read:
|
||||
BEGP(pt0);
|
||||
/* did we find a list? */
|
||||
if (!IsPairTerm(d0))
|
||||
FAIL();
|
||||
START_PREFETCH(xy);
|
||||
START_PREFETCH(yx);
|
||||
/* enter read mode */
|
||||
pt0 = RepPair(d0);
|
||||
SREG = pt0 + 1;
|
||||
@ -4393,9 +4396,9 @@ Yap_absmi(int inp)
|
||||
/* first argument is bound */
|
||||
BEGD(d1);
|
||||
BEGP(pt1);
|
||||
pt1 = YREG + PREG->u.xy.y;
|
||||
pt1 = YREG + PREG->u.yx.y;
|
||||
d1 = *pt1;
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
deref_head(d1, glist_valy_nonvar_unk);
|
||||
|
||||
glist_valy_nonvar_nonvar:
|
||||
@ -4422,12 +4425,12 @@ Yap_absmi(int inp)
|
||||
derefa_body(d0, pt0, glist_valy_unk, glist_valy_nonvar);
|
||||
/* first argument is unbound */
|
||||
BEGP(pt1);
|
||||
pt1 = YREG+PREG->u.xy.y;
|
||||
pt1 = YREG+PREG->u.yx.y;
|
||||
d1 = *pt1;
|
||||
deref_head(d1, glist_valy_var_unk);
|
||||
glist_valy_var_nonvar:
|
||||
/* first unbound, second bound */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
BIND_GLOBAL(pt0, d1, bind_glist_valy_var_nonvar);
|
||||
#ifdef COROUTINING
|
||||
DO_TRAIL(pt0, d1);
|
||||
@ -4438,7 +4441,7 @@ Yap_absmi(int inp)
|
||||
|
||||
derefa_body(d1, pt1, glist_valy_var_unk, glist_valy_var_nonvar);
|
||||
/* both arguments are unbound */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
UnifyGlobalRegCells(pt0, pt1, uc7, uc8);
|
||||
#ifdef COROUTINING
|
||||
DO_TRAIL(pt0, (CELL)pt1);
|
||||
@ -4461,7 +4464,7 @@ Yap_absmi(int inp)
|
||||
BEGP(pt0);
|
||||
deref_body(d0, pt0, glist_valy_write, glist_valy_read);
|
||||
/* enter write mode */
|
||||
START_PREFETCH_W(xy);
|
||||
START_PREFETCH_W(yx);
|
||||
BEGP(pt1);
|
||||
pt1 = H;
|
||||
d0 = AbsPair(pt1);
|
||||
@ -4476,13 +4479,13 @@ Yap_absmi(int inp)
|
||||
#endif
|
||||
BEGD(d0);
|
||||
/* include XREG on it */
|
||||
d0 = YREG[PREG->u.xy.y];
|
||||
d0 = YREG[PREG->u.yx.y];
|
||||
pt1[0] = d0;
|
||||
ENDD(d0);
|
||||
H = pt1 + 2;
|
||||
SREG = pt1 + 1;
|
||||
ENDP(pt1);
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
GONextW();
|
||||
END_PREFETCH_W();
|
||||
ENDP(pt0);
|
||||
@ -4536,9 +4539,9 @@ Yap_absmi(int inp)
|
||||
ENDD(d0);
|
||||
ENDOp();
|
||||
|
||||
Op(gl_void_vary, xy);
|
||||
Op(gl_void_vary, yx);
|
||||
BEGD(d0);
|
||||
d0 = XREG(PREG->u.xy.x);
|
||||
d0 = XREG(PREG->u.yx.x);
|
||||
deref_head(d0, glist_void_vary_write);
|
||||
glist_void_vary_read:
|
||||
/* did we find a list? */
|
||||
@ -4550,11 +4553,11 @@ Yap_absmi(int inp)
|
||||
d0 = pt0[1];
|
||||
ENDP(pt0);
|
||||
#if defined(SBA) && defined(FROZEN_STACKS)
|
||||
Bind_Local(YREG+PREG->u.xy.y,d0);
|
||||
Bind_Local(YREG+PREG->u.yx.y,d0);
|
||||
#else
|
||||
YREG[PREG->u.xy.y] = d0;
|
||||
YREG[PREG->u.yx.y] = d0;
|
||||
#endif /* SBA && FROZEN_STACKS */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
GONext();
|
||||
|
||||
BEGP(pt0);
|
||||
@ -4564,11 +4567,11 @@ Yap_absmi(int inp)
|
||||
pt1 = H;
|
||||
/* include XREG on it */
|
||||
#if defined(SBA) && defined(FROZEN_STACKS)
|
||||
Bind_Local(YREG+PREG->u.xy.y,Unsigned(pt1 + 1));
|
||||
Bind_Local(YREG+PREG->u.yx.y,Unsigned(pt1 + 1));
|
||||
#else
|
||||
YREG[PREG->u.xy.y] = Unsigned(pt1 + 1);
|
||||
YREG[PREG->u.yx.y] = Unsigned(pt1 + 1);
|
||||
#endif /* SBA && FROZEN_STACKS */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
RESET_VARIABLE(pt1);
|
||||
RESET_VARIABLE(pt1+1);
|
||||
d0 = AbsPair(pt1);
|
||||
@ -4697,9 +4700,9 @@ Yap_absmi(int inp)
|
||||
ENDD(d0);
|
||||
ENDOp();
|
||||
|
||||
Op(gl_void_valy, xy);
|
||||
Op(gl_void_valy, yx);
|
||||
BEGD(d0);
|
||||
d0 = XREG(PREG->u.xy.x);
|
||||
d0 = XREG(PREG->u.yx.x);
|
||||
deref_head(d0, glist_void_valy_write);
|
||||
glist_void_valy_read:
|
||||
BEGP(pt0);
|
||||
@ -4716,20 +4719,20 @@ Yap_absmi(int inp)
|
||||
/* first argument is bound */
|
||||
BEGD(d1);
|
||||
BEGP(pt1);
|
||||
pt1 = YREG+PREG->u.xy.y;
|
||||
pt1 = YREG+PREG->u.yx.y;
|
||||
d1 = *pt1;
|
||||
deref_head(d1, glist_void_valy_nonvar_unk);
|
||||
|
||||
glist_void_valy_nonvar_nonvar:
|
||||
/* both arguments are bound */
|
||||
/* we may have to bind structures */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
UnifyBound(d0, d1);
|
||||
|
||||
/* deref second argument */
|
||||
derefa_body(d1, pt1, glist_void_valy_nonvar_unk, glist_void_valy_nonvar_nonvar);
|
||||
/* first argument bound, second unbound */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
BIND(pt1, d0, bind_glist_void_valy_nonvar_var);
|
||||
#ifdef COROUTINING
|
||||
DO_TRAIL(pt1, d0);
|
||||
@ -4744,13 +4747,13 @@ Yap_absmi(int inp)
|
||||
derefa_body(d0, pt0, glist_void_valy_unk, glist_void_valy_nonvar);
|
||||
/* first argument is unbound */
|
||||
BEGP(pt1);
|
||||
pt1 = YREG+PREG->u.xy.y;
|
||||
pt1 = YREG+PREG->u.yx.y;
|
||||
d1 = *pt1;
|
||||
deref_head(d1, glist_void_valy_var_unk);
|
||||
|
||||
glist_void_valy_var_nonvar:
|
||||
/* first unbound, second bound */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
BIND_GLOBAL(pt0, d1, bind_glist_void_valy_var_nonvar);
|
||||
#ifdef COROUTINING
|
||||
DO_TRAIL(pt0, d1);
|
||||
@ -4761,7 +4764,7 @@ Yap_absmi(int inp)
|
||||
|
||||
deref_body(d1, pt1, glist_void_valy_var_unk, glist_void_valy_var_nonvar);
|
||||
/* both arguments are unbound */
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
UnifyGlobalRegCells(pt0, pt1, uc11, uc12);
|
||||
#ifdef COROUTINING
|
||||
DO_TRAIL(pt0, (CELL)pt1);
|
||||
@ -4796,11 +4799,11 @@ Yap_absmi(int inp)
|
||||
#endif
|
||||
/* include XREG on it */
|
||||
BEGD(d1);
|
||||
d1 = YREG[PREG->u.xy.y];
|
||||
d1 = YREG[PREG->u.yx.y];
|
||||
RESET_VARIABLE(S_SREG);
|
||||
S_SREG[1] = d1;
|
||||
ENDD(d1);
|
||||
PREG = NEXTOP(PREG, xy);
|
||||
PREG = NEXTOP(PREG, yx);
|
||||
H = S_SREG + 2;
|
||||
ENDCACHE_S();
|
||||
GONext();
|
||||
@ -11219,27 +11222,45 @@ Yap_absmi(int inp)
|
||||
flags = PREG->u.plxxs.flags;
|
||||
if (v > 0) {
|
||||
if (flags & GT_OK_IN_CMP) {
|
||||
PREG = NEXTOP(PREG, plxxs);
|
||||
JMPNext();
|
||||
yamop *nextp = NEXTOP(PREG, plxxs);
|
||||
ALWAYS_LOOKAHEAD(nextp->opc);
|
||||
PREG = nextp;
|
||||
ALWAYS_GONext();
|
||||
ALWAYS_END_PREFETCH();
|
||||
} else {
|
||||
PREG = PREG->u.plxxs.f;
|
||||
JMPNext();
|
||||
yamop *nextp = PREG->u.plxxs.f;
|
||||
ALWAYS_LOOKAHEAD(nextp->opc);
|
||||
PREG = nextp;
|
||||
ALWAYS_GONext();
|
||||
ALWAYS_END_PREFETCH();
|
||||
}
|
||||
} else if (v < 0) {
|
||||
if (flags & LT_OK_IN_CMP) {
|
||||
PREG = NEXTOP(PREG, plxxs);
|
||||
JMPNext();
|
||||
yamop *nextp = NEXTOP(PREG, plxxs);
|
||||
ALWAYS_LOOKAHEAD(nextp->opc);
|
||||
PREG = nextp;
|
||||
ALWAYS_GONext();
|
||||
ALWAYS_END_PREFETCH();
|
||||
} else {
|
||||
PREG = PREG->u.plxxs.f;
|
||||
JMPNext();
|
||||
yamop *nextp = PREG->u.plxxs.f;
|
||||
ALWAYS_LOOKAHEAD(nextp->opc);
|
||||
PREG = nextp;
|
||||
ALWAYS_GONext();
|
||||
ALWAYS_END_PREFETCH();
|
||||
}
|
||||
} else /* if (v == 0) */ {
|
||||
if (flags & EQ_OK_IN_CMP) {
|
||||
PREG = NEXTOP(PREG, plxxs);
|
||||
JMPNext();
|
||||
yamop *nextp = NEXTOP(PREG, plxxs);
|
||||
ALWAYS_LOOKAHEAD(nextp->opc);
|
||||
PREG = nextp;
|
||||
ALWAYS_GONext();
|
||||
ALWAYS_END_PREFETCH();
|
||||
} else {
|
||||
PREG = PREG->u.plxxs.f;
|
||||
JMPNext();
|
||||
yamop *nextp = PREG->u.plxxs.f;
|
||||
ALWAYS_LOOKAHEAD(nextp->opc);
|
||||
PREG = nextp;
|
||||
ALWAYS_GONext();
|
||||
ALWAYS_END_PREFETCH();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -919,6 +919,7 @@ ExtendWorkSpace(Int s, int fixed_allocation)
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
Yap_PrologMode = ExtendStackMode;
|
||||
|
||||
a = mmap(base, (size_t) s, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE | MAP_ANON | fixed_allocation, -1, 0);
|
||||
#else
|
||||
|
147
C/amasm.c
147
C/amasm.c
@ -874,9 +874,28 @@ a_vr(op_numbers opcodex, op_numbers opcodey, yamop *code_p, int pass_no, struct
|
||||
}
|
||||
cip->cpc = ncpc;
|
||||
GONEXT(yyxx);
|
||||
return code_p;
|
||||
/* simplify unification code */
|
||||
} else if (FALSE && cpc->rnd2 == 0 &&
|
||||
ncpc->op == get_var_op &&
|
||||
ncpc->rnd2 == 0 &&
|
||||
((Ventry *) ncpc->rnd1)->KindOfVE != PermVar) {
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
OPREG var_offset2;
|
||||
Ventry *ve2 = (Ventry *) ncpc->rnd1;
|
||||
|
||||
code_p->opc = emit_op(_put_y_var);
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
var_offset2 = Var_Ref(ve2, !is_y_var);
|
||||
code_p->u.yx.x = emit_xreg(var_offset2);
|
||||
code_p->u.yx.y = emit_yreg(var_offset);
|
||||
}
|
||||
cip->cpc = ncpc;
|
||||
GONEXT(yx);
|
||||
return code_p;
|
||||
}
|
||||
}
|
||||
if (opcodey == _get_y_var) {
|
||||
} else if (opcodey == _get_y_var) {
|
||||
struct PSEUDO *ncpc = cpc->nextInst;
|
||||
if (ncpc->op == get_var_op &&
|
||||
((Ventry *) ncpc->rnd1)->KindOfVE == PermVar ) {
|
||||
@ -896,6 +915,7 @@ a_vr(op_numbers opcodex, op_numbers opcodey, yamop *code_p, int pass_no, struct
|
||||
}
|
||||
cip->cpc = ncpc;
|
||||
GONEXT(yyxx);
|
||||
return code_p;
|
||||
}
|
||||
}
|
||||
if (pass_no) {
|
||||
@ -904,46 +924,95 @@ a_vr(op_numbers opcodex, op_numbers opcodey, yamop *code_p, int pass_no, struct
|
||||
code_p->opc = emit_op(opcodey);
|
||||
code_p->u.yx.y = emit_yreg(var_offset);
|
||||
code_p->u.yx.x = emit_x(cpc->rnd2);
|
||||
}
|
||||
GONEXT(yx);
|
||||
}
|
||||
else if (opcodex == _put_x_val &&
|
||||
cpc->nextInst &&
|
||||
cpc->nextInst->op == put_val_op &&
|
||||
!(((Ventry *) cpc->nextInst->rnd1)->KindOfVE == PermVar)) {
|
||||
/* peephole! two put_x_vars in a row */
|
||||
if (pass_no) {
|
||||
}
|
||||
GONEXT(yx);
|
||||
return code_p;
|
||||
}
|
||||
if (opcodex == _put_x_val &&
|
||||
cpc->nextInst) {
|
||||
if (cpc->nextInst->op == put_val_op &&
|
||||
!(((Ventry *) cpc->nextInst->rnd1)->KindOfVE == PermVar)) {
|
||||
PInstr *ncpc = cpc->nextInst;
|
||||
/* peephole! two put_x_vars in a row */
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
OPREG var_offset2;
|
||||
Ventry *ve2 = (Ventry *) ncpc->rnd1;
|
||||
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(_put_xx_val);
|
||||
code_p->u.xxxx.xl1 = emit_xreg(var_offset);
|
||||
code_p->u.xxxx.xr1 = emit_x(cpc->rnd2);
|
||||
var_offset2 = Var_Ref(ve2, is_y_var);
|
||||
code_p->u.xxxx.xl2 = emit_xreg(var_offset2);
|
||||
code_p->u.xxxx.xr2 = emit_x(ncpc->rnd2);
|
||||
}
|
||||
cip->cpc = ncpc;
|
||||
GONEXT(xxxx);
|
||||
return code_p;
|
||||
/* simplify unification */
|
||||
} else if (cpc->rnd2 == 0 &&
|
||||
cpc->nextInst->rnd2 == 0) {
|
||||
OPREG var_offset;
|
||||
OPREG var_offset2;
|
||||
Ventry *ve2 = (Ventry *) cpc->nextInst->rnd1;
|
||||
Ventry *ve2;
|
||||
int is_y_var2;
|
||||
PInstr *ncpc;
|
||||
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(_put_xx_val);
|
||||
code_p->u.xxxx.xl1 = emit_xreg(var_offset);
|
||||
code_p->u.xxxx.xr1 = emit_x(cpc->rnd2);
|
||||
var_offset2 = Var_Ref(ve2, is_y_var);
|
||||
code_p->u.xxxx.xl2 = emit_xreg(var_offset2);
|
||||
code_p->u.xxxx.xr2 = emit_x(cpc->nextInst->rnd2);
|
||||
}
|
||||
cip->cpc = cpc->nextInst;
|
||||
GONEXT(xxxx);
|
||||
} else {
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(opcodex);
|
||||
code_p->u.xx.xl = emit_xreg(var_offset);
|
||||
code_p->u.xx.xr = emit_x(cpc->rnd2);
|
||||
/* a small trick, usualy the lower argument is the one bound */
|
||||
if (opcodex == _get_x_val && code_p->u.xx.xl > code_p->u.xx.xr) {
|
||||
wamreg x1 = code_p->u.xx.xl;
|
||||
code_p->u.xx.xl = code_p->u.xx.xr;
|
||||
code_p->u.xx.xr = x1;
|
||||
ncpc = cpc->nextInst;
|
||||
ve2 = (Ventry *) ncpc->rnd1;
|
||||
is_y_var2 = (ve2->KindOfVE == PermVar);
|
||||
/* put + get */
|
||||
if (ncpc->op == get_var_op ||
|
||||
ncpc->op == get_val_op) {
|
||||
if (is_y_var2) {
|
||||
if (pass_no) {
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
var_offset2 = Var_Ref(ve2, is_y_var2);
|
||||
if (ncpc->op == get_var_op)
|
||||
code_p->opc = emit_op(_get_y_var);
|
||||
else
|
||||
code_p->opc = emit_op(_get_y_val);
|
||||
code_p->u.yx.x = emit_xreg(var_offset);
|
||||
code_p->u.yx.y = emit_yreg(var_offset2);
|
||||
}
|
||||
GONEXT(yx);
|
||||
cip->cpc = ncpc;
|
||||
return code_p;
|
||||
} else {
|
||||
if (pass_no) {
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
var_offset2 = Var_Ref(ve2, is_y_var2);
|
||||
code_p->u.xx.xl = emit_xreg(var_offset);
|
||||
code_p->u.xx.xr = emit_xreg(var_offset2);
|
||||
if (ncpc->op == get_var_op)
|
||||
code_p->opc = emit_op(_put_x_var);
|
||||
else {
|
||||
code_p->opc = emit_op(_get_x_val);
|
||||
}
|
||||
}
|
||||
GONEXT(xx);
|
||||
cip->cpc = ncpc;
|
||||
return code_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
GONEXT(xx);
|
||||
}
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(opcodex);
|
||||
code_p->u.xx.xl = emit_xreg(var_offset);
|
||||
code_p->u.xx.xr = emit_x(cpc->rnd2);
|
||||
/* a small trick, usualy the lower argument is the one bound */
|
||||
if (opcodex == _get_x_val && code_p->u.xx.xl > code_p->u.xx.xr) {
|
||||
wamreg x1 = code_p->u.xx.xl;
|
||||
code_p->u.xx.xl = code_p->u.xx.xr;
|
||||
code_p->u.xx.xr = x1;
|
||||
}
|
||||
}
|
||||
GONEXT(xx);
|
||||
return code_p;
|
||||
}
|
||||
|
||||
@ -956,10 +1025,10 @@ a_rv(op_numbers opcodex, op_numbers opcodey, OPREG var_offset, yamop *code_p, in
|
||||
if (is_y_var) {
|
||||
if (pass_no) {
|
||||
code_p->opc = emit_op(opcodey);
|
||||
code_p->u.xy.x = emit_x(cpc->rnd2);
|
||||
code_p->u.xy.y = emit_yreg(var_offset);
|
||||
code_p->u.yx.x = emit_x(cpc->rnd2);
|
||||
code_p->u.yx.y = emit_yreg(var_offset);
|
||||
}
|
||||
GONEXT(xy);
|
||||
GONEXT(yx);
|
||||
}
|
||||
else {
|
||||
if (pass_no) {
|
||||
|
107
C/compiler.c
107
C/compiler.c
@ -887,12 +887,14 @@ c_eq(Term t1, Term t2, compiler_struct *cglobs)
|
||||
cglobs->onhead = FALSE;
|
||||
}
|
||||
} else {
|
||||
Int v = --cglobs->tmpreg;
|
||||
c_var(t1, v, 0, 0, cglobs);
|
||||
cglobs->onhead = TRUE;
|
||||
if (IsVarTerm(t2)) {
|
||||
c_var(t2, v, 0, 0, cglobs);
|
||||
c_var(t1, 0, 0, 0, cglobs);
|
||||
cglobs->onhead = TRUE;
|
||||
c_var(t2, 0, 0, 0, cglobs);
|
||||
} else {
|
||||
Int v = --cglobs->tmpreg;
|
||||
c_var(t1, v, 0, 0, cglobs);
|
||||
cglobs->onhead = TRUE;
|
||||
c_arg(v, t2, 0, 0, cglobs);
|
||||
}
|
||||
cglobs->onhead = FALSE;
|
||||
@ -2260,6 +2262,7 @@ int nperm;
|
||||
static int nperm;
|
||||
#endif
|
||||
|
||||
|
||||
inline static int
|
||||
usesvar(compiler_vm_op ic)
|
||||
{
|
||||
@ -2757,7 +2760,7 @@ checktemp(Int arg, Int rn, compiler_vm_op ic, compiler_struct *cglobs)
|
||||
target2 = cglobs->MaxCTemps;
|
||||
n = v->RCountOfVE - 1;
|
||||
while (q != v->LastOpForV && (q = q->nextInst) != NIL) {
|
||||
if (q->rnd2 <= 0); /* don't try to use REGISTER 0 */
|
||||
if (q->rnd2 <= 0); /* don't try to reuse REGISTER 0 */
|
||||
else if (usesvar(ic = q->op) && arg == q->rnd1) {
|
||||
--n;
|
||||
if (ic == put_val_op) {
|
||||
@ -3078,11 +3081,13 @@ c_layout(compiler_struct *cglobs)
|
||||
rn = checkreg(arg, rn, ic, TRUE, cglobs);
|
||||
checktemp(arg, rn, ic, cglobs);
|
||||
#ifdef BEAM
|
||||
if (cglobs->Contents[rn] == (Term)cglobs->vadr && !EAM)
|
||||
if (rn && cglobs->Contents[rn] == (Term)cglobs->vadr && !EAM)
|
||||
#else
|
||||
if (cglobs->Contents[rn] == (Term)cglobs->vadr)
|
||||
if (rn && cglobs->Contents[rn] == (Term)cglobs->vadr)
|
||||
#endif
|
||||
cglobs->cint.cpc->op = nop_op;
|
||||
{
|
||||
cglobs->cint.cpc->op = nop_op;
|
||||
}
|
||||
cglobs->Contents[rn] = cglobs->vadr;
|
||||
++cglobs->Uses[rn];
|
||||
if (rn_kills) {
|
||||
@ -3231,13 +3236,78 @@ c_layout(compiler_struct *cglobs)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
push_allocate(PInstr *pc, PInstr *oldpc)
|
||||
{
|
||||
/*
|
||||
The idea is to push an allocate forward as much as we can. This
|
||||
delays work in the emulated code, and in the best case we may get rid of
|
||||
allocates altogether.
|
||||
*/
|
||||
/* we can push the allocate */
|
||||
int safe = TRUE;
|
||||
PInstr *initial = oldpc, *dealloc_founds[16];
|
||||
int d_founds = 0;
|
||||
int level = 0;
|
||||
|
||||
while (pc) {
|
||||
switch (pc->op) {
|
||||
case jump_op:
|
||||
return;
|
||||
case call_op:
|
||||
case safe_call_op:
|
||||
if (!safe)
|
||||
return;
|
||||
else {
|
||||
PInstr *where = initial->nextInst->nextInst;
|
||||
while (d_founds)
|
||||
dealloc_founds[--d_founds]->op = nop_op;
|
||||
if (where == pc || oldpc == initial->nextInst)
|
||||
return;
|
||||
oldpc->nextInst = initial->nextInst;
|
||||
initial->nextInst->nextInst = pc;
|
||||
initial->nextInst = where;
|
||||
return;
|
||||
}
|
||||
case push_or_op:
|
||||
/* we cannot just put an allocate here, because it may never be executed */
|
||||
level++;
|
||||
safe = FALSE;
|
||||
break;
|
||||
case pushpop_or_op:
|
||||
/* last branch and we did not need an allocate so far, cool! */
|
||||
level--;
|
||||
if (!level)
|
||||
safe = TRUE;
|
||||
break;
|
||||
case cut_op:
|
||||
case either_op:
|
||||
case execute_op:
|
||||
return;
|
||||
case deallocate_op:
|
||||
dealloc_founds[d_founds++] = pc;
|
||||
if (d_founds == 16)
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
oldpc = pc;
|
||||
pc = pc->nextInst;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
c_optimize(PInstr *pc)
|
||||
{
|
||||
char onTail;
|
||||
Ventry *v;
|
||||
PInstr *opc = NULL;
|
||||
PInstr *inpc = pc;
|
||||
|
||||
pc = inpc;
|
||||
opc = NULL;
|
||||
/* first reverse the pointers */
|
||||
while (pc != NULL) {
|
||||
PInstr *tpc = pc->nextInst;
|
||||
@ -3252,15 +3322,22 @@ c_optimize(PInstr *pc)
|
||||
PInstr *npc = pc->nextInst;
|
||||
pc->nextInst = opc;
|
||||
switch (pc->op) {
|
||||
case put_val_op:
|
||||
case get_var_op:
|
||||
/* handle clumsy either branches */
|
||||
if (npc->op == f_0_op) {
|
||||
npc->rnd1 = pc->rnd1;
|
||||
npc->op = f_var_op;
|
||||
pc->op = nop_op;
|
||||
break;
|
||||
}
|
||||
case put_val_op:
|
||||
case get_val_op:
|
||||
{
|
||||
Ventry *ve = (Ventry *) pc->rnd1;
|
||||
|
||||
if (ve->KindOfVE == TempVar) {
|
||||
UInt argno = ve->NoOfVE & MaskVarAdrs;
|
||||
if (argno == pc->rnd2) {
|
||||
if (argno && argno == pc->rnd2) {
|
||||
pc->op = nop_op;
|
||||
}
|
||||
}
|
||||
@ -3390,6 +3467,16 @@ c_optimize(PInstr *pc)
|
||||
opc = pc;
|
||||
pc = npc;
|
||||
} while (pc != NULL);
|
||||
pc = inpc;
|
||||
opc = NULL;
|
||||
while (pc != NULL) {
|
||||
if (pc->op == allocate_op) {
|
||||
push_allocate(pc, opc);
|
||||
break;
|
||||
}
|
||||
opc = pc;
|
||||
pc = pc->nextInst;
|
||||
}
|
||||
}
|
||||
|
||||
yamop *
|
||||
|
@ -592,7 +592,6 @@ static char *opformat[] =
|
||||
"put_float\t\t%w,%r",
|
||||
"get_dbterm\t%w,%r",
|
||||
"put_dbterm\t%w,%r",
|
||||
"align_float",
|
||||
"get_longint\t\t%w,%r",
|
||||
"put_longint\t\t%w,%r",
|
||||
"get_bigint\t\t%l,%r",
|
||||
@ -623,6 +622,25 @@ static char *opformat[] =
|
||||
"unify_struct\t%f",
|
||||
"write_struct\t%f",
|
||||
"write_unsafe\t%v",
|
||||
"unify_local\t%v",
|
||||
"write local\t%v",
|
||||
"unify_last_list",
|
||||
"write_last_list",
|
||||
"unify_last_struct\t%f",
|
||||
"write_last_struct\t%f",
|
||||
"unify_last_var\t%v",
|
||||
"unify_last_val\t%v",
|
||||
"unify_last_local\t%v",
|
||||
"unify_last_atom\t%a",
|
||||
"unify_last_num\t%n",
|
||||
"unify_last_float\t%w",
|
||||
"unify_last_dbterm\t%w",
|
||||
"unify_last_longint\t%w",
|
||||
"unify_last_bigint\t%l",
|
||||
"function_to_var\t%v,%B",
|
||||
"function_to_val\t%v,%B",
|
||||
"function_to_0\t%B",
|
||||
"align_float",
|
||||
"fail",
|
||||
"cut",
|
||||
"cutexit",
|
||||
@ -670,21 +688,6 @@ static char *opformat[] =
|
||||
"check_var\t %r",
|
||||
"save_pair\t%v",
|
||||
"save_appl\t%v",
|
||||
"unify_local\t%v",
|
||||
"write local\t%v",
|
||||
"unify_last_list",
|
||||
"write_last_list",
|
||||
"unify_last_struct\t%f",
|
||||
"write_last_struct\t%f",
|
||||
"unify_last_var\t%v",
|
||||
"unify_last_val\t%v",
|
||||
"unify_last_local\t%v",
|
||||
"unify_last_atom\t%a",
|
||||
"unify_last_num\t%n",
|
||||
"unify_last_float\t%w",
|
||||
"unify_last_dbterm\t%w",
|
||||
"unify_last_longint\t%w",
|
||||
"unify_last_bigint\t%l",
|
||||
"pvar_bitmap\t%l,%b",
|
||||
"pvar_live_regs\t%l,%b",
|
||||
"fetch_reg1_reg2\t%N,%N",
|
||||
@ -692,9 +695,6 @@ static char *opformat[] =
|
||||
"fetch_reg_constant\t%l,%N",
|
||||
"fetch_integer_reg\t%d,%N",
|
||||
"fetch_reg_integer\t%d,%N",
|
||||
"function_to_var\t%v,%B",
|
||||
"function_to_val\t%v,%B",
|
||||
"function_to_0\t%B",
|
||||
"enter_profiling\t\t%g",
|
||||
"retry_profiled\t\t%g",
|
||||
"count_call_op\t\t%g",
|
||||
|
12
C/index.c
12
C/index.c
@ -1178,6 +1178,9 @@ has_cut(yamop *pc)
|
||||
case _put_y_var:
|
||||
case _put_y_val:
|
||||
case _put_unsafe:
|
||||
case _glist_valy:
|
||||
case _gl_void_vary:
|
||||
case _gl_void_valy:
|
||||
pc = NEXTOP(pc,yx);
|
||||
break;
|
||||
/* instructions type xd */
|
||||
@ -1222,12 +1225,7 @@ has_cut(yamop *pc)
|
||||
case _put_struct:
|
||||
pc = NEXTOP(pc,xfa);
|
||||
break;
|
||||
/* instructions type xy */
|
||||
case _glist_valy:
|
||||
case _gl_void_vary:
|
||||
case _gl_void_valy:
|
||||
pc = NEXTOP(pc,xy);
|
||||
break;
|
||||
/* instructions type yx */
|
||||
/* instructions type ox */
|
||||
case _unify_x_var:
|
||||
case _unify_x_var_write:
|
||||
@ -1622,7 +1620,7 @@ add_arg_info(ClauseDef *clause, PredEntry *ap, UInt argno)
|
||||
return;
|
||||
}
|
||||
argno = 2;
|
||||
cl = NEXTOP(cl,xy);
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _unify_l_x_var:
|
||||
case _unify_l_x_val:
|
||||
|
@ -172,6 +172,8 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args)
|
||||
LOCK(Yap_heap_regs->low_level_trace_lock);
|
||||
sc = Yap_heap_regs;
|
||||
vsc_count++;
|
||||
if (vsc_count == 533)
|
||||
jmp_deb(1);
|
||||
#ifdef THREADS
|
||||
Yap_heap_regs->thread_handle[worker_id].thread_inst_count++;
|
||||
#endif
|
||||
|
@ -71,11 +71,11 @@
|
||||
OPCODE(get_bigint ,xc),
|
||||
OPCODE(get_dbterm ,xc),
|
||||
OPCODE(glist_valx ,xx),
|
||||
OPCODE(glist_valy ,xy),
|
||||
OPCODE(glist_valy ,yx),
|
||||
OPCODE(gl_void_varx ,xx),
|
||||
OPCODE(gl_void_vary ,xy),
|
||||
OPCODE(gl_void_vary ,yx),
|
||||
OPCODE(gl_void_valx ,xx),
|
||||
OPCODE(gl_void_valy ,xy),
|
||||
OPCODE(gl_void_valy ,yx),
|
||||
OPCODE(unify_x_var ,ox),
|
||||
OPCODE(unify_x_var_write ,ox),
|
||||
OPCODE(unify_l_x_var ,ox),
|
||||
|
@ -702,11 +702,6 @@ typedef struct yami {
|
||||
Int c;
|
||||
CELL next;
|
||||
} xxn;
|
||||
struct {
|
||||
wamreg x;
|
||||
yslot y;
|
||||
CELL next;
|
||||
} xy;
|
||||
struct {
|
||||
wamreg x;
|
||||
wamreg x1;
|
||||
|
66
H/compile.h
66
H/compile.h
@ -32,7 +32,6 @@ typedef enum compiler_op {
|
||||
put_float_op,
|
||||
get_dbterm_op,
|
||||
put_dbterm_op,
|
||||
align_float_op,
|
||||
get_longint_op,
|
||||
put_longint_op,
|
||||
get_bigint_op,
|
||||
@ -63,6 +62,25 @@ typedef enum compiler_op {
|
||||
unify_struct_op,
|
||||
write_struct_op,
|
||||
write_unsafe_op,
|
||||
unify_local_op,
|
||||
write_local_op,
|
||||
unify_last_list_op,
|
||||
write_last_list_op,
|
||||
unify_last_struct_op,
|
||||
write_last_struct_op,
|
||||
unify_last_var_op,
|
||||
unify_last_val_op,
|
||||
unify_last_local_op,
|
||||
unify_last_atom_op,
|
||||
unify_last_num_op,
|
||||
unify_last_float_op,
|
||||
unify_last_dbterm_op,
|
||||
unify_last_longint_op,
|
||||
unify_last_bigint_op,
|
||||
f_var_op,
|
||||
f_val_op,
|
||||
f_0_op,
|
||||
align_float_op,
|
||||
fail_op,
|
||||
cut_op,
|
||||
cutexit_op,
|
||||
@ -110,21 +128,6 @@ typedef enum compiler_op {
|
||||
if_nonvar_op,
|
||||
save_pair_op,
|
||||
save_appl_op,
|
||||
unify_local_op,
|
||||
write_local_op,
|
||||
unify_last_list_op,
|
||||
write_last_list_op,
|
||||
unify_last_struct_op,
|
||||
write_last_struct_op,
|
||||
unify_last_var_op,
|
||||
unify_last_val_op,
|
||||
unify_last_local_op,
|
||||
unify_last_atom_op,
|
||||
unify_last_num_op,
|
||||
unify_last_float_op,
|
||||
unify_last_dbterm_op,
|
||||
unify_last_longint_op,
|
||||
unify_last_bigint_op,
|
||||
mark_initialised_pvars_op,
|
||||
mark_live_regs_op,
|
||||
fetch_args_vv_op,
|
||||
@ -132,9 +135,6 @@ typedef enum compiler_op {
|
||||
fetch_args_vc_op,
|
||||
fetch_args_iv_op,
|
||||
fetch_args_vi_op,
|
||||
f_var_op,
|
||||
f_val_op,
|
||||
f_0_op,
|
||||
enter_profiling_op,
|
||||
retry_profiled_op,
|
||||
count_call_op,
|
||||
@ -268,20 +268,20 @@ typedef struct PSEUDO {
|
||||
#define rnd4 ops.opseqt[2]
|
||||
|
||||
typedef struct VENTRY {
|
||||
CELL SelfOfVE;
|
||||
Term AdrsOfVE;
|
||||
Int KindOfVE;
|
||||
CELL NoOfVE;
|
||||
PInstr *FirstOpForV;
|
||||
PInstr *LastOpForV;
|
||||
BITS16 AgeOfVE;
|
||||
BITS16 BranchOfVE;
|
||||
BITS16 LastBranchOfVE;
|
||||
BITS16 FirstOfVE;
|
||||
BITS16 RCountOfVE;
|
||||
BITS16 FlagsOfVE;
|
||||
struct VENTRY *NextOfVE;
|
||||
} Ventry;
|
||||
CELL SelfOfVE;
|
||||
Term AdrsOfVE;
|
||||
Int KindOfVE;
|
||||
CELL NoOfVE;
|
||||
PInstr *FirstOpForV;
|
||||
PInstr *LastOpForV;
|
||||
BITS16 AgeOfVE;
|
||||
BITS16 BranchOfVE;
|
||||
BITS16 LastBranchOfVE;
|
||||
BITS16 FirstOfVE;
|
||||
BITS16 RCountOfVE;
|
||||
BITS16 FlagsOfVE;
|
||||
struct VENTRY *NextOfVE;
|
||||
} Ventry;
|
||||
|
||||
typedef struct CEXPENTRY {
|
||||
Term TermOfCE;
|
||||
|
@ -1182,34 +1182,6 @@
|
||||
}
|
||||
cl = NEXTOP(cl,xxy);
|
||||
break;
|
||||
case _gl_void_valy:
|
||||
if (is_regcopy(myregs, nofregs, cl->u.xy.y)) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,xy);
|
||||
break;
|
||||
case _gl_void_vary:
|
||||
if (is_regcopy(myregs, nofregs, cl->u.xy.y)) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
if (!(nofregs = delete_regcopy(myregs, nofregs, cl->u.xy.y))) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,xy);
|
||||
break;
|
||||
case _glist_valy:
|
||||
if (is_regcopy(myregs, nofregs, cl->u.xy.x)) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,xy);
|
||||
break;
|
||||
case _save_b_y:
|
||||
if (!(nofregs = delete_regcopy(myregs, nofregs, cl->u.y.y))) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
@ -1359,6 +1331,34 @@
|
||||
}
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _gl_void_valy:
|
||||
if (is_regcopy(myregs, nofregs, cl->u.yx.y)) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _gl_void_vary:
|
||||
if (is_regcopy(myregs, nofregs, cl->u.yx.y)) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
if (!(nofregs = delete_regcopy(myregs, nofregs, cl->u.yx.y))) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _glist_valy:
|
||||
if (is_regcopy(myregs, nofregs, cl->u.yx.x)) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _put_unsafe:
|
||||
if (!(nofregs = add_regcopy(myregs, nofregs, cl->u.yx.y, cl->u.yx.x))) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
|
@ -593,20 +593,6 @@
|
||||
}
|
||||
cl = NEXTOP(cl,xxxx);
|
||||
break;
|
||||
case _gl_void_valy:
|
||||
cl = NEXTOP(cl,xy);
|
||||
break;
|
||||
case _gl_void_vary:
|
||||
cl = NEXTOP(cl,xy);
|
||||
break;
|
||||
case _glist_valy:
|
||||
if (iarg == cl->u.xy.x) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,xy);
|
||||
break;
|
||||
case _get_y_val:
|
||||
if (cl->u.yx.x == iarg) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
@ -621,6 +607,20 @@
|
||||
}
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _gl_void_valy:
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _gl_void_vary:
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _glist_valy:
|
||||
if (iarg == cl->u.yx.x) {
|
||||
clause->Tag = AbsPair(NULL);
|
||||
clause->u.WorkPC = cl;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _put_unsafe:
|
||||
if (cl->u.yx.x == iarg) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
|
11
H/rclause.h
11
H/rclause.h
@ -764,14 +764,6 @@ restore_opcodes(yamop *pc)
|
||||
pc->u.xxy.y2 = YAdjust(pc->u.xxy.y2);
|
||||
pc = NEXTOP(pc,xxy);
|
||||
break;
|
||||
/* instructions type xy */
|
||||
case _gl_void_valy:
|
||||
case _gl_void_vary:
|
||||
case _glist_valy:
|
||||
pc->u.xy.x = XAdjust(pc->u.xy.x);
|
||||
pc->u.xy.y = YAdjust(pc->u.xy.y);
|
||||
pc = NEXTOP(pc,xy);
|
||||
break;
|
||||
/* instructions type y */
|
||||
case _save_b_y:
|
||||
case _write_y_loc:
|
||||
@ -805,6 +797,9 @@ restore_opcodes(yamop *pc)
|
||||
/* instructions type yx */
|
||||
case _get_y_val:
|
||||
case _get_y_var:
|
||||
case _gl_void_valy:
|
||||
case _gl_void_vary:
|
||||
case _glist_valy:
|
||||
case _put_unsafe:
|
||||
case _put_y_val:
|
||||
case _put_y_var:
|
||||
|
@ -581,12 +581,6 @@
|
||||
case _p_func2f_xy:
|
||||
pc = NEXTOP(pc,xxy);
|
||||
break;
|
||||
/* instructions type xy */
|
||||
case _gl_void_valy:
|
||||
case _gl_void_vary:
|
||||
case _glist_valy:
|
||||
pc = NEXTOP(pc,xy);
|
||||
break;
|
||||
/* instructions type y */
|
||||
case _save_b_y:
|
||||
case _write_y_loc:
|
||||
@ -615,6 +609,9 @@
|
||||
/* instructions type yx */
|
||||
case _get_y_val:
|
||||
case _get_y_var:
|
||||
case _gl_void_valy:
|
||||
case _gl_void_vary:
|
||||
case _glist_valy:
|
||||
case _put_unsafe:
|
||||
case _put_y_val:
|
||||
case _put_y_var:
|
||||
|
Reference in New Issue
Block a user