new implementation of corourining...

This commit is contained in:
Vítor Santos Costa 2011-03-18 19:34:58 +00:00
parent f31e15deb8
commit 0d8aed7971
12 changed files with 261 additions and 1083 deletions

745
C/absmi.c

File diff suppressed because it is too large Load Diff

View File

@ -73,8 +73,8 @@ BuildNewAttVar( USES_REGS1 )
attvar_record *newv;
/* add a new attributed variable */
if (!(newv = (attvar_record *)Yap_GetFromArena(&GlobalArena, sizeof(attvar_record)/sizeof(CELL),2)))
return NULL;
newv = (attvar_record *)H;
H = (CELL *)(newv+1);
newv->AttFunc = FunctorAttVar;
RESET_VARIABLE(&(newv->Value));
RESET_VARIABLE(&(newv->Done));
@ -90,13 +90,14 @@ CopyAttVar(CELL *orig, struct cp_frame **to_visit_ptr, CELL *res USES_REGS)
struct cp_frame *to_visit = *to_visit_ptr;
CELL *vt;
if (!(newv = BuildNewAttVar( PASS_REGS1 )))
return FALSE;
vt = &(attv->Atts);
to_visit->start_cp = vt-1;
to_visit->end_cp = vt;
if (IsVarTerm(attv->Atts)) {
Bind(&newv->Atts, (CELL)H);
Bind_Global_NonAtt(&newv->Atts, (CELL)H);
to_visit->to = H;
H++;
} else {
@ -123,7 +124,7 @@ TermToAttVar(Term attvar, Term to USES_REGS)
attvar_record *attv = BuildNewAttVar( PASS_REGS1 );
if (!attv)
return FALSE;
Bind(&attv->Atts, attvar);
Bind_Global_NonAtt(&attv->Atts, attvar);
*VarOfTerm(to) = AbsAttVar(attv);
return TRUE;
}
@ -155,12 +156,12 @@ WakeAttVar(CELL* pt1, CELL reg2 USES_REGS)
AddFailToQueue( PASS_REGS1 );
}
}
Bind_Global(&(susp2->Value), (CELL)pt1);
Bind_Global_NonAtt(&(susp2->Value), (CELL)pt1);
AddToQueue(susp2 PASS_REGS);
return;
}
} else {
Bind(VarOfTerm(reg2), (CELL)pt1);
Bind_NonAtt(VarOfTerm(reg2), (CELL)pt1);
return;
}
}
@ -179,7 +180,7 @@ WakeAttVar(CELL* pt1, CELL reg2 USES_REGS)
reg2 = AbsAppl(H);
}
*bind_ptr = reg2;
Bind_Global(&(attv->Value), reg2);
Bind_Global_NonAtt(&(attv->Value), reg2);
}
void
@ -187,7 +188,10 @@ Yap_WakeUp(CELL *pt0) {
CACHE_REGS
CELL d0 = *pt0;
RESET_VARIABLE(pt0);
TR--;
/* did we trail */
if (pt0 < HB) {
TR--;
}
WakeAttVar(pt0, d0 PASS_REGS);
}
@ -258,14 +262,16 @@ AddNewModule(attvar_record *attv, Term t, int new, int do_it USES_REGS)
}
if (!do_it)
return;
if (IsVarTerm(attv->Atts)) {
Bind(&(attv->Atts),t);
if (new) {
attv->Atts = t;
} else if (IsVarTerm(attv->Atts)) {
MaBind(&(attv->Atts),t);
} else {
Term *wherep = &attv->Atts;
do {
if (IsVarTerm(*wherep)) {
Bind_Global(wherep,t);
Bind_Global_NonAtt(wherep,t);
return;
} else {
wherep = RepAppl(Deref(*wherep))+1;
@ -365,7 +371,7 @@ PutAtt(Int pos, Term atts, Term att USES_REGS)
if (IsVarTerm(att) && (CELL *)att > H && (CELL *)att < LCL0) {
/* globalise locals */
Term tnew = MkVarTerm();
Bind((CELL *)att, tnew);
Bind_NonAtt((CELL *)att, tnew);
att = tnew;
}
MaBind(RepAppl(atts)+pos, att);
@ -376,23 +382,23 @@ BindAttVar(attvar_record *attv USES_REGS) {
if (IsVarTerm(attv->Done) && IsUnboundVar(&attv->Done)) {
/* make sure we are not trying to bind a variable against itself */
if (!IsVarTerm(attv->Value)) {
Bind_Global(&(attv->Done), attv->Value);
Bind_Global_NonAtt(&(attv->Done), attv->Value);
} else if (IsVarTerm(attv->Value)) {
Term t = Deref(attv->Value);
if (IsVarTerm(t)) {
if (IsAttachedTerm(t)) {
attvar_record *attv2 = RepAttVar(VarOfTerm(t));
if (attv2 < attv) {
Bind_Global(&(attv->Done), t);
Bind_Global_NonAtt(&(attv->Done), t);
} else {
Bind_Global(&(attv2->Done), AbsAttVar(attv));
Bind_Global_NonAtt(&(attv2->Done), AbsAttVar(attv));
}
} else {
Yap_Error(SYSTEM_ERROR,(CELL)&(attv->Done),"attvar was bound when unset");
return(FALSE);
}
} else {
Bind_Global(&(attv->Done), t);
Bind_Global_NonAtt(&(attv->Done), t);
}
}
return(TRUE);
@ -448,7 +454,7 @@ p_put_att( USES_REGS1 ) {
return FALSE;
}
}
Yap_unify(ARG1, AbsAttVar(attv));
Bind_NonAtt(VarOfTerm(Deref(ARG1)), AbsAttVar(attv));
AddNewModule(attv, tatts, new, TRUE PASS_REGS);
}
PutAtt(IntegerOfTerm(Deref(ARG4)), tatts, Deref(ARG5) PASS_REGS);
@ -466,10 +472,10 @@ p_put_att_term( USES_REGS1 ) {
/* if this is unbound, ok */
if (IsVarTerm(inp)) {
attvar_record *attv;
int new = FALSE;
if (IsAttachedTerm(inp)) {
attv = RepAttVar(VarOfTerm(inp));
MaBind(&(attv->Atts), Deref(ARG2));
} else {
while (!(attv = BuildNewAttVar( PASS_REGS1 ))) {
Yap_Error_Size = sizeof(attvar_record);
@ -479,13 +485,8 @@ p_put_att_term( USES_REGS1 ) {
}
inp = Deref(ARG1);
}
new = TRUE;
}
if (new) {
Bind(VarOfTerm(inp), AbsAttVar(attv));
Bind(&attv->Atts, Deref(ARG2));
} else {
MaBind(&(attv->Atts), Deref(ARG2));
Bind_NonAtt(VarOfTerm(inp), AbsAttVar(attv));
attv->Atts = Deref(ARG2);
}
return TRUE;
} else {
@ -1012,9 +1013,9 @@ p_fast_unify( USES_REGS1 )
a = VarOfTerm(t1);
b = VarOfTerm(t2);
if(a > b) {
Bind_Global(a,t2);
Bind_Global_NonAtt(a,t2);
} else if((a) < (b)){
Bind_Global(b,t1);
Bind_Global_NonAtt(b,t1);
}
return TRUE;
}

View File

@ -4024,12 +4024,7 @@ p_is_profiled( USES_REGS1 )
if (PROFILING) ta = MkAtomTerm(AtomOn);
else ta = MkAtomTerm(AtomOff);
BIND((CELL *)t,ta,bind_is_profiled);
#ifdef COROUTINING
DO_TRAIL(VarOfTerm(t), ta);
if (IsAttVar(VarOfTerm(t))) Yap_WakeUp((CELL *)t);
bind_is_profiled:
#endif
Bind((CELL *)t,ta);
return(TRUE);
} else if (!IsAtomTerm(t)) return(FALSE);
s = RepAtom(AtomOfTerm(t))->StrOfAE;
@ -4127,12 +4122,7 @@ p_is_call_counted( USES_REGS1 )
if (CALL_COUNTING) ta = MkAtomTerm(AtomOn);
else ta = MkAtomTerm(AtomOff);
BIND((CELL *)t,ta,bind_is_call_counted);
#ifdef COROUTINING
DO_TRAIL(VarOfTerm(t), ta);
if (IsAttVar(VarOfTerm(t))) Yap_WakeUp((CELL *)t);
bind_is_call_counted:
#endif
Bind((CELL *)t,ta);
return(TRUE);
} else if (!IsAtomTerm(t)) return(FALSE);
s = RepAtom(AtomOfTerm(t))->StrOfAE;

View File

@ -126,12 +126,7 @@ p_save_cp( USES_REGS1 )
#endif
if (!IsVarTerm(t)) return(FALSE);
td = cp_as_integer(B PASS_REGS);
BIND((CELL *)t,td,bind_save_cp);
#ifdef COROUTINING
DO_TRAIL(VarOfTerm(t), td);
if (IsAttVar(VarOfTerm(t))) Yap_WakeUp((CELL *)t);
bind_save_cp:
#endif
Bind((CELL *)t,td);
return(TRUE);
}
@ -145,12 +140,7 @@ p_save_env_b( USES_REGS1 )
#endif
if (!IsVarTerm(t)) return(FALSE);
td = cp_as_integer((choiceptr)YENV[E_CB] PASS_REGS);
BIND((CELL *)t,td,bind_save_cp);
#ifdef COROUTINING
DO_TRAIL(VarOfTerm(t), td);
if (IsAttVar(VarOfTerm(t))) Yap_WakeUp((CELL *)t);
bind_save_cp:
#endif
Bind((CELL *)t,td);
return(TRUE);
}
@ -1468,8 +1458,13 @@ static int is_cleanup_cp(choiceptr cp_b)
static Int
JumpToEnv(Term t USES_REGS) {
#ifndef YAPOR
yamop *pos = NEXTOP(PredDollarCatch->cs.p_code.TrueCodeOfPred,l),
*catchpos = NEXTOP(PredHandleThrow->cs.p_code.TrueCodeOfPred,l);
#else
yamop *pos = NEXTOP(PredDollarCatch->cs.p_code.TrueCodeOfPred,Otapl),
*catchpos = NEXTOP(PredHandleThrow->cs.p_code.TrueCodeOfPred,Otapl);
#endif
CELL *env, *env1;
choiceptr handler, previous = NULL;
@ -1559,7 +1554,8 @@ JumpToEnv(Term t USES_REGS) {
}
handler->cp_cp = (yamop *)env[E_CP];
handler->cp_env = (CELL *)env[E_E];
handler->cp_ap = NEXTOP(PredHandleThrow->CodeOfPred,Otapl);
handler->cp_ap = catchpos;
/* can recover Heap thanks to copy term :-( */
/* B->cp_h = H; */
/* I could backtrack here, but it is easier to leave the unwinding

View File

@ -291,9 +291,6 @@ copy_complex_term(register CELL *pt0, register CELL *pt0_end, int share, int cop
CELL *HB0 = HB;
tr_fr_ptr TR0 = TR;
int ground = TRUE;
#ifdef COROUTINING
CELL *dvarsmin = NULL, *dvarsmax=NULL;
#endif
HB = HLow;
to_visit0 = to_visit;
@ -470,34 +467,25 @@ copy_complex_term(register CELL *pt0, register CELL *pt0_end, int share, int cop
*ptf++ = (CELL) ptd0;
} else {
#if COROUTINING
if (copy_att_vars && IsAttachedTerm((CELL)ptd0)) {
if (copy_att_vars && FastIsAttachedTerm((CELL)ptd0)) {
/* if unbound, call the standard copy term routine */
struct cp_frame *bp;
CELL new;
if (IN_BETWEEN(dvarsmin, ptd0, dvarsmax)) {
*ptf++ = (CELL) ptd0;
} else {
CELL new;
bp = to_visit;
if (!attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) {
goto overflow;
}
to_visit = bp;
new = *ptf;
if (TR > (tr_fr_ptr)Yap_TrailTop - 256) {
/* Trail overflow */
if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) {
goto trail_overflow;
}
}
Bind_and_Trail(ptd0, new);
if (dvarsmin == NULL) {
dvarsmin = CellPtr(new);
}
dvarsmax = CellPtr(new)+1;
ptf++;
bp = to_visit;
if (!attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) {
goto overflow;
}
to_visit = bp;
new = *ptf;
if (TR > (tr_fr_ptr)Yap_TrailTop - 256) {
/* Trail overflow */
if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) {
goto trail_overflow;
}
}
Bind_and_Trail(ptd0, new);
ptf++;
} else {
#endif
/* first time we met this term */
@ -602,7 +590,7 @@ CopyTermToArena(Term t, Term arena, int share, int copy_att_vars, UInt arity, Te
ASP = ArenaLimit(arena);
H = HB = ArenaPt(arena);
#if COROUTINING
if (IsAttachedTerm(t)) {
if (FastIsAttachedTerm(t)) {
CELL *Hi;
*H = t;
@ -1106,7 +1094,7 @@ p_b_setval( USES_REGS1 )
{
/* but first make sure we are doing on a global object, or a constant! */
Term t = Deref(ARG2);
if (IsVarTerm(t) && VarOfTerm(t) > H && VarOfTerm(t) < ASP) {
if (IsVarTerm(t) && VarOfTerm(t) > H && VarOfTerm(t) < LCL0) {
Term tn = MkVarTerm();
Bind_Local(VarOfTerm(t), tn);
t = tn;

View File

@ -24,7 +24,7 @@ static char SccsId[] = "%W% %G%";
#include "attvar.h"
#if !defined(TABLING)
#define EASY_SHUNTING 1
//#define EASY_SHUNTING 1
#endif /* !TABLING */
#define HYBRID_SCHEME 1
@ -1172,7 +1172,7 @@ mark_variable(CELL_PTR current USES_REGS)
next = GET_NEXT(ccur);
if (IsVarTerm(ccur)) {
if (IN_BETWEEN(Yap_GlobalBase,current,H) && IsAttVar(current) && current==next) {
if (IN_BETWEEN(Yap_GlobalBase,current,H) && FastIsAttVar(current) && current==next) {
if (next < H0) POP_CONTINUATION();
if (!UNMARKED_MARK(next-1,local_bp)) {
total_marked++;
@ -1656,7 +1656,7 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
nondeterministically, I know that after backtracking it will be back to be an unbound variable.
The ideal solution would be to unbind all variables. The current solution is to
remark it as an attributed variable */
if (IN_BETWEEN(Yap_GlobalBase,hp,H) && IsAttVar(hp) && !UNMARKED_MARK(hp-1,Yap_bp)) {
if (IN_BETWEEN(Yap_GlobalBase,hp,H) && FastIsAttVar(hp) && !UNMARKED_MARK(hp-1,Yap_bp)) {
total_marked++;
PUSH_POINTER(hp-1 PASS_REGS);
if (hp-1 < HGEN) {
@ -1697,7 +1697,7 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
/* can safely ignore this */
CELL *cptr = RepPair(trail_cell);
if (IN_BETWEEN(Yap_GlobalBase,cptr,H) &&
IsAttVar(cptr)) {
FastIsAttVar(cptr)) {
TrailTerm(trail_base) = (CELL)cptr;
mark_external_reference(&TrailTerm(trail_base) PASS_REGS);
TrailTerm(trail_base) = trail_cell;
@ -2486,7 +2486,7 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR USES_REGS)
CELL *pt0 = RepPair(trail_cell);
CELL flags;
if (IN_BETWEEN(Yap_GlobalBase, pt0, H) && IsAttVar(pt0)) {
if (IN_BETWEEN(Yap_GlobalBase, pt0, H) && FastIsAttVar(pt0)) {
TrailTerm(dest) = trail_cell;
/* be careful with partial gc */
if (HEAP_PTR(TrailTerm(dest))) {

View File

@ -638,12 +638,7 @@ p_functor( USES_REGS1 ) /* functor(?,?,?) */
BEGP(pt0);
deref_body(d1, pt0, func_nvar_unk, func_nvar_nvar);
/* A2 is a variable, go and bind it */
BIND(pt0, d0, bind_func_nvar_var);
#ifdef COROUTINING
DO_TRAIL(pt0, d0);
if (IsAttVar(pt0)) Yap_WakeUp(pt0);
bind_func_nvar_var:
#endif
Bind(pt0, d0);
/* have to buffer ENDP and label */
d0 = arity;
ENDP(pt0);
@ -664,13 +659,7 @@ p_functor( USES_REGS1 ) /* functor(?,?,?) */
BEGP(pt0);
deref_body(d1, pt0, func_nvar3_unk, func_nvar3_nvar);
/* A3 is a variable, go and bind it */
BIND(pt0, d0, bind_func_nvar3_var);
/* Done */
#ifdef COROUTINING
DO_TRAIL(pt0, d0);
if (IsAttVar(pt0)) Yap_WakeUp(pt0);
bind_func_nvar3_var:
#endif
Bind(pt0, d0);
return(TRUE);
ENDP(pt0);
@ -748,12 +737,7 @@ p_functor( USES_REGS1 ) /* functor(?,?,?) */
}
/* else if arity is 0 just pass d0 through */
/* Ding, ding, we made it */
BIND(pt0, d0, bind_func_var_3nvar);
#ifdef COROUTINING
DO_TRAIL(pt0, d0);
if (IsAttVar(pt0)) Yap_WakeUp(pt0);
bind_func_var_3nvar:
#endif
Bind(pt0, d0);
return(TRUE);

111
C/unify.c
View File

@ -259,12 +259,7 @@ loop:
derefa_body(d1, ptd1, unify_comp_nvar_unk, unify_comp_nvar_nvar);
/* d1 and pt2 have the unbound value, whereas d0 is bound */
BIND_GLOBAL(ptd1, d0, bind_ocunify1);
#ifdef COROUTINING
DO_TRAIL(ptd1, d0);
if (IsAttVar(ptd1)) Yap_WakeUp(ptd1);
bind_ocunify1:
#endif
Bind_Global(ptd1, d0);
if (Yap_rational_tree_loop(ptd1-1, ptd1, (CELL **)to_visit, (CELL **)unif))
goto cufail;
continue;
@ -282,12 +277,7 @@ loop:
deref_head(d1, unify_comp_var_unk);
unify_comp_var_nvar:
/* pt2 is unbound and d1 is bound */
BIND_GLOBAL(ptd0, d1, bind_ocunify2);
#ifdef COROUTINING
DO_TRAIL(ptd0, d1);
if (IsAttVar(ptd0)) Yap_WakeUp(ptd0);
bind_ocunify2:
#endif
Bind_Global(ptd0, d1);
if (Yap_rational_tree_loop(ptd0-1, ptd0, (CELL **)to_visit, (CELL **)unif))
goto cufail;
continue;
@ -403,12 +393,7 @@ oc_unify_nvar_nvar:
deref_body(d1, pt1, oc_unify_nvar_unk, oc_unify_nvar_nvar);
/* d0 is bound and d1 is unbound */
BIND(pt1, d0, bind_ocunify4);
#ifdef COROUTINING
DO_TRAIL(pt1, d0);
if (IsAttVar(pt1)) Yap_WakeUp(pt1);
bind_ocunify4:
#endif
Bind(pt1, d0);
/* local variables cannot be in a term */
if (pt1 > H && pt1 < LCL0)
return TRUE;
@ -421,12 +406,7 @@ oc_unify_nvar_nvar:
deref_head(d1, oc_unify_var_unk);
oc_unify_var_nvar:
/* pt0 is unbound and d1 is bound */
BIND(pt0, d1, bind_ocunify5);
#ifdef COROUTINING
DO_TRAIL(pt0, d1);
if (IsAttVar(pt0)) Yap_WakeUp(pt0);
bind_ocunify5:
#endif
Bind(pt0, d1);
/* local variables cannot be in a term */
if (pt0 > H && pt0 < LCL0)
return TRUE;
@ -436,20 +416,8 @@ oc_unify_var_nvar:
deref_body(d1, pt1, oc_unify_var_unk, oc_unify_var_nvar);
/* d0 and pt1 are unbound */
UnifyCells(pt0, pt1, uc1, uc2);
#ifdef COROUTINING
DO_TRAIL(pt0, (CELL)pt1);
if (IsAttVar(pt0)) Yap_WakeUp(pt0);
uc1:
#endif
UnifyCells(pt0, pt1);
return (TRUE);
#ifdef COROUTINING
uc2:
DO_TRAIL(pt1, (CELL)pt0);
if (IsAttVar(pt1)) {
Yap_WakeUp(pt1);
}
#endif
return (TRUE);
}
@ -551,12 +519,7 @@ unify_nvar_nvar:
deref_body(d1, pt1, unify_nvar_unk, unify_nvar_nvar);
/* d0 is bound and d1 is unbound */
BIND(pt1, d0, bind_unify3);
#ifdef COROUTINING
DO_TRAIL(pt1, d0);
if (IsAttVar(pt1)) Yap_WakeUp(pt1);
bind_unify3:
#endif
Bind(pt1, d0);
return (TRUE);
deref_body(d0, pt0, unify_unk, unify_nvar);
@ -564,12 +527,7 @@ unify_nvar_nvar:
deref_head(d1, unify_var_unk);
unify_var_nvar:
/* pt0 is unbound and d1 is bound */
BIND(pt0, d1, bind_unify4);
#ifdef COROUTINING
DO_TRAIL(pt0, d1);
if (IsAttVar(pt0)) Yap_WakeUp(pt0);
bind_unify4:
#endif
Bind(pt0, d1);
return TRUE;
#if TRAILING_REQUIRES_BRANCH
@ -580,21 +538,9 @@ unify_var_nvar_trail:
deref_body(d1, pt1, unify_var_unk, unify_var_nvar);
/* d0 and pt1 are unbound */
UnifyCells(pt0, pt1, uc1, uc2);
#ifdef COROUTINING
DO_TRAIL(pt0, (CELL)pt1);
if (IsAttVar(pt0)) Yap_WakeUp(pt0);
uc1:
#endif
UnifyCells(pt0, pt1);
return (TRUE);
#ifdef COROUTINING
uc2:
DO_TRAIL(pt1, (CELL)pt0);
if (IsAttVar(pt1)) {
Yap_WakeUp(pt1);
}
return (TRUE);
#endif
#if THREADS
#undef Yap_REGS
#define Yap_REGS (*Yap_regp)
@ -661,9 +607,9 @@ InitReverseLookupOpcode(void)
#define UnifiableGlobalCells(a, b) \
if((a) > (b)) { \
BIND_GLOBALCELL_NONATT((a),(CELL)(b)); \
Bind_Global_NonAtt((a),(CELL)(b)); \
} else if((a) < (b)){ \
BIND_GLOBALCELL_NONATT((b),(CELL) (a)); \
Bind_Global_NonAtt((b),(CELL) (a)); \
}
static int
@ -790,11 +736,7 @@ loop:
derefa_body(d1, ptd1, unifiable_comp_nvar_unk, unifiable_comp_nvar_nvar);
/* d1 and pt2 have the unbound value, whereas d0 is bound */
BIND(ptd1, d0, bind_unifiable3);
#ifdef COROUTINING
DO_TRAIL(ptd1, d0);
bind_unifiable3:
#endif
Bind(ptd1, d0);
continue;
}
@ -810,11 +752,7 @@ loop:
deref_head(d1, unifiable_comp_var_unk);
unifiable_comp_var_nvar:
/* pt2 is unbound and d1 is bound */
BIND(ptd0, d1, bind_unifiable4);
#ifdef COROUTINING
DO_TRAIL(ptd0, d1);
bind_unifiable4:
#endif
Bind(ptd0, d1);
continue;
derefa_body(d1, ptd1, unifiable_comp_var_unk, unifiable_comp_var_nvar);
@ -941,11 +879,7 @@ unifiable_nvar_nvar:
deref_body(d1, pt1, unifiable_nvar_unk, unifiable_nvar_nvar);
/* d0 is bound and d1 is unbound */
BIND(pt1, d0, bind_unifiable3);
#ifdef COROUTINING
DO_TRAIL(pt1, d0);
bind_unifiable3:
#endif
Bind(pt1, d0);
return (TRUE);
deref_body(d0, pt0, unifiable_unk, unifiable_nvar);
@ -953,11 +887,7 @@ unifiable_nvar_nvar:
deref_head(d1, unifiable_var_unk);
unifiable_var_nvar:
/* pt0 is unbound and d1 is bound */
BIND(pt0, d1, bind_unifiable4);
#ifdef COROUTINING
DO_TRAIL(pt0, d1);
bind_unifiable4:
#endif
Bind(pt0, d1);
return TRUE;
#if TRAILING_REQUIRES_BRANCH
@ -968,17 +898,8 @@ unifiable_var_nvar_trail:
deref_body(d1, pt1, unifiable_var_unk, unifiable_var_nvar);
/* d0 and pt1 are unbound */
UnifyCells(pt0, pt1, uc1, uc2);
#ifdef COROUTINING
DO_TRAIL(pt0, (CELL)pt1);
uc1:
#endif
UnifyCells(pt0, pt1);
return (TRUE);
#ifdef COROUTINING
uc2:
DO_TRAIL(pt1, (CELL)pt0);
return (TRUE);
#endif
#if THREADS
#undef Yap_REGS
#define Yap_REGS (*Yap_regp)

View File

@ -79,9 +79,6 @@ copy_complex_term(CELL *pt0, CELL *pt0_end, int share, int newattvs, CELL *ptf,
CELL *HB0 = HB;
tr_fr_ptr TR0 = TR;
int ground = TRUE;
#ifdef COROUTINING
CELL *dvarsmin = NULL, *dvarsmax=NULL;
#endif
HB = HLow;
to_visit0 = to_visit;
@ -238,32 +235,22 @@ copy_complex_term(CELL *pt0, CELL *pt0_end, int share, int newattvs, CELL *ptf,
if (ptd0 >= HLow && ptd0 < H) {
/* we have already found this cell */
*ptf++ = (CELL) ptd0;
} else {
} else
#if COROUTINING
if (newattvs && IsAttachedTerm((CELL)ptd0)) {
/* if unbound, call the standard copy term routine */
struct cp_frame *bp;
CELL new;
if (IN_BETWEEN(dvarsmin, ptd0, dvarsmax)) {
*ptf++ = (CELL) ptd0;
} else {
CELL new;
bp = to_visit;
if (!attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) {
goto overflow;
}
to_visit = bp;
new = *ptf;
Bind(ptd0, new);
if (dvarsmin == NULL) {
dvarsmin = CellPtr(new);
} else {
*dvarsmax = (CELL)(CellPtr(new)+1);
}
dvarsmax = CellPtr(new)+1;
ptf++;
bp = to_visit;
if (!attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) {
goto overflow;
}
to_visit = bp;
new = *ptf;
Bind_NonAtt(ptd0, new);
ptf++;
} else {
#endif
/* first time we met this term */
@ -274,12 +261,11 @@ copy_complex_term(CELL *pt0, CELL *pt0_end, int share, int newattvs, CELL *ptf,
goto trail_overflow;
}
}
Bind(ptd0, (CELL)ptf);
Bind_NonAtt(ptd0, (CELL)ptf);
ptf++;
#ifdef COROUTINING
}
#endif
}
#endif
}
/* Do we still have compound terms to visit */
if (to_visit > to_visit0) {
@ -307,7 +293,6 @@ copy_complex_term(CELL *pt0, CELL *pt0_end, int share, int newattvs, CELL *ptf,
/* restore our nice, friendly, term to its original state */
clean_dirty_tr(TR0 PASS_REGS);
close_attvar_chain(dvarsmin, dvarsmax);
HB = HB0;
return ground;
@ -328,7 +313,6 @@ copy_complex_term(CELL *pt0, CELL *pt0_end, int share, int newattvs, CELL *ptf,
#endif
reset_trail(TR0);
/* follow chain of multi-assigned variables */
reset_attvars(dvarsmin, dvarsmax);
return -1;
trail_overflow:
@ -349,7 +333,6 @@ trail_overflow:
{
tr_fr_ptr oTR = TR;
reset_trail(TR0);
reset_attvars(dvarsmin, dvarsmax);
if (!Yap_growtrail((oTR-TR0)*sizeof(tr_fr_ptr *), TRUE)) {
return -4;
}
@ -372,7 +355,6 @@ trail_overflow:
}
#endif
reset_trail(TR0);
reset_attvars(dvarsmin, dvarsmax);
Yap_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0;
return -3;
}
@ -1265,9 +1247,6 @@ export_complex_term(Term tf, CELL *pt0, CELL *pt0_end, char * buf, size_t len0,
CELL *HB0 = HB;
tr_fr_ptr TR0 = TR;
int ground = TRUE;
#ifdef COROUTINING
CELL *dvarsmin = NULL, *dvarsmax=NULL;
#endif
char *bptr = buf+ 3*sizeof(CELL);
size_t len = len0;
@ -1418,26 +1397,16 @@ export_complex_term(Term tf, CELL *pt0, CELL *pt0_end, char * buf, size_t len0,
/* if unbound, call the standard export term routine */
struct cp_frame *bp;
if (IN_BETWEEN(dvarsmin, ptd0, dvarsmax)) {
*ptf++ = (CELL) ptd0;
} else {
CELL new;
CELL new;
bp = to_visit;
if (!attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) {
goto overflow;
}
to_visit = bp;
new = *ptf;
Bind(ptd0, new);
if (dvarsmin == NULL) {
dvarsmin = CellPtr(new);
} else {
*dvarsmax = (CELL)(CellPtr(new)+1);
}
dvarsmax = CellPtr(new)+1;
ptf++;
bp = to_visit;
if (!attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) {
goto overflow;
}
to_visit = bp;
new = *ptf;
Bind_NonAtt(ptd0, new);
ptf++;
} else {
#endif
/* first time we met this term */
@ -1448,7 +1417,7 @@ export_complex_term(Term tf, CELL *pt0, CELL *pt0_end, char * buf, size_t len0,
goto trail_overflow;
}
}
Bind(ptd0, (CELL)ptf);
Bind_NonAtt(ptd0, (CELL)ptf);
ptf++;
#ifdef COROUTINING
}
@ -1470,7 +1439,6 @@ export_complex_term(Term tf, CELL *pt0, CELL *pt0_end, char * buf, size_t len0,
/* restore our nice, friendly, term to its original state */
clean_dirty_tr(TR0 PASS_REGS);
close_attvar_chain(dvarsmin, dvarsmax);
HB = HB0;
return export_term_to_buffer(tf, buf, bptr, HLow, H, len0);
@ -1491,7 +1459,6 @@ export_complex_term(Term tf, CELL *pt0, CELL *pt0_end, char * buf, size_t len0,
#endif
reset_trail(TR0);
/* follow chain of multi-assigned variables */
reset_attvars(dvarsmin, dvarsmax);
return -1;
trail_overflow:
@ -1512,7 +1479,6 @@ trail_overflow:
{
tr_fr_ptr oTR = TR;
reset_trail(TR0);
reset_attvars(dvarsmin, dvarsmax);
if (!Yap_growtrail((oTR-TR0)*sizeof(tr_fr_ptr *), TRUE)) {
return -4;
}
@ -1535,7 +1501,6 @@ trail_overflow:
}
#endif
reset_trail(TR0);
reset_attvars(dvarsmin, dvarsmax);
Yap_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0;
return -3;
}

View File

@ -67,6 +67,13 @@ IsAttVar (CELL *pt)
return (pt)[-1] == (CELL)attvar_e && pt < H;
}
inline EXTERN int
FastIsAttVar (CELL *pt)
{
CACHE_REGS
return (pt)[-1] == (CELL)attvar_e;
}
typedef enum
{
BIG_INT = 0x01,
@ -507,6 +514,14 @@ IsAttachedTerm (Term t)
return (Int) ((IsVarTerm (t) && IsAttVar(VarOfTerm(t))));
}
inline EXTERN Int IsAttachedTerm (Term);
inline EXTERN Int
FastIsAttachedTerm (Term t)
{
return (Int) ((IsVarTerm (t) && FastIsAttVar(VarOfTerm(t))));
}

View File

@ -972,57 +972,39 @@ Macros to check the limits of stacks
* *
**********************************************************************/
#ifdef COROUTINING
#define UnifyCells(a, b, l1, l2) \
if((a) > (b)) { \
if ((a)<=H) { BIND_GLOBAL((a),(CELL)(b),l1); } \
else if ((b)<= H) { Bind_Local((a),(CELL)(b)); goto l1;} \
else { Bind_Local((b),(CELL) (a)); goto l1;} \
} else if((a) < (b)){ \
if((b) <= H) { BIND_GLOBAL2((b),(CELL) (a),l2,l1); } \
else if ((a) <= H) { Bind_Local((b),(CELL) (a)); goto l1;} \
else { Bind_Local((a),(CELL) (b)); goto l1;} \
} else goto l1;
/* I know (a) <= H */
#define UnifyGlobalRegCells(a, b, l1, l2) \
if((a) > (b)) { \
BIND_GLOBAL((a),(CELL)(b),l1); \
} else if((a) < (b)){ \
if((b) <= H) { BIND_GLOBAL2((b),(CELL) (a),l2,l1); } \
Bind_Local((b),(CELL) (a)); \
goto l1; \
} else goto l1;
#else
#define UnifyCells(a, b, l1, l2) \
if((a) > (b)) { \
if ((a)<=H) { BIND_GLOBAL((a),(CELL)(b),l1); } \
else if ((b)<= H) { Bind_Local((a),(CELL)(b)); } \
else { Bind_Local((b),(CELL) (a)); } \
} else if((a) < (b)){ \
if((b) <= H) { BIND_GLOBAL2((b),(CELL) (a),l2,l1); } \
else if ((a) <= H) { Bind_Local((b),(CELL) (a)); } \
else { Bind_Local((a),(CELL) (b)); } \
}
/* I know (a) <= H */
#define UnifyGlobalRegCells(a, b, l1, l2) \
if((a) > (b)) { \
BIND_GLOBAL((a),(CELL)(b),l1); \
} else if((a) < (b)){ \
if((b) <= H) { BIND_GLOBAL2((b),(CELL) (a),l2,l1); } \
Bind_Local((b),(CELL) (a)); \
}
#endif
#define UnifyGlobalCells(a, b) \
if((a) > (b)) { \
BIND_GLOBALCELL((a),(CELL)(b)); \
} else if((a) < (b)){ \
BIND_GLOBALCELL((b),(CELL) (a)); \
}
if ((b) > (a)) { \
if (FastIsAttVar(b) && !FastIsAttVar(a)) { \
Bind_Global((a),(CELL)(b)); \
} else { \
Bind_Global((b),(CELL)(a)); \
} \
} else if ((b) < (a)) { \
if (FastIsAttVar(a) && !FastIsAttVar(b)) { \
Bind_Global((b),(CELL)(a)); \
} else { \
Bind_Global((a),(CELL)(b)); \
} \
}
#define UnifyGlobalCellToCell(b, a) \
if ((a) < H) { /* two globals */ \
UnifyGlobalCells(a,b); \
} else { \
Bind_Local((a),(CELL)(b)); \
}
#define UnifyCells(a, b) \
if ((a) < H) { /* at least one global */ \
if ((b) > H) { Bind_Local((b),(CELL)(a)); } \
else { UnifyGlobalCells(a,b); } \
} else { \
if ((b) > (a)) { Bind_Local((a),(CELL)(b)); } \
else if ((a) > (b)) { \
if ((b) < H) { Bind_Local((a),(CELL)(b)); } \
else { Bind_Local((b),(CELL)(a)); } \
} \
}
/* unify two complex terms.
*
@ -1236,7 +1218,8 @@ loop:
derefa_body(d1, ptd1, unify_comp_nvar_unk, unify_comp_nvar_nvar);
/* d1 and pt2 have the unbound value, whereas d0 is bound */
BIND_GLOBALCELL(ptd1, d0);
Bind_Global(ptd1, d0);
continue;
}
derefa_body(d0, ptd0, unify_comp_unk, unify_comp_nvar);
@ -1251,7 +1234,8 @@ loop:
deref_head(d1, unify_comp_var_unk);
unify_comp_var_nvar:
/* pt2 is unbound and d1 is bound */
BIND_GLOBALCELL(ptd0, d1);
Bind_Global(ptd0, d1);
continue;
derefa_body(d1, ptd1, unify_comp_var_unk, unify_comp_var_nvar);
/* ptd0 and ptd1 are unbound */
@ -1585,10 +1569,14 @@ prune(choiceptr cp)
}
}
#define SET_ASP(Y,S) SET_ASP__(Y,S PASS_REGS)
static inline
void SET_ASP(CELL *yreg, Int sz) {
CACHE_REGS
void SET_ASP__(CELL *yreg, Int sz USES_REGS) {
ASP = (CELL *) (((char *) yreg) + sz);
if (ASP > (CELL *)PROTECT_FROZEN_B(B))
ASP = (CELL *)PROTECT_FROZEN_B(B);
}

View File

@ -151,50 +151,12 @@ AlignGlobalForDouble( USES_REGS1 )
if ((TERM) > (CELL *)B || (TERM) > (CELL *)B_FZ) \
DO_TRAIL(TERM, VAL)
#ifdef TERM_EXTENSIONS
#define Trail(TERM, VAL, LAB) \
if (IN_BETWEEN(HBREG,TERM,B) && \
((TERM) < (CELL *)B_FZ)) \
goto LAB
#define TrailAndJump(TERM, VAL) \
if (IN_BETWEEN(HBREG,TERM,B) && \
((TERM) < (CELL *)B_FZ)) \
GONext();
#else
#define Trail(TERM, VAL, LAB) \
TRAIL(TERM, VAL)
#define Trail(TERM, VAL, LAB) \
TRAIL_AND_JUMP(TERM, VAL)
#endif
#else /* BBREG_TRAIL_SCHEME */
#define TRAIL(TERM, VAL) \
if (OUTSIDE(HBREG,TERM,BBREG)) \
DO_TRAIL(TERM, VAL)
#ifdef TERM_EXTENSIONS
#define Trail(TERM, VAL, LAB) \
if (IN_BETWEEN(HBREG,TERM,BBREG)) \
goto LAB
#define TrailAndJump(TERM, VAL) \
if (IN_BETWEEN(HBREG,TERM,BBREG)) \
GONext();
#else
#define Trail(TERM, VAL, LAB) \
TRAIL(TERM, VAL)
#define TrailAndJump(TERM, VAL) \
TRAIL_AND_JUMP(TERM, VAL)
#endif
#define TRAIL_LOCAL(TERM, VAL) \
if ((TERM) > (CELL *)BBREG) DO_TRAIL(TERM, VAL)
@ -205,14 +167,6 @@ AlignGlobalForDouble( USES_REGS1 )
#define TRAIL_GLOBAL(TERM, VAL) \
if ((TERM) < HBREG) DO_TRAIL(TERM, VAL)
#ifdef TERM_EXTENSIONS
#define Trail_Global(TERM, VAL, LAB) \
if ((TERM) >= HBREG) goto LAB
#else
#define Trail_Global(TERM, VAL, LAB) \
TRAIL_GLOBAL(TERM, VAL)
#endif
#define DO_MATRAIL(TERM, OLDVAL, NEWVAL) \
{ \
register tr_fr_ptr r = TR; \
@ -241,15 +195,8 @@ AlignGlobalForDouble( USES_REGS1 )
#define TRAIL(A,D) if (OUTSIDE(HBREG,A,B)) \
DO_TRAIL(A,D);
#define TRAIL_AND_JUMP(A,D) if (!OUTSIDE(HBREG,A,B)) GONext(); \
DO_TRAIL(A,D);
#define Trail(A, D, LAB) TRAIL(A,D)
#define TRAIL_GLOBAL(A,D) if ((A) < HBREG) DO_TRAIL(A,D);
#define Trail_Global(A,D,LAB) if ((A) < HBREG) DO_TRAIL(A,D);
#define TRAIL_LOCAL(A,D) if ((A) > (CELL *)B) DO_TRAIL(A,D);
@ -265,12 +212,8 @@ AlignGlobalForDouble( USES_REGS1 )
if (!OUTSIDE(HBREG,A,B)) \
GONext();
#define Trail(A,D,LAB) TRAIL(A,D)
#define TRAIL_GLOBAL(A,D) TR[0] = (CELL)(A); if ((A) < HBREG) TR++
#define Trail_Global(A,D,LAB) TRAIL_GLOBAL(A,D)
#define TRAIL_LOCAL(A,D) TR[0] = (CELL)(A); if ((A) > ((CELL *)(B))) TR++
#elif !defined(TERM_EXTENSIONS)
@ -283,14 +226,8 @@ AlignGlobalForDouble( USES_REGS1 )
#define TRAIL_AND_JUMP(A,D) if (IN_BETWEEN(HBREG,A,B)) GONext(); \
DO_TRAIL(A,D)
#define Trail(A,D,LAB) TRAIL(A,D)
#define TRAIL_GLOBAL(A,D) if ((A) < HBREG) DO_TRAIL(A,D)
#define Trail_Global(A,D,LAB) TRAIL_GLOBAL(A,D)
#define Trail_Global2(A,D,LAB) TRAIL_GLOBAL(A,D)
#define TRAIL_LOCAL(A,D) if ((A) > ((CELL *)B)) DO_TRAIL(A,D)
#else
@ -300,18 +237,11 @@ AlignGlobalForDouble( USES_REGS1 )
#define TRAIL(A,D) if (OUTSIDE(HBREG,A,B)) \
DO_TRAIL(A,D)
#define Trail(A,D,LAB) if (IN_BETWEEN(HBREG,A,B)) \
goto LAB
#define TrailAndJump(A,D) if (IN_BETWEEN(HBREG,A,B)) \
GONext();
#define TRAIL_GLOBAL(A,D) if ((A) < HBREG) DO_TRAIL(A,D)
#define Trail_Global(A,D,LAB) if ((A) >= HBREG) goto LAB
#define Trail_Global2(A,D,LAB) if ((A) < HBREG) goto LAB
#define TRAIL_LOCAL(A,D) if ((A) > ((CELL *)B)) DO_TRAIL(A,D)
#endif
@ -342,61 +272,19 @@ Binding Macros for Multiple Assignment Variables.
#define TRAIL_LINK(REF) TrailTerm(TR++) = AbsPair((CELL *)(REF))
#define TRAIL_FRAME(FR) DO_TRAIL(AbsPair((CELL *)(Yap_TrailBase)), FR)
#define Bind(A,D) TRAIL(A,D); *(A) = (D)
#define Bind_Global(A,D) TRAIL_GLOBAL(A,D); *(A) = (D)
#define Bind_and_Trail(A,D) DO_TRAIL(A,D); *(A) = (D)
#define BIND(A,D,L) *(A) = (D); Trail(A,D,L)
#define BIND_AND_JUMP(A,D) *(A) = (D); TrailAndJump(A,D)
#define BIND_GLOBAL(A,D,L) *(A) = (D); Trail_Global(A,D,L)
extern void Yap_WakeUp(CELL *v);
#ifdef COROUTINING
#define BIND_GLOBAL2(A,D,LAB,LAB1) *(A) = (D); if ((A) < HBREG) goto LAB; goto LAB1
#define BIND_GLOBALCELL(A,D) *(A) = (D); \
if ((A) >= HBREG) continue; \
TRAIL_GLOBAL(A,D); if (!IsAttVar(A)) continue; \
Yap_WakeUp((A)); continue
#define BIND_GLOBALCELL_NONATT(A,D) *(A) = (D); \
if ((A) >= HBREG) continue; \
TRAIL_GLOBAL(A,D);
#else
#define BIND_GLOBAL2(A,D,LAB,LAB1) BIND_GLOBAL(A,D,LAB)
#define BIND_GLOBALCELL(A,D) BIND_GLOBAL(A,D,L); continue
#define BIND_GLOBALCELL_NONATT(A,D) BIND_GLOBALCELL; continue
#endif
#define Bind(A,D) { *(A) = (D); TRAIL(A,D); if (FastIsAttVar(A)) Yap_WakeUp(A); }
#define Bind_NonAtt(A,D) { *(A) = (D); TRAIL(A,D); }
#define Bind_Global(A,D) { *(A) = (D); TRAIL_GLOBAL(A,D); if (FastIsAttVar(A)) Yap_WakeUp(A); }
#define Bind_Global_NonAtt(A,D) { *(A) = (D); TRAIL_GLOBAL(A,D); }
#define Bind_and_Trail(A,D) { *(A) = (D); DO_TRAIL(A, D); }
#define Bind_Local(A,D) { TRAIL_LOCAL(A,D); *(A) = (D); }
#define MaBind(VP,D) { MATRAIL((VP),*(VP),(D)); *(VP) = (D); }
#if defined(__GNUC__) && defined(i386) && !defined(TERM_EXTENSIONS) && !defined(TABLING)
/* destroy d0 and pt0 */
#define DBIND(A,D,L) \
{ register CELL *t1=HBREG; \
__asm__("movl %4,(%0)\n\t" \
"movl %2,%4\n\t" \
"subl %1,%2\n\t" \
"subl %0,%4\n\t" \
"cmpl %2,%4\n\t" \
"jae 1f\n\t" \
"movl %3,%4\n\t" \
"movl %0,(%4)\n\t" \
"addl $4,%4\n\t" \
"movl %4,%3\n\t" \
"1:" \
: /* no outputs */ \
: "r" (A), "m" (B), "r" (t1), "m" (TR), "r" (D) ); \
}
#else
#define DBIND(A,D,L) BIND(A,D,L)
#endif
/************************************************************
Unification Routines
@ -535,12 +423,7 @@ Yap_unify_constant(register Term a, register Term cons)
}
deref_body(a,pt,unify_cons_unk,unify_cons_nonvar);
BIND(pt,cons,wake_for_cons);
#ifdef COROUTINING
DO_TRAIL(pt, cons);
if (IsAttVar(pt)) Yap_WakeUp(pt);
wake_for_cons:
#endif
Bind(pt,cons);
return(TRUE);
}