From d290885f8f6af4aa3b7aa0e113f0b9fb3f7e17d1 Mon Sep 17 00:00:00 2001 From: vsc Date: Wed, 30 Apr 2003 17:46:05 +0000 Subject: [PATCH] new indexing algorithm git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@822 b08c6af1-5177-4d33-ba66-4b1c6b8b522a --- C/absmi.c | 1197 +++------------ C/adtdefs.c | 4 +- C/amasm.c | 487 +++---- C/arith2.c | 3 +- C/cdmgr.c | 306 ++-- C/compiler.c | 70 - C/computils.c | 191 ++- C/dbase.c | 97 +- C/exec.c | 12 +- C/heapgc.c | 217 ++- C/index.c | 3764 ++++++++++++++++++++++++++++++++---------------- C/init.c | 36 +- C/save.c | 18 +- C/tracer.c | 3 +- H/Heap.h | 37 +- H/YapOpcodes.h | 24 +- H/absmi.h | 1 - H/amidefs.h | 38 +- H/clause.h | 107 +- H/compile.h | 37 +- H/index.h | 90 +- H/rheap.h | 153 +- m4/Yatom.h.m4 | 14 +- pl/arith.yap | 1 - pl/boot.yap | 4 +- 25 files changed, 3592 insertions(+), 3319 deletions(-) diff --git a/C/absmi.c b/C/absmi.c index 566f75657..c3f1de5f3 100644 --- a/C/absmi.c +++ b/C/absmi.c @@ -1079,7 +1079,7 @@ Yap_absmi(int inp) BOp(try_logical_pred, l); /* mark the indexing code */ { - Clause *cl = (Clause *)PREG->u.l.l; + LogUpdClause *cl = (LogUpdClause *)PREG->u.l.l; PREG = NEXTOP(PREG, l); LOCK(cl->ClLock); /* indicate the indexing code is being used */ @@ -1104,7 +1104,7 @@ Yap_absmi(int inp) /* unmark the indexing code */ /* mark the indexing code */ { - Clause *cl = (Clause *)PREG->u.l.l; + LogUpdClause *cl = (LogUpdClause *)PREG->u.l.l; PREG = NEXTOP(PREG, l); /* check if we are the ones using this code */ #if defined(YAPOR) || defined(THREADS) @@ -1113,12 +1113,12 @@ Yap_absmi(int inp) /* clear the entry from the trail */ TR = --(B->cp_tr); /* actually get rid of the code */ - if (!CL_IN_USE(cl) && cl->ClFlags & ErasedMask) { + if (cl->ref_count == 0 && cl->ClFlags & ErasedMask) { UNLOCK(cl->ClLock); /* I am the last one using this clause, hence I don't need a lock to dispose of it */ - Yap_ErCl(cl); + Yap_ErLogUpdCl(cl); } else { UNLOCK(cl->ClLock); } @@ -1130,7 +1130,7 @@ Yap_absmi(int inp) TR = --(B->cp_tr); /* next, recover space for the indexing code if it was erased */ if (cl->ClFlags & ErasedMask) { - Yap_ErCl(cl); + Yap_ErLogUpdCl(cl); } } #endif @@ -1144,7 +1144,7 @@ Yap_absmi(int inp) /* we have our own copy for the clause */ #if defined(YAPOR) || defined(THREADS) { - Clause *cl = (Clause *)PREG->u.EC.ClBase; + LogUpdClause *cl = (LogUpdClause *)PREG->u.EC.ClBase; LOCK(cl->ClLock); /* always add an extra reference */ @@ -1154,7 +1154,7 @@ Yap_absmi(int inp) } #else { - Clause *cl = (Clause *)PREG->u.EC.ClBase; + LogUpdClause *cl = (LogUpdClause *)PREG->u.EC.ClBase; if (!(cl->ClFlags |= InUseMask)) { /* Clause *cl = (Clause *)PREG->u.EC.ClBase; @@ -1223,14 +1223,14 @@ Yap_absmi(int inp) SET_BB(B_YREG); ENDCACHE_Y(); #if defined(YAPOR) || defined(THREADS) - INC_CLREF_COUNT(ClauseCodeToClause(PREG)); + INC_CLREF_COUNT(ClauseCodeToDynamicClause(PREG)); UNLOCK(DynamicLock(PREG)); - TRAIL_CLREF(ClauseCodeToClause(PREG)); + TRAIL_CLREF(ClauseCodeToDynamicClause(PREG)); #else if (FlagOff(InUseMask, DynamicFlags(PREG))) { SetFlag(InUseMask, DynamicFlags(PREG)); - TRAIL_CLREF(ClauseCodeToClause(PREG)); + TRAIL_CLREF(ClauseCodeToDynamicClause(PREG)); } #endif PREG = NEXTOP(PREG,ld); @@ -1285,14 +1285,14 @@ Yap_absmi(int inp) SET_BB(B_YREG); ENDCACHE_Y(); #if defined(YAPOR) || defined(THREADS) - INC_CLREF_COUNT(ClauseCodeToClause(PREG)); - TRAIL_CLREF(ClauseCodeToClause(PREG)); + INC_CLREF_COUNT(ClauseCodeToDynamicClause(PREG)); + TRAIL_CLREF(ClauseCodeToDynamicClause(PREG)); UNLOCK(DynamicLock(PREG)); #else if (FlagOff(InUseMask, DynamicFlags(PREG))) { SetFlag(InUseMask, DynamicFlags(PREG)); - TRAIL_CLREF(ClauseCodeToClause(PREG)); + TRAIL_CLREF(ClauseCodeToDynamicClause(PREG)); } #endif PREG = NEXTOP(PREG,ld); @@ -1395,7 +1395,7 @@ Yap_absmi(int inp) break; case _table_retry_me: case _table_trust_me: - low_level_trace(retry_pred, (PredEntry *)(PREG->u.lds.p), (CELL *)(((gen_cp_ptr)B)+1)); + low_level_trace(retry_pred, PREG->u.lds.p, (CELL *)(((gen_cp_ptr)B)+1)); break; #endif case _or_else: @@ -1403,15 +1403,11 @@ Yap_absmi(int inp) low_level_trace(retry_or, (PredEntry *)PREG, &(B->cp_a1)); break; case _trust_logical_pred: - low_level_trace(retry_pred, (PredEntry *)(NEXTOP(PREG,l)->u.ld.p), &(B->cp_a1)); - break; - case _switch_last: - case _switch_l_list: - low_level_trace(retry_pred, (PredEntry *)(PREG->u.slll.p), &(B->cp_a1)); + low_level_trace(retry_pred, NEXTOP(PREG,l)->u.ld.p, B->cp_args); break; case _retry_c: case _retry_userc: - low_level_trace(retry_pred, (PredEntry *)(PREG->u.lds.p), &(B->cp_a1)); + low_level_trace(retry_pred, PREG->u.lds.p, B->cp_args); break; case _retry_profiled: opnum = Yap_op_from_opcode(NEXTOP(B->cp_ap,l)->opc); @@ -1433,18 +1429,9 @@ Yap_absmi(int inp) case _retry_and_mark: case _profiled_retry_and_mark: case _retry: - case _trust_in: case _trust: - case _retry_first: - case _trust_first_in: - case _trust_first: - case _retry_tail: - case _trust_tail_in: - case _trust_tail: - case _retry_head: - case _trust_head_in: - case _trust_head: - low_level_trace(retry_pred, (PredEntry *)(PREG->u.ld.p), &(B->cp_a1)); + low_level_trace(retry_pred, PREG->u.ld.p, B->cp_args); + break; default: break; } @@ -1474,39 +1461,55 @@ Yap_absmi(int inp) #endif { register CELL flags; + CELL *pt0 = RepPair(d1); - d1 = (CELL) RepPair(d1); #ifdef FROZEN_STACKS /* TRAIL */ /* avoid frozen segments */ #ifdef SBA - if ((ADDR) d1 >= HeapTop) + if ((ADDR) pt0 >= HeapTop) #else - if ((ADDR) d1 >= Yap_TrailBase) + if ((ADDR) pt0 >= Yap_TrailBase) #endif { - pt0 = (tr_fr_ptr) d1; + pt0 = (tr_fr_ptr) pt0; goto failloop; } #endif /* FROZEN_STACKS */ - flags = Flags(d1); + flags = *pt0; #if defined(YAPOR) || defined(THREADS) if (!FlagOn(DBClMask, flags)) { - Clause *cl = ClauseFlagsToClause(d1); - int erase; - LOCK(cl->ClLock); - DEC_CLREF_COUNT(cl); - erase = (cl->ClFlags & ErasedMask) && (cl->ref_count == 0); - UNLOCK(cl->ClLock); - if (erase) { - saveregs(); - /* at this point, - we are the only ones accessing the clause, - hence we don't need to have a lock it */ - Yap_ErCl(cl); - setregs(); + if (flags & LogUpdMask) { + LogUpdClause *cl = ClauseFlagsToLogUpdClause(pt0); + int erase; + LOCK(cl->ClLock); + DEC_CLREF_COUNT(cl); + erase = (cl->ClFlags & ErasedMask) && (cl->ref_count == 0); + UNLOCK(cl->ClLock); + if (erase) { + saveregs(); + /* at this point, + we are the only ones accessing the clause, + hence we don't need to have a lock it */ + Yap_ErLogUpdCl(cl); + setregs(); + } else { + DynamicClause *cl = ClauseFlagsToDynamicClause(pt0); + int erase; + LOCK(cl->ClLock); + DEC_CLREF_COUNT(cl); + erase = (cl->ClFlags & ErasedMask) && (cl->ref_count == 0); + UNLOCK(cl->ClLock); + if (erase) { + saveregs(); + /* at this point, + we are the only ones accessing the clause, + hence we don't need to have a lock it */ + Yap_ErCl(cl); + setregs(); + } } } else { - DBRef dbr = DBStructFlagsToDBStruct(d1); + DBRef dbr = DBStructFlagsToDBStruct(pt0); int erase; LOCK(dbr->lock); @@ -1521,22 +1524,19 @@ Yap_absmi(int inp) } #else ResetFlag(InUseMask, flags); - Flags(d1) = flags; - /* vsc??? if (FlagOn(StaticMask, flags)) { - if (FlagOff(SpiedMask, flags)) { - PredCode(d1) = TruePredCode(d1); - } - } - else - */ + *pt0 = flags; if (FlagOn(ErasedMask, flags)) { if (FlagOn(DBClMask, flags)) { saveregs(); - Yap_ErDBE(DBStructFlagsToDBStruct(d1)); + Yap_ErDBE(DBStructFlagsToDBStruct(pt0)); setregs(); } else { saveregs(); - Yap_ErCl(ClauseFlagsToClause(d1)); + if (flags & LogUpdMask) { + Yap_ErLogUpdCl(ClauseFlagsToLogUpdClause(pt0)); + } else { + Yap_ErCl(ClauseFlagsToDynamicClause(pt0)); + } setregs(); } } @@ -6257,7 +6257,7 @@ Yap_absmi(int inp) /* Point AP to the code that follows this instruction */ store_at_least_one_arg(PREG->u.ld.s); store_yaam_regs(NEXTOP(PREG, ld), 0); - PREG = (yamop *) (PREG->u.ld.d); + PREG = PREG->u.ld.d; set_cut(S_YREG, B); B = B_YREG; #ifdef YAPOR @@ -6268,19 +6268,6 @@ Yap_absmi(int inp) JMPNext(); ENDBOp(); - /* do a jump, but make sure the alternative pointer is set to - point to the next instruction */ - BOp(try_in, l); -#ifdef YAPOR - if (SCH_top_shared_cp(B)) { - SCH_new_alternative(PREG, NEXTOP(PREG,l)); - } else -#endif /* YAPOR */ - B->cp_ap = NEXTOP(PREG,l); - PREG = (yamop *) (PREG->u.l.l); - JMPNext(); - ENDBOp(); - BOp(retry, ld); CACHE_Y(B); restore_yaam_regs(NEXTOP(PREG, ld)); @@ -6293,23 +6280,7 @@ Yap_absmi(int inp) #endif /* FROZEN_STACKS */ SET_BB(B_YREG); ENDCACHE_Y(); - PREG = (yamop *) (PREG->u.ld.d); - JMPNext(); - ENDBOp(); - - BOp(trust_in, ldl); - CACHE_Y(B); - restore_yaam_regs(PREG->u.ldl.bl); - restore_at_least_one_arg(PREG->u.ldl.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); - set_cut(S_YREG, B->cp_b); -#else - set_cut(S_YREG, B_YREG->cp_b); -#endif /* FROZEN_STACKS */ - SET_BB(B_YREG); - ENDCACHE_Y(); - PREG = (yamop *) (PREG->u.ldl.d); + PREG = PREG->u.ld.d; JMPNext(); ENDBOp(); @@ -6336,639 +6307,17 @@ Yap_absmi(int inp) } SET_BB(B_YREG); ENDCACHE_Y(); - PREG = (yamop *) (PREG->u.ld.d); + PREG = PREG->u.ld.d; JMPNext(); ENDBOp(); - -/************************************************************************\ -* retry_first and trust_first go straight to the first arg. * -\************************************************************************/ - /* relies on an extra S */ - BOp(retry_first, ld); - CACHE_Y(B); - restore_yaam_regs(NEXTOP(PREG, ld)); - restore_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); - set_cut(S_YREG, B->cp_b); -#else - set_cut(S_YREG, B_YREG->cp_b); -#endif /* FROZEN_STACKS */ - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - d0 = ARG1; - /* der it first */ - PREG = (yamop *) (PREG->u.ld.d); - deref_head(d0,retry_first_unk); - retry_first_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0); - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0,"argument to retry_first is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - SREG = RepAppl(d0)+1; - JMPNext(); - } - - BEGP(pt0); - deref_body(d0, pt0, retry_first_unk, retry_first_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "unbound argument to retry_first"); - setregs(); + BOp(try_in, l); + B->cp_ap = NEXTOP(PREG, l); + PREG = PREG->u.l.l; JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); ENDBOp(); - /* just like retry_first, but set B->cp_ap to point to the - beginning of the next group */ - BOp(trust_first_in, ldl); - CACHE_Y(B); - restore_yaam_regs(PREG->u.ldl.bl); - restore_at_least_one_arg(PREG->u.ldl.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); - set_cut(S_YREG, B->cp_b); -#else - set_cut(S_YREG, B_YREG->cp_b); -#endif /* FROZEN_STACKS */ - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - d0 = ARG1; - /* deref it first */ - PREG = (yamop *) (PREG->u.lds.f); - deref_head(d0,trust_first_in_unk); - trust_first_in_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0); - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "argument to trust_first_in is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - SREG = RepAppl(d0)+1; - JMPNext(); - } - - BEGP(pt0); - deref_body(d0, pt0, trust_first_in_unk, trust_first_in_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, d0,"unbound argument to trust_first_in"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - /* recover S and avoid doing a get_list or get_struct */ - BOp(trust_first, ld); - CACHE_Y(B); -#ifdef YAPOR - if (SCH_top_shared_cp(B)) { - SCH_last_alternative(PREG, B_YREG); - restore_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); -#endif /* FROZEN_STACKS */ - set_cut(S_YREG, B->cp_b); - } - else -#endif /* YAPOR */ - { - pop_yaam_regs(); - pop_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); -#endif /* FROZEN_STACKS */ - set_cut(S_YREG, B); - } - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - d0 = ARG1; - /* deref it first */ - PREG = (yamop *) (PREG->u.ld.d); - deref_head(d0,trust_first_unk); - trust_first_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0); - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR,d0,"argument to trust_first is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - SREG = RepAppl(d0)+1; - JMPNext(); - } - - BEGP(pt0); - deref_body(d0, pt0, trust_first_unk, trust_first_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR,(CELL)pt0,"argument to trust_first is a variable"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - -/************************************************************************\ -* retry_tail and trust_tail go straight to the tail of a list * -\************************************************************************/ - - /* relies on an extra S */ - BOp(retry_tail, ld); - CACHE_Y(B); - restore_yaam_regs(NEXTOP(PREG, ld)); - restore_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); - set_cut(S_YREG, B->cp_b); -#else - set_cut(S_YREG, B_YREG->cp_b); -#endif /* FROZEN_STACKS */ - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - d0 = ARG1; - /* deref it first */ - deref_head(d0,retry_tail_unk); - retry_tail_nvar: - PREG = (yamop *) (PREG->u.ld.d); - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0)+1; - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR,d0,"argument to retry_tail is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ -#ifdef DEBUG - /* this should never happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR,d0,"argument to retry_tail is a compound term"); - setregs(); - JMPNext(); -#endif - } - - BEGP(pt0); - deref_body(d0, pt0, retry_tail_unk, retry_tail_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR,(CELL)pt0,"unbound argument to retry_tail"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - - /* just like retry_tail, but set B->cp_ap to point to the - beginning of the next group */ - BOp(trust_tail_in, ldl); - CACHE_Y(B); - restore_yaam_regs(PREG->u.ldl.bl); - restore_at_least_one_arg(PREG->u.ldl.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); - set_cut(S_YREG, B->cp_b); -#else - set_cut(S_YREG, B_YREG->cp_b); -#endif /* FROZEN_STACKS */ - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - d0 = ARG1; - /* deref it first */ - PREG = (yamop *) (PREG->u.lds.f); - deref_head(d0,trust_tail_in_unk); - trust_tail_in_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0)+1; - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "argument to trust_tail_in is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "argument to trust_tail_in is a compound term"); - setregs(); - JMPNext(); -#endif - } - - BEGP(pt0); - deref_body(d0, pt0, trust_tail_in_unk, trust_tail_in_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, (CELL)pt0, "unbound argument to trust_tail_in"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - /* recover S and avoid doing a get_list or get_struct */ - BOp(trust_tail, ld); - CACHE_Y(B); -#ifdef YAPOR - if (SCH_top_shared_cp(B)) { - SCH_last_alternative(PREG, B_YREG); - restore_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); -#endif /* FROZEN_STACKS */ - set_cut(S_YREG, B->cp_b); - } - else -#endif /* YAPOR */ - { - pop_yaam_regs(); - pop_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); -#endif /* FROZEN_STACKS */ - set_cut(S_YREG, B); - } - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - d0 = ARG1; - /* deref it first */ - PREG = (yamop *) (PREG->u.ld.d); - deref_head(d0,trust_tail_unk); - trust_tail_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0)+1; - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "argument to trust_tail is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ -#ifdef DEBUG - /* this should ever happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "argument to trust_tail is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } - - BEGP(pt0); - deref_body(d0, pt0, trust_tail_unk, trust_tail_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, (CELL)pt0, "unbound argument to trust_tail"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - -/************************************************************************\ -* retry_head and trust_head assume the first argument is known * -\************************************************************************/ - - /* retry an instruction, and avoid a get and unify */ - BOp(retry_head, ld); - CACHE_Y(B); - restore_yaam_regs(NEXTOP(PREG, ld)); - restore_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); - set_cut(S_YREG, B->cp_b); -#else - set_cut(S_YREG, B_YREG->cp_b); -#endif /* FROZEN_STACKS */ - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - BEGP(pt0); - d0 = ARG1; - /* deref it first */ - PREG = (yamop *) (PREG->u.ld.d); - deref_head(d0,retry_head_unk); - retry_head_nvar: - if (IsPairTerm(d0)) { - /* pair */ - pt0 = RepPair(d0); - /* get the head of the list or the first argument of the struct */ - d0 = *pt0; - inner_retry_head: - /* inform that we were reading a structure or list */ - SP[-1] = (CELL)(pt0+1); - SP[-2] = READ_MODE; - SP -= 2; - deref_head(d0,retry_head_first_unk); - retry_head_first_nvar: - if (IsPairTerm(d0)) { - SREG = RepPair(d0); - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "constant argument to retry_head"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - SREG = RepAppl(d0)+1; - JMPNext(); - } - - deref_body(d0, pt0, retry_head_first_unk, retry_head_first_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, (CELL)pt0, "unbound argument to retry_head"); - setregs(); - JMPNext(); - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "constant argument to retry_head"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - pt0 = RepAppl(d0)+1; - d0 = *pt0; - goto inner_retry_head; - } - - deref_body(d0, pt0, retry_head_unk, retry_head_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, (CELL)pt0, "unbound argument to retry_head"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - /* This is a retry head that closes a subblock */ - BOp(trust_head_in, ldl); - CACHE_Y(B); - restore_yaam_regs(PREG->u.ldl.bl); - restore_at_least_one_arg(PREG->u.ldl.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); - set_cut(S_YREG, B->cp_b); -#else - set_cut(S_YREG, B_YREG->cp_b); -#endif /* FROZEN_STACKS */ - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - BEGP(pt0); - d0 = ARG1; - /* deref it first */ - PREG = (yamop *) (PREG->u.ldl.d); - deref_head(d0,trust_head_in_unk); - trust_head_in_nvar: - if (IsPairTerm(d0)) { - /* pair */ - pt0 = RepPair(d0); - /* get the head of the list or the first argument of the struct */ - d0 = *pt0; - inner_trust_head_in: - /* inform that we were reading a structure or list */ - SP[-1] = (CELL)(pt0+1); - SP[-2] = READ_MODE; - SP -= 2; - deref_head(d0,trust_head_in_first_unk); - trust_head_in_first_nvar: - if (IsPairTerm(d0)) { - SREG = RepPair(d0); - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "head of argument to trust_head_in is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - SREG = RepAppl(d0)+1; - JMPNext(); - } - - deref_body(d0, pt0, trust_head_in_first_unk, trust_head_in_first_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "head of argument to trust_head_in is unbound"); - setregs(); - JMPNext(); - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "argument to trust_head_in is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - pt0 = RepAppl(d0)+1; - d0 = *pt0; - goto inner_trust_head_in; - } - - deref_body(d0, pt0, trust_head_in_unk, trust_head_in_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "unbound argument to trust_head_in"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - - BOp(trust_head, ld); - CACHE_Y(B); -#ifdef YAPOR - if (SCH_top_shared_cp(B)) { - SCH_last_alternative(PREG, B_YREG); - restore_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); -#endif /* FROZEN_STACKS */ - set_cut(S_YREG, B->cp_b); - } - else -#endif /* YAPOR */ - { - pop_yaam_regs(); - pop_at_least_one_arg(PREG->u.ld.s); -#ifdef FROZEN_STACKS - B_YREG = PROTECT_FROZEN_B(B_YREG); -#endif /* FROZEN_STACKS */ - set_cut(S_YREG, B); - } - SET_BB(B_YREG); - ENDCACHE_Y(); - /* recover the value of SREG */ - BEGD(d0); - BEGP(pt0); - d0 = ARG1; - /* deref it first */ - PREG = (yamop *) (PREG->u.ld.d); - deref_head(d0,trust_head_unk); - trust_head_nvar: - if (IsPairTerm(d0)) { - /* pair */ - pt0 = RepPair(d0); - /* get the head of the list or the first argument of the struct */ - d0 = *pt0; - inner_trust_head: - /* inform that we were reading a structure or list */ - SP[-1] = (CELL)(pt0+1); - SP[-2] = READ_MODE; - SP -= 2; - deref_head(d0,trust_head_first_unk); - trust_head_first_nvar: - if (IsPairTerm(d0)) { - SREG = RepPair(d0); - JMPNext(); -#ifdef DEBUG - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "head of argument to trust_head is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - SREG = RepAppl(d0)+1; - JMPNext(); - } - - deref_body(d0, pt0, trust_head_first_unk, trust_head_first_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "unbound head of argument to trust_head"); - setregs(); - JMPNext(); - } else if (!IsApplTerm(d0)) { - /* this should not happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "argument to trust_head is a constant"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - } else { - /* appl */ - /* pair */ - pt0 = RepAppl(d0)+1; - d0 = *pt0; - goto inner_trust_head; - } - - deref_body(d0, pt0, trust_head_unk, trust_head_nvar); - /* this should never happen */ -#ifdef DEBUG - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "unbound argument to trust_head"); - setregs(); - JMPNext(); -#endif /* DEBUG */ - ENDP(pt0); - ENDD(d0); - ENDBOp(); - /************************************************************************\ * Indexing in ARG1 * @@ -6983,18 +6332,18 @@ Yap_absmi(int inp) if (IsPairTerm(d0)) { /* pair */ SREG = RepPair(d0); - PREG = (yamop *) (PREG->u.llll.l1); + PREG = PREG->u.llll.l1; JMPNext(); } else if (!IsApplTerm(d0)) { /* constant */ - PREG = (yamop *) (PREG->u.llll.l2); + PREG = PREG->u.llll.l2; I_R = d0; JMPNext(); } else { /* appl */ - PREG = (yamop *) (PREG->u.llll.l3); + PREG = PREG->u.llll.l3; SREG = RepAppl(d0); JMPNext(); } @@ -7002,94 +6351,12 @@ Yap_absmi(int inp) BEGP(pt0); deref_body(d0, pt0, swt_unk, swt_nvar); /* variable */ - PREG = (yamop *) (PREG->u.llll.l4); + PREG = PREG->u.llll.l4; JMPNext(); ENDP(pt0); ENDD(d0); ENDBOp(); - BOp(switch_on_nonv, lll); - BEGD(d0); - d0 = ARG1; - deref_head(d0, swnv_unk); - swnv_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0); - PREG = (yamop *) (PREG->u.lll.l1); - JMPNext(); - } - else if (!IsApplTerm(d0)) { - /* constant */ - PREG = (yamop *) (PREG->u.lll.l2); - I_R = d0; - JMPNext(); - } - else { - /* appl */ - PREG = (yamop *) (PREG->u.lll.l3); - SREG = RepAppl(d0); - JMPNext(); - } - - BEGP(pt0); - deref_body(d0, pt0, swnv_unk, swnv_nvar); -#ifdef DEBUG - /* This should never happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "unbound argument to switch_nonvar"); - setregs(); - JMPNext(); -#endif - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - BOp(jump_if_var, l); - BEGD(d0); - d0 = CACHED_A1(); - deref_head(d0, jump_if_unk); - /* non var */ - jump_if_nonvar: - PREG = NEXTOP(PREG, l); - JMPNext(); - - BEGP(pt0); - deref_body(d0, pt0, jump_if_unk, jump_if_nonvar); - /* variable */ - PREG = (yamop *) (PREG->u.l.l); - ENDP(pt0); - JMPNext(); - ENDD(d0); - ENDBOp(); - - BOp(if_not_then, cll); - BEGD(d0); - d0 = CACHED_A1(); - deref_head(d0, if_n_unk); - if_n_nvar: - /* not variable */ - if (d0 == PREG->u.cll.c) { - /* equal to test value */ - PREG = (yamop *) PREG->u.cll.l2; - JMPNext(); - } - else { - /* different from test value */ - /* the case to optimise */ - PREG = (yamop *) PREG->u.cll.l1; - JMPNext(); - } - - BEGP(pt0); - deref_body(d0, pt0, if_n_unk, if_n_nvar); - ENDP(pt0); - /* variable */ - PREG = (yamop *) PREG->u.cll.l2; - JMPNext(); - ENDD(d0); - ENDBOp(); - /* specialised case where the arguments may be: * a list; * the empty list; @@ -7097,69 +6364,7 @@ Yap_absmi(int inp) * a variable; * */ - BOp(switch_list_nl, llll); - BEGD(d0); - d0 = CACHED_A1(); -#if UNIQUE_TAG_FOR_PAIRS - deref_list_head(d0, swlnl_unk); - swlnl_list: -#else - deref_head(d0, swlnl_unk); - /* non variable */ - swlnl_nvar: - if (IsPairTerm(d0)) { - /* pair */ -#endif - PREG = (yamop *) (PREG->u.llll.l1); - SREG = RepPair(d0); - JMPNext(); -#if UNIQUE_TAG_FOR_PAIRS - swlnl_nlist: - if (d0 == TermNil) { -#else - } - else if (d0 == TermNil) { -#endif - /* empty list */ - PREG = (yamop *) (PREG->u.llll.l2); - JMPNext(); - } - else { - /* appl or constant */ - if (IsApplTerm(d0)) { - SREG = RepAppl(d0); - PREG = (yamop *) (PREG->u.llll.l3); - JMPNext(); - } else { - I_R = d0; - PREG = (yamop *) (PREG->u.llll.l3); - JMPNext(); - } - } - - BEGP(pt0); -#if UNIQUE_TAG_FOR_PAIRS - swlnl_unk: - deref_list_body(d0, pt0, swlnl_list, swlnl_nlist); -#else - deref_body(d0, pt0, swlnl_unk, swlnl_nvar); -#endif - ENDP(pt0); - /* variable */ - PREG = (yamop *) (PREG->u.llll.l4); - JMPNext(); - ENDD(d0); - ENDBOp(); - - /* specialised case where the arguments may be: - * a list; - * the empty list; - * some other atom; - * a variable; - * and we know where we are jumping to! - * - */ - BOp(switch_list_nl_prefetch, ollll); + BOp(switch_list_nl, ollll); ALWAYS_LOOKAHEAD(PREG->u.ollll.pop); BEGD(d0); d0 = CACHED_A1(); @@ -7214,49 +6419,119 @@ Yap_absmi(int inp) } ENDBOp(); - BOp(switch_nv_list, lll); + BOp(switch_on_arg_type, xllll); BEGD(d0); - d0 = ARG1; - deref_head(d0, swnvl_unk); - swnvl_nvar: + d0 = XREG(PREG->u.xllll.x); + deref_head(d0, arg_swt_unk); + /* nonvar */ + arg_swt_nvar: if (IsPairTerm(d0)) { /* pair */ SREG = RepPair(d0); - PREG = (yamop *) (PREG->u.lll.l1); + PREG = PREG->u.xllll.l1; JMPNext(); } - else if (d0 == TermNil) { - /* empty list */ - PREG = (yamop *) (PREG->u.lll.l2); + else if (!IsApplTerm(d0)) { + /* constant */ + PREG = PREG->u.xllll.l2; + I_R = d0; JMPNext(); } else { - /* appl or other constant */ - if (IsApplTerm(d0)) { - PREG = (yamop *) (PREG->u.lll.l3); - SREG = RepAppl(d0); - JMPNext(); - } else { - PREG = (yamop *) (PREG->u.lll.l3); - I_R = d0; - JMPNext(); - } - ALWAYS_END_PREFETCH(); + /* appl */ + PREG = PREG->u.xllll.l3; + SREG = RepAppl(d0); + JMPNext(); + } BEGP(pt0); - deref_body(d0, pt0, swnvl_unk, swnvl_nvar); -#ifdef DEBUG - /* This should never happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "switch_nv_list has unbound argument"); - setregs(); + deref_body(d0, pt0, arg_swt_unk, arg_swt_nvar); + /* variable */ + PREG = PREG->u.xllll.l4; JMPNext(); -#endif /* DEBUG */ ENDP(pt0); - ENDD(d0); ENDBOp(); - + + BOp(switch_on_sub_arg_type, sllll); + BEGD(d0); + d0 = SREG[PREG->u.sllll.s]; + deref_head(d0, sub_arg_swt_unk); + /* nonvar */ + sub_arg_swt_nvar: + if (IsPairTerm(d0)) { + /* pair */ + SREG = RepPair(d0); + PREG = PREG->u.sllll.l1; + JMPNext(); + } + else if (!IsApplTerm(d0)) { + /* constant */ + PREG = PREG->u.sllll.l2; + I_R = d0; + JMPNext(); + } + else { + /* appl */ + PREG = PREG->u.sllll.l3; + SREG = RepAppl(d0); + JMPNext(); + } + + BEGP(pt0); + deref_body(d0, pt0, sub_arg_swt_unk, sub_arg_swt_nvar); + /* variable */ + PREG = PREG->u.sllll.l4; + JMPNext(); + ENDP(pt0); + ENDD(d0); + ENDBOp(); + + BOp(jump_if_var, l); + BEGD(d0); + d0 = CACHED_A1(); + deref_head(d0, jump_if_unk); + /* non var */ + jump_if_nonvar: + PREG = NEXTOP(PREG, l); + JMPNext(); + + BEGP(pt0); + deref_body(d0, pt0, jump_if_unk, jump_if_nonvar); + /* variable */ + PREG = PREG->u.l.l; + ENDP(pt0); + JMPNext(); + ENDD(d0); + ENDBOp(); + + BOp(if_not_then, cll); + BEGD(d0); + d0 = CACHED_A1(); + deref_head(d0, if_n_unk); + if_n_nvar: + /* not variable */ + if (d0 == PREG->u.cll.c) { + /* equal to test value */ + PREG = PREG->u.cll.l2; + JMPNext(); + } + else { + /* different from test value */ + /* the case to optimise */ + PREG = PREG->u.cll.l1; + JMPNext(); + } + + BEGP(pt0); + deref_body(d0, pt0, if_n_unk, if_n_nvar); + ENDP(pt0); + /* variable */ + PREG = PREG->u.cll.l2; + JMPNext(); + ENDD(d0); + ENDBOp(); + /************************************************************************\ * Indexing on ARG1 * \************************************************************************/ @@ -7416,145 +6691,13 @@ Yap_absmi(int inp) else pt0 += 2; } - PREG = (yamop *) (PREG->u.sl.l); + PREG = PREG->u.sl.l; JMPNext(); ENDP(pt0); ENDD(d0); ENDD(d1); ENDBOp(); -/************************************************************************\ -* Indexing on the Head of a list * -\************************************************************************/ - - BOp(switch_on_head, llll); - BEGD(d0); - BEGP(pt0); - pt0 = SREG; - d0 = *pt0; - deref_head(d0, swh_unk); - /* nonvar */ - swh_nvar: - /* advance S if not a list */ - ++SREG; - if (IsPairTerm(d0)) { - /* pair */ - PREG = (yamop *) (PREG->u.llll.l1); - /* push: we are entering within a list */ - SP[-1] = (CELL) SREG; - SP[-2] = READ_MODE; - SP -= 2; - SREG = RepPair(d0); - JMPNext(); - } - else if (!IsApplTerm(d0)) { - /* constant */ - PREG = (yamop *) (PREG->u.llll.l2); - I_R = d0; - JMPNext(); - } - else { - /* appl */ - /* jump */ - PREG = (yamop *) (PREG->u.llll.l3); - /* push: we are entering the compound term */ - SP[-1] = (CELL) SREG; - SP[-2] = READ_MODE; - SP -= 2; - SREG = RepAppl(d0); - JMPNext(); - } - - derefa_body(d0, pt0, swh_unk, swh_nvar); - ENDP(pt0); - /* variable */ - PREG = (yamop *) (PREG->u.llll.l4); - JMPNext(); - ENDD(d0); - ENDBOp(); - -/************************************************************************\ -* Switch for final block, we know the information is in a choicepoint * -\************************************************************************/ - BOp(switch_last, slll); - BEGD(d0); - d0 = B->cp_a1; - deref_head(d0, swl_unk); - swl_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0); - PREG = (yamop *) (PREG->u.slll.l1); - JMPNext(); - } - else if (!IsApplTerm(d0)) { - /* constant */ - PREG = (yamop *) (PREG->u.slll.l2); - I_R = d0; - JMPNext(); - } - else { - /* appl */ - PREG = (yamop *) (PREG->u.slll.l3); - SREG = RepAppl(d0); - JMPNext(); - } - - BEGP(pt0); - deref_body(d0, pt0, swl_unk, swl_nvar); -#ifdef DEBUG - /* This should never happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "switch_last has unbound argument"); - setregs(); - JMPNext(); -#endif - ENDP(pt0); - ENDD(d0); - ENDBOp(); - - BOp(switch_l_list, slll); - BEGD(d0); - d0 = B->cp_a1; - deref_head(d0, swll_unk); - swll_nvar: - if (IsPairTerm(d0)) { - /* pair */ - SREG = RepPair(d0); - PREG = (yamop *) (PREG->u.slll.l1); - JMPNext(); - } - else if (d0 == TermNil) { - /* empty list */ - PREG = (yamop *) (PREG->u.slll.l2); - JMPNext(); - } - else { - /* anything else */ - if (IsApplTerm(d0)) { - PREG = (yamop *) (PREG->u.slll.l3); - SREG = RepAppl(d0); - JMPNext(); - } else { - PREG = (yamop *) (PREG->u.slll.l3); - I_R = d0; - JMPNext(); - } - } - - BEGP(pt0); - deref_body(d0, pt0, swll_unk, swll_nvar); -#ifdef DEBUG - /* This should never happen */ - saveregs(); - Yap_Error(SYSTEM_ERROR, d0, "switch_l_list has unbound argument"); - setregs(); - JMPNext(); -#endif - ENDP(pt0); - ENDD(d0); - ENDBOp(); - /************************************************************************\ * Basic Primitive Predicates * \************************************************************************/ diff --git a/C/adtdefs.c b/C/adtdefs.c index 70f8ce9d9..28d20d1b9 100644 --- a/C/adtdefs.c +++ b/C/adtdefs.c @@ -400,8 +400,8 @@ Yap_NewPredPropByFunctor(FunctorEntry *fe, SMALLUNSGN cur_mod) p->KindOfPE = PEProp; p->ArityOfPE = fe->ArityOfFE; p->cs.p_code.FirstClause = p->cs.p_code.LastClause = NULL; + p->cs.p_code.NOfClauses = 0; p->PredFlags = 0L; - p->StateOfPred = 0; p->OwnerFile = AtomNil; p->OpcodeOfPred = UNDEF_OPCODE; p->CodeOfPred = p->cs.p_code.TrueCodeOfPred = (yamop *)(&(p->OpcodeOfPred)); @@ -435,8 +435,8 @@ Yap_NewPredPropByAtom(AtomEntry *ae, SMALLUNSGN cur_mod) p->KindOfPE = PEProp; p->ArityOfPE = 0; p->cs.p_code.FirstClause = p->cs.p_code.LastClause = NULL; + p->cs.p_code.NOfClauses = 0; p->PredFlags = 0L; - p->StateOfPred = 0; p->OwnerFile = AtomNil; p->OpcodeOfPred = UNDEF_OPCODE; p->CodeOfPred = p->cs.p_code.TrueCodeOfPred = (yamop *)(&(p->OpcodeOfPred)); diff --git a/C/amasm.c b/C/amasm.c index 585a85528..139bcfe99 100644 --- a/C/amasm.c +++ b/C/amasm.c @@ -65,12 +65,6 @@ STATIC_PROTO(void a_r, (op_numbers)); STATIC_PROTO(void a_p, (op_numbers)); STATIC_PROTO(void a_pl, (op_numbers,PredEntry *)); STATIC_PROTO(void a_l, (op_numbers)); -STATIC_PROTO(void a_3sw, (op_numbers)); -STATIC_PROTO(void a_3sws, (op_numbers)); -STATIC_PROTO(void a_4sw, (op_numbers)); -#if USE_THREADED_CODE -STATIC_PROTO(void a_4_lsw, (op_numbers)); -#endif STATIC_PROTO(void a_hx, (op_numbers)); STATIC_PROTO(void a_if, (op_numbers)); STATIC_PROTO(void a_go, (op_numbers)); @@ -82,7 +76,6 @@ STATIC_PROTO(void a_either, (op_numbers, CELL, CELL, int, int)); STATIC_PROTO(void a_try, (op_numbers, CELL, CELL)); STATIC_PROTO(void a_either, (op_numbers, CELL, CELL)); #endif /* YAPOR */ -STATIC_PROTO(void a_gl_in, (op_numbers)); STATIC_PROTO(void a_gl, (op_numbers)); STATIC_PROTO(void a_bfunc, (CELL)); STATIC_PROTO(wamreg compile_cmp_flags, (char *)); @@ -90,7 +83,7 @@ STATIC_PROTO(void a_igl, (op_numbers)); STATIC_PROTO(void a_ucons, (compiler_vm_op)); STATIC_PROTO(void a_uvar, (void)); STATIC_PROTO(void a_wvar, (void)); -STATIC_PROTO(void do_pass, (void)); +STATIC_PROTO(yamop *do_pass, (void)); #ifdef DEBUG_OPCODES STATIC_PROTO(void DumpOpCodes, (void)); #endif @@ -144,6 +137,20 @@ static int c_type; static int clause_has_blobs; +wamreg +Yap_regnotoreg(UInt regnbr) +{ +#if PRECOMPUTE_REGADDRESS + return (wamreg)(XREGS + regnbr); +#else +#if MSHIFTOFFS + return regnbr; +#else + return CELLSIZE*regnbr; +#endif +#endif /* ALIGN_LONGS */ +} + inline static yslot emit_y(Ventry *ve) { @@ -336,7 +343,7 @@ static void a_cl(op_numbers opcode) { if (pass_no) { - Clause *cl = (Clause *)code_addr; + LogUpdClause *cl = (LogUpdClause *)code_addr; code_p->opc = emit_op(opcode); code_p->u.l.l = code_addr; cl->u.ClVarChain = (yamop *)(Unsigned(code_addr) + label_offset[1]); @@ -348,7 +355,7 @@ static void a_cle(op_numbers opcode) { if (pass_no) { - Clause *cl = (Clause *)code_addr; + LogUpdClause *cl = (LogUpdClause *)code_addr; code_p->opc = emit_op(opcode); code_p->u.EC.ClTrail = 0; @@ -705,6 +712,17 @@ a_r(op_numbers opcode) GONEXT(x); } +inline static void +a_sp(op_numbers opcode, COUNT sv) +{ + if (pass_no) { + code_p->opc = emit_op(opcode); + code_p->u.sp.s = sv-1; + code_p->u.sp.p = CurrentPred; + } + GONEXT(dp); +} + static void check_alloc(void) { @@ -892,6 +910,16 @@ a_l(op_numbers opcode) GONEXT(l); } +static void +a_il(op_numbers opcode) +{ + if (pass_no) { + code_p->opc = emit_op(opcode); + code_p->u.l.l = emit_ilabel(cpc->rnd1); + } + GONEXT(l); +} + static void a_pl(op_numbers opcode, PredEntry *pred) { @@ -988,96 +1016,86 @@ a_igl(op_numbers opcode) GONEXT(l); } -static void -a_3sw(op_numbers opcode) -{ - CELL *seq_ptr; - - if (pass_no) { - code_p->opc = emit_op(opcode); - seq_ptr = cpc->arnds; - code_p->u.lll.l1 = emit_ilabel(seq_ptr[0]); - code_p->u.lll.l2 = emit_ilabel(seq_ptr[1]); - code_p->u.lll.l3 = emit_ilabel(seq_ptr[2]); - } - GONEXT(lll); -} - -static void -a_3sws(op_numbers opcode) -{ - CELL *seq_ptr; - - if (pass_no) { - code_p->opc = emit_op(opcode); - seq_ptr = cpc->arnds; - code_p->u.slll.s = IPredArity; - code_p->u.slll.p = CurrentPred; -#ifdef YAPOR - INIT_YAMOP_LTT(code_p, cpc->rnd1 >> 1); - if (cpc->rnd1 & 1) - PUT_YAMOP_CUT(code_p); - if (CurrentPred->PredFlags & SequentialPredFlag) - PUT_YAMOP_SEQ(code_p); -#endif /* YAPOR */ - code_p->u.slll.l1 = emit_ilabel(seq_ptr[0]); - code_p->u.slll.l2 = emit_ilabel(seq_ptr[1]); - code_p->u.slll.l3 = emit_ilabel(seq_ptr[2]); - } - GONEXT(slll); -} - static void a_4sw(op_numbers opcode) { CELL *seq_ptr; - if (pass_no) { - code_p->opc = emit_op(opcode); - seq_ptr = cpc->arnds; - code_p->u.llll.l1 = emit_ilabel(seq_ptr[0]); - code_p->u.llll.l2 = emit_ilabel(seq_ptr[1]); - code_p->u.llll.l3 = emit_ilabel(seq_ptr[2]); - code_p->u.llll.l4 = emit_ilabel(seq_ptr[3]); - } - GONEXT(llll); -} - -#if USE_THREADED_CODE -/* specialised code for fast switch_on_list, taking advantage of the - fact that in this case we are sure it is a list */ -static void -a_4_lsw(op_numbers opcode) -{ - CELL *seq_ptr; - - seq_ptr = cpc->arnds; - if (opcode == _switch_list_nl && (seq_ptr[0] & 1)) { - /* local address, don't do anything because we - don't know what is supposed to be there */ + if (opcode == _switch_on_type && + cpc->nextInst != NULL && + cpc->nextInst->op == label_op && + cpc->arnds[1] == cpc->nextInst->rnd1 && + !(cpc->arnds[0] & 1) && + cpc->nextInst->nextInst != NULL && + cpc->nextInst->nextInst->op == if_c_op && + cpc->nextInst->nextInst->rnd1 == 1 && + cpc->nextInst->nextInst->arnds[1] == TermNil && + cpc->nextInst->nextInst->arnds[0] == cpc->arnds[2]) { + if (pass_no) { + code_p->opc = emit_op(_switch_list_nl); + seq_ptr = cpc->arnds; + code_p->u.ollll.pop = ((yamop *)(seq_ptr[0]))->opc; + code_p->u.ollll.l1 = emit_ilabel(seq_ptr[0]); + code_p->u.ollll.l2 = emit_ilabel(cpc->nextInst->nextInst->arnds[2]); + code_p->u.ollll.l3 = emit_ilabel(seq_ptr[2]); + code_p->u.ollll.l4 = emit_ilabel(seq_ptr[3]); + } + GONEXT(ollll); + cpc = cpc->nextInst->nextInst; + } else { if (pass_no) { code_p->opc = emit_op(opcode); + seq_ptr = cpc->arnds; code_p->u.llll.l1 = emit_ilabel(seq_ptr[0]); code_p->u.llll.l2 = emit_ilabel(seq_ptr[1]); code_p->u.llll.l3 = emit_ilabel(seq_ptr[2]); code_p->u.llll.l4 = emit_ilabel(seq_ptr[3]); } GONEXT(llll); - } else { - /* optimise direct jumps to list like code, by prefetching the - first address for lists */ - if (pass_no) { - code_p->opc = emit_op(_switch_list_nl_prefetch); - code_p->u.ollll.pop = ((yamop *)(seq_ptr[0]))->opc; - code_p->u.ollll.l1 = emit_ilabel(seq_ptr[0]); - code_p->u.ollll.l2 = emit_ilabel(seq_ptr[1]); - code_p->u.ollll.l3 = emit_ilabel(seq_ptr[2]); - code_p->u.ollll.l4 = emit_ilabel(seq_ptr[3]); - } - GONEXT(ollll); } } -#endif + +static void +a_4sw_x(op_numbers opcode) +{ + CELL *seq_ptr; + + if (pass_no) { + code_p->opc = emit_op(opcode); + code_p->u.xllll.x = emit_xreg2(); + cpc = cpc->nextInst; + seq_ptr = cpc->arnds; + code_p->u.xllll.l1 = emit_ilabel(seq_ptr[0]); + code_p->u.xllll.l2 = emit_ilabel(seq_ptr[1]); + code_p->u.xllll.l3 = emit_ilabel(seq_ptr[2]); + code_p->u.xllll.l4 = emit_ilabel(seq_ptr[3]); + } else { + /* skip one */ + cpc = cpc->nextInst; + } + GONEXT(xllll); +} + +static void +a_4sw_s(op_numbers opcode) +{ + CELL *seq_ptr; + + if (pass_no) { + code_p->opc = emit_op(opcode); + code_p->u.sllll.s = cpc->rnd2; + cpc = cpc->nextInst; + seq_ptr = cpc->arnds; + code_p->u.sllll.l1 = emit_ilabel(seq_ptr[0]); + code_p->u.sllll.l2 = emit_ilabel(seq_ptr[1]); + code_p->u.sllll.l3 = emit_ilabel(seq_ptr[2]); + code_p->u.sllll.l4 = emit_ilabel(seq_ptr[3]); + } else { + /* skip one */ + cpc = cpc->nextInst; + } + GONEXT(sllll); +} static void a_hx(op_numbers opcode) @@ -1121,9 +1139,21 @@ a_go(op_numbers opcode) { if (pass_no) { code_p->opc = emit_op(opcode); - code_p->u.cll.c = emit_count(cpc->arnds[0]); - code_p->u.cll.l1 = emit_ilabel(cpc->arnds[1]); - code_p->u.cll.l2 = emit_ilabel(cpc->arnds[2]); + code_p->u.cll.c = emit_count(cpc->arnds[1]); /* tag */ + code_p->u.cll.l1 = emit_ilabel(cpc->arnds[2]); /* success point */ + code_p->u.cll.l2 = emit_ilabel(cpc->arnds[0]); /* fail point */ + } + GONEXT(cll); +} + +static void +a_ifnot(op_numbers opcode) +{ + if (pass_no) { + code_p->opc = emit_op(opcode); + code_p->u.cll.c = cpc->arnds[0]; /* tag */ + code_p->u.cll.l1 = emit_ilabel(cpc->arnds[1]); /* success point */ + code_p->u.cll.l2 = emit_ilabel(cpc->arnds[2]); /* fail point */ } GONEXT(cll); } @@ -1163,30 +1193,6 @@ a_try(op_numbers opcode, CELL lab, CELL opr) GONEXT(ld); } -static void -a_gl_in(op_numbers opcode) -{ - if (pass_no) { - code_p->opc = emit_op(opcode); - code_p->u.ldl.d = emit_a(cpc->rnd1); - code_p->u.ldl.s = emit_count(IPredArity); - code_p->u.ldl.p = CurrentPred; -#ifdef YAPOR - INIT_YAMOP_LTT(code_p, cpc->rnd2 >> 1); - if (cpc->rnd2 & 1) - PUT_YAMOP_CUT(code_p); - if (CurrentPred->PredFlags & SequentialPredFlag) - PUT_YAMOP_SEQ(code_p); -#endif /* YAPOR */ - /* next op is a jump, with the jump giving the address to fail to - after this alternative */ - cpc = cpc->nextInst; - code_p->u.ldl.bl = emit_ilabel(cpc->rnd1); - } else - cpc = cpc->nextInst; - GONEXT(ldl); -} - static void #ifdef YAPOR a_either(op_numbers opcode, CELL opr, CELL lab, int nofalts, int hascut) @@ -1952,80 +1958,87 @@ a_f2(int var) #define TRYCODE(G,P) a_try(TRYOP(G,P), Unsigned(code_addr) + label_offset[cpc->rnd1], IPredArity); #endif /* YAPOR */ -static void +static yamop * do_pass(void) { + yamop *entry_code; #ifdef YAPOR #define EITHER_INST 50 - yamop *entry_code; yamop *either_inst[EITHER_INST]; int either_cont = 0; #endif /* YAPOR */ int log_update; -#if defined(YAPOR) || defined(THREADS) int dynamic; -#endif int ystop_found = FALSE; + union clause_obj *cl_u; alloc_found = dealloc_found = FALSE; code_p = code_addr; + cl_u = (union clause_obj *)code_p; cpc = CodeStart; comit_lab = 0L; /* Space while for the clause flags */ log_update = CurrentPred->PredFlags & LogUpdatePredFlag; -#if defined(YAPOR) || defined(THREADS) dynamic = CurrentPred->PredFlags & DynamicPredFlag; -#endif if (assembling != ASSEMBLING_INDEX) { - Clause *cl_p = (Clause *)code_p; - if (pass_no) { - cl_p->u.ClValue = clause_store; - cl_p->ClFlags = clause_mask; - if (log_update) - cl_p->ClFlags |= LogUpdMask; - if (clause_has_blobs) { - cl_p->ClFlags |= HasBlobsMask; - } - cl_p->u2.ClExt = NULL; - cl_p->Owner = Yap_ConsultingFile(); - } - code_p = (yamop *)(cl_p->ClCode); - IPredArity = cpc->rnd2; /* number of args */ + if (log_update) { + if (pass_no) { + cl_u->luc.ClFlags = LogUpdMask; + cl_u->luc.Owner = Yap_ConsultingFile(); + if (clause_has_blobs) { + cl_u->luc.ClFlags |= HasBlobsMask; + } + cl_u->luc.u2.ClExt = NULL; #if defined(YAPOR) || defined(THREADS) - if ((dynamic||log_update) && pass_no) { - INIT_LOCK(cl_p->ClLock); - INIT_CLREF_COUNT(cl_p); - } + INIT_LOCK(cl_u.luc->ClLock); + INIT_CLREF_COUNT(cl_u.luc); #endif -#ifdef YAPOR + } + code_p = cl_u->luc.ClCode; + } else if (dynamic) { + if (pass_no) { + cl_u->ic.Owner = Yap_ConsultingFile(); + if (clause_has_blobs) { + cl_u->ic.ClFlags |= HasBlobsMask; + } +#if defined(YAPOR) || defined(THREADS) + INIT_LOCK(cl_u.ic->ClLock); + INIT_CLREF_COUNT(cl_u.ic); +#endif + } + code_p = cl_u->ic.ClCode; + } else { + /* static clause */ + if (pass_no) { + cl_u->sc.ClFlags = 0; + cl_u->sc.Owner = Yap_ConsultingFile(); + if (clause_has_blobs) { + cl_u->sc.ClFlags |= HasBlobsMask; + } + } + code_p = cl_u->sc.ClCode; + } + IPredArity = cpc->rnd2; /* number of args */ entry_code = code_p; +#ifdef YAPOR a_try(TRYOP(_try_me, _try_me0), 0, IPredArity, 1, 0); #else a_try(TRYOP(_try_me, _try_me0), 0, IPredArity); #endif /* YAPOR */ } else { - Clause *cl_p = (Clause *)code_p; - if (pass_no) { - cl_p->u.ClValue = TermNil; - if (log_update) { - cl_p->u2.ClUse = 0; - cl_p->ClFlags = LogUpdatePredFlag|IndexedPredFlag|IndexMask; - } else { - cl_p->u2.ClExt = NULL; - cl_p->ClFlags = clause_mask|IndexMask; + if (log_update) { + if (pass_no) { + cl_u->luc.ClFlags = LogUpdatePredFlag|IndexedPredFlag|IndexMask; + cl_u->luc.u2.ClUse = 0; } - cl_p->Owner = CurrentPred->OwnerFile; + code_p = cl_u->luc.ClCode; + } else { + if (pass_no) { + cl_u->sc.ClFlags = IndexMask; + } + code_p = cl_u->sc.ClCode; } - code_p = (yamop *)(cl_p->ClCode); -#if defined(YAPOR) || defined(THREADS) - if ((dynamic||log_update) && pass_no) { - INIT_LOCK(cl_p->ClLock); - INIT_CLREF_COUNT(cl_p); - } -#endif -#ifdef YAPOR entry_code = code_p; -#endif } while (cpc) { @@ -2282,92 +2295,19 @@ do_pass(void) a_cl(_trust_logical_pred); a_gl(_trust); break; - case tryin_op: - a_igl(_try_in); - break; - case retryin_op: - a_gl(_retry); - break; - case trustin_op: - a_gl_in(_trust_in); - break; - case tryf_op: - if (log_update) - a_cl(_try_logical_pred); - a_gl(_try_clause); - break; - case retryf_op: - a_gl(_retry_first); - break; - case trustf_op: - if (log_update) - a_cl(_trust_logical_pred); - a_gl(_trust_first); - break; - case tryfin_op: - a_igl(_try_in); - break; - case retryfin_op: - a_gl(_retry_first); - break; - case trustfin_op: - a_gl_in(_trust_first_in); - break; - case tryt_op: - if (log_update) - a_cl(_try_logical_pred); - a_gl(_try_clause); - break; - case retryt_op: - a_gl(_retry_tail); - break; - case trustt_op: - if (log_update) - a_cl(_trust_logical_pred); - a_gl(_trust_tail); - break; - case trytin_op: - a_igl(_try_in); - break; - case retrytin_op: - a_gl(_retry_tail); - break; - case trusttin_op: - a_gl_in(_trust_tail_in); - break; - case tryh_op: - if (log_update) - a_cl(_try_logical_pred); - a_gl(_try_clause); - break; - case retryh_op: - a_gl(_retry_head); - break; - case trusth_op: - if (log_update) - a_cl(_trust_logical_pred); - a_gl(_trust_head); - break; - case tryhin_op: - a_igl(_try_in); - break; - case retryhin_op: - a_gl(_retry_head); - break; - case trusthin_op: - a_gl_in(_trust_head_in); - break; - case trylf_op: - /* now that we don't need to save the arguments this is just a - simple retry */ - a_gl(_retry); - break; - /* ibd */ - case trylh_op: - a_gl(_retry); + case try_in_op: + a_il(_try_in); break; case jump_op: - a_l(_jump); + /* don't assemble jumps to next instruction */ + if (cpc->nextInst == NULL || + cpc->nextInst->op != label_op || + cpc->rnd1 != cpc->nextInst->rnd1) { + a_l(_jump); + } + break; + case jumpi_op: + a_il(_jump); break; case restore_tmps_op: a_l(_move_back); @@ -2460,34 +2400,18 @@ do_pass(void) #endif /* YAPOR */ dealloc_found = FALSE; break; + case cache_arg_op: + a_4sw_x(_switch_on_arg_type); + break; + case cache_sub_arg_op: + a_4sw_s(_switch_on_sub_arg_type); + break; case jump_v_op: a_igl(_jump_if_var); break; - case switch_t_op: + case switch_on_type_op: a_4sw(_switch_on_type); break; - case switch_nv_op: - a_3sw(_switch_on_nonv); - break; - case switch_l_op: - a_3sws(_switch_last); - break; - case switch_h_op: - a_4sw(_switch_on_head); - break; - case switch_lnl_op: -#if USE_THREADED_CODE - a_4_lsw(_switch_list_nl); -#else - a_4sw(_switch_list_nl); -#endif - break; - case switch_nvl_op: - a_3sw(_switch_nv_list); - break; - case switch_ll_op: - a_3sws(_switch_l_list); - break; case switch_c_op: a_hx(_switch_on_cons); break; @@ -2495,19 +2419,21 @@ do_pass(void) a_hx(_switch_on_func); break; case if_c_op: - a_if(_if_cons); + if (cpc->rnd1 == 1) { + a_go(_go_on_cons); + } else { + a_if(_if_cons); + } break; case if_f_op: - a_if(_if_func); - break; - case go_c_op: - a_go(_go_on_cons); - break; - case go_f_op: - a_go(_go_on_func); + if (cpc->rnd1 == 1) { + a_go(_go_on_func); + } else { + a_if(_if_func); + } break; case if_not_op: - a_go(_if_not_then); + a_ifnot(_if_not_then); break; case mark_initialised_pvars_op: a_bmap(); @@ -2576,6 +2502,7 @@ do_pass(void) } if (!ystop_found) a_e(_Ystop); + return entry_code; } yamop * @@ -2587,6 +2514,7 @@ Yap_assemble(int mode) * produces the final version of the code */ CELL size; + yamop *entry_code; code_addr = NULL; assembling = mode; @@ -2594,7 +2522,7 @@ Yap_assemble(int mode) label_offset = (int *)freep; pass_no = 0; asm_error = FALSE; - do_pass(); + entry_code = do_pass(); if (asm_error) { Yap_Error_TYPE = SYSTEM_ERROR; Yap_ErrorMessage = "internal assembler error"; @@ -2604,7 +2532,7 @@ Yap_assemble(int mode) YAPEnterCriticalSection(); { size = - (CELL)NEXTOP(NEXTOP(NEXTOP((yamop *)(((Clause *)NULL)->ClCode),ld),sla),e); + (CELL)NEXTOP(NEXTOP(NEXTOP((yamop *)(((DynamicClause *)NULL)->ClCode),ld),sla),e); if ((CELL)code_p > size) size = (CELL)code_p; } @@ -2614,17 +2542,12 @@ Yap_assemble(int mode) return NULL; } } - do_pass(); + entry_code = do_pass(); YAPLeaveCriticalSection(); - { - Clause *cl = (Clause *)code_addr; /* lcc, why? */ - #ifdef LOW_PROF - PROFSIZE=code_p; + PROFSIZE=code_p; #endif - - return(cl->ClCode); - } + return entry_code; } void diff --git a/C/arith2.c b/C/arith2.c index 1a60f1369..b538b2f39 100644 --- a/C/arith2.c +++ b/C/arith2.c @@ -1669,8 +1669,7 @@ static InitBinEntry InitBinTab[] = { {"exp", p_power}, {"gcd", p_gcd}, {"min", p_min}, - {"max", p_max}, - {"atan2", p_atan2} + {"max", p_max} }; static Int diff --git a/C/cdmgr.c b/C/cdmgr.c index 4418bb103..c5f7e9e02 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -49,7 +49,7 @@ STATIC_PROTO(Int search_for_static_predicate_in_use, (PredEntry *, int)); STATIC_PROTO(void mark_pred, (int, PredEntry *)); STATIC_PROTO(void do_toggle_static_predicates_in_use, (int)); #endif -STATIC_PROTO(void recover_log_upd_clause, (Clause *)); +STATIC_PROTO(void recover_log_upd_clause, (LogUpdClause *)); STATIC_PROTO(Int p_number_of_clauses, (void)); STATIC_PROTO(Int p_compile, (void)); STATIC_PROTO(Int p_compile_dynamic, (void)); @@ -107,7 +107,7 @@ static_in_use(PredEntry *p, int check_everything) return (FALSE); } if (STATIC_PREDICATES_MARKED) { - return (p->StateOfPred & InUseMask); + return (p->PredFlags & InUsePredFlag); } else { /* This code does not work for YAPOR or THREADS!!!!!!!! */ return(search_for_static_predicate_in_use(p, check_everything)); @@ -190,11 +190,9 @@ IPred(PredEntry *ap) ap->PredFlags |= IndexedPredFlag; } if (ap->PredFlags & SpiedPredFlag) { - ap->StateOfPred = StaticMask | SpiedMask; ap->OpcodeOfPred = Yap_opcode(_spy_pred); ap->CodeOfPred = (yamop *)(&(ap->OpcodeOfPred)); } else { - ap->StateOfPred = 0; ap->CodeOfPred = ap->cs.p_code.TrueCodeOfPred; ap->OpcodeOfPred = ((yamop *)(ap->CodeOfPred))->opc; } @@ -214,7 +212,7 @@ Yap_IPred(PredEntry *p) #define GONEXT(TYPE) code_p = ((yamop *)(&(code_p->u.TYPE.next))) static void -recover_log_upd_clause(Clause *cl) +recover_log_upd_clause(LogUpdClause *cl) { LOCK(cl->ClLock); if (cl->ClFlags & LogUpdRuleMask) { @@ -226,7 +224,7 @@ recover_log_upd_clause(Clause *cl) !(cl->ClFlags & InUseMask) #endif ) - Yap_ErCl(cl); + Yap_ErLogUpdCl(cl); } else { if (--(cl->u2.ClUse) == 0 && (cl->ClFlags & ErasedMask) && @@ -236,21 +234,21 @@ recover_log_upd_clause(Clause *cl) !(cl->ClFlags & InUseMask) #endif ) - Yap_ErCl(cl); + Yap_ErLogUpdCl(cl); } UNLOCK(cl->ClLock); } -static Clause * -ClauseBodyToClause(yamop *addr) +static LogUpdClause * +ClauseBodyToLogUpdClause(yamop *addr) { addr = (yamop *)((CODEADDR)addr - (Int)NEXTOP((yamop *)NULL,ld)); - return(ClauseCodeToClause(addr)); + return(ClauseCodeToLogUpdClause(addr)); } /* we already have a lock on the predicate */ static void -RemoveLogUpdIndex(Clause *cl) +RemoveLogUpdIndex(LogUpdClause *cl) { yamop *code_p; OPCODE last = Yap_opcode(_trust_logical_pred); @@ -266,20 +264,21 @@ RemoveLogUpdIndex(Clause *cl) code_p = cl->u.ClVarChain; /* skip try_log_update */ GONEXT(l); - recover_log_upd_clause(ClauseBodyToClause(code_p->u.ld.d)); + recover_log_upd_clause(ClauseBodyToLogUpdClause(code_p->u.ld.d)); GONEXT(ld); while(code_p->opc != last) { - recover_log_upd_clause(ClauseBodyToClause(code_p->u.ld.d)); + recover_log_upd_clause(ClauseBodyToLogUpdClause(code_p->u.ld.d)); GONEXT(ld); } /* skip trust_log_update */ GONEXT(l); - recover_log_upd_clause(ClauseBodyToClause(code_p->u.ld.d)); + recover_log_upd_clause(ClauseBodyToLogUpdClause(code_p->u.ld.d)); + /* don't need to worry about MultiFiles */ Yap_FreeCodeSpace((char *) cl); } void -Yap_RemoveLogUpdIndex(Clause *cl) +Yap_RemoveLogUpdIndex(LogUpdClause *cl) { RemoveLogUpdIndex(cl); } @@ -298,12 +297,15 @@ RemoveIndexation(PredEntry *ap) } spied = ap->PredFlags & SpiedPredFlag; if (ap->PredFlags & LogUpdatePredFlag) - RemoveLogUpdIndex(ClauseCodeToClause(ap->cs.p_code.TrueCodeOfPred)); + RemoveLogUpdIndex(ClauseCodeToLogUpdClause(ap->cs.p_code.TrueCodeOfPred)); else { - Clause *cl = ClauseCodeToClause(ap->cs.p_code.TrueCodeOfPred); + DeadClause *cl; + + cl = (DeadClause *)ClauseCodeToStaticClause(ap->cs.p_code.TrueCodeOfPred); if (static_in_use(ap, FALSE)) { /* This should never happen */ - cl->u.NextCl = DeadClauses; + cl->ClFlags = 0; + cl->NextCl = DeadClauses; DeadClauses = cl; } else { Yap_FreeCodeSpace((char *)cl); @@ -312,12 +314,10 @@ RemoveIndexation(PredEntry *ap) if (First != ap->cs.p_code.LastClause) ap->cs.p_code.TrueCodeOfPred = First; ap->PredFlags ^= IndexedPredFlag; - if (First != NIL && spied) { + if (First != NULL && spied) { ap->OpcodeOfPred = Yap_opcode(_spy_pred); ap->CodeOfPred = (yamop *)(&(ap->OpcodeOfPred)); - ap->StateOfPred = StaticMask | SpiedMask; } else { - ap->StateOfPred = StaticMask; ap->OpcodeOfPred = ap->cs.p_code.TrueCodeOfPred->opc; ap->CodeOfPred = ap->cs.p_code.TrueCodeOfPred; } @@ -346,36 +346,55 @@ retract_all(PredEntry *p, int in_use) { yamop *q, *q1; int multifile_pred = p->PredFlags & MultiFileFlag; - yamop *fclause = NIL, *lclause = NIL; + yamop *fclause = NULL, *lclause = NULL; q = p->cs.p_code.FirstClause; if (q != NIL) { - do { - Clause *cl; - q1 = q; - q = NextClause(q); - cl = ClauseCodeToClause(q1); - if (multifile_pred && cl->Owner != YapConsultingFile()) { - if (fclause == NIL) { - fclause = q1; + if (p->PredFlags & LogUpdatePredFlag) { + do { + LogUpdClause *cl; + q1 = q; + q = NextClause(q); + cl = ClauseCodeToLogUpdClause(q1); + if (multifile_pred && cl->Owner != YapConsultingFile()) { + if (fclause == NULL) { + fclause = q1; + } else { + yamop *clp = (yamop *)lclause; + clp->u.ld.d = q1; + } + lclause = q1; } else { - yamop *clp = (yamop *)lclause; - clp->u.ld.d = q1; + Yap_ErLogUpdCl(cl); } - lclause = q1; - } else { - if (p->PredFlags & LogUpdatePredFlag) - Yap_ErCl(cl); - else { + } while (q1 != p->cs.p_code.LastClause); + } else { + do { + StaticClause *cl; + q1 = q; + q = NextClause(q); + cl = ClauseCodeToStaticClause(q1); + if (multifile_pred && cl->Owner != YapConsultingFile()) { + if (fclause == NULL) { + fclause = q1; + } else { + yamop *clp = (yamop *)lclause; + clp->u.ld.d = q1; + } + lclause = q1; + } else { if (cl->ClFlags & HasBlobsMask) { - cl->u.NextCl = DeadClauses; - DeadClauses = cl; + DeadClause *dcl = (DeadClause *)cl; + dcl->NextCl = DeadClauses; + dcl->ClFlags = 0; + DeadClauses = dcl; } else { Yap_FreeCodeSpace((char *)cl); } + p->cs.p_code.NOfClauses--; } - } - } while (q1 != p->cs.p_code.LastClause); + } while (q1 != p->cs.p_code.LastClause); + } } p->cs.p_code.FirstClause = fclause; p->cs.p_code.LastClause = lclause; @@ -407,7 +426,6 @@ retract_all(PredEntry *p, int in_use) } } if (p->PredFlags & SpiedPredFlag) { - p->StateOfPred |= StaticMask | SpiedMask; p->OpcodeOfPred = Yap_opcode(_spy_pred); p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); } else if (p->PredFlags & IndexedPredFlag) { @@ -460,6 +478,7 @@ add_first_static(PredEntry *p, yamop *cp, int spy_flag) } p->cs.p_code.TrueCodeOfPred = pt; p->cs.p_code.FirstClause = p->cs.p_code.LastClause = cp; + p->cs.p_code.NOfClauses = 1; p->StatisticsForPred.NOfEntries = 0; p->StatisticsForPred.NOfHeadSuccesses = 0; p->StatisticsForPred.NOfRetries = 0; @@ -472,13 +491,8 @@ add_first_static(PredEntry *p, yamop *cp, int spy_flag) PUT_YAMOP_SEQ((yamop *)cp); #endif /* YAPOR */ if (spy_flag) { - p->StateOfPred |= StaticMask | SpiedMask; p->OpcodeOfPred = Yap_opcode(_spy_pred); p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); - } else if (is_fast(p)) { - p->StateOfPred |= StaticMask; - } else { - p->StateOfPred |= StaticMask; } if (yap_flags[SOURCE_MODE_FLAG]) { p->PredFlags |= SourcePredFlag; @@ -491,8 +505,8 @@ add_first_static(PredEntry *p, yamop *cp, int spy_flag) static void add_first_dynamic(PredEntry *p, yamop *cp, int spy_flag) { - yamop *ncp = ((Clause *)NIL)->ClCode; - Clause *cl; + yamop *ncp = ((DynamicClause *)NULL)->ClCode; + DynamicClause *cl; if (p == PredGoalExpansion) { PRED_GOAL_EXPANSION_ON = TRUE; Yap_InitComma(); @@ -510,25 +524,18 @@ add_first_dynamic(PredEntry *p, yamop *cp, int spy_flag) /* allocate starter block, containing info needed to start execution, * that is a try_mark to start the code and a fail to finish things up */ cl = - (Clause *) Yap_AllocCodeSpace((Int)NEXTOP(NEXTOP(NEXTOP(ncp,ld),e),e)); + (DynamicClause *) Yap_AllocCodeSpace((Int)NEXTOP(NEXTOP(NEXTOP(ncp,ld),e),e)); if (cl == NIL) { Yap_Error(SYSTEM_ERROR,TermNil,"Heap crashed against Stacks"); return; } - cl->Owner = p->OwnerFile; /* skip the first entry, this contains the back link and will always be empty for this entry */ ncp = (yamop *)(((CELL *)ncp)+1); /* next we have the flags. For this block mainly say whether we are * being spied */ - if (spy_flag) { - cl->ClFlags = DynamicMask | SpiedMask; - ncp = cl->ClCode; - } - else { - cl->ClFlags = DynamicMask; - ncp = cl->ClCode; - } + cl->ClFlags = DynamicMask; + ncp = cl->ClCode; INIT_LOCK(cl->ClLock); INIT_CLREF_COUNT(cl); /* next, set the first instruction to execute in the dyamic @@ -546,6 +553,7 @@ add_first_dynamic(PredEntry *p, yamop *cp, int spy_flag) #endif /* YAPOR */ /* This is the point we enter the code */ p->cs.p_code.TrueCodeOfPred = p->CodeOfPred = ncp; + p->cs.p_code.NOfClauses = 1; /* set the first clause to have a retry and mark which will * backtrack to the previous block */ if (p->PredFlags & ProfiledPredFlag) @@ -558,7 +566,7 @@ add_first_dynamic(PredEntry *p, yamop *cp, int spy_flag) cp->u.ld.p = p; cp->u.ld.d = ncp; /* also, keep a backpointer for the days you delete the clause */ - ClauseCodeToClause(cp)->u.ClPrevious = ncp; + ClauseCodeToDynamicClause(cp)->ClPrevious = ncp; /* Don't forget to say who is the only clause for the predicate so far */ p->cs.p_code.LastClause = p->cs.p_code.FirstClause = cp; @@ -621,6 +629,7 @@ asserta_stat_clause(PredEntry *p, yamop *cp, int spy_flag) } p->cs.p_code.TrueCodeOfPred = p->cs.p_code.FirstClause = cp; p->cs.p_code.LastClause->u.ld.d = cp; + p->cs.p_code.NOfClauses++; } /* p is already locked */ @@ -629,11 +638,11 @@ asserta_dynam_clause(PredEntry *p, yamop *cp) { yamop *q; q = cp; - LOCK(ClauseCodeToClause(p->cs.p_code.FirstClause)->ClLock); + LOCK(ClauseCodeToDynamicClause(p->cs.p_code.FirstClause)->ClLock); /* also, keep backpointers for the days we'll delete all the clause */ - ClauseCodeToClause(p->cs.p_code.FirstClause)->u.ClPrevious = q; - ClauseCodeToClause(cp)->u.ClPrevious = (yamop *)(p->CodeOfPred); - UNLOCK(ClauseCodeToClause(p->cs.p_code.FirstClause)->ClLock); + ClauseCodeToDynamicClause(p->cs.p_code.FirstClause)->ClPrevious = q; + ClauseCodeToDynamicClause(cp)->ClPrevious = (yamop *)(p->CodeOfPred); + UNLOCK(ClauseCodeToDynamicClause(p->cs.p_code.FirstClause)->ClLock); q->u.ld.d = p->cs.p_code.FirstClause; q->u.ld.s = p->ArityOfPE; q->u.ld.p = p; @@ -650,6 +659,7 @@ asserta_dynam_clause(PredEntry *p, yamop *cp) q->u.ld.d = cp; q->u.ld.s = p->ArityOfPE; q->u.ld.p = p; + p->cs.p_code.NOfClauses++; } /* p is already locked */ @@ -715,6 +725,7 @@ assertz_stat_clause(PredEntry *p, yamop *cp, int spy_flag) } } #endif /* YAPOR */ + p->cs.p_code.NOfClauses++; } /* p is already locked */ @@ -724,12 +735,12 @@ assertz_dynam_clause(PredEntry *p, yamop *cp) yamop *q; q = p->cs.p_code.LastClause; - LOCK(ClauseCodeToClause(q)->ClLock); + LOCK(ClauseCodeToDynamicClause(q)->ClLock); q->u.ld.d = cp; p->cs.p_code.LastClause = cp; /* also, keep backpointers for the days we'll delete all the clause */ - ClauseCodeToClause(cp)->u.ClPrevious = q; - UNLOCK(ClauseCodeToClause(q)->ClLock); + ClauseCodeToDynamicClause(cp)->ClPrevious = q; + UNLOCK(ClauseCodeToDynamicClause(q)->ClLock); q = (yamop *)cp; if (p->PredFlags & ProfiledPredFlag) q->opc = Yap_opcode(_profiled_retry_and_mark); @@ -740,6 +751,7 @@ assertz_dynam_clause(PredEntry *p, yamop *cp) q->u.ld.d = p->CodeOfPred; q->u.ld.s = p->ArityOfPE; q->u.ld.p = p; + p->cs.p_code.NOfClauses++; } static void expand_consult(void) @@ -883,8 +895,13 @@ addclause(Term t, yamop *cp, int mode, int mod) if (Yap_ErrorMessage && Yap_Error_TYPE == PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE) return; if (!is_dynamic(p)) { - Clause *clp = ClauseCodeToClause(cp); - clp->ClFlags |= StaticMask; + if (p->PredFlags & LogUpdatePredFlag) { + LogUpdClause *clp = ClauseCodeToLogUpdClause(cp); + clp->ClFlags |= StaticMask; + } else { + StaticClause *clp = ClauseCodeToStaticClause(cp); + clp->ClFlags |= StaticMask; + } if (compile_mode) p->PredFlags |= CompiledPredFlag | FastPredFlag; else @@ -1101,7 +1118,7 @@ p_compile_dynamic(void) Term t = Deref(ARG1); Term t1 = Deref(ARG2); Term t3 = Deref(ARG3); - Clause *cl; + DynamicClause *cl; yamop *code_adr; int old_optimize; Int mod; @@ -1119,25 +1136,20 @@ p_compile_dynamic(void) if (!Yap_ErrorMessage) { optimizer_on = old_optimize; - cl = ClauseCodeToClause(code_adr); + cl = ClauseCodeToDynamicClause(code_adr); addclause(t, code_adr, (int) (IntOfTerm(t1) & 3), mod); - } - if (Yap_ErrorMessage) { + } else { if (IntOfTerm(t1) & 4) { Yap_Error(Yap_Error_TYPE, Yap_Error_Term, "line %d, %s", Yap_FirstLineInParse(), Yap_ErrorMessage); } else Yap_Error(Yap_Error_TYPE, Yap_Error_Term, Yap_ErrorMessage); return (FALSE); } - cl = ClauseCodeToClause(code_adr); - if (!(cl->ClFlags & LogUpdMask)) - cl->ClFlags = DynamicMask; + cl->ClFlags = DynamicMask; t = MkIntegerTerm((Int)code_adr); return(Yap_unify(ARG4, t)); } - - static int consult_level = 0; static Atom @@ -1285,18 +1297,20 @@ p_purge_clauses(void) q1 = q; q = NextClause(q); if (pred->PredFlags & LogUpdatePredFlag) - Yap_ErCl(ClauseCodeToClause(q1)); + Yap_ErLogUpdCl(ClauseCodeToLogUpdClause(q1)); else { - Clause *cl = ClauseCodeToClause(q1); + StaticClause *cl = ClauseCodeToStaticClause(q1); if (cl->ClFlags & HasBlobsMask || in_use) { - cl->u.NextCl = DeadClauses; - DeadClauses = cl; + DeadClause *dcl = (DeadClause *)cl; + dcl->NextCl = DeadClauses; + dcl->ClFlags = 0; + DeadClauses = dcl; } else { Yap_FreeCodeSpace((char *)cl); } } } while (q1 != pred->cs.p_code.LastClause); - pred->cs.p_code.FirstClause = pred->cs.p_code.LastClause = NIL; + pred->cs.p_code.FirstClause = pred->cs.p_code.LastClause = NULL; if (pred->PredFlags & (DynamicPredFlag|LogUpdatePredFlag)) { pred->OpcodeOfPred = FAIL_OPCODE; } else { @@ -1371,7 +1385,6 @@ p_setspy(void) pred->OpcodeOfPred = Yap_opcode(_spy_pred); pred->CodeOfPred = (yamop *)(&(pred->OpcodeOfPred)); } - pred->StateOfPred |= SpiedMask; pred->PredFlags |= SpiedPredFlag; WRITE_UNLOCK(pred->PRWLock); return (TRUE); @@ -1407,10 +1420,7 @@ p_rmspy(void) return (FALSE); } if (!(pred->PredFlags & DynamicPredFlag)) { - if ((pred->StateOfPred ^= SpiedMask) & InUseMask) - pred->CodeOfPred = pred->cs.p_code.TrueCodeOfPred; - else - pred->CodeOfPred = pred->cs.p_code.TrueCodeOfPred; + pred->CodeOfPred = pred->cs.p_code.TrueCodeOfPred; pred->OpcodeOfPred = ((yamop *)(pred->CodeOfPred))->opc; } else if (pred->OpcodeOfPred == Yap_opcode(_spy_or_trymark)) { pred->OpcodeOfPred = Yap_opcode(_try_and_mark); @@ -1436,7 +1446,6 @@ p_number_of_clauses(void) int ncl = 0; Prop pe; yamop *q; - int testing; int mod; if (IsVarTerm(t2) || !IsAtomTerm(t2)) { @@ -1454,19 +1463,10 @@ p_number_of_clauses(void) q = RepPredProp(pe)->cs.p_code.FirstClause; READ_LOCK(RepPredProp(pe)->PRWLock); if (q != NIL) { - if (RepPredProp(pe)->PredFlags & DynamicPredFlag) - testing = TRUE; - else - testing = FALSE; while (q != RepPredProp(pe)->cs.p_code.LastClause) { - if (!testing || - !(ClauseCodeToClause(q)->ClFlags & ErasedMask)) - ncl++; + ncl++; q = NextClause(q); } - if (!testing || - !(ClauseCodeToClause(q)->ClFlags & ErasedMask)) - ncl++; } READ_UNLOCK(RepPredProp(pe)->PRWLock); t = MkIntegerTerm(ncl); @@ -1803,37 +1803,37 @@ p_compile_mode(void) } #if !defined(YAPOR) -static yamop *next_clause(PredEntry *pe, yamop *codeptr) -{ - yamop *clcode; - Clause *cl; - clcode = pe->cs.p_code.FirstClause; - cl = ClauseCodeToClause(clcode); - do { - if (clcode == pe->cs.p_code.LastClause) - break; - if (IN_BLOCK(codeptr,cl,Yap_SizeOfBlock((CODEADDR)cl))) { - return(NextClause(clcode)); - } - cl = ClauseCodeToClause(clcode = NextClause(clcode)); - } while (TRUE); - Yap_Error(SYSTEM_ERROR,TermNil,"could not find clause for indexing code"); - return(NULL); -} - static yamop *cur_clause(PredEntry *pe, yamop *codeptr) { yamop *clcode; - Clause *cl; + StaticClause *cl; clcode = pe->cs.p_code.FirstClause; - cl = ClauseCodeToClause(clcode); + cl = ClauseCodeToStaticClause(clcode); do { if (IN_BLOCK(codeptr,cl,Yap_SizeOfBlock((CODEADDR)cl))) { return((yamop *)clcode); } if (clcode == pe->cs.p_code.LastClause) break; - cl = ClauseCodeToClause(clcode = NextClause(clcode)); + cl = ClauseCodeToStaticClause(clcode = NextClause(clcode)); + } while (TRUE); + Yap_Error(SYSTEM_ERROR,TermNil,"could not find clause for indexing code"); + return(NULL); +} + +static yamop *cur_log_upd_clause(PredEntry *pe, yamop *codeptr) +{ + yamop *clcode; + LogUpdClause *cl; + clcode = pe->cs.p_code.FirstClause; + cl = ClauseCodeToLogUpdClause(clcode); + do { + if (IN_BLOCK(codeptr,cl,Yap_SizeOfBlock((CODEADDR)cl))) { + return((yamop *)clcode); + } + if (clcode == pe->cs.p_code.LastClause) + break; + cl = ClauseCodeToLogUpdClause(clcode = NextClause(clcode)); } while (TRUE); Yap_Error(SYSTEM_ERROR,TermNil,"could not find clause for indexing code"); return(NULL); @@ -1899,24 +1899,25 @@ search_for_static_predicate_in_use(PredEntry *p, int check_everything) READ_LOCK(pe->PRWLock); if (p->PredFlags & IndexedPredFlag) { yamop *code_p = b_ptr->cp_ap; - if (code_p >= p->cs.p_code.TrueCodeOfPred && - code_p <= p->cs.p_code.TrueCodeOfPred + Yap_SizeOfBlock((CODEADDR)ClauseCodeToClause(p->cs.p_code.TrueCodeOfPred))) { - yamop *prev; - /* fix the choicepoint */ - switch(opnum) { - case _switch_last: - case _switch_l_list: - { - prev = (yamop *)((CODEADDR)(code_p)-(CELL)NEXTOP((yamop *)NIL,ld)); - /* previous clause must be a try or a retry */ - b_ptr->cp_ap = next_clause(pe, prev->u.ld.d); - } - break; - default: - b_ptr->cp_ap = cur_clause(pe, b_ptr->cp_ap->u.ld.d); - } - READ_UNLOCK(pe->PRWLock); + char *code_end; + + if (p->PredFlags & LogUpdatePredFlag) { + LogUpdClause *cl = ClauseCodeToLogUpdClause(p->cs.p_code.TrueCodeOfPred); + code_end = (char *)cl + Yap_SizeOfBlock((CODEADDR)cl); + } else { + StaticClause *cl = ClauseCodeToStaticClause(p->cs.p_code.TrueCodeOfPred); + code_end = (char *)cl + Yap_SizeOfBlock((CODEADDR)cl); } + if (code_p >= p->cs.p_code.TrueCodeOfPred && + code_p <= (yamop *)code_end) { + /* fix the choicepoint */ + if (p->PredFlags & LogUpdatePredFlag) { + b_ptr->cp_ap = cur_log_upd_clause(pe, b_ptr->cp_ap->u.ld.d); + } else { + b_ptr->cp_ap = cur_clause(pe, b_ptr->cp_ap->u.ld.d); + } + } + READ_UNLOCK(pe->PRWLock); } else { READ_UNLOCK(pe->PRWLock); } @@ -1935,9 +1936,9 @@ mark_pred(int mark, PredEntry *pe) if (pe->ModuleOfPred) { WRITE_LOCK(pe->PRWLock); if (mark) { - pe->StateOfPred |= InUseMask; + pe->PredFlags |= InUsePredFlag; } else { - pe->StateOfPred &= ~InUseMask; + pe->PredFlags &= ~InUsePredFlag; } WRITE_UNLOCK(pe->PRWLock); } @@ -2116,12 +2117,21 @@ p_toggle_static_predicates_in_use(void) static Int code_in_pred(PredEntry *pp, Atom *pat, UInt *parity, yamop *codeptr) { yamop *clcode; - Clause *cl; int i = 1; READ_LOCK(pp->PRWLock); clcode = pp->cs.p_code.FirstClause; - if (clcode != NIL) { + if (clcode != NULL) { + char *code_end; + if (pp->PredFlags & LogUpdatePredFlag) { + LogUpdClause *cl = ClauseCodeToLogUpdClause(pp->cs.p_code.TrueCodeOfPred); + code_end = (char *)cl + Yap_SizeOfBlock((CODEADDR)cl); + } else if (!(pp->PredFlags & DynamicPredFlag)) { + code_end = NULL; + } else { + StaticClause *cl = ClauseCodeToStaticClause(pp->cs.p_code.TrueCodeOfPred); + code_end = (char *)cl + Yap_SizeOfBlock((CODEADDR)cl); + } /* check if the codeptr comes from the indexing code */ if ((pp->PredFlags & IndexedPredFlag) && IN_BLOCK(codeptr,pp->cs.p_code.TrueCodeOfPred,Yap_SizeOfBlock((CODEADDR)(pp->cs.p_code.TrueCodeOfPred)))) { @@ -2134,8 +2144,16 @@ code_in_pred(PredEntry *pp, Atom *pat, UInt *parity, yamop *codeptr) { READ_UNLOCK(pp->PRWLock); return(-1); } - cl = ClauseCodeToClause(clcode); do { + CODEADDR cl; + + if (pp->PredFlags & LogUpdatePredFlag) { + cl = (CODEADDR)ClauseCodeToLogUpdClause(clcode); + } else if (!(pp->PredFlags & DynamicPredFlag)) { + cl = (CODEADDR)ClauseCodeToDynamicClause(clcode); + } else { + cl = (CODEADDR)ClauseCodeToStaticClause(clcode); + } if (IN_BLOCK(codeptr,cl,Yap_SizeOfBlock((CODEADDR)cl))) { /* we found it */ *parity = pp->ArityOfPE; @@ -2149,8 +2167,8 @@ code_in_pred(PredEntry *pp, Atom *pat, UInt *parity, yamop *codeptr) { } if (clcode == pp->cs.p_code.LastClause) break; - cl = ClauseCodeToClause(clcode = NextClause(clcode)); i++; + clcode = NextClause(clcode); } while (TRUE); } READ_UNLOCK(pp->PRWLock); @@ -2381,7 +2399,7 @@ p_clean_up_dead_clauses(void) { while (DeadClauses != NULL) { char *pt = (char *)DeadClauses; - DeadClauses = DeadClauses->u.NextCl; + DeadClauses = DeadClauses->NextCl; Yap_FreeCodeSpace(pt); } return(TRUE); diff --git a/C/compiler.c b/C/compiler.c index 49c67cb76..38cd1b033 100644 --- a/C/compiler.c +++ b/C/compiler.c @@ -36,9 +36,7 @@ STATIC_PROTO(void c_eq, (Term, Term)); STATIC_PROTO(void c_test, (Int, Term)); STATIC_PROTO(void c_bifun, (Int, Term, Term, Term, int)); STATIC_PROTO(void c_goal, (Term, int)); -STATIC_PROTO(void get_type_info, (Term)); STATIC_PROTO(void c_body, (Term, int)); -STATIC_PROTO(void get_cl_info, (Term)); STATIC_PROTO(void c_head, (Term)); STATIC_PROTO(int usesvar, (int)); STATIC_PROTO(CELL *init_bvarray, (int)); @@ -1678,42 +1676,12 @@ c_goal(Term Goal, int mod) } } -static void -get_type_info(Term Goal) -{ - if (IsNonVarTerm(Goal) && IsApplTerm(Goal)) { - if (clause_mask == VarCl && - ArgOfTerm(1, Goal) == (Term) clause_store) { - if (FunctorOfTerm(Goal) == FunctorGVar) - clause_mask |= FIsVar; - else if (FunctorOfTerm(Goal) == FunctorGAtom) - clause_mask |= AtCl | FIsAtom; - else if (FunctorOfTerm(Goal) == FunctorGInteger) - clause_mask |= AtCl | FIsNum; - /* - * vsc: with the new scheme floats are structs, so - * the simple index switch cannot differentiate them - * from structs: - * else if (FunctorOfTerm(Goal) == FunctorGAtomic || - * FunctorOfTerm(Goal) == FunctorGPrimitive) - * clause_mask |= AtCl|FIsNum; - */ - } - } -} - static void c_body(Term Body, int mod) { onhead = FALSE; BodyStart = cpc; goalno = 1; - if (IsNonVarTerm(Body) && IsApplTerm(Body)) { - if (FunctorOfTerm(Body) == FunctorComma) - get_type_info(ArgOfTerm(1, Body)); - else - get_type_info(Body); - } while (IsNonVarTerm(Body) && IsApplTerm(Body) && FunctorOfTerm(Body) == FunctorComma) { Term t2 = ArgOfTerm(2, Body); @@ -1731,42 +1699,6 @@ c_body(Term Body, int mod) c_goal(Body, mod); } -static void -get_cl_info(register Term t) -{ - if (IsVarTerm(t)) { - clause_mask = VarCl; - clause_store = (CELL) t; - } - else if (IsPairTerm(t)) { - clause_mask = ListCl; - t = HeadOfTerm(t); - if (IsVarTerm(t)) - clause_mask |= FHeadVar; - else if (IsPairTerm(t)) - clause_mask |= FHeadList; - else if (IsApplTerm(t)) { - clause_store = (CELL) FunctorOfTerm(t); - clause_mask |= FHeadAppl; - } - else { - clause_store = (CELL) t; - clause_mask |= FHeadCons; - } - } - else if (IsApplTerm(t)) { - Functor fun = FunctorOfTerm(t); - if (!IsExtensionFunctor(fun)) { - clause_mask = (CELL)ApplCl; - clause_store = (CELL)fun; - } - } - else { - clause_store = (CELL) t; - clause_mask = AtCl; - } -} - static void c_head(Term t) { @@ -1784,7 +1716,6 @@ c_head(Term t) f = FunctorOfTerm(t); Yap_emit(name_op, (CELL) NameOfFunctor(f), ArityOfFunctor(f)); c_args(t, 0); - get_cl_info(ArgOfTerm(1, t)); } /* number of permanent variables in the clause */ @@ -2793,7 +2724,6 @@ Yap_cclause(Term inp_clause, int NOfArgs, int mod) return (0); } SaveH = H; - clause_mask = 0; or_found = 0; Yap_ErrorMessage = NULL; /* initialize variables for code generation */ diff --git a/C/computils.c b/C/computils.c index b1503e6f8..02cd03996 100644 --- a/C/computils.c +++ b/C/computils.c @@ -267,8 +267,50 @@ Yap_bip_name(Int op, char *s) { #ifdef DEBUG static void -ShowOp (f) - char *f; +write_address(CELL address) +{ + if (address < (CELL)AtomBase) { + Yap_DebugPutc(Yap_c_error_stream,'L'); + Yap_plwrite (MkIntTerm (address), Yap_DebugPutc, 0); + } else if (address == (CELL) FAILCODE) { + Yap_plwrite (MkAtomTerm (AtomFail), Yap_DebugPutc, 0); + } else { + char buf[32], *p = buf; + +#if HAVE_SNPRINTF + snprintf(buf,32,"%x",address); +#else + snprintf(buf,"%x",address); +#endif + p[31] = '\0'; /* so that I don't have to worry */ + Yap_DebugPutc(Yap_c_error_stream,'0'); + Yap_DebugPutc(Yap_c_error_stream,'x'); + while (*p != '\0') { + Yap_DebugPutc(Yap_c_error_stream,*p++); + } + } +} + +static void +write_functor(Functor f) +{ + if (IsExtensionFunctor(f)) { + if (f == FunctorDBRef) { + Yap_plwrite(MkAtomTerm(Yap_LookupAtom("DBRef")), Yap_DebugPutc, 0); + } else if (f == FunctorLongInt) { + Yap_plwrite(MkAtomTerm(Yap_LookupAtom("LongInt")), Yap_DebugPutc, 0); + } else if (f == FunctorDouble) { + Yap_plwrite(MkAtomTerm(Yap_LookupAtom("Double")), Yap_DebugPutc, 0); + } + } else { + Yap_plwrite(MkAtomTerm(NameOfFunctor (f)), Yap_DebugPutc, 0); + Yap_DebugPutc (Yap_c_error_stream,'/'); + Yap_plwrite(MkIntTerm(ArityOfFunctor (f)), Yap_DebugPutc, 0); + } +} + +static void +ShowOp (char *f) { char ch; while ((ch = *f++) != 0) @@ -291,7 +333,7 @@ ShowOp (f) } break; case 'l': - Yap_plwrite (MkIntTerm (arg), Yap_DebugPutc, 0); + write_address (arg); break; case 'B': { @@ -367,19 +409,7 @@ ShowOp (f) } break; case 'f': - if (IsExtensionFunctor((Functor)arg)) { - if ((Functor)arg == FunctorDBRef) { - Yap_plwrite(MkAtomTerm(Yap_LookupAtom("DBRef")), Yap_DebugPutc, 0); - } else if ((Functor)arg == FunctorLongInt) { - Yap_plwrite(MkAtomTerm(Yap_LookupAtom("LongInt")), Yap_DebugPutc, 0); - } else if ((Functor)arg == FunctorDouble) { - Yap_plwrite(MkAtomTerm(Yap_LookupAtom("Double")), Yap_DebugPutc, 0); - } - } else { - Yap_plwrite(MkAtomTerm(NameOfFunctor ((Functor) arg)), Yap_DebugPutc, 0); - Yap_DebugPutc (Yap_c_error_stream,'/'); - Yap_plwrite(MkIntTerm(ArityOfFunctor ((Functor) arg)), Yap_DebugPutc, 0); - } + write_functor((Functor)arg); break; case 'r': Yap_DebugPutc (Yap_c_error_stream,'A'); @@ -388,27 +418,14 @@ ShowOp (f) case 'h': { CELL my_arg = *cptr++; - if (my_arg & 1) - Yap_plwrite (MkIntTerm (my_arg), - Yap_DebugPutc, 0); - else if (my_arg == (CELL) FAILCODE) - Yap_plwrite (MkAtomTerm (AtomFail), Yap_DebugPutc, 0); - else - Yap_plwrite (MkIntegerTerm ((Int) my_arg), - Yap_DebugPutc, 0); + write_address(my_arg); } break; case 'g': - if (arg & 1) - Yap_plwrite (MkIntTerm (arg), - Yap_DebugPutc, 0); - else if (arg == (CELL) FAILCODE) - Yap_plwrite (MkAtomTerm (AtomFail), Yap_DebugPutc, 0); - else - Yap_plwrite (MkIntegerTerm ((Int) arg), Yap_DebugPutc, 0); + write_address(arg); break; case 'i': - Yap_plwrite (MkIntTerm (arg), Yap_DebugPutc, 0); + write_address (arg); break; case 'j': { @@ -441,59 +458,40 @@ ShowOp (f) case 'c': { int i; - for (i = 0; i < arg; ++i) - { - CELL my_arg; - if (*cptr) - { - Yap_plwrite ((Term) * cptr++, Yap_DebugPutc, 0); - } - else - { - Yap_plwrite (MkIntTerm (0), Yap_DebugPutc, 0); - cptr++; - } - Yap_DebugPutc (Yap_c_error_stream,'\t'); - my_arg = *cptr++; - if (my_arg & 1) - Yap_plwrite (MkIntTerm (my_arg), - Yap_DebugPutc, 0); - else if (my_arg == (CELL) FAILCODE) - Yap_plwrite (MkAtomTerm (AtomFail), Yap_DebugPutc, 0); - else - Yap_plwrite (MkIntegerTerm ((Int) my_arg), Yap_DebugPutc, 0); - Yap_DebugPutc (Yap_c_error_stream,'\n'); + for (i = 0; i < arg; ++i) { + CELL my_arg; + Yap_DebugPutc(Yap_c_error_stream,'\t'); + if (*cptr) { + Yap_plwrite ((Term) * cptr++, Yap_DebugPutc, 0); + } else { + Yap_plwrite (MkIntTerm (0), Yap_DebugPutc, 0); + cptr++; } + Yap_DebugPutc (Yap_c_error_stream,'\t'); + my_arg = *cptr++; + write_address (my_arg); + if (i+1 < arg) + Yap_DebugPutc (Yap_c_error_stream,'\n'); + } } break; case 'e': { int i; - for (i = 0; i < arg; ++i) - { - CELL my_arg; - if (*cptr) - { - Yap_plwrite (MkAtomTerm (NameOfFunctor ((Functor) * cptr)), Yap_DebugPutc, 0); - Yap_DebugPutc (Yap_c_error_stream,'/'); - Yap_plwrite (MkIntTerm (ArityOfFunctor ((Functor) * cptr++)), Yap_DebugPutc, 0); - } - else - { - Yap_plwrite (MkIntTerm (0), Yap_DebugPutc, 0); - cptr++; - } - Yap_DebugPutc (Yap_c_error_stream,'\t'); - my_arg = *cptr++; - if (my_arg & 1) - Yap_plwrite (MkIntTerm (my_arg), - Yap_DebugPutc, 0); - else if (my_arg == (CELL) FAILCODE) - Yap_plwrite (MkAtomTerm (AtomFail), Yap_DebugPutc, 0); - else - Yap_plwrite (MkIntegerTerm ((Int) my_arg), Yap_DebugPutc, 0); - Yap_DebugPutc (Yap_c_error_stream,'\n'); + for (i = 0; i < arg; ++i) { + CELL my_arg = cptr[0], lbl = cptr[1]; + Yap_DebugPutc(Yap_c_error_stream,'\t'); + if (my_arg) { + write_functor((Functor)my_arg); + } else { + Yap_plwrite(MkIntTerm (0), Yap_DebugPutc, 0); } + Yap_DebugPutc(Yap_c_error_stream,'\t'); + write_address(lbl); + cptr += 2; + if (i+1 < arg) + Yap_DebugPutc(Yap_c_error_stream,'\n'); + } } break; default: @@ -554,6 +552,7 @@ static char *opformat[] = "deallocate", "try_me_else\t\t%l\t%x", "jump\t\t%l", + "jump\t\t%l", "procceed", "call\t\t%p,%d,%z", "execute\t\t%p", @@ -576,42 +575,14 @@ static char *opformat[] = "retry\t\t%g\t%x", "trust\t\t%g\t%x", "try_in\t\t%g\t%x", - "retry_in\t\t%g\t%x", - "trust_in\t\t%g\t%x", - "try_first\t\t%g\t%x", - "retry_first\t\t%g\t%x", - "trust_first\t\t%g\t%x", - "try_first in\t\t%g\t%x", - "retry_first in\t\t%g\t%x", - "trust_first in\t\t%g\t%x", - "try_tail\t\t%g\t%x", - "retry_tail\t\t%g\t%x", - "trust_tail\t\t%g\t%x", - "try_tail_in\t\t%g\t%x", - "retry_tail_in\t\t%g\t%x", - "trust_tail_in\t\t%g\t%x", - "try_head\t\t%g\t%x", - "retry_head\t\t%g\t%x", - "trust_head\t\t%g\t%x", - "try_head_in\t\t%g\t%x", - "retry_head_in\t\t%g\t%x", - "trust_head_in\t\t%g\t%x", - "try_last_first\t\t%g\t%x", - "try_last_head\t\t%g\t%x", "jump_if_var\t\t%g", + "cache_arg\t%r", + "cache_sub_arg\t%d", "switch_on_type\t%h\t%h\t%h\t%h", - "switch_on_type_if_nonvar\t%h\t%h\t%h", - "switch_on_type_of_last\t%h\t%h\t%h", - "switch_on_type_of_head\t%h\t%h\t%h\t%h", - "switch_on_list_or_nil\t%h\t%h\t%h\t%h", - "switch_if_list_or_nil\t%h\t%h\t%h", - "switch_on_last_list_or_nil\t%h\t%h\t%h", "switch_on_constant\t%i\n%c", - "if_a_constant\t%i\t%h\n%c", - "go_if_ equals_constant\t%o\t%h\t%h", + "if_constant\t%i\t%h\n%c", "switch_on_functor\t%i\n%e", - "if_a_functor\t%i\t%h\n%e", - "go_if_equals_functor\t%j\t%h\t%h", + "if_functor\t%i\t%h\n%e", "if_not_then\t%i\t%h\t%h\t%h", "save_pair\t%v", "save_appl\t%v", diff --git a/C/dbase.c b/C/dbase.c index e42953b9b..b4ccfdf4b 100644 --- a/C/dbase.c +++ b/C/dbase.c @@ -226,9 +226,9 @@ STATIC_PROTO(Int co_rdedp, (void)); STATIC_PROTO(Int p_first_instance, (void)); STATIC_PROTO(void ErasePendingRefs, (DBRef)); STATIC_PROTO(void RemoveDBEntry, (DBRef)); -STATIC_PROTO(void EraseLogUpdCl, (Clause *)); -STATIC_PROTO(void MyEraseClause, (Clause *)); -STATIC_PROTO(void PrepareToEraseClause, (Clause *, DBRef)); +STATIC_PROTO(void EraseLogUpdCl, (LogUpdClause *)); +STATIC_PROTO(void MyEraseClause, (DynamicClause *)); +STATIC_PROTO(void PrepareToEraseClause, (DynamicClause *, DBRef)); STATIC_PROTO(void EraseEntry, (DBRef)); STATIC_PROTO(Int p_erase, (void)); STATIC_PROTO(Int p_eraseall, (void)); @@ -3584,7 +3584,7 @@ find_next_clause(DBRef ref0) like if we were executing a standard retry_and_mark */ #if defined(YAPOR) || defined(THREADS) { - Clause *cl = ClauseCodeToClause(newp); + DynamicClause *cl = ClauseCodeToDynamicClause(newp); LOCK(cl->ClLock); TRAIL_CLREF(cl); @@ -3594,7 +3594,7 @@ find_next_clause(DBRef ref0) #else if (!DynamicFlags(newp) & InUseMask) { DynamicFlags(newp) |= InUseMask; - TRAIL_CLREF(ClauseCodeToClause(newp)); + TRAIL_CLREF(ClauseCodeToDynamicClause(newp)); } #endif return(newp); @@ -3621,8 +3621,10 @@ p_jump_to_next_dynamic_clause(void) } static void -EraseLogUpdCl(Clause *clau) +EraseLogUpdCl(LogUpdClause *clau) { + if (CL_IN_USE(clau)) + return; if (clau->ClFlags & IndexMask) { Yap_RemoveLogUpdIndex(clau); } else { @@ -3636,7 +3638,7 @@ EraseLogUpdCl(Clause *clau) } static void -MyEraseClause(Clause *clau) +MyEraseClause(DynamicClause *clau) { DBRef ref; SMALLUNSGN clmask; @@ -3644,10 +3646,6 @@ MyEraseClause(Clause *clau) if (CL_IN_USE(clau)) return; clmask = clau->ClFlags; - if (clmask & LogUpdMask) { - EraseLogUpdCl(clau); - return; - } /* I don't need to lock the clause at this point because I am the last one using it anyway. @@ -3684,7 +3682,17 @@ MyEraseClause(Clause *clau) lock on the current predicate */ void -Yap_ErCl(Clause *clau) +Yap_ErLogUpdCl(LogUpdClause *clau) +{ + EraseLogUpdCl(clau); +} + +/* + This predicate is supposed to be called with a + lock on the current predicate +*/ +void +Yap_ErCl(DynamicClause *clau) { MyEraseClause(clau); } @@ -3692,12 +3700,15 @@ Yap_ErCl(Clause *clau) #define TRYCODE(G,F,N) ( (N)<5 ? (op_numbers)((int)(F)+(N)*3) : G) static void -PrepareToEraseLogUpdClause(Clause *clau, DBRef dbr) +PrepareToEraseLogUpdClause(LogUpdClause *clau, DBRef dbr) { yamop *code_p = clau->ClCode; PredEntry *p = (PredEntry *)(code_p->u.ld.p); yamop *cl = code_p; + if (clau->ClFlags & ErasedMask) + return; + clau->ClFlags |= ErasedMask; WRITE_LOCK(p->PRWLock); if (p->cs.p_code.FirstClause != cl) { /* we are not the first clause... */ @@ -3720,8 +3731,7 @@ PrepareToEraseLogUpdClause(Clause *clau, DBRef dbr) if (p->PredFlags & IndexedPredFlag) { Yap_RemoveIndexation(p); } else { - if (!(clau->ClFlags & InUseMask)) - EraseLogUpdCl(clau); + EraseLogUpdCl(clau); } if (p->cs.p_code.FirstClause == p->cs.p_code.LastClause) { if (p->cs.p_code.FirstClause != NULL) { @@ -3731,11 +3741,9 @@ PrepareToEraseLogUpdClause(Clause *clau, DBRef dbr) if (p->PredFlags & SpiedPredFlag) { p->OpcodeOfPred = Yap_opcode(_spy_pred); p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); - p->StateOfPred = StaticMask | SpiedMask; } else { p->CodeOfPred = p->cs.p_code.TrueCodeOfPred; p->OpcodeOfPred = p->cs.p_code.TrueCodeOfPred->opc; - p->StateOfPred = StaticMask; } } else { p->OpcodeOfPred = FAIL_OPCODE; @@ -3750,11 +3758,12 @@ PrepareToEraseLogUpdClause(Clause *clau, DBRef dbr) p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); } } + p->cs.p_code.NOfClauses--; WRITE_UNLOCK(p->PRWLock); } static void -PrepareToEraseClause(Clause *clau, DBRef dbr) +PrepareToEraseClause(DynamicClause *clau, DBRef dbr) { yamop *code_p; @@ -3762,10 +3771,6 @@ PrepareToEraseClause(Clause *clau, DBRef dbr) if (clau->ClFlags & ErasedMask) return; clau->ClFlags |= ErasedMask; - if (clau->ClFlags & LogUpdMask) { - PrepareToEraseLogUpdClause(clau, dbr); - return; - } /* skip mask */ code_p = clau->ClCode; /* skip retry instruction */ @@ -3777,17 +3782,17 @@ PrepareToEraseClause(Clause *clau, DBRef dbr) /* first we get the next clause */ yamop *next = code_p->u.ld.d; /* then we get the previous clause */ - yamop *previous = clau->u.ClPrevious; + yamop *previous = clau->ClPrevious; yamop *clau_code; /* next we check if we still have clauses left in the chain */ if (previous != next) { yamop *previous_code = (yamop *)previous; - Clause *next_cl = ClauseCodeToClause(next); + DynamicClause *next_cl = ClauseCodeToDynamicClause(next); /* we do, let's say the previous now backtracks to the next */ previous_code->u.ld.d = next; /* and tell next who it is the previous element */ - next_cl->u.ClPrevious = previous_code; + next_cl->ClPrevious = previous_code; } /* that's it about setting up the code, now let's tell the predicate entry that a clause left. */ @@ -3817,7 +3822,7 @@ PrepareToEraseClause(Clause *clau, DBRef dbr) } #endif /* nothing left here, let's clean the shop */ - Yap_FreeCodeSpace(((char *) ClauseCodeToClause(pred->CodeOfPred))); + Yap_FreeCodeSpace(((char *) ClauseCodeToDynamicClause(pred->CodeOfPred))); pred->cs.p_code.LastClause = pred->cs.p_code.FirstClause = NULL; pred->OpcodeOfPred = FAIL_OPCODE; pred->cs.p_code.TrueCodeOfPred = pred->CodeOfPred = @@ -3827,6 +3832,7 @@ PrepareToEraseClause(Clause *clau, DBRef dbr) } else if (clau_code == pred->cs.p_code.LastClause) { pred->cs.p_code.LastClause = previous; } + pred->cs.p_code.NOfClauses--; WRITE_UNLOCK(pred->PRWLock); } /* make sure we don't directly point to anyone else */ @@ -3845,17 +3851,32 @@ ErDBE(DBRef entryref) { if ((entryref->Flags & DBCode) && entryref->Code) { - Clause *clau = ClauseCodeToClause(entryref->Code); - LOCK(clau->ClLock); - if (CL_IN_USE(clau) || entryref->NOfRefsTo != 0) { - PrepareToEraseClause(clau, entryref); - UNLOCK(clau->ClLock); + if (entryref->Flags & LogUpdMask) { + LogUpdClause *clau = ClauseCodeToLogUpdClause(entryref->Code); + LOCK(clau->ClLock); + if (CL_IN_USE(clau) || entryref->NOfRefsTo != 0) { + PrepareToEraseLogUpdClause(clau, entryref); + UNLOCK(clau->ClLock); + } else { + if (!(clau->ClFlags & ErasedMask)) + PrepareToEraseLogUpdClause(clau, entryref); + UNLOCK(clau->ClLock); + /* the clause must have left the chain */ + EraseLogUpdCl(clau); + } } else { - if (!(clau->ClFlags & ErasedMask)) + DynamicClause *clau = ClauseCodeToDynamicClause(entryref->Code); + LOCK(clau->ClLock); + if (CL_IN_USE(clau) || entryref->NOfRefsTo != 0) { PrepareToEraseClause(clau, entryref); - UNLOCK(clau->ClLock); - /* the clause must have left the chain */ - MyEraseClause(clau); + UNLOCK(clau->ClLock); + } else { + if (!(clau->ClFlags & ErasedMask)) + PrepareToEraseClause(clau, entryref); + UNLOCK(clau->ClLock); + /* the clause must have left the chain */ + MyEraseClause(clau); + } } } else if (!(DBREF_IN_USE(entryref))) { if (entryref->NOfRefsTo == 0) @@ -3908,7 +3929,11 @@ EraseEntry(DBRef entryref) if (!DBREF_IN_USE(entryref)) { ErDBE(entryref); } else if ((entryref->Flags & DBCode) && entryref->Code) { - PrepareToEraseClause(ClauseCodeToClause(entryref->Code), entryref); + if (p->KindOfPE & LogUpdDBBit) { + PrepareToEraseLogUpdClause(ClauseCodeToLogUpdClause(entryref->Code), entryref); + } else { + PrepareToEraseClause(ClauseCodeToDynamicClause(entryref->Code), entryref); + } } } diff --git a/C/exec.c b/C/exec.c index b21a6926e..680fb6b2d 100644 --- a/C/exec.c +++ b/C/exec.c @@ -143,16 +143,16 @@ CallClause(PredEntry *pen, Int position) CLAUSECODE->arity = pen->ArityOfPE; CLAUSECODE->func = pen->FunctorOfPred; while (position > 1) { - while (ClauseCodeToClause(q)->ClFlags & ErasedMask) + while (ClauseCodeToDynamicClause(q)->ClFlags & ErasedMask) q = NextClause(q); position--; q = NextClause(q); } - while (ClauseCodeToClause(q)->ClFlags & ErasedMask) + while (ClauseCodeToDynamicClause(q)->ClFlags & ErasedMask) q = NextClause(q); #if defined(YAPOR) || defined(THREADS) { - Clause *cl = ClauseCodeToClause(q); + DynamicClause *cl = ClauseCodeToDynamicClause(q); LOCK(cl->ClLock); TRAIL_CLREF(cl); @@ -160,9 +160,9 @@ CallClause(PredEntry *pen, Int position) UNLOCK(cl->ClLock); } #else - if (!(ClauseCodeToClause(q)->ClFlags & InUseMask)) { - CELL *opp = &(ClauseCodeToClause(q)->ClFlags); - TRAIL_CLREF(ClauseCodeToClause(q)); + if (!(ClauseCodeToDynamicClause(q)->ClFlags & InUseMask)) { + CELL *opp = &(ClauseCodeToDynamicClause(q)->ClFlags); + TRAIL_CLREF(ClauseCodeToDynamicClause(q)); *opp |= InUseMask; } #endif diff --git a/C/heapgc.c b/C/heapgc.c index ca6826059..4b9709e4e 100644 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -62,8 +62,6 @@ STATIC_PROTO(void push_registers, (Int, yamop *)); STATIC_PROTO(void marking_phase, (tr_fr_ptr, CELL *, yamop *, CELL *)); STATIC_PROTO(void compaction_phase, (tr_fr_ptr, CELL *, yamop *, CELL *)); STATIC_PROTO(void pop_registers, (Int, yamop *)); -STATIC_PROTO(void store_ref_in_dbtable, (DBRef)); -STATIC_PROTO(DBRef find_ref_in_dbtable, (DBRef)); STATIC_PROTO(void init_dbtable, (tr_fr_ptr)); STATIC_PROTO(void mark_db_fixed, (CELL *)); STATIC_PROTO(void mark_regs, (tr_fr_ptr)); @@ -479,19 +477,27 @@ count_cells_marked(void) /* straightforward binary tree scheme that, given a key, finds a matching dbref */ +typedef enum { + db_entry, + cl_entry, + lcl_entry, + dcl_entry +} db_entry_type; + typedef struct db_entry { - DBRef val; + CODEADDR val; + db_entry_type db_type; struct db_entry *left; - CELL *lim; + CODEADDR lim; struct db_entry *right; } *dbentry; -static dbentry db_vec, db_vec0; +static dbentry db_vec, db_vec0; /* init the table */ static void -store_ref_in_dbtable(DBRef entry) +store_in_dbtable(CODEADDR entry, db_entry_type db_type) { dbentry parent = db_vec0; dbentry new = db_vec; @@ -499,7 +505,8 @@ store_ref_in_dbtable(DBRef entry) if ((ADDR)new > Yap_TrailTop-1024) Yap_growtrail(64 * 1024L); new->val = entry; - new->lim = (CELL *)((CODEADDR)entry+Yap_SizeOfBlock((CODEADDR)entry)); + new->db_type = db_type; + new->lim = entry+Yap_SizeOfBlock((CODEADDR)entry); new->left = new->right = NULL; if (db_vec == db_vec0) { db_vec++; @@ -525,51 +532,15 @@ store_ref_in_dbtable(DBRef entry) } } -/* init the table */ -static void -store_cl_in_dbtable(Clause *cl) -{ - dbentry parent = db_vec0; - dbentry new = db_vec; - - if ((ADDR)new > Yap_TrailTop-1024) - Yap_growtrail(64 * 1024L); - new->val = (DBRef)cl; - new->lim = (CELL *)((CODEADDR)cl + Yap_SizeOfBlock((CODEADDR)cl)); - new->left = new->right = NULL; - if (db_vec == db_vec0) { - db_vec++; - return; - } - db_vec++; - parent = db_vec0; - beg: - if ((DBRef)cl < parent->val) { - if (parent->right == NULL) { - parent->right = new; - } else { - parent = parent->right; - goto beg; - } - } else { - if (parent->left == NULL) { - parent->left = new; - } else { - parent = parent->left; - goto beg; - } - } -} - /* find an element in the dbentries table */ -static DBRef -find_ref_in_dbtable(DBRef entry) +static dbentry +find_ref_in_dbtable(CODEADDR entry) { dbentry current = db_vec0; while (current != NULL) { - if (current->val < entry && current->lim > (CELL *)entry) { - return(current->val); + if (current->val < entry && current->lim > entry) { + return(current); } if (entry < current->val) current = current->right; @@ -581,16 +552,30 @@ find_ref_in_dbtable(DBRef entry) static void mark_db_fixed(CELL *ptr) { - DBRef el; + dbentry el; - el = find_ref_in_dbtable((DBRef)ptr); - if (el != NULL) - el->Flags |= GcFoundMask; + el = find_ref_in_dbtable((CODEADDR)ptr); + if (el != NULL) { + switch (el->db_type) { + case db_entry: + ((DBRef)(el->val))->Flags |= GcFoundMask; + break; + case cl_entry: + ((DynamicClause *)(el->val))->ClFlags |= GcFoundMask; + break; + case lcl_entry: + ((LogUpdClause *)(el->val))->ClFlags |= GcFoundMask; + break; + case dcl_entry: + ((DeadClause *)(el->val))->ClFlags |= GcFoundMask; + break; + } + } } static void init_dbtable(tr_fr_ptr trail_ptr) { - Clause *cl = DeadClauses; + DeadClause *cl = DeadClauses; db_vec0 = db_vec = (dbentry)TR; while (trail_ptr > (tr_fr_ptr)Yap_TrailBase) { @@ -603,7 +588,6 @@ init_dbtable(tr_fr_ptr trail_ptr) { if (!IsVarTerm(trail_cell) && IsPairTerm(trail_cell)) { CELL *pt0 = RepPair(trail_cell); /* DB pointer */ - CODEADDR entry; CELL flags; #ifdef FROZEN_STACKS /* TRAIL */ @@ -619,20 +603,21 @@ init_dbtable(tr_fr_ptr trail_ptr) { } #endif /* FROZEN_STACKS */ - flags = Flags((CELL)pt0); + flags = *pt0; /* for the moment, if all references to the term in the stacks are only pointers, reset the flag */ - entry = ((CODEADDR)pt0 - (CELL) &(((DBRef) NIL)->Flags)); if (FlagOn(DBClMask, flags)) { - store_ref_in_dbtable((DBRef)entry); + store_in_dbtable((CODEADDR)DBStructFlagsToDBStruct(pt0), db_entry); + } else if (flags & LogUpdMask) { + store_in_dbtable((CODEADDR)ClauseFlagsToLogUpdClause(pt0), lcl_entry); } else { - store_cl_in_dbtable((Clause *)entry); + store_in_dbtable((CODEADDR)ClauseFlagsToDynamicClause(pt0), cl_entry); } } } while (cl != NULL) { - store_cl_in_dbtable(cl); - cl = cl->u.NextCl; + store_in_dbtable((CODEADDR)cl, dcl_entry); + cl = cl->NextCl; } if (db_vec == db_vec0) { /* could not find any entries: probably using LOG UPD semantics */ @@ -1121,15 +1106,12 @@ mark_environments(CELL_PTR gc_ENV, OPREG size, CELL *pvbmap) while (gc_ENV != NULL) { /* no more environments */ Int bmap = 0; int currv = 0; - Clause *cl; #ifdef DEBUG if (size < 0 || size > 512) fprintf(Yap_stderr,"Oops, env size for %p is %ld\n", gc_ENV, (unsigned long int)size); #endif - if ((cl = (Clause *)find_ref_in_dbtable((DBRef)gc_ENV[E_CP])) != NULL) { - cl->ClFlags |= GcFoundMask; - } + mark_db_fixed((CELL *)gc_ENV[E_CP]); /* for each saved variable */ if (size > EnvSizeInCells) { int tsize = size - EnvSizeInCells; @@ -1435,14 +1417,10 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) op_numbers opnum; register OPCODE op; yamop *rtp = gc_B->cp_ap; - Clause *cl; - if ((cl = (Clause *)find_ref_in_dbtable((DBRef)rtp)) != NULL) { - cl->ClFlags |= GcFoundMask; - } - if ((cl = (Clause *)find_ref_in_dbtable((DBRef)(gc_B->cp_b))) != NULL) { - cl->ClFlags |= GcFoundMask; - } + mark_db_fixed((CELL *)rtp); + mark_db_fixed((CELL *)(gc_B->cp_ap)); + mark_db_fixed((CELL *)(gc_B->cp_cp)); #ifdef EASY_SHUNTING current_B = gc_B; prev_HB = HB; @@ -1472,8 +1450,6 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) case _or_else: case _or_last: case _Nstop: - case _switch_last: - case _switch_l_list: case _retry_userc: case _trust_logical_pred: case _retry_profiled: @@ -1582,10 +1558,6 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) /* this is the last choice point, the work is done ;-) */ return; } - case _switch_last: - case _switch_l_list: - nargs = rtp->u.slll.s; - break; case _retry_c: case _retry_userc: if (gc_B->cp_ap == RETRY_C_RECORDED_CODE @@ -1721,7 +1693,7 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) case _profiled_retry_and_mark: case _count_retry_and_mark: case _retry_and_mark: - ClauseCodeToClause(gc_B->cp_ap)->ClFlags |= GcFoundMask; + ClauseCodeToDynamicClause(gc_B->cp_ap)->ClFlags |= GcFoundMask; #ifdef DEBUG case _retry_me: case _trust_me: @@ -1740,19 +1712,14 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) case _retry_me4: case _trust_me4: case _retry: - case _trust_in: case _trust: - case _retry_first: - case _trust_first_in: - case _trust_first: - case _retry_tail: - case _trust_tail_in: - case _trust_tail: - case _retry_head: - case _trust_head_in: - case _trust_head: nargs = rtp->u.ld.s; break; + case _jump: + rtp = rtp->u.l.l; + op = rtp->opc; + opnum = Yap_op_from_opcode(op); + goto restart_cp; default: fprintf(Yap_stderr, "OOps in GC: Unexpected opcode: %d\n", opnum); nargs = 0; @@ -1832,7 +1799,6 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR) Int hp_entrs = 0, hp_erased = 0, hp_not_in_use = 0, hp_in_use_erased = 0, code_entries = 0; #endif - Clause **cptr, *cl; #ifndef FROZEN_STACKS /* @@ -1932,7 +1898,7 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR) continue; } #endif /* FROZEN_STACKS */ - flags = Flags((CELL)pt0); + flags = *pt0; #ifdef DEBUG hp_entrs++; if (!FlagOn(GcFoundMask, flags)) { @@ -1958,25 +1924,42 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR) Yap_ErDBE(dbr); } } else { - Clause *cl = ClauseFlagsToClause((CELL)pt0); - int erase; - DEC_CLREF_COUNT(cl); - cl->ClFlags &= ~InUseMask; - erase = (cl->ClFlags & ErasedMask) + if (flags & LogUpdMask) { + LogUpdClause *cl = ClauseFlagsToLogUpdClause(pt0); + int erase; + DEC_CLREF_COUNT(cl); + cl->ClFlags &= ~InUseMask; + erase = (cl->ClFlags & ErasedMask) #if defined(YAPOR) || defined(THREADS) - && (cl->ref_count == 0) + && (cl->ref_count == 0) #endif ; - if (erase) { - /* at this point, - no one is accessing the clause */ - Yap_ErCl(cl); + if (erase) { + /* at this point, + no one is accessing the clause */ + Yap_ErLogUpdCl(cl); + } + } else { + DynamicClause *cl = ClauseFlagsToDynamicClause(pt0); + int erase; + DEC_CLREF_COUNT(cl); + cl->ClFlags &= ~InUseMask; + erase = (cl->ClFlags & ErasedMask) +#if defined(YAPOR) || defined(THREADS) + && (cl->ref_count == 0) +#endif + ; + if (erase) { + /* at this point, + no one is accessing the clause */ + Yap_ErCl(cl); + } } } RESET_VARIABLE(&TrailTerm(dest)); discard_trail_entries++; } else { - Flags((CELL)pt0) = ResetFlag(GcFoundMask, flags); + *pt0 = ResetFlag(GcFoundMask, flags); } #if MULTI_ASSIGNMENT_VARIABLES } else { @@ -2057,18 +2040,23 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR) (unsigned long int)((OldHeapUsed-HeapUsed)/(OldHeapUsed/100)), (unsigned long int)OldHeapUsed); } - cptr = &(DeadClauses); - cl = DeadClauses; - while (cl != NULL) { - if (!(cl->ClFlags & GcFoundMask)) { - char *ocl = (char *)cl; - cl = cl->u.NextCl; - *cptr = cl; - Yap_FreeCodeSpace(ocl); - } else { - cl->ClFlags &= ~GcFoundMask; - cptr = &(cl->u.NextCl); - cl = cl->u.NextCl; + { + DeadClause **cptr; + DeadClause *cl; + + cptr = &(DeadClauses); + cl = DeadClauses; + while (cl != NULL) { + if (!(cl->ClFlags & GcFoundMask)) { + char *ocl = (char *)cl; + cl = cl->NextCl; + *cptr = cl; + Yap_FreeCodeSpace(ocl); + } else { + cl->ClFlags &= ~GcFoundMask; + cptr = &(cl->NextCl); + cl = cl->NextCl; + } } } } @@ -2235,6 +2223,11 @@ sweep_choicepoints(choiceptr gc_B) op = rtp->opc; opnum = Yap_op_from_opcode(op); goto restart_cp; + case _jump: + rtp = rtp->u.l.l; + op = rtp->opc; + opnum = Yap_op_from_opcode(op); + goto restart_cp; #ifdef TABLING case _table_answer_resolution: { diff --git a/C/index.c b/C/index.c index 259abfc1f..34c1d6db4 100644 --- a/C/index.c +++ b/C/index.c @@ -24,6 +24,23 @@ static char SccsId[] = "%W% %G%"; * Some remarks: *try_me always point to inside the code; * try always points to outside * + + Algorithm: + + - fetch info on all clauses + - if #clauses =1 return + - compute groups: + seq of variable only clauses + seq: of one or more type instructions + bound clauses + - sort group + - select constant + --> type instructions + --> count constants + --> switch + for all arguments: + select new argument + */ #include "Yap.h" @@ -39,1289 +56,2651 @@ static char SccsId[] = "%W% %G%"; #ifndef NULL #define NULL (void *)0 #endif +#if HAVE_STRING_H +#include +#endif -STATIC_PROTO(int clause_has_cut, (yamop *)); -STATIC_PROTO(int followed_by_cut, (yamop *)); -STATIC_PROTO(void emit_tr, (compiler_vm_op, yamop *, int, int)); -STATIC_PROTO(void emit_try, (compiler_vm_op, int, yamop *, int, int)); -STATIC_PROTO(yamop * Body, (yamop *)); -STATIC_PROTO(yamop * SecB, (yamop *)); -STATIC_PROTO(yamop * SecLB, (yamop *)); -STATIC_PROTO(yamop * ThiB, (yamop *)); -STATIC_PROTO(yamop * ThiLB, (yamop *)); -STATIC_PROTO(void emit_cp_inst, (compiler_vm_op, yamop *, int, int)); -STATIC_PROTO(CELL emit_space, (compiler_vm_op, int, int)); -STATIC_PROTO(CELL emit_go, (int, Term)); -STATIC_PROTO(void emit_if_not, (Term, CELL, CELL)); -STATIC_PROTO(void fill_go, (CELL *, CELL)); -STATIC_PROTO(void fill_switch_slots, (CELL *, CELL, CELL, CELL, CELL, int)); -STATIC_PROTO(void ClrSpace, (CELL *, int)); -STATIC_PROTO(int NGroupsIn, (PredEntry *)); -STATIC_PROTO(void CountGroups, (GroupDef *, int)); -STATIC_PROTO(yamop *FindFirst, (int, int)); -STATIC_PROTO(int SizeTable, (int)); -STATIC_PROTO(void BuildHash, (CELL *, int, int, int)); -STATIC_PROTO(void BuildIfTable, (CELL *, int)); -STATIC_PROTO(void TreatEntry, (EntryDef *, int, int, GroupDef *)); -STATIC_PROTO(CELL DealFixed, (ClauseDef *, int, compiler_vm_op, int, GroupDef *)); -STATIC_PROTO(CELL DealFixedWithBips, (ClauseDef *, int, int, GroupDef *)); -STATIC_PROTO(CELL DealCons, (int)); -STATIC_PROTO(CELL DealAppl, (int)); -STATIC_PROTO(CELL StartList, (int)); -STATIC_PROTO(CELL DealLAt, (ClauseDef *, int, int)); -STATIC_PROTO(CELL DealLAppl, (ClauseDef *, int, int)); -STATIC_PROTO(CELL DealLList, (ClauseDef *, int, int, int)); -STATIC_PROTO(int NoHeadVar, (ClauseDef *, int)); -STATIC_PROTO(CELL DealList, (int)); -STATIC_PROTO(CELL GetFailToGo, (int)); -STATIC_PROTO(int IsExtendedSingle, (int)); -STATIC_PROTO(int gr_has_cuts, (GroupDef *)); -STATIC_PROTO(void EmitGrSwitch, (int)); -STATIC_PROTO(int IndexNonVarGr, (int)); -STATIC_PROTO(void IndexVarGr, (int)); -STATIC_PROTO(int SimpleCase, (void)); -STATIC_PROTO(int ComplexCase, (void)); -STATIC_PROTO(int SpecialCases, (void)); +UInt STATIC_PROTO(do_index, (ClauseDef *,ClauseDef *,PredEntry *,UInt,UInt,int,int,CELL *)); +UInt STATIC_PROTO(do_compound_index, (ClauseDef *,ClauseDef *,PredEntry *,UInt,UInt,UInt,int,int,int,CELL *)); -static int NClauses, NGroups; - -static ClauseDef *ArOfCl; - -static GroupDef *Groups; - -static EntryDef *Entries; - -static CELL labelno; - -static int ExtendedSingle, AtomsOnlyNil; - -static yamop *FailAddress; - -static CELL *StorePoint; - -static yamop * FirstCl; - -static int RemovedCl; /* There were some clauses removed */ - -static yamop * indexed_code_for_cut = NIL; - -static CELL log_update; +static UInt labelno; static inline int -clause_has_cut(yamop * C) +smaller(Term t1, Term t2) { -#ifdef YAPOR - return(YAMOP_CUT(C)); -#else - return(FALSE); -#endif /* YAPOR */ + if (IsVarTerm(t1)) { + if (!IsVarTerm(t2)) return TRUE; + return (t1 < t2); + } else if (IsIntTerm(t1)) { + if (IsVarTerm(t2)) return FALSE; + if (!IsIntTerm(t2)) return TRUE; + return (IntOfTerm(t1) < IntOfTerm(t2)); + } else if (IsAtomTerm(t1)) { + if (IsVarTerm(t2) || IsIntTerm(t2)) return FALSE; + if (IsApplTerm(t2) || IsPairTerm(t2)) return TRUE; + return (t1 < t2); + } else if (IsApplTerm(t1)) { + if (IsVarTerm(t2) || IsAtomTerm(t2) || IsIntTerm(t2)) return FALSE; + if (IsPairTerm(t2)) return TRUE; + return (t1 < t2); + } else /* if (IsPairTerm(t1)) */ { + return FALSE; + } +} + +static inline void +clcpy(ClauseDef *d, ClauseDef *s) +{ + memcpy((void *)d, (void *)s, sizeof(ClauseDef)); } /* - Detect whether the next instruction is a cut. - Only useful for try and friends. + original code from In Hyuk Choi, + found at http://userpages.umbc.edu/~ichoi1/project/cs441.htm */ -static int followed_by_cut(yamop * code) + +static inline void +exchange(ClauseDef b[], Int i, Int j) { - register yamop *p = code; - while (TRUE) - { - if (p->opc == Yap_opcode(_get_x_var)) - p = NEXTOP(p,xx); - if (p->opc == Yap_opcode(_get_y_var)) - p = NEXTOP(p,yx); - else if (p->opc == Yap_opcode(_allocate)) - p = NEXTOP(p,e); - else if (p->opc == Yap_opcode(_unify_x_var)) - p = NEXTOP(p,ox); - else if (p->opc == Yap_opcode(_unify_y_var)) - p = NEXTOP(p,oy); - else if (p->opc == Yap_opcode(_unify_l_x_var)) - p = NEXTOP(p,ox); - else if (p->opc == Yap_opcode(_unify_l_y_var)) - p = NEXTOP(p,oy); - else if (p->opc == Yap_opcode(_unify_void)) - p = NEXTOP(p,o); - else if (p->opc == Yap_opcode(_unify_n_voids)) - p = NEXTOP(p,os); - else if (p->opc == Yap_opcode(_unify_l_void)) - p = NEXTOP(p,o); - else if (p->opc == Yap_opcode(_unify_l_n_voids)) - p = NEXTOP(p,os); - else if (p->opc == Yap_opcode(_cut)) - return(TRUE); - else if (p->opc == Yap_opcode(_cut_t)) - return(TRUE); - else if (p->opc == Yap_opcode(_cut_e)) - return(TRUE); - else return(FALSE); - } - /* make lcc happy */ - return(FALSE); + ClauseDef t; + + clcpy(&t, b+j); + clcpy(b+j, b+i); + clcpy(b+i, &t); } +static UInt +partition(ClauseDef a[], Int p, Int r) +{ + Term x; + UInt i, j; -/* emits an opcode followed by an adress */ -inline static void -emit_tr(compiler_vm_op op, yamop * Address, int NClauses, int HasCut) -{ - Yap_emit(op, Unsigned(Address), (NClauses << 1) + HasCut); -} + x = a[p].Tag; + i = p+1; + j = r; -/* emits an opcode followed by an adress */ -static void -emit_try(compiler_vm_op op, int op_offset, yamop * Address, int NClauses, int HasCut) -{ - if (op == try_op) { - /* if a try, then try to use cuts if possible */ - indexed_code_for_cut = NIL; - if (followed_by_cut(Address)) { - indexed_code_for_cut = Address; - return; + while (smaller(x,a[j].Tag) && i < j) { + j--; + } + while (smaller(a[i].Tag, x) && i < j) { + i++; + } + while(i < j) { + exchange(a, i, j); + i++; + j--; + while (smaller(x, a[j].Tag) && i < j) { + j--; + } + while (smaller(a[i].Tag, x) && i < j) { + i++; } } - Yap_emit((compiler_vm_op)((int)op + op_offset), Unsigned(Address), (NClauses << 1) + HasCut); + if (smaller(x, a[i].Tag)) + i--; + exchange(a, p, i); + return(i); } -/* - * compute address of first instruction of clause: try addr,n - */ -inline static yamop * -Body(yamop * Arg) +static void +insort(ClauseDef a[], Int p, Int q) { - return (NEXTOP(Arg,ld)); + Int j; + + for (j = p+1; j <= q; j ++) { + ClauseDef key; + Int i; + + clcpy(&key, a+j); + i = j; + + while (i > p && smaller(key.Tag,a[i-1].Tag)) { + clcpy(a+i, a+(i-1)); + i --; + } + clcpy(a+i, &key); + } } -/* - * compute address of instruction after get_atom or get_struct try - * addr,n get_atom atom,reg - */ -inline static yamop * -SecB(yamop * Arg) + +static void +quicksort(ClauseDef a[], Int p, Int r) +{ + Int q; + if (p < r) { + if (r - p < 100) { + insort(a, p, r); + return; + } + exchange(a, p, (p+r)/2); + q = partition (a, p, r); + quicksort(a, p, q-1); + quicksort(a, q + 1, r); + } +} + +/* sort a group of clauses by using their tags */ +static void +sort_group(GroupDef *grp) { - yamop *pc = NEXTOP(Arg,ld); - if (pc->opc == Yap_opcode(_get_struct)) - return (NEXTOP(pc,xf)); - else - return (NEXTOP(pc,xc)); + quicksort(grp->FirstClause, 0, grp->LastClause-grp->FirstClause); } -/* - * compute address of instruction after get_list try addr,n - * et_list reg - */ -inline static yamop * -SecLB(yamop * Arg) +/* add copy to register stack for original reg */ +static int +add_regcopy(wamreg regs[MAX_REG_COPIES], int regs_count, wamreg copy) { - return (NEXTOP(NEXTOP(Arg,ld),x)); + if (regs_count == MAX_REG_COPIES) { + regs[0] = copy; + } + regs[regs_count] = copy; + return regs_count+1; } -/* - * compute address of instruction after get_list and unify try - * addr,n get_list reg - * nify_atom atom - */ -inline static yamop * -ThiB(yamop * Arg) +/* add copy to register stack for original reg */ +static int +delete_regcopy(wamreg regs[MAX_REG_COPIES], int regs_count, wamreg copy) { - yamop *pc = NEXTOP(NEXTOP(Arg,ld),x); - if (pc->opc == Yap_opcode(_unify_struct)) - return (NEXTOP(pc,of)); - else - return (NEXTOP(pc,oc)); + int i = 0; + while (i < regs_count) { + if (regs[i] == copy) { + /* we found it */ + regs[i] = regs[MAX_REG_COPIES-1]; + return regs_count-1; + } + i++; + } + /* this copy had overflowed */ + return regs_count; } -/* - * compute address of instruction after get_list unify_list try - * addr,n get_list reg unify_list - */ -inline static yamop * -ThiLB(yamop * Arg) +/* add copy to register stack for original reg */ +inline static int +regcopy_in(wamreg regs[MAX_REG_COPIES], int regs_count, wamreg copy) { - return ( NEXTOP(NEXTOP(NEXTOP(Arg,ld),x),o)); + int i = 0; + while (i < regs_count) { + if (regs[i] == copy) { + return TRUE; + } + i++; + } + /* this copy could not be found */ + return FALSE; +} + +/* Restores a prolog clause, in its compiled form */ +static int +has_cut(yamop *pc) +/* + * Cl points to the start of the code, IsolFlag tells if we have a single + * clause for this predicate or not + */ +{ + do { + op_numbers op = Yap_op_from_opcode(pc->opc); + pc->opc = Yap_opcode(op); + switch (op) { + case _Ystop: + case _Nstop: + return FALSE; + /* instructions type ld */ + case _cut: + case _cut_t: + case _cut_e: + case _p_cut_by_y: + case _p_cut_by_x: + case _comit_b_y: + case _comit_b_x: + return TRUE; + case _try_me: + case _retry_me: + case _trust_me: + case _profiled_retry_me: + case _profiled_trust_me: + case _count_retry_me: + case _count_trust_me: + case _try_me0: + case _retry_me0: + case _trust_me0: + case _try_me1: + case _retry_me1: + case _trust_me1: + case _try_me2: + case _retry_me2: + case _trust_me2: + case _try_me3: + case _retry_me3: + case _trust_me3: + case _try_me4: + case _retry_me4: + case _trust_me4: + case _spy_or_trymark: + case _try_and_mark: + case _profiled_retry_and_mark: + case _count_retry_and_mark: + case _retry_and_mark: + case _try_clause: + case _retry: + case _trust: +#ifdef YAPOR + case _getwork: + case _getwork_seq: + case _sync: +#endif +#ifdef TABLING + case _table_try_me_single: + case _table_try_me: + case _table_retry_me: + case _table_trust_me: + case _table_answer_resolution: + case _table_completion: +#endif + pc = NEXTOP(pc,ld); + break; + /* instructions type l */ + case _enter_profiling: + case _count_call: + case _retry_profiled: + case _count_retry: + case _try_logical_pred: + case _trust_logical_pred: + case _execute: + case _dexecute: + case _jump: + case _move_back: + case _skip: + case _jump_if_var: + case _try_in: + pc = NEXTOP(pc,l); + break; + /* instructions type EC */ + case _alloc_for_logical_pred: + pc = NEXTOP(pc,EC); + break; + /* instructions type e */ + case _trust_fail: + case _op_fail: + case _procceed: + case _allocate: + case _deallocate: + case _write_void: + case _write_list: + case _write_l_list: +#if !defined(YAPOR) + case _or_last: +#endif + case _pop: + case _index_pred: + case _undef_p: + case _spy_pred: + case _p_equal: + case _p_dif: + case _p_eq: + case _p_functor: + case _p_execute_tail: + case _enter_a_profiling: + case _count_a_call: +#ifdef YAPOR + case _getwork_first_time: +#endif +#ifdef TABLING + case _trie_do_var: + case _trie_trust_var: + case _trie_try_var: + case _trie_retry_var: + case _trie_do_val: + case _trie_trust_val: + case _trie_try_val: + case _trie_retry_val: + case _trie_do_atom: + case _trie_trust_atom: + case _trie_try_atom: + case _trie_retry_atom: + case _trie_do_list: + case _trie_trust_list: + case _trie_try_list: + case _trie_retry_list: + case _trie_do_struct: + case _trie_trust_struct: + case _trie_try_struct: + case _trie_retry_struct: +#endif + pc = NEXTOP(pc,e); + break; + /* instructions type x */ + case _save_b_x: + case _get_list: + case _put_list: + case _write_x_var: + case _write_x_val: + case _write_x_loc: + case _p_atom_x: + case _p_atomic_x: + case _p_integer_x: + case _p_nonvar_x: + case _p_number_x: + case _p_var_x: + case _p_db_ref_x: + case _p_primitive_x: + case _p_compound_x: + case _p_float_x: + pc = NEXTOP(pc,x); + break; + /* instructions type y */ + case _save_b_y: + case _write_y_var: + case _write_y_val: + case _write_y_loc: + case _p_atom_y: + case _p_atomic_y: + case _p_integer_y: + case _p_nonvar_y: + case _p_number_y: + case _p_var_y: + case _p_db_ref_y: + case _p_primitive_y: + case _p_compound_y: + case _p_float_y: + pc = NEXTOP(pc,y); + break; + /* instructions type sla */ + case _p_execute: + case _fcall: + case _call: +#ifdef YAPOR + case _or_last: +#endif + pc = NEXTOP(pc,sla); + break; + /* instructions type sla, but for disjunctions */ + case _either: + case _or_else: + pc = NEXTOP(pc,sla); + break; + /* instructions type sla, but for functions */ + case _call_cpred: + case _call_usercpred: + pc = NEXTOP(pc,sla); + break; + /* instructions type xx */ + case _get_x_var: + case _get_x_val: + case _glist_valx: + case _gl_void_varx: + case _gl_void_valx: + case _put_x_var: + case _put_x_val: + pc = NEXTOP(pc,xx); + break; + /* instructions type yx */ + case _get_y_var: + case _get_y_val: + case _put_y_var: + case _put_y_val: + case _put_unsafe: + pc = NEXTOP(pc,yx); + break; + /* instructions type xc */ + case _get_atom: + case _put_atom: + case _get_float: + case _get_longint: + case _get_bigint: + pc = NEXTOP(pc,xc); + break; + /* instructions type xf */ + case _get_struct: + case _put_struct: + pc = NEXTOP(pc,xf); + break; + /* instructions type xy */ + case _glist_valy: + case _gl_void_vary: + case _gl_void_valy: + pc = NEXTOP(pc,xy); + break; + /* instructions type ox */ + case _unify_x_var: + case _unify_x_var_write: + case _unify_l_x_var: + case _unify_l_x_var_write: + case _unify_x_val_write: + case _unify_x_val: + case _unify_l_x_val_write: + case _unify_l_x_val: + case _unify_x_loc_write: + case _unify_x_loc: + case _unify_l_x_loc_write: + case _unify_l_x_loc: + case _save_pair_x_write: + case _save_pair_x: + case _save_appl_x_write: + case _save_appl_x: + pc = NEXTOP(pc,ox); + break; + /* instructions type oxx */ + case _unify_x_var2: + case _unify_x_var2_write: + case _unify_l_x_var2: + case _unify_l_x_var2_write: + pc = NEXTOP(pc,oxx); + break; + /* instructions type oy */ + case _unify_y_var: + case _unify_y_var_write: + case _unify_l_y_var: + case _unify_l_y_var_write: + case _unify_y_val_write: + case _unify_y_val: + case _unify_l_y_val_write: + case _unify_l_y_val: + case _unify_y_loc_write: + case _unify_y_loc: + case _unify_l_y_loc_write: + case _unify_l_y_loc: + case _save_pair_y_write: + case _save_pair_y: + case _save_appl_y_write: + case _save_appl_y: + pc = NEXTOP(pc,oy); + break; + /* instructions type o */ + case _unify_void_write: + case _unify_void: + case _unify_l_void_write: + case _unify_l_void: + case _unify_list_write: + case _unify_list: + case _unify_l_list_write: + case _unify_l_list: + pc = NEXTOP(pc,o); + break; + /* instructions type os */ + case _unify_n_voids_write: + case _unify_n_voids: + case _unify_l_n_voids_write: + case _unify_l_n_voids: + pc = NEXTOP(pc,os); + break; + /* instructions type oc */ + case _unify_atom_write: + case _unify_atom: + case _unify_l_atom_write: + case _unify_l_atom: + case _unify_float: + case _unify_l_float: + case _unify_longint: + case _unify_l_longint: + case _unify_bigint: + case _unify_l_bigint: + pc = NEXTOP(pc,oc); + break; + /* instructions type osc */ + case _unify_n_atoms_write: + case _unify_n_atoms: + pc = NEXTOP(pc,osc); + break; + /* instructions type of */ + case _unify_struct_write: + case _unify_struct: + case _unify_l_struc_write: + case _unify_l_struc: + pc = NEXTOP(pc,of); + break; + /* instructions type s */ + case _write_n_voids: + case _pop_n: +#ifdef TABLING + case _table_new_answer: +#endif + pc = NEXTOP(pc,s); + break; + /* instructions type ps */ + case _write_atom: + pc = NEXTOP(pc,c); + break; + /* instructions type sc */ + case _write_n_atoms: + pc = NEXTOP(pc,sc); + break; + /* instructions type f */ + case _write_struct: + case _write_l_struc: + pc = NEXTOP(pc,f); + break; + /* instructions type sdl */ + case _call_c_wfail: + pc = NEXTOP(pc,sdl); + break; + /* instructions type lds */ + case _try_c: + case _try_userc: + pc = NEXTOP(pc,lds); + break; + case _retry_c: + case _retry_userc: + pc = NEXTOP(pc,lds); + break; + /* instructions type llll */ + case _switch_on_type: + pc = NEXTOP(pc,llll); + break; + case _switch_list_nl: + pc = NEXTOP(pc,ollll); + break; + case _switch_on_arg_type: + pc = NEXTOP(pc,xllll); + break; + case _switch_on_sub_arg_type: + pc = NEXTOP(pc,sllll); + break; + /* instructions type lll */ + /* instructions type cll */ + case _if_not_then: + pc = NEXTOP(pc,cll); + break; + /* instructions type ollll */ + case _switch_on_func: + case _switch_on_cons: + case _if_func: + case _if_cons: + { + int i; + CELL *startcode; + + i = pc->u.s.s; + startcode = (CELL *)NEXTOP(pc,s); + pc = (yamop *)(startcode+2*i); + } + break; + case _go_on_func: + pc = NEXTOP(pc,fll); + break; + /* instructions type cll */ + case _go_on_cons: + pc = NEXTOP(pc,cll); + break; + /* instructions type xxx */ + case _p_plus_vv: + case _p_minus_vv: + case _p_times_vv: + case _p_div_vv: + case _p_and_vv: + case _p_or_vv: + case _p_sll_vv: + case _p_slr_vv: + case _p_arg_vv: + case _p_func2s_vv: + case _p_func2f_xx: + pc = NEXTOP(pc,xxx); + break; + /* instructions type xxc */ + case _p_plus_vc: + case _p_minus_cv: + case _p_times_vc: + case _p_div_cv: + case _p_and_vc: + case _p_or_vc: + case _p_sll_vc: + case _p_slr_vc: + case _p_func2s_vc: + pc = NEXTOP(pc,xxc); + break; + case _p_div_vc: + case _p_sll_cv: + case _p_slr_cv: + case _p_arg_cv: + pc = NEXTOP(pc,xcx); + break; + case _p_func2s_cv: + pc = NEXTOP(pc,xcx); + break; + /* instructions type xyx */ + case _p_func2f_xy: + pc = NEXTOP(pc,xyx); + break; + /* instructions type yxx */ + case _p_plus_y_vv: + case _p_minus_y_vv: + case _p_times_y_vv: + case _p_div_y_vv: + case _p_and_y_vv: + case _p_or_y_vv: + case _p_sll_y_vv: + case _p_slr_y_vv: + case _p_arg_y_vv: + case _p_func2s_y_vv: + case _p_func2f_yx: + pc = NEXTOP(pc,yxx); + break; + /* instructions type yyx */ + case _p_func2f_yy: + pc = NEXTOP(pc,yyx); + break; + /* instructions type yxc */ + case _p_plus_y_vc: + case _p_minus_y_cv: + case _p_times_y_vc: + case _p_div_y_vc: + case _p_div_y_cv: + case _p_and_y_vc: + case _p_or_y_vc: + case _p_sll_y_vc: + case _p_slr_y_vc: + case _p_func2s_y_vc: + pc = NEXTOP(pc,yxc); + break; + /* instructions type ycx */ + case _p_sll_y_cv: + case _p_slr_y_cv: + case _p_arg_y_cv: + pc = NEXTOP(pc,ycx); + break; + /* instructions type lxx */ + case _p_func2s_y_cv: + pc = NEXTOP(pc,ycx); + break; + /* instructions type lxx */ + case _call_bfunc_xx: + pc = NEXTOP(pc,lxx); + break; + /* instructions type lxy */ + case _call_bfunc_yx: + case _call_bfunc_xy: + pc = NEXTOP(pc,lxy); + break; + case _call_bfunc_yy: + pc = NEXTOP(pc,lyy); + break; + } + } while (TRUE); } -/* emits a try, retry or trust, optimizing for a particular case */ static void -emit_cp_inst(compiler_vm_op op, yamop * Address, int Flag, int NClausesAfter) +add_info(ClauseDef *clause, UInt regno) { - int HasCut = clause_has_cut(Address); - - indexed_code_for_cut = NIL; - if (op != try_op && profiling) - Yap_emit(retry_profiled_op, Unsigned(CurrentPred), Zero); - else if (op != try_op && call_counting) - Yap_emit(count_retry_op, Unsigned(CurrentPred), Zero); - if (NGroups == 1) - Flag = Flag | LoneGroup; - else if (Flag & LastGroup) { - if (op == try_op) { - Flag &= (FirstIndex | LastFoundList | HeadIndex | IsAtom); - switch (Flag) { - case 0: - emit_tr(trylf_op, Body(Address), NClausesAfter, HasCut); - return; - case FirstIndex | LastFoundList: - emit_tr(trylf_op, SecLB(Address), NClausesAfter, HasCut); - return; - case FirstIndex | IsAtom: - emit_tr(retry_op, SecB(Address), NClausesAfter, HasCut); - return; - case FirstIndex: - emit_tr(trylf_op, SecB(Address), NClausesAfter, HasCut); - return; - case HeadIndex | LastFoundList: - emit_tr(trylh_op, ThiLB(Address), NClausesAfter, HasCut); - return; - case HeadIndex | IsAtom: - emit_tr(trylf_op, ThiB(Address), NClausesAfter, HasCut); - return; - case HeadIndex: - emit_tr(trylh_op, ThiB(Address), NClausesAfter, HasCut); + wamreg myregs[MAX_REG_COPIES]; + int nofregs; + yslot ycopy = 0; + yamop *cl; + + nofregs = add_regcopy(myregs, 0, Yap_regnotoreg(regno)); + cl = clause->CurrentCode; + while (TRUE) { + op_numbers op = Yap_op_from_opcode(cl->opc); + switch (op) { + case _Ystop: + case _Nstop: + case _try_me: + case _retry_me: + case _trust_me: + case _profiled_retry_me: + case _profiled_trust_me: + case _count_retry_me: + case _count_trust_me: + case _try_me0: + case _retry_me0: + case _trust_me0: + case _try_me1: + case _retry_me1: + case _trust_me1: + case _try_me2: + case _retry_me2: + case _trust_me2: + case _try_me3: + case _retry_me3: + case _trust_me3: + case _try_me4: + case _retry_me4: + case _trust_me4: + case _spy_or_trymark: + case _try_and_mark: + case _profiled_retry_and_mark: + case _count_retry_and_mark: + case _retry_and_mark: + case _try_clause: + case _retry: + case _trust: +#ifdef YAPOR + case _getwork: + case _getwork_seq: + case _sync: +#endif +#ifdef TABLING + case _table_try_me_single: + case _table_try_me: + case _table_retry_me: + case _table_trust_me: + case _table_answer_resolution: + case _table_completion: +#endif + case _enter_profiling: + case _count_call: + case _retry_profiled: + case _count_retry: + case _try_logical_pred: + case _trust_logical_pred: + case _execute: + case _dexecute: + case _jump: + case _move_back: + case _skip: + case _jump_if_var: + case _try_in: + clause->Tag = (CELL)NULL; + return; + case _alloc_for_logical_pred: + cl = NEXTOP(cl,EC); + break; + /* instructions type e */ + case _trust_fail: + case _op_fail: + case _procceed: +#if !defined(YAPOR) + case _or_last: +#endif + case _pop: + case _index_pred: + case _undef_p: + case _spy_pred: + case _p_equal: + case _p_dif: + case _p_eq: + case _p_functor: + case _p_execute_tail: +#ifdef YAPOR + case _getwork_first_time: +#endif +#ifdef TABLING + case _trie_do_var: + case _trie_trust_var: + case _trie_try_var: + case _trie_retry_var: + case _trie_do_val: + case _trie_trust_val: + case _trie_try_val: + case _trie_retry_val: + case _trie_do_atom: + case _trie_trust_atom: + case _trie_try_atom: + case _trie_retry_atom: + case _trie_do_list: + case _trie_trust_list: + case _trie_try_list: + case _trie_retry_list: + case _trie_do_struct: + case _trie_trust_struct: + case _trie_try_struct: + case _trie_retry_struct: +#endif + clause->Tag = (CELL)NULL; + return; + case _cut: + case _cut_t: + case _cut_e: + case _allocate: + case _deallocate: + case _write_void: + case _write_list: + case _write_l_list: + case _enter_a_profiling: + case _count_a_call: + cl = NEXTOP(cl,e); + break; + case _save_b_x: + case _comit_b_x: + case _p_cut_by_x: + case _write_x_val: + case _write_x_loc: + case _write_x_var: + case _put_list: + case _p_nonvar_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (CELL)NULL; return; } - } else - Flag ^= LastGroup; - Flag |= LoneGroup; - } - if (ExtendedSingle) { - if (op == trust_op) { - emit_cp_inst(retry_op, Address, Flag, NClausesAfter); - emit_tr(trust_op, FailAddress, NClausesAfter-1, HasCut); + cl = NEXTOP(cl,x); + break; + case _p_number_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (_number+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_atomic_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (_atomic+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_integer_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (_integer+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_primitive_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (_primitive+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_compound_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (_compound+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_var_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (_var+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_db_ref_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = AbsAppl((CELL *)FunctorDBRef); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_float_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = AbsAppl((CELL *)FunctorDouble); + return; + } + cl = NEXTOP(cl,x); + break; + case _p_atom_x: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = (_atom+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,x); + break; + case _get_list: + if (regcopy_in(myregs, nofregs, cl->u.x.x)) { + clause->Tag = AbsPair(NULL); + clause->WorkPC = NEXTOP(cl,x); + return; + } + cl = NEXTOP(cl,x); + break; + case _save_b_y: + case _comit_b_y: + case _write_y_var: + case _write_y_val: + case _write_y_loc: + case _p_cut_by_y: + case _p_nonvar_y: + if (cl->u.y.y == ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,y); + break; + case _p_atomic_y: + if (ycopy == cl->u.y.y) { + clause->WorkPC = cl; + clause->Tag = (_atomic+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_integer_y: + if (ycopy == cl->u.y.y) { + clause->WorkPC = cl; + clause->Tag = (_integer+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_number_y: + if (ycopy == cl->u.y.y) { + clause->WorkPC = cl; + clause->Tag = (_number+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_primitive_y: + if (ycopy == cl->u.y.y) { + clause->WorkPC = cl; + clause->Tag = (_primitive+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_compound_y: + if (ycopy == cl->u.y.y) { + clause->WorkPC = cl; + clause->Tag = (_compound+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_db_ref_y: + if (ycopy == cl->u.y.y) { + clause->WorkPC = cl; + clause->Tag = AbsAppl((CELL *)FunctorDBRef); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_float_y: + if (ycopy == cl->u.y.y) { + clause->WorkPC = cl; + clause->Tag = AbsAppl((CELL *)FunctorDouble); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_atom_y: + if (cl->u.y.y == ycopy) { + clause->Tag = (_atom+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_var_y: + if (cl->u.y.y == ycopy) { + clause->Tag = (_var+1)*sizeof(CELL); + return; + } + cl = NEXTOP(cl,y); + break; + case _p_execute: + case _fcall: + case _call: +#ifdef YAPOR + case _or_last: +#endif + case _either: + case _or_else: + case _call_cpred: + case _call_usercpred: + clause->Tag = (CELL)NULL; return; + case _get_x_var: + if (regcopy_in(myregs, nofregs, cl->u.xx.xr)) { + nofregs = add_regcopy(myregs, nofregs, cl->u.xx.xl); + break; + } + case _put_x_var: + /* if the last slot I am using, get out */ + if (regcopy_in(myregs, nofregs, cl->u.xx.xl) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xx.xl)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,xx); + break; + case _get_x_val: + /* alias two registers */ + if (regcopy_in(myregs, nofregs, cl->u.xx.xl)) { + nofregs = add_regcopy(myregs, nofregs, cl->u.xx.xr); + } else if (regcopy_in(myregs, nofregs, cl->u.xx.xr)) { + nofregs = add_regcopy(myregs, nofregs, cl->u.xx.xl); + } + cl = NEXTOP(cl,xx); + break; + case _put_x_val: + if (regcopy_in(myregs, nofregs, cl->u.xx.xl)) { + nofregs = add_regcopy(myregs, nofregs, cl->u.xx.xr); + } else if (regcopy_in(myregs, nofregs, cl->u.xx.xr) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xx.xr)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,xx); + break; + case _glist_valx: + case _gl_void_varx: + case _gl_void_valx: + if (regcopy_in(myregs, nofregs, cl->u.xx.xl)) { + clause->WorkPC = cl; + clause->Tag = AbsPair(NULL); + return; + } + cl = NEXTOP(cl,xx); + break; + case _get_y_var: + if (regcopy_in(myregs, nofregs, cl->u.xx.xr)) { + ycopy = cl->u.yx.y; + } + case _put_y_var: + cl = NEXTOP(cl,yx); + break; + case _put_y_val: + case _put_unsafe: + if (regcopy_in(myregs, nofregs, cl->u.yx.x)) { + ycopy = cl->u.yx.y; + } + cl = NEXTOP(cl,yx); + break; + case _get_y_val: + if (regcopy_in(myregs, nofregs, cl->u.xy.x)) { + ycopy = cl->u.yx.y; + } else if (ycopy == cl->u.yx.y) { + nofregs = add_regcopy(myregs, nofregs, cl->u.xy.x); + } + cl = NEXTOP(cl,xy); + break; + case _get_atom: + if (regcopy_in(myregs, nofregs, cl->u.xc.x)) { + clause->Tag = cl->u.xc.c; + return; + } else { + cl = NEXTOP(cl,xc); + } + break; + case _get_float: + if (regcopy_in(myregs, nofregs, cl->u.xc.x)) { + clause->WorkPC = cl; + clause->Tag = AbsAppl((CELL *)FunctorDouble); + return; + } else { + cl = NEXTOP(cl,xc); + } + break; + case _get_longint: + if (regcopy_in(myregs, nofregs, cl->u.xc.x)) { + clause->WorkPC = cl; + clause->Tag = AbsAppl((CELL *)FunctorLongInt); + return; + } else { + cl = NEXTOP(cl,xc); + } + break; + case _get_bigint: + if (regcopy_in(myregs, nofregs, cl->u.xc.x)) { + clause->WorkPC = cl; + clause->Tag = AbsAppl((CELL *)FunctorBigInt); + return; + } else { + cl = NEXTOP(cl,xc); + } + break; + case _put_atom: + if (regcopy_in(myregs, nofregs, cl->u.xc.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xc.x)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } else { + cl = NEXTOP(cl,xc); + } + break; + case _get_struct: + if (regcopy_in(myregs, nofregs, cl->u.xf.x)) { + clause->WorkPC = NEXTOP(cl,xf); + clause->Tag = AbsAppl((CELL *)cl->u.xf.f); + return; + } else { + cl = NEXTOP(cl,xf); + } + break; + case _put_struct: + if (regcopy_in(myregs, nofregs, cl->u.xf.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xf.x)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } else { + cl = NEXTOP(cl,xf); + } + break; + case _glist_valy: + case _gl_void_vary: + case _gl_void_valy: + if (regcopy_in(myregs, nofregs, cl->u.xy.x)) { + clause->WorkPC = cl; + clause->Tag = AbsPair(NULL); + return; + } + cl = NEXTOP(cl,xy); + break; + case _unify_x_var: + case _unify_x_var_write: + case _unify_l_x_var: + case _unify_l_x_var_write: + if (regcopy_in(myregs, nofregs, cl->u.ox.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.ox.x)) == 0 && + !ycopy) { + /* we just initialised the argument, so nothing can happen now */ + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,ox); + break; + case _unify_x_val_write: + case _unify_x_val: + case _unify_l_x_val_write: + case _unify_l_x_val: + case _unify_x_loc_write: + case _unify_x_loc: + case _unify_l_x_loc_write: + case _unify_l_x_loc: + /* we're just done with the head of a list, but there + is nothing inside. + */ + cl = NEXTOP(cl,ox); + break; + case _save_pair_x_write: + case _save_pair_x: + case _save_appl_x_write: + case _save_appl_x: + if (regcopy_in(myregs, nofregs, cl->u.ox.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.ox.x)) == 0 && + !ycopy) { + /* we just initialised the argument, so nothing can happen now */ + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,ox); + break; + case _unify_x_var2: + case _unify_x_var2_write: + case _unify_l_x_var2: + case _unify_l_x_var2_write: + if (regcopy_in(myregs, nofregs, cl->u.oxx.xl) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.oxx.xl)) == 0 && + !ycopy) { + /* we just initialised the argument, so nothing can happen now */ + clause->Tag = (CELL)NULL; + return; + } + if (regcopy_in(myregs, nofregs, cl->u.oxx.xr) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.oxx.xr)) == 0 && + !ycopy) { + /* we just initialised the argument, so nothing can happen now */ + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,oxx); + break; + case _unify_y_var: + case _unify_y_var_write: + case _unify_l_y_var: + case _unify_l_y_var_write: + /* we're just done with the head of a list, but there + is nothing inside. + */ + if (cl->u.oy.y == ycopy) { + ycopy = 0; /* weird stuff, let's just reset ycopy */ + if (nofregs == 0) { + clause->Tag = (CELL)NULL; + return; + } + } + cl = NEXTOP(cl,oy); + break; + case _unify_y_val_write: + case _unify_y_val: + case _unify_l_y_val_write: + case _unify_l_y_val: + case _unify_y_loc_write: + case _unify_y_loc: + case _unify_l_y_loc_write: + case _unify_l_y_loc: + /* we're just done with the head of a list, but there + is nothing inside. + */ + cl = NEXTOP(cl,oy); + break; + case _save_pair_y_write: + case _save_pair_y: + case _save_appl_y_write: + case _save_appl_y: + if (cl->u.oy.y == ycopy) { + ycopy = 0; /* weird stuff, let's just reset ycopy */ + if (nofregs == 0) { + clause->Tag = (CELL)NULL; + return; + } + } + cl = NEXTOP(cl,oy); + break; + case _unify_void_write: + case _unify_void: + case _unify_l_void_write: + case _unify_l_void: + /* we're just done with the head of a list, but there + is nothing inside. + */ + cl = NEXTOP(cl,o); + break; + case _unify_list_write: + case _unify_list: + case _unify_l_list_write: + case _unify_l_list: + cl = NEXTOP(cl,o); + break; + case _unify_n_voids_write: + case _unify_n_voids: + case _unify_l_n_voids_write: + case _unify_l_n_voids: + cl = NEXTOP(cl,os); + break; + case _unify_atom_write: + case _unify_atom: + case _unify_l_atom_write: + case _unify_l_atom: + cl = NEXTOP(cl,oc); + break; + case _unify_float: + case _unify_l_float: + cl = NEXTOP(cl,oc); + break; + case _unify_longint: + case _unify_l_longint: + cl = NEXTOP(cl,oc); + break; + case _unify_bigint: + case _unify_l_bigint: + cl = NEXTOP(cl,oc); + break; + case _unify_n_atoms_write: + case _unify_n_atoms: + cl = NEXTOP(cl,osc); + break; + case _unify_struct_write: + case _unify_struct: + case _unify_l_struc_write: + case _unify_l_struc: + cl = NEXTOP(cl,of); + break; + case _write_n_voids: + case _pop_n: + cl = NEXTOP(cl,s); + break; + case _write_atom: + cl = NEXTOP(cl,c); + break; + case _write_n_atoms: + cl = NEXTOP(cl,sc); + break; + case _write_struct: + case _write_l_struc: + cl = NEXTOP(cl,f); + break; + case _call_c_wfail: + case _try_c: + case _try_userc: + case _retry_c: + case _retry_userc: + case _switch_on_type: + case _switch_list_nl: + case _switch_on_arg_type: + case _switch_on_sub_arg_type: + case _if_not_then: + case _switch_on_func: + case _switch_on_cons: + case _go_on_func: + case _go_on_cons: + case _if_func: + case _if_cons: + clause->Tag = (CELL)NULL; + return; + case _p_plus_vv: + case _p_minus_vv: + case _p_times_vv: + case _p_div_vv: + case _p_and_vv: + case _p_or_vv: + case _p_sll_vv: + case _p_slr_vv: + case _p_arg_vv: + case _p_func2s_vv: + case _p_func2f_xx: + if (regcopy_in(myregs, nofregs, cl->u.xxx.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xxx.x)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,xxx); + break; + case _p_plus_vc: + case _p_minus_cv: + case _p_times_vc: + case _p_div_cv: + case _p_and_vc: + case _p_or_vc: + case _p_sll_vc: + case _p_slr_vc: + case _p_func2s_vc: + if (regcopy_in(myregs, nofregs, cl->u.xxc.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xxc.x)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,xxc); + break; + case _p_div_vc: + case _p_sll_cv: + case _p_slr_cv: + case _p_arg_cv: + case _p_func2s_cv: + if (regcopy_in(myregs, nofregs, cl->u.xcx.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xcx.x)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,xcx); + break; + case _p_func2f_xy: + if (regcopy_in(myregs, nofregs, cl->u.xyx.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.xyx.x)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,xyx); + break; + case _p_plus_y_vv: + case _p_minus_y_vv: + case _p_times_y_vv: + case _p_div_y_vv: + case _p_and_y_vv: + case _p_or_y_vv: + case _p_sll_y_vv: + case _p_slr_y_vv: + case _p_arg_y_vv: + case _p_func2s_y_vv: + case _p_func2f_yx: + if (cl->u.yxx.y == ycopy) { + ycopy = 0; /* weird stuff, let's just reset ycopy */ + if (nofregs == 0) { + clause->Tag = (CELL)NULL; + return; + } + } + cl = NEXTOP(cl,yxx); + break; + case _p_func2f_yy: + if (regcopy_in(myregs, nofregs, cl->u.yyx.x) && + (nofregs = delete_regcopy(myregs, nofregs, cl->u.yyx.x)) == 0 && + !ycopy) { + clause->Tag = (CELL)NULL; + return; + } + cl = NEXTOP(cl,yyx); + break; + case _p_plus_y_vc: + case _p_minus_y_cv: + case _p_times_y_vc: + case _p_div_y_vc: + case _p_div_y_cv: + case _p_and_y_vc: + case _p_or_y_vc: + case _p_sll_y_vc: + case _p_slr_y_vc: + case _p_func2s_y_vc: + if (cl->u.yxc.y == ycopy) { + ycopy = 0; /* weird stuff, let's just reset ycopy */ + if (nofregs == 0) { + clause->Tag = (CELL)NULL; + return; + } + } + cl = NEXTOP(cl,yxc); + break; + case _p_sll_y_cv: + case _p_slr_y_cv: + case _p_arg_y_cv: + case _p_func2s_y_cv: + if (cl->u.ycx.y == ycopy) { + ycopy = 0; /* weird stuff, let's just reset ycopy */ + if (nofregs == 0) { + clause->Tag = (CELL)NULL; + return; + } + } + cl = NEXTOP(cl,ycx); + break; + case _call_bfunc_xx: + cl = NEXTOP(cl,lxx); + break; + case _call_bfunc_yx: + case _call_bfunc_xy: + cl = NEXTOP(cl,lxy); + break; + case _call_bfunc_yy: + cl = NEXTOP(cl,lyy); + break; } - Flag |= LoneGroup; } - switch (Flag) { - case 0: - emit_try(op, tryin_op - try_op, Body(Address), NClausesAfter, HasCut); +} + +static void +move_next(ClauseDef *clause, UInt regno) +{ + yamop *cl = clause->CurrentCode; + wamreg wreg = Yap_regnotoreg(regno); + op_numbers op = Yap_op_from_opcode(cl->opc); + + switch (op) { + case _p_db_ref_x: + case _p_float_x: + if (wreg == cl->u.x.x) { + clause->CurrentCode = NEXTOP(cl,x); + } return; - case LoneGroup: - emit_try(op, try_op - try_op, Body(Address), NClausesAfter, HasCut); + case _get_list: + if (wreg == cl->u.x.x) { + clause->CurrentCode = NEXTOP(cl,x); + } return; - case FirstIndex: - emit_try(op, tryfin_op - try_op, SecB(Address), NClausesAfter, HasCut); - return; - case FirstIndex | IsAtom: - emit_try(op, tryin_op - try_op, SecB(Address), NClausesAfter, HasCut); - return; - case FirstIndex | LastFoundList: - emit_try(op, tryfin_op - try_op, SecLB(Address), NClausesAfter, HasCut); - return; - case FirstIndex | LoneGroup: - emit_try(op, tryf_op - try_op, SecB(Address), NClausesAfter, HasCut); - return; - case FirstIndex | LoneGroup | IsAtom: - emit_try(op, try_op - try_op, SecB(Address), NClausesAfter, HasCut); - return; - case FirstIndex | LoneGroup | LastFoundList: - emit_try(op, tryf_op - try_op, SecLB(Address), NClausesAfter, HasCut); - return; - case HeadIndex: - emit_try(op, tryhin_op - try_op, ThiB(Address), NClausesAfter, HasCut); - return; - case HeadIndex | LastFoundList: - emit_try(op, tryhin_op - try_op, ThiLB(Address), NClausesAfter, HasCut); - return; - case HeadIndex | IsAtom: - emit_try(op, trytin_op - try_op, ThiB(Address), NClausesAfter, HasCut); - return; - case HeadIndex | LoneGroup: - emit_try(op, tryh_op - try_op, ThiB(Address), NClausesAfter, HasCut); - return; - case HeadIndex | LoneGroup | LastFoundList: - emit_try(op, tryh_op - try_op, ThiLB(Address), NClausesAfter, HasCut); - return; - case HeadIndex | LoneGroup | IsAtom: - emit_try(op, tryt_op - try_op, ThiB(Address), NClausesAfter, HasCut); + case _get_atom: + case _get_float: + case _get_longint: + case _get_bigint: + if (wreg == cl->u.xc.x) { + clause->CurrentCode = NEXTOP(cl,xc); + } return; + case _get_struct: + if (wreg == cl->u.xf.x) { + clause->CurrentCode = NEXTOP(cl,xf); + } default: return; } } - -/* emits a large switch instruction */ -static CELL -emit_space(compiler_vm_op op, int space, int nof) -{ - labelno += 2; - Yap_emit(label_op, labelno, Zero); - StorePoint = Yap_emit_extra_size(op, Unsigned(nof), space); - return (labelno); -} - -/* emits a go instruction */ -static CELL -emit_go(int Gender, Term Name) -{ - labelno += 2; - Yap_emit(label_op, labelno, Zero); - if (Gender == ApplCl) - StorePoint = Yap_emit_extra_size(go_f_op, Zero, 3 * CellSize); - else - StorePoint = Yap_emit_extra_size(go_c_op, Zero, 3 * CellSize); - *StorePoint++ = Unsigned(Name); - StorePoint[1] = (CELL)FailAddress; - return (labelno); -} - - -/* emits an if_not_then instruction */ -static void -emit_if_not(Term T1, CELL Ad1, CELL Ad2) -{ - StorePoint = Yap_emit_extra_size(if_not_op, Zero, 3 * CellSize); - *StorePoint++ = Unsigned(T1); - *StorePoint++ = Unsigned(Ad1); - StorePoint[0] = Unsigned(Ad2); -} - - -/* places the code where to go in a go instruction */ -static void -fill_go(CELL *LCons, CELL Code) -{ - LCons[0] = Code; -} - - -/* fills a space after a first instruction with four addresses */ -static void -fill_switch_slots(CELL *WhereTo, CELL FAddr, CELL SecAddr, CELL ThirdAddr, CELL ThourthAddr, int NOf) -{ - *WhereTo++ = FAddr; - *WhereTo++ = SecAddr; - *WhereTo++ = ThirdAddr; - if (NOf > 3) - *WhereTo = ThourthAddr; -} - -/* Places in a space pairs 0 -> Fail */ -static void -ClrSpace(CELL *StSpace, int NBytes) -{ - int i; - - NBytes /= 2 * CellSize; - for (i = 0; i < NBytes; i++) { - *StSpace++ = Zero; - *StSpace++ = (CELL)FailAddress; - } -} - -/* Evaluates the number of groups and builds the clause and group arrays */ -static int -NGroupsIn(PredEntry *ap) -{ - int x, y, PresentGroup; - ClauseDef *ActualCl = ArOfCl, *LastClauses[MaxOptions]; - GroupDef *Group = Groups; - yamop *q = ap->cs.p_code.FirstClause, *LastOne = ap->cs.p_code.LastClause; - - NGroups = 1; - LastClauses[VarCl] = NIL; - LastClauses[AtCl] = NIL; - LastClauses[ApplCl] = NIL; - LastClauses[ListCl] = NIL; - Group = Groups; - NClauses = 0; - while (IsVarClause(q)) { - RemovedCl = TRUE; - if (q == LastOne) - return (NGroups); - else - q = (yamop *)NextClause(q); - } - x = KindOfArg(q); - if (NonVarCl(x)) - PresentGroup = 1; - else - PresentGroup = 0; - LastClauses[x] = Group->Start = ActualCl; - Group->NCl = 0; - Group->First = q; - Group->Type[VarCl] = 0; - Group->Type[AtCl] = 0; - Group->Type[ApplCl] = 0; - Group->Type[ListCl] = 0; - Group->SInfo = OnlyNils; - do { - while (IsVarClause(q)) { - RemovedCl = TRUE; - if (q == LastOne) - return (NGroups); - else - q = (yamop *)NextClause(q); - } - x = KindOfArg(q); - NClauses++; - ActualCl->Kind = x; - ActualCl->Code = q; - if (x == ListCl) { - ActualCl->Name = HeadOfList(q); - y = 1; - } else if (NonVarCl(x)) { - ActualCl->Name = TermOfCl(q); - y = 1; - } else { - y = 0; - } - if (y != PresentGroup) { - Group++->Last = (ActualCl - 1)->Code; - NGroups++; - if ((ADDR)Group > Yap_TrailTop-1024) - Yap_growtrail(64 * 1024L); - Group->First = q; - Group->Start = ActualCl; - Group->NCl = 0; - Group->Type[VarCl] = 0; - Group->Type[AtCl] = 0; - Group->Type[ApplCl] = 0; - Group->Type[ListCl] = 0; - Group->SInfo = OnlyNils; - LastClauses[VarCl] = NIL; - LastClauses[AtCl] = NIL; - LastClauses[ApplCl] = NIL; - LastClauses[ListCl] = NIL; - PresentGroup = y; - } - if (x == AtCl) { - if (ActualCl->Name != MkAtomTerm(AtomNil)) - Group->SInfo &= ~OnlyNils; - if (KindOfBipArg(q) & (FIsAtom|FIsNum|FIsPrimi)) { - Group->SInfo |= UsesBips; - ActualCl->Name = 0x0; - } - } - ActualCl->Next = NIL; - if (LastClauses[x] != NIL) - LastClauses[x]->Next = ActualCl; - LastClauses[x] = ActualCl++; - /* check for overflow in case we have a really big database */ - if (ASP <= CellPtr (ActualCl) + 256) { - freep = (char *)ActualCl; - save_machine_regs(); - longjmp(Yap_CompilerBotch, 3); - } - (Group->Type[x])++; - (Group->NCl)++; - if (q == LastOne) - q = NIL; - else - q = (yamop *)NextClause(q); - } while (q != NIL); - return (NGroups); -} - -/* for each group find out how many clauses follow that group */ static void -CountGroups(GroupDef *Gr, int NGr) +add_arg_info(ClauseDef *clause, UInt argno) { - GroupDef *grp = Gr+NGr; - int cls = 0; - do { - grp--; - grp->NofClausesAfter = cls; - cls += grp->NCl; - } while(grp > Gr); + yamop *cl = clause->WorkPC; + while (TRUE) { + op_numbers op = Yap_op_from_opcode(cl->opc); + switch (op) { + case _glist_valx: + if (argno == 1) { + clause->Tag = (CELL)NULL; + return; + } + argno--; + cl = NEXTOP(cl,xx); + break; + case _gl_void_vary: + case _gl_void_valy: + case _gl_void_varx: + case _gl_void_valx: + clause->Tag = (CELL)NULL; + return; + case _glist_valy: + if (argno == 1) { + clause->Tag = (CELL)NULL; + return; + } + argno--; + cl = NEXTOP(cl,xy); + break; + case _unify_l_x_var: + case _unify_l_x_val: + case _unify_l_x_loc: + case _unify_x_var: + case _unify_x_val: + case _unify_x_loc: + if (argno == 1) { + clause->Tag = (CELL)NULL; + return; + } + argno--; + case _unify_l_x_var_write: + case _unify_l_x_val_write: + case _unify_l_x_loc_write: + case _unify_x_var_write: + case _unify_x_val_write: + case _unify_x_loc_write: + cl = NEXTOP(cl,ox); + break; + case _save_pair_x_write: + case _save_pair_x: + case _save_appl_x_write: + case _save_appl_x: + cl = NEXTOP(cl,ox); + break; + case _unify_l_x_var2: + case _unify_x_var2: + if (argno == 1 || argno == 2) { + clause->Tag = (CELL)NULL; + return; + } + argno -= 2; + case _unify_l_x_var2_write: + case _unify_x_var2_write: + cl = NEXTOP(cl,oxx); + break; + case _unify_y_var: + case _unify_y_val: + case _unify_y_loc: + case _unify_l_y_var: + case _unify_l_y_val: + case _unify_l_y_loc: + /* we're just done with the head of a list, but there + is nothing inside. + */ + if (argno == 1) { + clause->Tag = (CELL)NULL; + return; + } + argno--; + case _unify_y_var_write: + case _unify_y_val_write: + case _unify_y_loc_write: + case _unify_l_y_var_write: + case _unify_l_y_val_write: + case _unify_l_y_loc_write: + cl = NEXTOP(cl,oy); + break; + case _save_pair_y_write: + case _save_pair_y: + case _save_appl_y_write: + case _save_appl_y: + cl = NEXTOP(cl,oy); + break; + case _unify_l_void: + case _unify_void: + if (argno == 1) { + clause->Tag = (CELL)NULL; + return; + } + argno--; + case _unify_l_void_write: + case _unify_void_write: + cl = NEXTOP(cl,o); + break; + case _unify_list: + case _unify_l_list: + if (argno == 1) { + clause->Tag = AbsPair(NULL); + return; + } + argno += 1; /* 2-1: have two extra arguments to skip */ + case _unify_list_write: + case _unify_l_list_write: + cl = NEXTOP(cl,o); + break; + case _unify_n_voids: + case _unify_l_n_voids: + if (argno <= cl->u.os.s) { + clause->Tag = (CELL)NULL; + return; + } + argno -= cl->u.os.s; + case _unify_n_voids_write: + case _unify_l_n_voids_write: + cl = NEXTOP(cl,os); + break; + case _unify_atom: + case _unify_l_atom: + if (argno == 1) { + clause->Tag = cl->u.oc.c; + return; + } + argno--; + case _unify_atom_write: + case _unify_l_atom_write: + cl = NEXTOP(cl,oc); + break; + case _unify_l_float: + if (argno == 1) { + clause->Tag = AbsAppl((CELL *)FunctorDouble); + return; + } + argno--; + case _unify_longint: + case _unify_l_longint: + if (argno == 1) { + clause->Tag = AbsAppl((CELL *)FunctorLongInt); + return; + } + argno--; + case _unify_bigint: + case _unify_l_bigint: + if (argno == 1) { + clause->Tag = AbsAppl((CELL *)FunctorBigInt); + return; + } + argno--; + case _unify_n_atoms: + if (argno <= cl->u.osc.s) { + clause->Tag = cl->u.osc.c; + return; + } + argno -= cl->u.osc.s; + case _unify_n_atoms_write: + cl = NEXTOP(cl,osc); + break; + case _unify_struct: + case _unify_l_struc: + if (argno == 1) { + clause->Tag = AbsAppl((CELL *)cl->u.of.f); + return; + } + argno--; + case _unify_l_struc_write: + case _unify_struct_write: + cl = NEXTOP(cl,of); + break; + case _pop: + cl = NEXTOP(cl,e); + break; + case _pop_n: + cl = NEXTOP(cl,s); + break; + default: + return; + } + } } -/* Finds the first clause whose arg is neither a list or a var */ -static yamop * -FindFirst(int i, int kind) +static void +skip_to_arg(ClauseDef *clause, UInt argno, int at_point) { - ClauseDef *GrClaus = Groups[i].Start; + yamop *cl = clause->WorkPC; + int done = FALSE; - while (GrClaus->Kind != kind) - GrClaus++; - if (AtomsOnlyNil) - return (SecB(GrClaus->Code)); - return (Body(GrClaus->Code)); + at_point = at_point & (clause->WorkPC == clause->CurrentCode); + while (!done) { + op_numbers op = Yap_op_from_opcode(cl->opc); + switch (op) { + case _glist_valx: + at_point = FALSE; + cl = NEXTOP(cl,xx); + if (argno == 1) { + clause->WorkPC=cl; + done = TRUE; + } else { + /* looking to adjust workpc */ + argno--; + } + break; + case _gl_void_vary: + case _gl_void_valy: + if (argno == 2) { + clause->WorkPC = NEXTOP(cl,xy); + } else { + clause->WorkPC = cl; + } + done = TRUE; + break; + case _gl_void_varx: + case _gl_void_valx: + if (argno == 2) { + clause->WorkPC = NEXTOP(cl,xx); + } else { + clause->WorkPC = cl; + } + done = TRUE; + break; + case _glist_valy: + done = TRUE; + at_point = FALSE; + clause->WorkPC = NEXTOP(cl,xy); + break; + case _unify_l_x_var: + case _unify_l_x_val: + case _unify_l_x_loc: + case _unify_x_var: + case _unify_x_val: + case _unify_x_loc: + if (argno == 1) { + clause->WorkPC = NEXTOP(cl,ox); + done = TRUE; + } else { + argno--; + at_point = FALSE; + } + case _unify_l_x_var_write: + case _unify_l_x_val_write: + case _unify_l_x_loc_write: + case _unify_x_var_write: + case _unify_x_val_write: + case _unify_x_loc_write: + cl = NEXTOP(cl,ox); + break; + case _save_pair_x_write: + case _save_pair_x: + case _save_appl_x_write: + case _save_appl_x: + at_point = FALSE; + cl = NEXTOP(cl,ox); + break; + case _unify_l_x_var2: + case _unify_x_var2: + at_point = FALSE; + if (argno == 1 || argno == 2) { + if (argno == 2) { + clause->WorkPC = NEXTOP(cl,oxx); + } else { + clause->WorkPC = cl; + } + done = TRUE; + } else { + argno -= 2; + } + case _unify_l_x_var2_write: + case _unify_x_var2_write: + break; + case _unify_y_var: + case _unify_y_val: + case _unify_y_loc: + case _unify_l_y_var: + case _unify_l_y_val: + case _unify_l_y_loc: + /* we're just done with the head of a list, but there + is nothing inside. + */ + at_point = FALSE; + if (argno == 1) { + clause->WorkPC = NEXTOP(cl,oy); + done = TRUE; + } else { + argno--; + } + case _unify_y_var_write: + case _unify_y_val_write: + case _unify_y_loc_write: + case _unify_l_y_var_write: + case _unify_l_y_val_write: + case _unify_l_y_loc_write: + cl = NEXTOP(cl,oy); + break; + case _save_pair_y_write: + case _save_pair_y: + case _save_appl_y_write: + case _save_appl_y: + at_point = FALSE; + cl = NEXTOP(cl,oy); + break; + case _unify_l_void: + case _unify_void: + if (argno == 1) { + done = TRUE; + } else { + argno--; + } + case _unify_l_void_write: + case _unify_void_write: + cl = NEXTOP(cl,o); + break; + case _unify_list: + case _unify_l_list: + if (argno == 1) { + clause->WorkPC = NEXTOP(cl,o); + done = TRUE; + } else { + argno += 1; /* 2-1: have two extra arguments to skip */ + at_point = FALSE; + } + case _unify_list_write: + case _unify_l_list_write: + cl = NEXTOP(cl,o); + break; + case _unify_n_voids: + case _unify_l_n_voids: + if (argno <= cl->u.os.s) { + clause->WorkPC = cl; + done = TRUE; + } else { + argno -= cl->u.os.s; + } + case _unify_n_voids_write: + case _unify_l_n_voids_write: + cl = NEXTOP(cl,os); + break; + case _unify_atom: + case _unify_l_atom: + case _unify_longint: + case _unify_l_longint: + case _unify_bigint: + case _unify_l_bigint: + case _unify_l_float: + if (argno == 1) { + clause->WorkPC = NEXTOP(cl,oc); + done = TRUE; + } else { + at_point = FALSE; + argno--; + } + case _unify_atom_write: + case _unify_l_atom_write: + cl = NEXTOP(cl,oc); + break; + case _unify_n_atoms: + if (argno <= cl->u.osc.s) { + if (argno == cl->u.osc.s) { + clause->WorkPC = NEXTOP(cl,oc); + } else { + clause->WorkPC = cl; + at_point = FALSE; + } + done = TRUE; + } else { + at_point = FALSE; + argno -= cl->u.osc.s; + } + case _unify_n_atoms_write: + cl = NEXTOP(cl,osc); + break; + case _unify_struct: + case _unify_l_struc: + if (argno == 1) { + clause->WorkPC = NEXTOP(cl,of); + done = TRUE; + } else { + at_point = FALSE; + argno--; + } + case _unify_l_struc_write: + case _unify_struct_write: + cl = NEXTOP(cl,of); + break; + case _pop: + cl = NEXTOP(cl,e); + break; + case _pop_n: + cl = NEXTOP(cl,s); + break; + default: + done = TRUE; + } + } + if (at_point) { + clause->CurrentCode = clause->WorkPC; + } else { + clause->CurrentCode = clause->Code; + } } -/* evaluates the size (power of two) necessary for a table */ -static int -SizeTable(int Cases) +static UInt +groups_in(ClauseDef *min, ClauseDef *max, GroupDef *grp) { - register int i = 2; + UInt groups = 0; - if (Cases <= MinHashEntries) - return (Cases); - while ((Cases /= 2) > 0) - i *= 2; - return (i * 2); + while(min <= max) { + grp->FirstClause = min; + grp->AtomClauses = 0; + grp->PairClauses = 0; + grp->StructClauses = 0; + grp->TestClauses = 0; + if (min->Tag == (_var+1)*sizeof(CELL)) { + min++; + continue; + } + /* only do this for the first clauses in a group */ + if (IsVarTerm(min->Tag)) { + ClauseDef *clp = min+1; + + grp->VarClauses = 1; + do { + if (clp > max || + !IsVarTerm(clp->Tag)) { + grp->LastClause = (min = clp)-1; + break; + } + clp++; + if (clp->Tag != (_var+1)*sizeof(CELL)) + grp->VarClauses++; + } while (TRUE); + } else { + grp->VarClauses = 0; + do { + restart_loop: + if (IsAtomTerm(min->Tag) || IsIntTerm(min->Tag)) { + grp->AtomClauses++; + } else if (IsPairTerm(min->Tag)) { + grp->PairClauses++; + } else if (IsApplTerm(min->Tag)) { + grp->StructClauses++; + } else { + grp->TestClauses++; + } + min++; + } while (min <= max && + (!IsVarTerm(min->Tag))); + if (min <= max && min->Tag == (_var+1)*sizeof(CELL)) { + min++; + goto restart_loop; + } + grp->LastClause = min-1; + } + groups++; + grp++; + } + return groups; +} + +static UInt +new_label(void) +{ + UInt lbl = labelno; + labelno += 2; + return lbl; +} + +static void +emit_trust(ClauseDef *cl, PredEntry *ap, UInt nxtlbl, int clauses) +{ + if (CurrentPred->PredFlags & ProfiledPredFlag) { + Yap_emit(retry_profiled_op, Unsigned(ap), Zero); + } + if (CurrentPred->PredFlags & CountPredFlag) { + Yap_emit(count_retry_op, Unsigned(ap), Zero); + } + if (clauses == 0) { + Yap_emit(trust_op, (CELL)(cl->Code), has_cut(cl->CurrentCode) ); + } else { + Yap_emit(retry_op, (CELL)(cl->Code), (clauses << 1) | has_cut(cl->CurrentCode) ); + Yap_emit(jump_op, nxtlbl, Zero); + } +} + +static void +emit_retry(ClauseDef *cl, PredEntry *ap, int clauses) +{ + if (CurrentPred->PredFlags & ProfiledPredFlag) { + Yap_emit(retry_profiled_op, Unsigned(ap), Zero); + } + if (CurrentPred->PredFlags & CountPredFlag) { + Yap_emit(count_retry_op, Unsigned(ap), Zero); + } + Yap_emit(retry_op, (CELL)(cl->Code), (clauses << 1) | has_cut(cl->CurrentCode) ); +} + +static void +emit_try(ClauseDef *cl, PredEntry *ap, int var_group, int first, int clauses, int clleft, UInt nxtlbl) +{ + /* var group */ + if (var_group || clauses == 0) { + if (first) { + Yap_emit(try_op, (CELL)(cl->CurrentCode), ((clauses+clleft) << 1) | has_cut(cl->CurrentCode) ); + } else if (clleft+clauses) { + Yap_emit(retry_op, (CELL)(cl->CurrentCode), ((clauses+clleft) << 1) | has_cut(cl->CurrentCode) ); + } else { + Yap_emit(trust_op, (CELL)(cl->CurrentCode), ((clauses+clleft) << 1) | has_cut(cl->CurrentCode)); + } + } else if (clleft == 0) { + /* last group */ + Yap_emit(try_op, (CELL)(cl->CurrentCode), ((clauses+clleft) << 1) | has_cut(cl->CurrentCode)); + } else { + /* nonvar group */ + Yap_emit(try_in_op, (CELL)(cl->CurrentCode), ((clauses+clleft) << 1) | has_cut(cl->CurrentCode) ); + } +} + +static TypeSwitch * +emit_type_switch(compiler_vm_op op) +{ + return (TypeSwitch *)Yap_emit_extra_size(op, 0, sizeof(TypeSwitch)); } -#define HASH_SHIFT 6 - -/* - * creates the hash table works if TableSize is a power of two - */ -static void -BuildHash(CELL *WhereTo, int NOfEntries, int TableSize, int Gend) +static AtomSwiEntry * +emit_cswitch(int n, UInt fail_l) { - register int hash; - register int i; -#ifdef DEBUG -#ifdef CLASHES - int clashes = 0; -#endif /* CLASHES */ -#endif /* DEBUG */ - Term WorkTerm; - EntryDef *EntryP = Entries; - yamop *Base = (yamop *)CodePtr(WhereTo); - yamop *EndSpace = (yamop *)((char *)Base + TableSize * 2 * CellSize); + compiler_vm_op op; + AtomSwiEntry *target; - ClrSpace(WhereTo, ((int) ((char *)EndSpace - (char *)Base))); - TableSize--; - for (i = 0; i < NOfEntries; ++i) { - register Int d; - CELL *hentry; + if (n > MIN_HASH_ENTRIES) { + int cases = MIN_HASH_ENTRIES, i; + while (cases < n+1) cases *= 2; + n = cases; + op = switch_c_op; + target = (AtomSwiEntry *)Yap_emit_extra_size(op, Unsigned(n), n*sizeof(FuncSwiEntry)); + for (i=0; iClass; - hash = (Unsigned(WorkTerm) >> HASH_SHIFT) & TableSize; - hentry = (CELL *)Base + hash * 2; - d = TableSize & (Unsigned(WorkTerm) | 1); - while (*hentry) { + op = if_c_op; + tmp = Yap_emit_extra_size(op, Unsigned(n), n*sizeof(AtomSwiEntry)+sizeof(CELL)); + *tmp++ = fail_l; + target = (AtomSwiEntry *)tmp; + } + return target; +} + +static AtomSwiEntry * +fetch_centry(AtomSwiEntry *cebase, Term wt, int i, int n) +{ + if (n > MIN_HASH_ENTRIES) { + int cases = MIN_HASH_ENTRIES, hash, d; + AtomSwiEntry *hentry; + + while (cases < n+1) cases *= 2; + hash = (wt >> HASH_SHIFT) & (cases-1); + hentry = cebase + hash; + d = (cases-1) & (wt|1); + while (hentry->Tag != Zero) { #ifdef DEBUG #ifdef CLASHES ++clashes; #endif /* CLASHES */ #endif /* DEBUG */ - hash = (hash + d) & TableSize; - hentry = (CELL *)Base + hash * 2; + hash = (hash + d) & (cases-1); + hentry = cebase + hash; } - hentry[0] = Unsigned(WorkTerm); - hentry[1] = (CELL)((EntryP++)->Code); + return hentry; + } else { + return cebase + i; } +} + +static FuncSwiEntry * +emit_fswitch(int n, UInt fail_l) +{ + compiler_vm_op op; + FuncSwiEntry *target; + + if (n > MIN_HASH_ENTRIES) { + int cases = MIN_HASH_ENTRIES, i; + while (cases < n+1) cases *= 2; + n = cases; + op = switch_f_op; + target = (FuncSwiEntry *)Yap_emit_extra_size(op, Unsigned(n), n*sizeof(FuncSwiEntry)); + for (i=0; i MIN_HASH_ENTRIES) { + int cases = MIN_HASH_ENTRIES, hash, d; + FuncSwiEntry *hentry; + Term wt = (CELL)ft; + + while (cases < n+1) cases *= 2; + hash = (wt >> HASH_SHIFT) & (cases-1); + hentry = febase + hash; + d = (cases-1) & (wt|1); + while (hentry->Tag != NULL) { #ifdef DEBUG #ifdef CLASHES - fprintf(Yap_stderr,"hash table clashes: %d %d\n", clashes, NOfEntries); + ++clashes; #endif /* CLASHES */ #endif /* DEBUG */ -} - - -static void -BuildIfTable(CELL *WhereTo, int NOfEntries) -{ - register EntryDef *EntryP = Entries; - register int j; - - *WhereTo++ = (CELL)FailAddress; - for (j = 0; j < NOfEntries; ++j) { - *WhereTo++ = Unsigned(EntryP->Class); - *WhereTo++ = (CELL)((EntryP++)->Code); + hash = (hash + d) & (cases-1); + hentry = febase + hash; + } + return hentry; + } else { + return febase + i; } } +/* we assume there is at least one clause, that is, c0 < cf */ +static void +do_var_clauses(ClauseDef *c0, ClauseDef *cf, int var_group, PredEntry *ap, UInt labl, int first, int clleft, UInt nxtlbl) { + Yap_emit(label_op, labl, Zero); + if (c0 == cf) { + emit_try(c0, ap, var_group, first, 0, clleft, nxtlbl); + } else { + if (c0 < cf) { + emit_try(c0, ap, var_group, first, cf-c0, clleft, nxtlbl); + } + c0++; + while (c0 < cf) { + emit_retry(c0, ap, clleft+(cf-c0)); + c0++; + } + if (c0 == cf) { + emit_trust(c0, ap, nxtlbl, clleft); + } + } +} -/* Creates the code for each entry in a group */ -static void -TreatEntry(EntryDef *Entrance, int Gender, int PositionFlag, GroupDef *Gr) +static void +do_var_group(GroupDef *grp, PredEntry *ap, UInt labl, int var_group, int first, int clleft, UInt nxtlbl) { + return do_var_clauses(grp->FirstClause, grp->LastClause, var_group, ap, labl, first, clleft, nxtlbl); +} + +static void +add_lu_cl_info(yamop *codep) { - if (Entrance->Last == Entrance->First) { - if (PositionFlag & LastGroup) { - /* last group, meaning we already have a choice point set */ - register yamop * k = (Entrance->First)->Code; - labelno += 2; - Yap_emit(label_op, Entrance->Code = labelno, Zero); - if (PositionFlag & HeadIndex) { - emit_tr(trust_op, ThiB(k), 1, clause_has_cut(k)); + LogUpdClause *cl = ClauseCodeToLogUpdClause(codep); + if (cl->ClFlags & LogUpdRuleMask) { + cl->u2.ClExt->u.EC.ClRefs++; + } else { + cl->u2.ClUse++; + } +} + +static UInt +log_update_chain(PredEntry *ap) +{ + yamop *codep = ap->cs.p_code.FirstClause; + yamop *lastp = ap->cs.p_code.LastClause; + + Yap_emit(label_op, 1, Zero); + Yap_emit(try_op, (CELL)NEXTOP(codep,ld), Zero); + add_lu_cl_info(codep); + codep = NextClause(codep); + while (codep != lastp) { + Yap_emit(retry_op, (CELL)NEXTOP(codep,ld), Zero); + add_lu_cl_info(codep); + codep = NextClause(codep); + } + Yap_emit(trust_op, (CELL)NEXTOP(codep,ld), Zero); + add_lu_cl_info(codep); + return 1; +} + + +/* count the number of different constants */ +static UInt +count_consts(GroupDef *grp) +{ + Term current = MkAtomTerm(AtomFoundVar); + UInt i = 0; + ClauseDef *cl = grp->FirstClause; + + while (IsAtomTerm(cl->Tag) || IsIntTerm(cl->Tag)) { + if (current != cl->Tag) { + i++; + current = cl->Tag; + } + if (cl == grp->LastClause) { + return i; + } + cl++; + } + return i; +} + +/* count the number of different constants */ +static UInt +count_funcs(GroupDef *grp) +{ + Term current = MkAtomTerm(AtomFoundVar); + UInt i = 0; + ClauseDef *cl = grp->FirstClause; + + while (IsApplTerm(cl->Tag)) { + if (current != cl->Tag) { + i++; + current = cl->Tag; + } + if (cl == grp->LastClause) { + return i; + } + cl++; + } + return i; +} + +static UInt +emit_single_switch_case(ClauseDef *min, PredEntry *ap, int first, int clleft, UInt nxtlbl) +{ + return (UInt)(min->CurrentCode); +} + + +static UInt +do_var_entries(GroupDef *grp, PredEntry *ap, UInt argno, int first, int clleft, UInt nxtlbl){ + if (argno == 1) { + /* in this case we want really to jump to the first clause */ + if (ap->PredFlags & LogUpdatePredFlag) { + if (first && clleft == 0) { + return log_update_chain(ap); } else { - /* we cannot emit to SecLB because switch might have already - set SREG :-(, hence making us jump one step ahead. This - is not a problem with a direct jump, in this case the - work on S will just have been squandered */ - emit_tr(trust_op, Body(k), 1, clause_has_cut(k)); + /* 1 is label for log_update_chain, which should never be taken */ + return 1; } - } else if (ExtendedSingle) { - /* a single alternative and a catchall clause */ - register yamop * k = (Entrance->First)->Code; - labelno += 2; - Yap_emit(label_op, Entrance->Code = labelno, Zero); - /* if we are in a list */ - if (PositionFlag & HeadIndex) { - /* we cannot emit to SecLB because switch might have already - set SREG :-( */ - emit_try(try_op, 0, Body(k), 1, clause_has_cut(k)); - if (indexed_code_for_cut != NIL) { - Entrance->Code = - (CELL)indexed_code_for_cut; - } else { - emit_tr(trust_op, FailAddress, 1, clause_has_cut(k)); - Entrance->Code = labelno; - } + } else { + if (first && clleft == 0) { + /* not protected by a choice-point */ + return (UInt)PREVOP(grp->FirstClause->Code,ld); } else { - emit_try(try_op, 0, SecB(k), 2, clause_has_cut(k)); - if (indexed_code_for_cut != NIL) { - Entrance->Code = - (CELL)indexed_code_for_cut; - } else { - emit_tr(trust_op, FailAddress, 1, clause_has_cut(k)); - Entrance->Code = labelno; - } + /* this code should never execute */ + return nxtlbl; } - } else if (PositionFlag & HeadIndex) { - /* single clause in the middle of code, no need to worry about - choicepoints */ - Entrance->Code = Unsigned(ThiB((Entrance->First)->Code)); + } + } else { + UInt labl = new_label(); + do_var_group(grp, ap, labl, FALSE, first, clleft, nxtlbl); + return labl; + } +} + +static UInt +do_consts(GroupDef *grp, PredEntry *ap, UInt argno, int first, UInt nxtlbl, int clleft, CELL *top) +{ + UInt n; + ClauseDef *min = grp->FirstClause; + UInt i; + UInt lbl; + /* generate a switch */ + AtomSwiEntry *cs; + + if (!IsAtomTerm(min->Tag) && !IsIntTerm(min->Tag)) { + /* no clauses, just skip */ + return nxtlbl; + } + n = count_consts(grp); + lbl = new_label(); + Yap_emit(label_op, lbl, Zero); + cs = emit_cswitch(n, nxtlbl); + for (i = 0; i < n; i++) { + AtomSwiEntry *ics; + ClauseDef *max = min; + + ics = fetch_centry(cs, min->Tag, i, n); + ics->Tag = min->Tag; + while ((max+1)->Tag == min->Tag && + max != grp->LastClause) max++; + ics->Label = do_index(min, max, ap, argno+1, nxtlbl, first, clleft, top); + grp->FirstClause = min = max+1; + } + return lbl; +} + +static UInt +do_funcs(GroupDef *grp, PredEntry *ap, UInt argno, int first, int last_arg, UInt nxtlbl, int clleft, CELL *top) +{ + UInt n = count_funcs(grp); + ClauseDef *min = grp->FirstClause; + UInt i; + FuncSwiEntry *fs; + UInt lbl; + + if (min > grp->LastClause || !IsApplTerm(min->Tag)) { + /* no clauses, just skip */ + return nxtlbl; + } + lbl = new_label(); + Yap_emit(label_op, lbl, Zero); + /* generate a switch */ + fs = emit_fswitch(n, nxtlbl); + for (i = 0; i < n ; i++) { + Functor f = (Functor)RepAppl(min->Tag); + FuncSwiEntry *ifs; + ClauseDef *max = min; + + ifs = fetch_fentry(fs, f, i, n); + ifs->Tag = f; + while ((max+1)->Tag == min->Tag && + max != grp->LastClause) max++; + if (IsExtensionFunctor(f)) { + ifs->Label = do_index(min, max, ap, argno+1, nxtlbl, first, clleft, top); } else { - Entrance->Code = Unsigned(SecB((Entrance->First)->Code)); + ifs->Label = do_compound_index(min, max, ap, ArityOfFunctor(f), argno+1, nxtlbl, first, last_arg, clleft, top); + } + grp->FirstClause = min = max+1; + } + return lbl; +} + +static UInt +do_pair(GroupDef *grp, PredEntry *ap, UInt argno, int first, int last_arg, UInt nxtlbl, int clleft, CELL *top) +{ + ClauseDef *min = grp->FirstClause; + ClauseDef *max = grp->LastClause; + + if (min > max) { + /* no clauses, just skip */ + return nxtlbl; + } else if (min == max) { + /* single clause, no need to do indexing, but we do know it is a list */ + return (UInt)(min->CurrentCode); + } + return do_compound_index(min, max, ap, 2, argno+1, nxtlbl, first, last_arg, clleft, top); +} + +static void +group_prologue(int compound_term, UInt argno, int first) +{ + if (compound_term) { + Yap_emit(cache_sub_arg_op, compound_term-1, compound_term-1); + } else { + if (!first || argno != 1) { + Yap_emit(cache_arg_op, argno, argno); + } + } +} + +/* make sure that we can handle failure correctly */ +static void +emit_protection_choicepoint(int first, int clleft, UInt nxtlbl) +{ + if (first) { + if (clleft) { + Yap_emit(tryme_op, nxtlbl, (clleft << 1)); } } else { - ClauseDef *k = Entrance->First; - int nofentries = 1, nofalts; - - while (k != Entrance->Last) { - nofentries++; - k = k->Next; - } - - nofalts = Gr->NofClausesAfter+nofentries; - k = Entrance->First; - labelno += 2; - Yap_emit(label_op, (Entrance->Code = labelno), Zero); - emit_cp_inst(try_op, k->Code, PositionFlag, nofalts); - nofalts--; - if (indexed_code_for_cut != NIL) { - Entrance->Code = (CELL)indexed_code_for_cut; + /* !first */ + if (clleft) { + Yap_emit(retryme_op, nxtlbl, (clleft << 1)); } else { - while ((k = k->Next) != Entrance->Last) { - emit_cp_inst(retry_op, k->Code, PositionFlag, nofalts); - nofalts--; - } - emit_cp_inst(trust_op, k->Code, PositionFlag, nofalts); - /* emit a jump with the place to jump to after finishing this group */ - if (NGroups > 1 && !(PositionFlag & LastGroup) && !ExtendedSingle) - Yap_emit(jump_op, (CELL)((Gr+1)->First), Zero); + Yap_emit(trustme_op, 0, 0); } } } -/* Creates the code for either appl or atomic cases */ -static CELL -DealFixed(ClauseDef *j, int Gender, compiler_vm_op op, int Flag, GroupDef *Gr) + +static ClauseDef * +cls_move(ClauseDef *min, ClauseDef *max, int compound_term, UInt argno, int last_arg) { - int NDiffTerms = 1; - int TableSize, k; - ClauseDef *NextInChain; - Term HeadName; - CELL LFixed; - CELL *WhereToStore; - EntryDef *Entry = Entries; + ClauseDef *cl=min; - Entry->Class = j->Name; - Entry->Last = Entry->First = j; - do { - int l = 0; - - HeadName = j->Name; - NextInChain = j->Next; - j->Next = NIL; - Entry = Entries; - while (l < NDiffTerms && Entry->Class != HeadName) - Entry++, l++; - if (l == NDiffTerms) { - if ((ADDR)Entry > Yap_TrailTop-1024) - Yap_growtrail(64 * 1024L); - Entry->Class = HeadName; - Entry->Last = Entry->First = j; - NDiffTerms++; - } else { - (Entry->Last)->Next = j; - Entry->Last = j; + cl = min; + if (compound_term) { + while (cl <= max) { + skip_to_arg(cl, compound_term, last_arg ); + cl++; } - } while ((j = NextInChain) != NIL && j->Name != 0x0); - Entry = Entries; - if (NDiffTerms == 1) { - CELL *WhereToStore; - - if (AtomsOnlyNil) { - TreatEntry(Entry, Gender, Flag, Gr); - return ((CELL)(Entry->Code)); - } - LFixed = emit_go(Gender, Entry->Class); - WhereToStore = StorePoint; - TreatEntry(Entry, Gender, Flag, Gr); - fill_go(WhereToStore, (CELL)(Entry->Code)); - return (LFixed); - } - TableSize = SizeTable(NDiffTerms); - if (NDiffTerms <= MinHashEntries) { - if (op == switch_c_op) - op = if_c_op; - else - op = if_f_op; - LFixed = emit_space(op, CellSize + TableSize * 2 * CellSize, TableSize); - } else - LFixed = emit_space(op, TableSize * 2 * CellSize, TableSize); - WhereToStore = StorePoint; - for (k = 0; k < NDiffTerms; k++) { - TreatEntry(Entry, Gender, Flag, Gr); - Entry++; - } - if (NDiffTerms > MinHashEntries) - BuildHash(WhereToStore, NDiffTerms, TableSize, Gender); - else - BuildIfTable(WhereToStore, NDiffTerms); - return (LFixed); -} - -/* - If atom(X) and friends are around, and for the moment, just forget - about doing indexing for constants and generate a traditional try, - retry chain. - */ -static CELL -DealFixedWithBips(ClauseDef *j, int NClauses, int Flag, GroupDef *Gr) -{ - int i = 2; - CELL my_labelno; - int nofalts = Gr->NofClausesAfter+NClauses; - - labelno += 2; - my_labelno = labelno; - Yap_emit(label_op, labelno, Zero); -#ifdef AGRESSIVE_BIPS - if (j->Name != 0x0 && j->Next->Name != 0x0) { - /* - we've got a sequence of i clauses with known argument. Can - index as normal for them - */ - CELL old_labelno; - yamop *old_FailAddress; - int old_ExtendedSingle, old_NAlts; - ClauseDef *j0 = j; - - labelno += 2; - old_labelno = labelno; - old_FailAddress = FailAddress; - FailAddress = labelno; - /* the clauses behaves as if a new group */ - NGroups++; - old_ExtendedSingle = ExtendedSingle; - ExtendedSingle = FALSE; - j = j->Next; - old_NAlts = Gr->NofClausesAfter; - while (j->Name != 0x0) i++, j = j->Next; - Gr->NofClausesAfter = old_NAlts + G->NCl - i; - DealFixed(j0, AtCl, switch_c_op, FirstIndex | IsAtom, Gr); - Yap_emit(label_op, old_labelno, Zero); - FailAddress = old_FailAddress; - ExtendedSingle = old_ExtendedSingle; - Gr->NofClausesAfter = old_NAlts; - NGroups--; } else { -#endif /* AGRESSIVE_BIPS */ - emit_cp_inst(try_op, j->Code, Flag, nofalts); - - if (indexed_code_for_cut != NIL) { - /* Unfortunately, this is bound never to happen */ - return((CELL)indexed_code_for_cut); - } - else j = j->Next; - nofalts--; -#ifdef AGRESSIVE_BIPS - } -#endif /* AGRESSIVE_BIPS */ - /* we handled a group */ - for (; i < NClauses; i++) { - emit_cp_inst(retry_op, j->Code, Flag, nofalts); - j = j->Next; - nofalts--; - } - emit_cp_inst(trust_op, j->Code, Flag, nofalts); - /* emit a jump with the place to jump to after finishing this group */ - if (NGroups > 1 && !(Flag & LastGroup) && !ExtendedSingle) - Yap_emit(jump_op, (CELL)((Gr+1)->First), Zero); - return(my_labelno); -} - -static CELL -DealCons(int i) -{ - int NAtCl = Groups[i].Type[AtCl]; - ClauseDef *Cla = Groups[i].Start; - - if (NAtCl == 1) { - if (FinalGr(i)) { - yamop * Cl = FindFirst(i, AtCl); - labelno += 2; - Yap_emit(label_op, labelno, Zero); - emit_tr(trust_op, Cl, 1, clause_has_cut(Cl)); - return (labelno); - } else if (ExtendedSingle) { - yamop * Cl = FindFirst(i, AtCl); - - labelno += 2; - Yap_emit(label_op, labelno, Zero); - emit_tr(try_op, Cl, 2, clause_has_cut(Cl)); - emit_tr(trust_op, FailAddress, 1, clause_has_cut(FailAddress)); - return (labelno); - } - return ((CELL)FindFirst(i, AtCl)); - - } else if (NAtCl == 0) - return ((CELL)FailAddress); - - while (Cla->Kind != AtCl) - Cla++; - - if (FinalGr(i)) { - if (Groups[i].SInfo & UsesBips) - return(DealFixedWithBips(Cla, NAtCl, LastGroup, Groups+i)); - else - return (DealFixed(Cla, AtCl, switch_c_op, - FirstIndex | IsAtom | LastGroup, Groups+i)); - } else { - if (Groups[i].SInfo & UsesBips) - return(DealFixedWithBips(Cla, NAtCl, 0, Groups+i)); - else - return (DealFixed(Cla, AtCl, switch_c_op, - FirstIndex | IsAtom, Groups+i)); - } -} - -static CELL -DealAppl(int i) -{ - int NApCl = Groups[i].Type[ApplCl]; - ClauseDef *Cla = Groups[i].Start; - - if (NApCl == 1) { - if (FinalGr(i)) { - yamop * Cl = FindFirst(i, ApplCl); - labelno += 2; - Yap_emit(label_op, labelno, Zero); - emit_tr(trust_op, Cl, 1, clause_has_cut(Cl)); - return (labelno); - } else if (ExtendedSingle) { - yamop * Cl = FindFirst(i, ApplCl); - labelno += 2; - Yap_emit(label_op, labelno, Zero); - emit_tr(try_op, Cl, 2, clause_has_cut(Cl)); - emit_tr(trust_op, FailAddress, 1, clause_has_cut(FailAddress)); - return (labelno); - } - return ((CELL)FindFirst(i, ApplCl)); - - } else if (NApCl == 0) - return ((CELL)FailAddress); - while (Cla->Kind != ApplCl) - Cla++; - if (FinalGr(i)) { - int Flag = FirstIndex | LastGroup; - return (DealFixed(Cla, ApplCl, switch_f_op, Flag, Groups+i)); - } - return (DealFixed(Cla, ApplCl, switch_f_op, FirstIndex, Groups+i)); -} - -/* Finds the body of the first clause of a group whose first arg is a list */ -static CELL -StartList(int i) -{ - ClauseDef *j = Groups[i].Start; - - while (j->Kind != ListCl) - j++; - if (FinalGr(i)) { - labelno += 2; - Yap_emit(label_op, labelno, Zero); - emit_tr(trust_op, SecLB(j->Code), 1, clause_has_cut(j->Code)); - return (labelno); - } else if (ExtendedSingle) { - labelno += 2; - Yap_emit(label_op, labelno, Zero); - emit_tr(try_op, SecLB(j->Code), 2, clause_has_cut(j->Code)); - emit_tr(trust_op, FailAddress, 1, clause_has_cut(FailAddress)); - return (labelno); - } else { - return (Unsigned(SecLB(j->Code))); - } -} - -static CELL -DealLAt(ClauseDef *Cla, int NOfClau, int NG) -{ - if (NOfClau == 0) - return ((CELL)FailAddress); - if (FinalGr(NG)) { - int Flag = HeadIndex | IsAtom | LastGroup; - return (DealFixed(Cla, AtCl, switch_c_op, Flag, Groups+NG)); - } - return (DealFixed(Cla, AtCl, switch_c_op, HeadIndex | IsAtom, Groups+NG)); -} - -static CELL -DealLAppl(ClauseDef *Cla, int NOfClauses, int NG) -{ - if (NOfClauses == 0) - return ((CELL)FailAddress); - if (FinalGr(NG)) { - int Flag = HeadIndex | LastGroup; - - return (DealFixed(Cla, ApplCl, switch_f_op, Flag, Groups+NG)); - } - return (DealFixed(Cla, ApplCl, switch_f_op, HeadIndex, Groups+NG)); -} - -static CELL -DealLList(ClauseDef *j, int NOfClauses, int PositionFlag, int NG) -{ - int k, nofalts = 1; - - if (NOfClauses == 0) - return ((CELL)FailAddress); - else if (NOfClauses == 1) { - if (FinalGr(NG)) { - labelno += 2; - Yap_emit(label_op, labelno, Zero); - if (PositionFlag & FirstIndex) - emit_tr(trust_op, SecLB(j->Code), 1, clause_has_cut(j->Code)); - else - emit_tr(trust_op, ThiLB(j->Code), 1, clause_has_cut(j->Code)); - return (labelno); - } else if (ExtendedSingle) { - labelno += 2; - Yap_emit(label_op, labelno, Zero); - if (PositionFlag & FirstIndex) - emit_tr(try_op, SecLB(j->Code), 2, clause_has_cut(j->Code)); - else - emit_tr(try_op, ThiLB(j->Code), 2, clause_has_cut(j->Code)); - emit_tr(trust_op, FailAddress, 1, clause_has_cut(FailAddress)); - return (labelno); - } - if (PositionFlag & FirstIndex) - return (Unsigned(SecLB(j->Code))); - return (Unsigned(ThiLB(j->Code))); - } - if (FinalGr(NG)) - PositionFlag |= LastGroup; - labelno += 2; - Yap_emit(label_op, labelno, Zero); - nofalts = Groups[NG].NofClausesAfter+NOfClauses; - emit_cp_inst(try_op, j->Code, PositionFlag, nofalts); - nofalts--; - if (indexed_code_for_cut != NIL) { - return((CELL)indexed_code_for_cut); - } else { - j = j->Next; - for (k = 2; k < NOfClauses; ++k) { - emit_cp_inst(retry_op, j->Code, PositionFlag, nofalts); - nofalts--; - j = j->Next; - } - emit_cp_inst(trust_op, j->Code, PositionFlag, nofalts); - /* emit a jump with the place to jump to after finishing this group */ - if (NGroups > 1 && !(PositionFlag & LastGroup) && !ExtendedSingle) - Yap_emit(jump_op, (CELL)(Groups[NG+1].First), Zero); - return (labelno); - } -} - - -static int -NoHeadVar(ClauseDef *CInfo, int NClauses) -{ - while (NClauses--) { - if (KindOfListArg(CInfo->Code) == VarCl) - return (FALSE); - CInfo = CInfo->Next; + while (cl <= max) { + if (cl->Tag == (_var+1)*sizeof(CELL)) { + ClauseDef *cli = cl; + while (cli < max) { + clcpy(cli,cli+1); + cli++; } - return (TRUE); + max--; + } else { + move_next(cl, argno); + } + cl++; + } + } + return max; } -/* Creates code when several clauses first arg is a list */ -static CELL -DealList(int i) -{ - int k; - ClauseDef *j; - CELL LLFirst; - CELL *WhereToStore; - int NListCl = Groups[i].Type[ListCl]; - int VFlags; - int nofalts = Groups[i].NofClausesAfter+NListCl; +static void +purge_pvar(GroupDef *group) { + ClauseDef *max = group->LastClause; + ClauseDef *cl = group->FirstClause; - if (NListCl == 0) - return ((CELL)FailAddress); - if (NListCl == 1) - return (StartList(i)); - j = Groups[i].Start; - while (j->Kind != ListCl) - j++; - if (NoHeadVar(j, NListCl)) { - CELL LLVar, LLAt, LLList, LLAppl; - ClauseDef *Firsts[MaxOptions], *Lasts[MaxOptions]; - int NOfSameCl[MaxOptions], l; - - NOfSameCl[AtCl] = 0; - NOfSameCl[VarCl] = 0; - NOfSameCl[ListCl] = 0; - NOfSameCl[ApplCl] = 0; - LLFirst = emit_space(switch_h_op, 4 * CellSize, 0); - WhereToStore = StorePoint; - LLVar = DealLList(j, NListCl, LastFoundList | FirstIndex, i); - for (l = 0; l < NListCl; ++l) { - int z = KindOfListArg(j->Code); - if (NOfSameCl[z] != 0) - Lasts[z]->Next = j; - else - Firsts[z] = j; - Lasts[z] = j; - (NOfSameCl[z])++; - j = j->Next; + while (cl <= max) { + if (cl->Tag == (_var+1)*sizeof(CELL)) { + ClauseDef *cli = cl; + while (cli < max) { + clcpy(cli,cli+1); + cli++; + } + group->VarClauses--; + max--; } - if (NOfSameCl[AtCl]) - Lasts[AtCl]->Next = NIL; - if (NOfSameCl[VarCl]) - Lasts[VarCl]->Next = NIL; - if (NOfSameCl[ListCl]) - Lasts[ListCl]->Next = NIL; - if (NOfSameCl[ApplCl]) - Lasts[ApplCl]->Next = NIL; - LLAppl = DealLAppl(Firsts[ApplCl], NOfSameCl[ApplCl], i); - LLAt = DealLAt(Firsts[AtCl], NOfSameCl[AtCl], i); - LLList = DealLList(Firsts[ListCl], NOfSameCl[ListCl], - LastFoundList | HeadIndex, i); - fill_switch_slots(WhereToStore, LLList, LLAt, LLAppl, LLVar, 4); - return (LLFirst); + cl++; } - if (FinalGr(i)) - VFlags = FirstIndex | LastFoundList | LastGroup; - else - VFlags = FirstIndex | LastFoundList; - labelno += 2; - Yap_emit(label_op, labelno, Zero); - emit_cp_inst(try_op, j->Code, VFlags, nofalts); - nofalts--; - if (indexed_code_for_cut != NIL) { - return((CELL)indexed_code_for_cut); + group->LastClause = max; +} + + +static void +do_nonvar_group(GroupDef *grp, int compound_term, UInt labl, PredEntry *ap, UInt argno, int first, int last_arg, UInt nxtlbl, int clleft, CELL *top) { + TypeSwitch *type_sw; + + /* move cl pointer */ + if (grp->AtomClauses + grp->PairClauses + grp->StructClauses > 1) { + Yap_emit(label_op, labl, Zero); + if (argno == 1) { + emit_protection_choicepoint(first, clleft, nxtlbl); + } + group_prologue(compound_term, argno, first); + if (grp->LastClause < grp->FirstClause) { /* only tests */ + return; + } + type_sw = emit_type_switch(switch_on_type_op); + type_sw->VarEntry = do_var_entries(grp, ap, argno, first, clleft, nxtlbl); + grp->LastClause = cls_move(grp->FirstClause, grp->LastClause, compound_term, argno, last_arg); + sort_group(grp); + type_sw->ConstEntry = do_consts(grp, ap, argno, first, nxtlbl, clleft, top); + type_sw->FuncEntry = do_funcs(grp, ap, argno, first, last_arg, nxtlbl, clleft, top); + type_sw->PairEntry = do_pair(grp, ap, argno, first, last_arg, nxtlbl, clleft, top); } else { - j = j->Next; - for (k = 2; k < NListCl; ++k) { - emit_cp_inst(retry_op, j->Code, VFlags, nofalts); - j = j->Next; - nofalts--; - } - emit_cp_inst(trust_op, j->Code, VFlags, nofalts); - /* emit a jump with the place to jump to after finishing this group */ - if (NGroups > 1 && !(VFlags & LastGroup) && !ExtendedSingle) - Yap_emit(jump_op, (CELL)(Groups[i+1].First), Zero); - return (labelno); + do_var_group(grp, ap, labl, TRUE, first, clleft, nxtlbl); } } - -/* Finds the place where to go if we have a flop */ -static CELL -GetFailToGo(int NG) +static UInt +do_optims(GroupDef *group, int ngroups, UInt fail_l) { - if (NGroups == 1) - return (Unsigned(FAILCODE)); - if (FinalGr(NG)) - return (Unsigned(TRUSTFAILCODE)); - if (ExtendedSingle) - return (Unsigned(Body(Groups[NG + 1].Start->Code))); - return (Unsigned(FAILCODE)); -} + if (ngroups==2 && group[0].FirstClause == group[0].LastClause && + group[0].AtomClauses == 1 && group[1].VarClauses == 1) { + CELL *sp; + UInt labl; - -/* Verifies if we have a group and a var first clause (catchall, usually) */ -static int -IsExtendedSingle(int NG) -{ - if (NGroups == 2 && NG == 0 && Groups[1].NCl == 1 && - NClauses <= CLAUSES_FOR_EXTENDED_SINGLE) - return (TRUE); - return (FALSE); + labl = new_label(); + sp = Yap_emit_extra_size(if_not_op, Zero, 3*CellSize); + sp[0] = (CELL)(group[0].FirstClause->Tag); + sp[1] = (CELL)(group[1].FirstClause->Code); + sp[2] = (CELL)PREVOP(group[0].FirstClause->Code,ld); + return labl; + } + return fail_l; } static int -gr_has_cuts(GroupDef *gr) +cls_info(ClauseDef *min, ClauseDef *max, UInt argno) { - return(0); + ClauseDef *cl=min; + int found_pvar = FALSE; + + while (cl <= max) { + add_info(cl, argno); + if (cl->Tag == (_var+1)*sizeof(CELL)) { + found_pvar = TRUE; + } + /* if (IsVarTerm(cl->Tag)) cl->Tag = (CELL)NULL; */ + cl++; + } + return found_pvar; } -static void -EmitGrSwitch(int Count) +static UInt +do_index(ClauseDef *min, ClauseDef* max, PredEntry *ap, UInt argno, UInt fail_l, int first, int clleft, CELL *top) { - GroupDef Gr; + UInt ngroups, found_pvar = FALSE; + UInt i = 0; + GroupDef *group = (GroupDef *)top; + UInt labl, labl0; - Gr = Groups[Count]; - if (!Gr.Type[ApplCl] && (Gr.SInfo & OnlyNils)) { - AtomsOnlyNil = TRUE; - if (FinalGr(Count)) { - emit_space(switch_ll_op, 3 * CellSize, - ((Gr.NCl) << 1)+gr_has_cuts(Groups+Count)); - } else if (NGroups == 1 || ExtendedSingle) - emit_space(switch_lnl_op, 4 * CellSize, 0); - else - emit_space(switch_nvl_op, 3 * CellSize, 0); + if (min == max) { + /* base case, just commit to the current code */ + return emit_single_switch_case(min, ap, first, clleft, fail_l); + } + if (ap->ArityOfPE < argno) { + UInt labl = new_label(); + do_var_clauses(min, max, FALSE, ap, labl, first, clleft, fail_l); + return labl; + } + found_pvar = cls_info(min, max, argno); + ngroups = groups_in(min, max, group); + top = (CELL *)(group+ngroups); + labl0 = labl = new_label(); + if (argno >1) { + /* don't try being smart for other arguments than the first */ + if (ngroups > 1 || group->VarClauses != 0 || found_pvar) { + if (ap->KindOfPE == argno) { + labl = new_label(); + do_var_clauses(min, max, FALSE, ap, labl, first, clleft, fail_l); + return labl; + } else { + return do_index(min, max, ap, argno+1, fail_l, first, clleft, top); + } + } else { + ClauseDef *cl = min; + /* + need to reset the code pointer, otherwise I could be in + the middle of a compound term. + */ + while (cl <= max) { + cl->CurrentCode = cl->Code; + cl++; + } + } } else { - AtomsOnlyNil = FALSE; - if (FinalGr(Count)) - emit_space(switch_l_op, 3 * CellSize, - ((Gr.NCl) << 1)+gr_has_cuts(Groups+Count)); - else if (NGroups == 1 || ExtendedSingle) - emit_space(switch_t_op, 4 * CellSize, 0); - else - emit_space(switch_nv_op, 3 * CellSize, 0); + UInt special_options; + if ((special_options = do_optims(group, ngroups, fail_l)) != fail_l) { + return special_options; + } + if (ap->PredFlags & LogUpdatePredFlag) { + /* complicated stuff */ + if (ngroups == 1 && group->VarClauses) { + return log_update_chain(ap); + } else if (ngroups > 1) { + TypeSwitch *type_sw; + + Yap_emit(label_op, labl0, Zero); + /* first group has variables */ + type_sw = emit_type_switch(switch_on_type_op); + type_sw->VarEntry = log_update_chain(ap); + labl = new_label(); + type_sw->ConstEntry = + type_sw->FuncEntry = + type_sw->PairEntry = + labl; + } + } else if (ngroups == 1 && group->VarClauses && !found_pvar) { + return fail_l; + } else if (ngroups > 1 || found_pvar) { + Yap_emit(label_op, labl0, Zero); + Yap_emit(jump_v_op, (CELL)PREVOP(min->Code,ld), Zero); + labl = new_label(); + } } + for (i=0; i < ngroups; i++) { + UInt nextlbl; + int left_clauses = clleft+(max-group->LastClause); + /* a group may end up not having clauses*/ + + if (i < ngroups-1) { + nextlbl = new_label(); + } else { + nextlbl = fail_l; + } + if (found_pvar && argno == 1) { + purge_pvar(group); + } + if (group->FirstClause==group->LastClause && first && left_clauses == 0) { + Yap_emit(jumpi_op, (CELL)(group->FirstClause->Code), Zero); + } else { + if (group->VarClauses) { + do_var_group(group, ap, labl, argno == 1, first, left_clauses, nextlbl); + } else { + do_nonvar_group(group, 0, labl, ap, argno, first, TRUE, nextlbl, left_clauses, top); + } + } + first = FALSE; + group++; + labl = nextlbl; + } + return labl0; } -/* Creates the indexation code for a non var group */ -static int -IndexNonVarGr(int Count) +/* execute an index inside a structure */ +static UInt +do_compound_index(ClauseDef *min, ClauseDef* max, PredEntry *ap, UInt arity, UInt argno, UInt fail_l, int first, int last_arg, int clleft, CELL *top) { - CELL LVar, LCons, LA, LL; - GroupDef Gr; - CELL *WhereToStore; + UInt ngroups; + UInt i = 0; + GroupDef *group; + int labl; + ClauseDef *cl = min; - Gr = Groups[Count]; - ExtendedSingle = IsExtendedSingle(Count); - FailAddress = (yamop *)GetFailToGo(Count); - if (NGroups > 1 && !(ExtendedSingle) && Count < NGroups - 1) { - labelno += 2; - Groups[Count + 1].First = (yamop *)labelno; + if (min == max) { + /* base case, just commit to the current code */ + return emit_single_switch_case(cl, ap, first, clleft, fail_l); } - if (Gr.NCl == 1) { - yamop * Cl = (Gr.Start)->Code; - if (Count == 0) - emit_tr(try_op, Body(Cl), Gr.NofClausesAfter+1, clause_has_cut(Cl)); - else if (FinalGr(Count)) - emit_tr(trust_op, Body(Cl), Gr.NofClausesAfter+1, clause_has_cut(Cl)); - else - emit_tr(retry_op, Body(Cl), Gr.NofClausesAfter+1, clause_has_cut(Cl)); - return (FALSE); /* Indexation is not necessary */ + group = (GroupDef *)top; + cl = min; + while (i < arity) { + ClauseDef *cl = min; + /* search for a subargument */ + while (cl <= max) { + add_arg_info(cl, i+1); + cl++; + } + ngroups = groups_in(min, max, group); + if (ngroups == 1 && group->VarClauses == 0) break; + i++; } - if (NGroups > 1 && !(ExtendedSingle) && Count < NGroups - 1) { - if (Count == 0) - emit_tr(tryme_op, (yamop *) labelno, - Gr.NofClausesAfter+1, clause_has_cut((Gr.Start)->Code)); - else - emit_tr(retryme_op, (yamop *) labelno, - Gr.NofClausesAfter+1, clause_has_cut((Gr.Start)->Code)); - } - EmitGrSwitch(Count); - WhereToStore = StorePoint; - LCons = DealCons(Count); - AtomsOnlyNil = FALSE; - LA = DealAppl(Count); - LL = DealList(Count); - if (log_update) { - LVar = log_update; - } else - LVar = Unsigned(FirstCl); - if (NGroups == 1 || ExtendedSingle) - fill_switch_slots(WhereToStore, LL, LCons, LA, LVar, 4); - else - fill_switch_slots(WhereToStore, LL, LCons, LA, LVar, 3); - return (TRUE); -} - -static void -IndexVarGr(int Count) -{ - GroupDef *Gr; - ClauseDef *Cla; - int j; - int nofalts; - - Gr = Groups + Count; - Cla = Gr->Start; - nofalts = Gr->NofClausesAfter+Gr->NCl; - if (Count == 0) { - emit_tr(try_op, Body((Cla)->Code), nofalts, clause_has_cut(Cla->Code)); - Cla++; - nofalts--; - } else if (Count == NGroups - 1 && Gr->NCl == 1) { - Yap_emit(label_op, Unsigned(Gr->First), Zero); - emit_tr(trust_op, Body((Cla)->Code), 1, clause_has_cut(Cla->Code)); - return; + if (i == arity) { + return do_index(min, max, ap, argno+1, fail_l, first, clleft, top); } else { - Yap_emit(label_op, Unsigned(Gr->First), Zero); - emit_tr(retry_op, Body((Cla)->Code), nofalts, clause_has_cut(Cla->Code)); - Cla++; - nofalts--; + last_arg = (last_arg && i+1 == arity); } - for (j = 2; j < Gr->NCl; ++j) { - emit_tr(retry_op, Body((Cla)->Code), nofalts, clause_has_cut(Cla->Code)); - Cla++; - nofalts--; - } - if (Gr->NCl > 1) { - if (Count == NGroups - 1) - emit_tr(trust_op, Body(Cla->Code), 1, clause_has_cut(Cla->Code)); - else - emit_tr(retry_op, Body(Cla->Code), nofalts, clause_has_cut(Cla->Code)); + /* ok, we are doing a sub-argument */ + /* process groups */ + labl = new_label(); + top = (CELL *)(group+1); + do_nonvar_group(group, i+1, labl, ap, argno, argno == 1, last_arg, fail_l, clleft, top); + return labl; +} + +static void +init_clauses(ClauseDef *cl, PredEntry *ap) +{ + yamop *codep = ap->cs.p_code.FirstClause; + UInt n = ap->cs.p_code.NOfClauses; + + while (n > 0) { + cl->Code = cl->CurrentCode = NEXTOP(codep,ld); + n--; + cl++; + codep = NextClause(codep); } } - -static int -SimpleCase(void) +static UInt +compile_index(PredEntry *ap) { - if (Groups[0].Type[VarCl] != 0) - return (FALSE); - return (IndexNonVarGr(0)); -} + int NClauses = ap->cs.p_code.NOfClauses; + ClauseDef *cls = (ClauseDef *)H; + CELL *top = (CELL *) TR; + /* only global variable I use directly */ + labelno = 1; -static int -ComplexCase(void) -{ - int Indexable = FALSE, i; - - if (IsExtendedSingle(0)) - return (SimpleCase()); - Yap_emit(jump_v_op, (CELL) FirstCl, Zero); - if (Groups[0].Type[VarCl] == 0) - i = 0; - else { - IndexVarGr(0); - i = 1; + if (cls+NClauses > (ClauseDef *)(ASP-4096)) { + /* grow stack */ + longjmp(Yap_CompilerBotch,3); } - for (; i < NGroups; i += 2) { - Indexable |= IndexNonVarGr(i); - if (i < NGroups - 1) - IndexVarGr(i + 1); - } - return (Indexable); -} - - -static int -SpecialCases(void) -{ - CELL LVar; - - if (log_update) { - LVar = log_update; - } else { - LVar = (CELL)(ArOfCl->Code); - } - /* Clear what was left before */ - freep = (char *) (ArOfCl + NClauses); + freep = (char *)(cls+NClauses); CodeStart = cpc = NIL; - /* For now just a special case */ - if (NGroups == 2 && NClauses == 2 && Groups[0].Type[AtCl] == 1 && - !RemovedCl && !(Groups[0].SInfo & UsesBips)) { - emit_if_not(ArOfCl->Name, Unsigned(Body(ArOfCl[1].Code)), - LVar); - return (TRUE); - } else - return (FALSE); + if (ap->PredFlags & LogUpdatePredFlag) { + /* throw away a label */ + new_label(); + } + /* prepare basic data structures */ + init_clauses(cls,ap); + return do_index(cls, cls+(NClauses-1), ap, 1, (UInt)FAILCODE, TRUE, 0, top); } + yamop * Yap_PredIsIndexable(PredEntry *ap) { - int NGr, Indexable = 0; - yamop *indx_out = NULL; - log_update = 0; + yamop *indx_out; if (setjmp(Yap_CompilerBotch) == 3) { /* just duplicate the stack */ @@ -1330,94 +2709,23 @@ Yap_PredIsIndexable(PredEntry *ap) } restart_index: Yap_ErrorMessage = NULL; - labelno = 1; - RemovedCl = FALSE; - FirstCl = ap->cs.p_code.FirstClause; - CurrentPred = ap; - if (CurrentPred->PredFlags & ProfiledPredFlag) - profiling = TRUE; - else if (CurrentPred->PredFlags & CountPredFlag) - call_counting = TRUE; - else - profiling = FALSE; - IPredArity = ap->ArityOfPE; - /* Store the clauses in the Global */ - ArOfCl = (ClauseDef *) H; - /* and the groups in the Auxiliary */ - Groups = (GroupDef *) TR; - NGr = NGroupsIn(ap); - CountGroups(Groups, NGr); - /* store entries after groups */ - Entries = (EntryDef *) (Groups + NGroups); - CodeStart = cpc = NIL; - freep = (char *) (ArOfCl + NClauses); - if (Yap_ErrorMessage != NULL) { + if (compile_index(ap) == (UInt)FAILCODE) { return NULL; } - if (CurrentPred->PredFlags & LogUpdatePredFlag) { - log_update = labelno; - labelno += 2; - } - if (NClauses == 0) { - Indexable = FALSE; - return NULL; - } else { - if (NGr == 1) - Indexable = SimpleCase(); - else - Indexable = ComplexCase(); - if (!Indexable) - Indexable = SpecialCases(); - } - if (CellPtr(freep) >= ASP) { - Yap_Error(SYSTEM_ERROR, TermNil, "out of stack space while indexing"); - return NULL; - } - if (log_update && NClauses > 1) { - int i; - Clause *cl; - - Indexable = TRUE; - Yap_emit(label_op, log_update, Zero); - Yap_emit(try_op, Unsigned(Body(ArOfCl[0].Code)), Zero); - cl = ClauseCodeToClause(ArOfCl[0].Code); - if (cl->ClFlags & LogUpdRuleMask) { - cl->u2.ClExt->u.EC.ClRefs++; - } else { - cl->u2.ClUse++; - } - for (i = 1; i < NClauses-1; i++) { - Yap_emit(retry_op, Unsigned(Body(ArOfCl[i].Code)), Zero); - cl = ClauseCodeToClause(ArOfCl[0].Code); - if (cl->ClFlags & LogUpdRuleMask) { - cl->u2.ClExt->u.EC.ClRefs++; - } else { - cl->u2.ClUse++; - } - } - Yap_emit(trust_op, Unsigned(Body(ArOfCl[i].Code)), Zero); - cl = ClauseCodeToClause(ArOfCl[i].Code); - if (cl->ClFlags & LogUpdRuleMask) { - cl->u2.ClExt->u.EC.ClRefs++; - } else { - cl->u2.ClUse++; - } - } - if (!Indexable) { - return NULL; - } else { #ifdef DEBUG - if (Yap_Option['i' - 'a' + 1]) { - Yap_ShowCode(); - } + if (Yap_Option['i' - 'a' + 1]) { + Yap_ShowCode(); + } #endif - if ((indx_out = Yap_assemble(ASSEMBLING_INDEX)) == NIL) { - if (!Yap_growheap(FALSE)) { - Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage); - return NULL; - } - goto restart_index; + /* globals for assembler */ + CurrentPred = ap; + IPredArity = ap->ArityOfPE; + if ((indx_out = Yap_assemble(ASSEMBLING_INDEX)) == NULL) { + if (!Yap_growheap(FALSE)) { + Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage); + return NULL; } + goto restart_index; } return(indx_out); } diff --git a/C/init.c b/C/init.c index 062af8b9e..f4a85da22 100644 --- a/C/init.c +++ b/C/init.c @@ -446,10 +446,9 @@ Yap_InitCPred(char *Name, unsigned long int Arity, CPredicate code, int flags) { Atom atom = Yap_LookupAtom(Name); PredEntry *pe; - yamop *p_code = ((Clause *)NULL)->ClCode; - Clause *cl = (Clause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(((yamop *)p_code),sla),e)); + yamop *p_code = ((StaticClause *)NULL)->ClCode; + StaticClause *cl = (StaticClause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(((yamop *)p_code),sla),e)); - cl->u.ClValue = 0; cl->ClFlags = 0; cl->Owner = Yap_LookupAtom("user"); p_code = cl->ClCode; @@ -481,10 +480,9 @@ Yap_InitCmpPred(char *Name, unsigned long int Arity, CmpPredicate cmp_code, int { Atom atom = Yap_LookupAtom(Name); PredEntry *pe; - yamop *p_code = ((Clause *)NULL)->ClCode; - Clause *cl = (Clause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(((yamop *)p_code),lxx),e)); + yamop *p_code = ((StaticClause *)NULL)->ClCode; + StaticClause *cl = (StaticClause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(((yamop *)p_code),lxx),e)); - cl->u.ClValue = 0; cl->ClFlags = 0; cl->Owner = Yap_LookupAtom("user"); p_code = cl->ClCode; @@ -519,10 +517,9 @@ Yap_InitAsmPred(char *Name, unsigned long int Arity, int code, CPredicate def, pe->cs.f_code = def; pe->ModuleOfPred = CurrentModule; if (def != NULL) { - yamop *p_code = ((Clause *)NULL)->ClCode; - Clause *cl = (Clause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(((yamop *)p_code),sla),e)); + yamop *p_code = ((StaticClause *)NULL)->ClCode; + StaticClause *cl = (StaticClause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(((yamop *)p_code),sla),e)); - cl->u.ClValue = 0; cl->ClFlags = 0; cl->Owner = Yap_LookupAtom("user"); p_code = cl->ClCode; @@ -587,18 +584,17 @@ Yap_InitCPredBack(char *Name, unsigned long int Arity, unsigned int Extra, CPred if (pe->cs.p_code.FirstClause != NIL) CleanBack(pe, Start, Cont); else { - Clause *cl; - yamop *code = ((Clause *)NULL)->ClCode; + StaticClause *cl; + yamop *code = ((StaticClause *)NULL)->ClCode; pe->PredFlags = CompiledPredFlag | StandardPredFlag; #ifdef YAPOR pe->PredFlags |= SequentialPredFlag; #endif /* YAPOR */ - cl = (Clause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(NEXTOP(code,lds),lds),e)); + cl = (StaticClause *)Yap_AllocCodeSpace((CELL)NEXTOP(NEXTOP(NEXTOP(code,lds),lds),e)); if (cl == NIL) { Yap_Error(SYSTEM_ERROR,TermNil,"No Heap Space in InitCPredBack"); return; } - cl->u.ClValue = 0; cl->ClFlags = 0; cl->Owner = Yap_LookupAtom("user"); code = cl->ClCode; @@ -710,7 +706,7 @@ InitCodes(void) INIT_YAMOP_LTT(&(heap_regs->tableanswerresolutioncode), 0); #endif /* YAPOR */ #endif /* TABLING */ - heap_regs->failcode = Yap_opcode(_op_fail); + heap_regs->failcode->opc = Yap_opcode(_op_fail); heap_regs->failcode_1 = Yap_opcode(_op_fail); heap_regs->failcode_2 = Yap_opcode(_op_fail); heap_regs->failcode_3 = Yap_opcode(_op_fail); @@ -721,17 +717,17 @@ InitCodes(void) heap_regs->env_for_trustfail_code.op = Yap_opcode(_call); heap_regs->env_for_trustfail_code.s = -Signed(RealEnvSize); heap_regs->env_for_trustfail_code.l2 = NULL; - heap_regs->trustfailcode = Yap_opcode(_trust_fail); + heap_regs->trustfailcode->opc = Yap_opcode(_trust_fail); heap_regs->env_for_yes_code.op = Yap_opcode(_call); heap_regs->env_for_yes_code.s = -Signed(RealEnvSize); heap_regs->env_for_yes_code.l2 = NULL; - heap_regs->yescode.opc = Yap_opcode(_Ystop); + heap_regs->yescode->opc = Yap_opcode(_Ystop); heap_regs->undef_op = Yap_opcode(_undef_p); heap_regs->index_op = Yap_opcode(_index_pred); heap_regs->fail_op = Yap_opcode(_op_fail); - heap_regs->nocode.opc = Yap_opcode(_Nstop); + heap_regs->nocode->opc = Yap_opcode(_Nstop); ((yamop *)(&heap_regs->rtrycode))->opc = Yap_opcode(_retry_and_mark); ((yamop *)(&heap_regs->rtrycode))->u.ld.s = 0; @@ -748,9 +744,9 @@ InitCodes(void) heap_regs->n_of_threads = 1; heap_regs->heap_top_owner = -1; #endif /* YAPOR */ - heap_regs->clausecode.arity = 0; - heap_regs->clausecode.clause = NULL; - heap_regs->clausecode.func = NIL; + heap_regs->clausecode->arity = 0; + heap_regs->clausecode->clause = NULL; + heap_regs->clausecode->func = NIL; heap_regs->invisiblechain.Entry = NIL; INIT_RWLOCK(heap_regs->invisiblechain.AERWLock); diff --git a/C/save.c b/C/save.c index aebe54442..23e29e4c2 100644 --- a/C/save.c +++ b/C/save.c @@ -107,8 +107,8 @@ STATIC_PROTO(void restore_codes, (void)); STATIC_PROTO(void ConvDBList, (Term, char *,CELL)); STATIC_PROTO(Term AdjustDBTerm, (Term)); STATIC_PROTO(void RestoreDB, (DBEntry *)); -STATIC_PROTO(void RestoreClause, (Clause *,int)); -STATIC_PROTO(void CleanClauses, (yamop *, yamop *)); +STATIC_PROTO(void RestoreClause, (yamop *, PredEntry *, int)); +STATIC_PROTO(void CleanClauses, (yamop *, yamop *,PredEntry *)); STATIC_PROTO(void rehash, (CELL *, int, int)); STATIC_PROTO(void CleanCode, (PredEntry *)); STATIC_PROTO(void RestoreEntries, (PropEntry *)); @@ -1379,17 +1379,21 @@ UnmarkTrEntries(void) if (IsVarTerm(entry)) { RESET_VARIABLE((CELL *)entry); } else if (IsPairTerm(entry)) { - CODEADDR ent = CodeAddrAdjust((CODEADDR)RepPair(entry)); + CELL *ent = CellPtoHeapAdjust(RepPair(entry)); register CELL flags; - flags = Flags(ent); + flags = *ent; ResetFlag(InUseMask, flags); - Flags(ent) = flags; + *ent = flags; if (FlagOn(ErasedMask, flags)) { if (FlagOn(DBClMask, flags)) { - Yap_ErDBE((DBRef) (ent - (CELL) &(((DBRef) NIL)->Flags))); + Yap_ErDBE(DBStructFlagsToDBStruct(ent)); } else { - Yap_ErCl(ClauseFlagsToClause(ent)); + if (flags & LogUpdMask) { + Yap_ErLogUpdCl(ClauseFlagsToLogUpdClause(ent)); + } else { + Yap_ErCl(ClauseFlagsToDynamicClause(ent)); + } } } } diff --git a/C/tracer.c b/C/tracer.c index 101a057e1..972725aef 100644 --- a/C/tracer.c +++ b/C/tracer.c @@ -111,9 +111,8 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args) /* extern int gc_calls; */ vsc_count++; - /* return;*/ #ifdef COMMENTED - if (vsc_count < 124840LL) return; + return; if (vsc_count == 124881LL) { printf("Here I go\n"); } diff --git a/H/Heap.h b/H/Heap.h index 1b8e6a847..af6574c0b 100644 --- a/H/Heap.h +++ b/H/Heap.h @@ -10,7 +10,7 @@ * File: Heap.h * * mods: * * comments: Heap Init Structure * -* version: $Id: Heap.h,v 1.39 2003-03-20 15:10:16 vsc Exp $ * +* version: $Id: Heap.h,v 1.40 2003-04-30 17:45:53 vsc Exp $ * *************************************************************************/ /* information that can be stored in Code Space */ @@ -58,7 +58,7 @@ typedef struct various_codes { yamop tableanswerresolutioncode; #endif /* TABLING */ yamop comma_code[5]; - OPCODE failcode; + yamop failcode[1]; OPCODE failcode_1; OPCODE failcode_2; OPCODE failcode_3; @@ -77,7 +77,7 @@ typedef struct various_codes { struct pred_entry *p; struct pred_entry *p0; } env_for_trustfail_code; /* sla */ - OPCODE trustfailcode; + yamop trustfailcode[1]; struct { OPCODE op; #ifdef YAPOR @@ -90,14 +90,14 @@ typedef struct various_codes { struct pred_entry *p; struct pred_entry *p0; } env_for_yes_code; /* sla */ - yamop yescode; - yamop nocode; - yamop rtrycode; + yamop yescode[1]; + yamop nocode[1]; + yamop rtrycode[1]; struct { OPREG arity; struct yami *clause; Functor func; - } clausecode; + } clausecode[1]; union CONSULT_OBJ *consultsp; union CONSULT_OBJ *consultbase; union CONSULT_OBJ *consultlow; @@ -127,7 +127,7 @@ typedef struct various_codes { int compiler_compile_mode; struct pred_entry *compiler_current_pred; AtomHashEntry invisiblechain; - OPCODE dummycode; + OPCODE dummycode[1]; UInt maxdepth, maxlist; int update_mode; Atom atprompt; @@ -159,7 +159,7 @@ typedef struct various_codes { Term module_name[MaxModules]; struct pred_entry *module_pred[MaxModules]; SMALLUNSGN no_of_modules; - struct clause_struct *dead_clauses; + struct dead_clause *dead_clauses; int primitives_module; int user_module; Atom @@ -314,8 +314,6 @@ typedef struct various_codes { struct PSEUDO *compiler_CodeStart; struct PSEUDO *compiler_icpc; struct PSEUDO *compiler_BlobsStart; - int compiler_clause_mask; - CELL compiler_clause_store; int *compiler_label_offset; UInt i_pred_arity; int compiler_profiling; @@ -350,14 +348,13 @@ typedef struct various_codes { #define ANSWER_RESOLUTION ((yamop *)&(heap_regs->tableanswerresolutioncode )) #endif /* TABLING */ #define COMMA_CODE heap_regs->comma_code -#define FAILCODE ((CODEADDR)&(heap_regs->failcode )) -#define FAILCODE ((CODEADDR)&(heap_regs->failcode )) -#define TRUSTFAILCODE ((CODEADDR)&(heap_regs->trustfailcode )) -#define YESCODE (&(heap_regs->yescode )) -#define NOCODE (&(heap_regs->nocode )) -#define RTRYCODE (&(heap_regs->rtrycode )) -#define DUMMYCODE (&(heap_regs->dummycode )) -#define CLAUSECODE (&(heap_regs->clausecode )) +#define FAILCODE heap_regs->failcode +#define TRUSTFAILCODE heap_regs->trustfailcode +#define YESCODE heap_regs->yescode +#define NOCODE heap_regs->nocode +#define RTRYCODE heap_regs->rtrycode +#define DUMMYCODE heap_regs->dummycode +#define CLAUSECODE heap_regs->clausecode #define INVISIBLECHAIN heap_regs->invisiblechain #define max_depth heap_regs->maxdepth #define max_list heap_regs->maxlist @@ -535,8 +532,6 @@ typedef struct various_codes { #define CodeStart heap_regs->compiler_CodeStart #define icpc heap_regs->compiler_icpc #define BlobsStart heap_regs->compiler_BlobsStart -#define clause_mask heap_regs->compiler_clause_mask -#define clause_store heap_regs->compiler_clause_store #define label_offset heap_regs->compiler_label_offset #define IPredArity heap_regs->i_pred_arity #define profiling heap_regs->compiler_profiling diff --git a/H/YapOpcodes.h b/H/YapOpcodes.h index ffc1118c1..1c7edfd6c 100644 --- a/H/YapOpcodes.h +++ b/H/YapOpcodes.h @@ -140,29 +140,15 @@ OPCODE(cut_t ,e), OPCODE(cut_e ,e), OPCODE(try_clause ,ld), - OPCODE(try_in ,l), OPCODE(retry ,ld), - OPCODE(trust_in ,ldl), OPCODE(trust ,ld), - OPCODE(retry_first ,ld), - OPCODE(trust_first_in ,ldl), - OPCODE(trust_first ,ld), - OPCODE(retry_tail ,ld), - OPCODE(trust_tail_in ,ldl), - OPCODE(trust_tail ,ld), - OPCODE(retry_head ,ld), - OPCODE(trust_head_in ,ldl), - OPCODE(trust_head ,ld), + OPCODE(try_in ,l), OPCODE(jump_if_var ,l), - OPCODE(switch_on_type ,llll), - OPCODE(switch_on_nonv ,lll), - OPCODE(switch_last ,slll), - OPCODE(switch_on_head ,llll), - OPCODE(switch_list_nl ,llll), - OPCODE(switch_list_nl_prefetch ,llll), - OPCODE(switch_nv_list ,lll), - OPCODE(switch_l_list ,slll), OPCODE(switch_on_cons ,c), + OPCODE(switch_on_type ,llll), + OPCODE(switch_list_nl ,ollll), + OPCODE(switch_on_arg_type ,xllll), + OPCODE(switch_on_sub_arg_type ,sllll), OPCODE(go_on_cons ,cll), OPCODE(if_cons ,sl), OPCODE(switch_on_func ,s), diff --git a/H/absmi.h b/H/absmi.h index 03d9c9fdc..e110cac01 100644 --- a/H/absmi.h +++ b/H/absmi.h @@ -533,7 +533,6 @@ typedef CELL label; #define pred_entry(X) ((PredEntry *)(Unsigned(X)-(CELL)(&(((PredEntry *)NULL)->StateOfPred)))) #define pred_entry_from_code(X) ((PredEntry *)(Unsigned(X)-(CELL)(&(((PredEntry *)NULL)->CodeOfPred)))) #define PredFromDefCode(X) ((PredEntry *)(Unsigned(X)-(CELL)(&(((PredEntry *)NULL)->OpcodeOfPred)))) -#define Flags(X) pred_entry(X)->StateOfPred #define PredCode(X) pred_entry(X)->CodeOfPred #define PredOpCode(X) pred_entry(X)->OpcodeOfPred #define TruePredCode(X) pred_entry(X)->TrueCodeOfPred diff --git a/H/amidefs.h b/H/amidefs.h index df8e6e082..a678943aa 100644 --- a/H/amidefs.h +++ b/H/amidefs.h @@ -142,6 +142,11 @@ typedef struct yami { CODEADDR d; CELL next; } d; + struct { + CODEADDR d; + struct pred_entry *p; + CELL next; + } dp; struct { Int ClTrail; Int ClENV; @@ -234,6 +239,22 @@ typedef struct yami { struct yami *l4; CELL next; } llll; + struct { + wamreg x; + struct yami *l1; + struct yami *l2; + struct yami *l3; + struct yami *l4; + CELL next; + } xllll; + struct { + COUNT s; + struct yami *l1; + struct yami *l2; + struct yami *l3; + struct yami *l4; + CELL next; + } sllll; struct { struct pred_entry *p; wamreg x1; @@ -313,6 +334,11 @@ typedef struct yami { COUNT s; CELL next; } s; + struct { + COUNT s; + struct pred_entry *p; + CELL next; + } sp; struct { COUNT s; CELL c; @@ -431,6 +457,8 @@ typedef yamop yamopp; #define NEXTOP(V,TYPE) ((yamop *)(&((V)->u.TYPE.next))) +#define PREVOP(V,TYPE) ((yamop *)((CODEADDR)(V)-(CELL)NEXTOP((yamop *)NULL,TYPE))) + #if defined(TABLING) || defined(SBA) typedef struct trail_frame { Term term; @@ -554,12 +582,12 @@ typedef struct choicept { #endif #define RealEnvSize (EnvSizeInCells*sizeof(CELL)) -#define ENV_Size(cp) (((yamop *)((CODEADDR)(cp) - (CELL)NEXTOP((yamop *)NIL,sla)))->u.sla.s) -#define ENV_ToP(cp) (((yamop *)((CODEADDR)(cp) - (CELL)NEXTOP((yamop *)NIL,sla)))->u.sla.sla_u.p) -#define ENV_ToOp(cp) (((yamop *)((CODEADDR)(cp) - (CELL)NEXTOP((yamop *)NIL,sla)))->opc) +#define ENV_Size(cp) (((yamop *)((CODEADDR)(cp) - (CELL)NEXTOP((yamop *)NULL,sla)))->u.sla.s) +#define ENV_ToP(cp) (((yamop *)((CODEADDR)(cp) - (CELL)NEXTOP((yamop *)NULL,sla)))->u.sla.sla_u.p) +#define ENV_ToOp(cp) (((yamop *)((CODEADDR)(cp) - (CELL)NEXTOP((yamop *)NULL,sla)))->opc) #define EnvSize(cp) ((-ENV_Size(cp))/(OPREG)sizeof(CELL)) -#define EnvBMap(p) (((yamop *)((CODEADDR)(p) - (CELL)NEXTOP((yamop *)NIL,sla)))->u.sla.bmap) -#define EnvPreg(p) (((yamop *)((CODEADDR)(p) - (CELL)NEXTOP((yamop *)NIL,sla)))->u.sla.p0) +#define EnvBMap(p) (((yamop *)((CODEADDR)(p) - (CELL)NEXTOP((yamop *)NULL,sla)))->u.sla.bmap) +#define EnvPreg(p) (((yamop *)((CODEADDR)(p) - (CELL)NEXTOP((yamop *)NULL,sla)))->u.sla.p0) /* access to instructions */ diff --git a/H/clause.h b/H/clause.h index aeb39a71f..13cb14aab 100644 --- a/H/clause.h +++ b/H/clause.h @@ -32,54 +32,13 @@ typedef union CONSULT_OBJ { #define ASSEMBLING_CLAUSE 0 #define ASSEMBLING_INDEX 1 -/* This information is put at the start of every clause */ - -#define VarCl 0x0000 /* The clause's first argument is a var */ -#define ListCl 0x0001 /* The clause's first argument is a list */ -#define ApplCl 0x0002 /* The clause's first argument is an Appl */ -#define AtCl 0x0003 /* The clause's first argument is a const */ - -/* If the firs argument is a list, then we care about what - we have in its head */ -#define FHeadVar 0x0000 /* The head of the first argument is a var */ -#define FHeadList 0x0004 /* The head of the first argument is a list */ -#define FHeadAppl 0x0008 /* The head of the first argument ia an Appl */ -#define FHeadCons 0x000c /* The head of the first argument is a cons */ - -/* If the first argument is a variable, then it may be tipified later */ -#define FIsVar 0x0010 /* ... :- var(X)... */ -#define FIsAtom 0x0020 /* ... :- atom(X) .... */ -#define FIsNum 0x0040 /* ... :- integer(X) ... - ... :- number(X) ... */ -#define FIsPrimi 0x0080 /* ... :- atomic(X) ... - ... :- primitive(X) ... */ - -#define FirstArgOfClType(X) ((X) & 0x03 ) -#define HeadOfClType(X) ( ((X) >> 2) & 0x03 ) - -#define KindOfArg(X) FirstArgOfClType(ClauseCodeToClause(X)->ClFlags) -#define KindOfListArg(X) HeadOfClType(ClauseCodeToClause(X)->ClFlags) -#define KindOfBipArg(X) ClauseCodeToClause(X)->ClFlags - #define NextClause(X) (((yamop *)X)->u.ld.d) #define PredFirstClause 0 #define PredMiddleClause 1 #define PredLastClause 2 -typedef struct clause_struct { - /* This info is used by the indexing algorithm and by the dynamic clauses. - It is either the value of the first arg for static clauses or a pointer - to the previous clause */ - union { - CELL ClValue; /* indexable clause */ - yamop *ClPrevious; /* immediate update clause */ - CODEADDR ClInfo; /* indexing code for log. sem. */ - yamop *ClVarChain; /* log. sem. indexing code */ - struct clause_struct *NextCl; /* dead clause */ - } u; - /* the actual owner of the clause */ - Atom Owner; +typedef struct logic_upd_clause { /* A set of flags describing info on the clause */ CELL ClFlags; #if defined(YAPOR) || defined(THREADS) @@ -87,6 +46,10 @@ typedef struct clause_struct { lockvar ClLock; UInt ref_count; #endif + union { + yamop *ClVarChain; /* indexing code for log. sem. */ + } u; + /* extra clause information for logical update indices and facts */ union { /* extra clause information for logical update semantics, rules with envs */ yamop *ClExt; @@ -95,14 +58,58 @@ typedef struct clause_struct { } u2; /* The instructions, at least one of the form sl */ yamop ClCode[MIN_ARRAY]; -} Clause; + Atom Owner; +} LogUpdClause; -#define ClauseCodeToClause(p) ((Clause *)((CODEADDR)(p)-(CELL)(((Clause *)NULL)->ClCode))) -#define ClauseFlagsToClause(p) ((Clause *)((CODEADDR)(p)-(CELL)(&(((Clause *)NULL)->ClFlags)))) +typedef struct dynamic_clause { + /* A set of flags describing info on the clause */ + CELL ClFlags; +#if defined(YAPOR) || defined(THREADS) + /* A lock for manipulating the clause */ + lockvar ClLock; + UInt ref_count; +#endif + Atom Owner; + yamop *ClPrevious; /* immediate update clause */ + /* The instructions, at least one of the form sl */ + yamop ClCode[MIN_ARRAY]; +} DynamicClause; -#define DynamicFlags(X) (ClauseCodeToClause(X)->ClFlags) +typedef struct static_clause { + /* A set of flags describing info on the clause */ + CELL ClFlags; + Atom Owner; + /* The instructions, at least one of the form sl */ + yamop ClCode[MIN_ARRAY]; +} StaticClause; -#define DynamicLock(X) (ClauseCodeToClause(X)->ClLock) +typedef struct dead_clause { + CELL ClFlags; + struct dead_clause *NextCl; /* dead clause */ +#if defined(YAPOR) || defined(THREADS) + /* A lock for manipulating the clause */ + lockvar ClLock; + UInt ref_count; +#endif +} DeadClause; + +typedef union clause_obj { + struct logic_upd_clause luc; + struct dynamic_clause ic; + struct static_clause sc; +} ClauseUnion; + +#define ClauseCodeToDynamicClause(p) ((DynamicClause *)((CODEADDR)(p)-(CELL)(((DynamicClause *)NULL)->ClCode))) +#define ClauseCodeToStaticClause(p) ((StaticClause *)((CODEADDR)(p)-(CELL)(((StaticClause *)NULL)->ClCode))) +#define ClauseCodeToLogUpdClause(p) ((LogUpdClause *)((CODEADDR)(p)-(CELL)(((LogUpdClause *)NULL)->ClCode))) + +#define ClauseFlagsToDynamicClause(p) ((DynamicClause *)(p)) +#define ClauseFlagsToLogUpdClause(p) ((LogUpdClause *)(p)) +#define ClauseFlagsToStaticClause(p) ((StaticClause *)(p)) + +#define DynamicFlags(X) (ClauseCodeToDynamicClause(X)->ClFlags) + +#define DynamicLock(X) (ClauseCodeToDynamicClause(X)->ClLock) #if defined(YAPOR) || defined(THREADS) #define INIT_CLREF_COUNT(X) (X)->ref_count = 0 @@ -120,14 +127,16 @@ typedef struct clause_struct { wamreg STD_PROTO(Yap_emit_x,(CELL)); wamreg STD_PROTO(Yap_compile_cmp_flags,(PredEntry *)); void STD_PROTO(Yap_InitComma,(void)); +wamreg STD_PROTO(Yap_regnotoreg,(UInt)); /* cdmgr.c */ -void STD_PROTO(Yap_RemoveLogUpdIndex,(Clause *)); +void STD_PROTO(Yap_RemoveLogUpdIndex,(LogUpdClause *)); void STD_PROTO(Yap_IPred,(PredEntry *)); void STD_PROTO(Yap_addclause,(Term,yamop *,int,int)); /* dbase.c */ -void STD_PROTO(Yap_ErCl,(Clause *)); +void STD_PROTO(Yap_ErCl,(DynamicClause *)); +void STD_PROTO(Yap_ErLogUpdCl,(LogUpdClause *)); /* exec.c */ Term STD_PROTO(Yap_cp_as_integer,(choiceptr)); diff --git a/H/compile.h b/H/compile.h index 2a40743b3..518efbf5c 100644 --- a/H/compile.h +++ b/H/compile.h @@ -65,6 +65,7 @@ typedef enum compiler_op { deallocate_op, tryme_op, jump_op, + jumpi_op, procceed_op, call_op, execute_op, @@ -86,43 +87,15 @@ typedef enum compiler_op { try_op, retry_op, trust_op, - tryin_op, - retryin_op, - trustin_op, - tryf_op, - retryf_op, - trustf_op, - tryfin_op, - retryfin_op, - trustfin_op, - tryt_op, - retryt_op, - trustt_op, - trytin_op, - retrytin_op, - trusttin_op, - tryh_op, - retryh_op, - trusth_op, - tryhin_op, - retryhin_op, - trusthin_op, - trylf_op, - trylh_op, + try_in_op, jump_v_op, - switch_t_op, - switch_nv_op, - switch_l_op, - switch_h_op, - switch_lnl_op, - switch_nvl_op, - switch_ll_op, + cache_arg_op, + cache_sub_arg_op, + switch_on_type_op, switch_c_op, if_c_op, - go_c_op, switch_f_op, if_f_op, - go_f_op, if_not_op, save_pair_op, save_appl_op, diff --git a/H/index.h b/H/index.h index 048bd8d78..736182fc3 100644 --- a/H/index.h +++ b/H/index.h @@ -15,68 +15,70 @@ * * *************************************************************************/ -/* Minimum number of clauses needed to build an hash table */ -#define MinHashEntries 4 +/* allowed types for clauses */ +typedef enum clause_type_enum { + pair_clause = 0x01, + struct_clause = 0x02, + atom_clause = 0x04, + int_clause = 0x08, + flt_clause = 0x10, + lgint_clause = 0x20, + dbref_clause = 0x40 +} clause_type; /* Four types of Clauses */ -#define NonVarCl(X) ((X) != VarCl) -#define MaxOptions (AtCl+1) - -/* Some Flags */ -#define LoneGroup 0x01 /* just a group */ -#define FirstIndex 0x02 /* we are working over first arg */ -#define HeadIndex 0x04 /* we are working over the head */ -#define LastFoundList 0x08 /* informs first arg is a list */ -#define LastGroup 0x10 /* this is the last group */ -#define IsAtom 0x20 /* the last value is an atom */ -#define IsStruct 0x40 /* the last value is a compound term */ +#define MaxOptions 4 +/* Minimum number of clauses needed to build an hash table */ +/* must be a power of two */ +#define MIN_HASH_ENTRIES 4 +#define HASH_SHIFT 6 /* Intermediate Data structures, used to build the indexing code */ /* Used to store all important information about a clause */ typedef struct StructClauseDef { - int Kind; /* type of first argument */ - Term Name; /* if nonvar or nonlist, first argument */ - yamop *Code; /* start of code for clause */ - struct StructClauseDef *Next; /* next clause in chain */ - } ClauseDef; + Term Tag; /* if nonvar or nonlist, first argument */ + yamop *Code; /* start of code for clause */ + yamop *CurrentCode; /* start of code for clause */ + yamop *WorkPC; /* start of code for clause */ +} ClauseDef; /* Relevant information for groups */ typedef struct { - int Type[MaxOptions]; /* quantity of elements of each kind */ - int NCl; /* total amount of clauses */ - int SInfo; /* special info about group */ - int NofClausesAfter; /* number of clauses after the group */ - ClauseDef *Start; /* first clause of group */ - yamop *First,*Last; /* first and last code of clauses in group */ - } GroupDef; - -/* SInfo may be one of: */ -#define OnlyNils 0x1 -#define UsesBips 0x2 + ClauseDef *FirstClause; + ClauseDef *LastClause; + UInt VarClauses; + UInt AtomClauses; + UInt PairClauses; + UInt StructClauses; + UInt TestClauses; +} GroupDef; -/* Different elements of the same kind in a group */ -typedef struct { - Term Class; /* description of element */ - CELL Code; /* code that deals with it */ - ClauseDef *First, *Last; /* first and last clause with that term */ - } EntryDef; -#define IsVarClause(X) ( ClauseCodeToClause(X)->ClFlags & FIsVar ) +/* switch_on_cons */ +typedef struct { + Term Tag; + UInt Label; +} AtomSwiEntry; -#define TermOfCl(X) ( ClauseCodeToClause(X)->u.ClValue ) -#define HeadOfList(X) ( ClauseCodeToClause(X)->u.ClValue ) +/* switch_on_func */ +typedef struct { + Functor Tag; + UInt Label; +} FuncSwiEntry; -#define FinalGr(I) ((I) == NGroups - 1 && (I) != 0) - -/* - * Number of clauses before you disable extended single optimisation. - */ -#define CLAUSES_FOR_EXTENDED_SINGLE 16 +/* switch_on_type */ +typedef struct { + UInt PairEntry; + UInt ConstEntry; + UInt FuncEntry; + UInt VarEntry; +} TypeSwitch; +#define MAX_REG_COPIES 32 diff --git a/H/rheap.h b/H/rheap.h index d94342ae2..1921a7ddc 100644 --- a/H/rheap.h +++ b/H/rheap.h @@ -53,7 +53,7 @@ restore_codes(void) INIT_YAMOP_LTT(&(heap_regs->tableanswerresolutioncode), 0); #endif /* YAPOR */ #endif /* TABLING */ - heap_regs->failcode = Yap_opcode(_op_fail); + heap_regs->failcode->opc = Yap_opcode(_op_fail); heap_regs->failcode_1 = Yap_opcode(_op_fail); heap_regs->failcode_2 = Yap_opcode(_op_fail); heap_regs->failcode_3 = Yap_opcode(_op_fail); @@ -62,19 +62,16 @@ restore_codes(void) heap_regs->failcode_6 = Yap_opcode(_op_fail); heap_regs->env_for_trustfail_code.op = Yap_opcode(_call); - heap_regs->trustfailcode = Yap_opcode(_trust_fail); + heap_regs->trustfailcode->opc = Yap_opcode(_trust_fail); heap_regs->env_for_yes_code.op = Yap_opcode(_call); - heap_regs->yescode.opc = Yap_opcode(_Ystop); + heap_regs->yescode->opc = Yap_opcode(_Ystop); heap_regs->undef_op = Yap_opcode(_undef_p); heap_regs->index_op = Yap_opcode(_index_pred); heap_regs->fail_op = Yap_opcode(_op_fail); - heap_regs->nocode.opc = Yap_opcode(_Nstop); + heap_regs->nocode->opc = Yap_opcode(_Nstop); #ifdef YAPOR INIT_YAMOP_LTT(&(heap_regs->nocode), 1); -#endif /* YAPOR */ - -#ifdef YAPOR INIT_YAMOP_LTT(&(heap_regs->rtrycode), 1); #endif /* YAPOR */ ((yamop *)(&heap_regs->rtrycode))->opc = Yap_opcode(_retry_and_mark); @@ -83,17 +80,17 @@ restore_codes(void) PtoOpAdjust(((yamop *)(&heap_regs->rtrycode))->u.ld.d); { int arity; - arity = heap_regs->clausecode.arity; - if (heap_regs->clausecode.clause != NIL) - heap_regs->clausecode.clause = - PtoOpAdjust(heap_regs->clausecode.clause); + arity = heap_regs->clausecode->arity; + if (heap_regs->clausecode->clause != NIL) + heap_regs->clausecode->clause = + PtoOpAdjust(heap_regs->clausecode->clause); if (arity) { - heap_regs->clausecode.func = - FuncAdjust(heap_regs->clausecode.func); + heap_regs->clausecode->func = + FuncAdjust(heap_regs->clausecode->func); } else { /* an atom */ - heap_regs->clausecode.func = - (Functor)AtomAdjust((Atom)(heap_regs->clausecode.func)); + heap_regs->clausecode->func = + (Functor)AtomAdjust((Atom)(heap_regs->clausecode->func)); } } /* restore consult stack. It consists of heap pointers, so it @@ -131,7 +128,7 @@ restore_codes(void) AddrAdjust((ADDR)heap_regs->char_conversion_table2); } if (heap_regs->dead_clauses != NULL) { - heap_regs->dead_clauses = (Clause *) + heap_regs->dead_clauses = (DeadClause *) AddrAdjust((ADDR)(heap_regs->dead_clauses)); } heap_regs->retry_recorded_code = @@ -562,38 +559,32 @@ RestoreBB(BlackBoardEntry *pp) /* Restores a prolog clause, in its compiled form */ static void -RestoreClause(Clause *Cl, int mode) +RestoreClause(yamop *pc, PredEntry *pp, int mode) /* * Cl points to the start of the code, IsolFlag tells if we have a single * clause for this predicate or not */ - { - yamop *pc; - OPREG cl_type = FirstArgOfClType(Cl->ClFlags); - if (mode == ASSEMBLING_CLAUSE) { - if (cl_type == ApplCl || - (cl_type == ListCl && HeadOfClType(cl_type) == ApplCl)) { -#ifdef DEBUG_RESTORE2 - YP_fprintf(errout, "at %p, appl: %lx -> %lx", Cl, Cl->u.ClValue, - (CELL)FuncAdjust((Functor)(Cl->u.ClValue))); -#endif - Cl->u.ClValue = (CELL)FuncAdjust((Functor)(Cl->u.ClValue)); - } else if ((cl_type == AtCl || - (cl_type == ListCl && HeadOfClType(cl_type) == AtCl)) && - IsAtomTerm(Cl->u.ClValue)) { -#ifdef DEBUG_RESTORE2 - if (IsAtomTerm(Cl->u.ClValue)) - YP_fprintf(errout, "at %p, atom: %lx -> %lx", Cl, Cl->u.ClValue, - AtomTermAdjust(Cl->u.ClValue)); -#endif - Cl->u.ClValue = AtomTermAdjust(Cl->u.ClValue); + if (pp->PredFlags & DynamicPredFlag) { + DynamicClause *cl = ClauseCodeToDynamicClause(pc); + if (cl->ClPrevious != NULL) { + cl->ClPrevious = PtoOpAdjust(cl->ClPrevious); + } + cl->Owner = AtomAdjust(cl->Owner); + } else if (pp->PredFlags & LogUpdatePredFlag) { + LogUpdClause *cl = ClauseCodeToLogUpdClause(pc); + + if (cl->ClFlags & LogUpdRuleMask) { + cl->u2.ClExt = PtoOpAdjust(cl->u2.ClExt); + } + cl->Owner = AtomAdjust(cl->Owner); + } else { + StaticClause *cl = ClauseCodeToStaticClause(pc); + + cl->Owner = AtomAdjust(cl->Owner); } } - /* TO DO: log update semantics */ - /* Get the stored operator */ - pc = Cl->ClCode; do { op_numbers op = Yap_op_from_opcode(pc->opc); pc->opc = Yap_opcode(op); @@ -638,12 +629,6 @@ RestoreClause(Clause *Cl, int mode) case _try_clause: case _retry: case _trust: - case _retry_first: - case _trust_first: - case _retry_tail: - case _trust_tail: - case _retry_head: - case _trust_head: #ifdef YAPOR case _getwork: case _getwork_seq: @@ -673,8 +658,8 @@ RestoreClause(Clause *Cl, int mode) case _jump: case _move_back: case _skip: - case _try_in: case _jump_if_var: + case _try_in: pc->u.l.l = PtoOpAdjust(pc->u.l.l); pc = NEXTOP(pc,l); break; @@ -1035,35 +1020,41 @@ RestoreClause(Clause *Cl, int mode) pc->u.lds.p = PtoPredAdjust(pc->u.lds.p); pc = NEXTOP(pc,lds); break; - /* instructions type ldl */ - case _trust_in: - case _trust_first_in: - case _trust_tail_in: - case _trust_head_in: - pc->u.ldl.p = PtoPredAdjust(pc->u.ldl.p); - pc->u.ldl.d = PtoOpAdjust(pc->u.ldl.d); - pc->u.ldl.bl = PtoOpAdjust(pc->u.ldl.bl); - pc = NEXTOP(pc,ldl); - break; /* instructions type llll */ case _switch_on_type: - case _switch_list_nl: - case _switch_on_head: pc->u.llll.l1 = PtoOpAdjust(pc->u.llll.l1); pc->u.llll.l2 = PtoOpAdjust(pc->u.llll.l2); pc->u.llll.l3 = PtoOpAdjust(pc->u.llll.l3); pc->u.llll.l4 = PtoOpAdjust(pc->u.llll.l4); pc = NEXTOP(pc,llll); break; - /* instructions type lll */ - case _switch_on_nonv: - case _switch_nv_list: - pc->u.lll.l1 = PtoOpAdjust(pc->u.lll.l1); - pc->u.lll.l2 = PtoOpAdjust(pc->u.lll.l2); - pc->u.lll.l3 = PtoOpAdjust(pc->u.lll.l3); - pc = NEXTOP(pc,lll); + /* instructions type xllll */ + case _switch_list_nl: + pc->u.ollll.pop = Yap_opcode(Yap_op_from_opcode(pc->u.ollll.pop)); + pc->u.ollll.l1 = PtoOpAdjust(pc->u.llll.l1); + pc->u.ollll.l2 = PtoOpAdjust(pc->u.llll.l2); + pc->u.ollll.l3 = PtoOpAdjust(pc->u.llll.l3); + pc->u.ollll.l4 = PtoOpAdjust(pc->u.llll.l4); + pc = NEXTOP(pc,ollll); break; - /* instructions type cll */ + /* instructions type xllll */ + case _switch_on_arg_type: + pc->u.xllll.x = XAdjust(pc->u.xllll.x); + pc->u.xllll.l1 = PtoOpAdjust(pc->u.xllll.l1); + pc->u.xllll.l2 = PtoOpAdjust(pc->u.xllll.l2); + pc->u.xllll.l3 = PtoOpAdjust(pc->u.xllll.l3); + pc->u.xllll.l4 = PtoOpAdjust(pc->u.xllll.l4); + pc = NEXTOP(pc,xllll); + break; + /* instructions type sllll */ + case _switch_on_sub_arg_type: + pc->u.sllll.l1 = PtoOpAdjust(pc->u.sllll.l1); + pc->u.sllll.l2 = PtoOpAdjust(pc->u.sllll.l2); + pc->u.sllll.l3 = PtoOpAdjust(pc->u.sllll.l3); + pc->u.sllll.l4 = PtoOpAdjust(pc->u.sllll.l4); + pc = NEXTOP(pc,sllll); + break; + /* instructions type lll */ case _if_not_then: { Term t = pc->u.cll.c; @@ -1074,15 +1065,6 @@ RestoreClause(Clause *Cl, int mode) pc->u.cll.l2 = PtoOpAdjust(pc->u.cll.l2); pc = NEXTOP(pc,cll); break; - /* instructions type ollll */ - case _switch_list_nl_prefetch: - pc->u.ollll.pop = Yap_opcode(Yap_op_from_opcode(pc->u.ollll.pop)); - pc->u.ollll.l1 = PtoOpAdjust(pc->u.ollll.l1); - pc->u.ollll.l2 = PtoOpAdjust(pc->u.ollll.l2); - pc->u.ollll.l3 = PtoOpAdjust(pc->u.ollll.l3); - pc->u.ollll.l4 = PtoOpAdjust(pc->u.ollll.l4); - pc = NEXTOP(pc,ollll); - break; /* switch_on_func */ case _switch_on_func: { @@ -1197,15 +1179,6 @@ RestoreClause(Clause *Cl, int mode) pc = (yamop *)oldcode; } break; - /* instructions type slll */ - case _switch_last: - case _switch_l_list: - pc->u.slll.p = PtoPredAdjust(pc->u.slll.p); - pc->u.slll.l1 = PtoOpAdjust(pc->u.slll.l1); - pc->u.slll.l2 = PtoOpAdjust(pc->u.slll.l2); - pc->u.slll.l3 = PtoOpAdjust(pc->u.slll.l3); - pc = NEXTOP(pc,slll); - break; /* instructions type xxx */ case _p_plus_vv: case _p_minus_vv: @@ -1344,11 +1317,11 @@ RestoreClause(Clause *Cl, int mode) * and ending with Last, First may be equal to Last */ static void -CleanClauses(yamop *First, yamop *Last) +CleanClauses(yamop *First, yamop *Last, PredEntry *pp) { yamop *cl = First; do { - RestoreClause(ClauseCodeToClause(cl), ASSEMBLING_CLAUSE); + RestoreClause(cl, pp, ASSEMBLING_CLAUSE); if (cl == Last) return; cl = NextClause(cl); } while (TRUE); @@ -1472,7 +1445,7 @@ CleanCode(PredEntry *pp) /* assembly */ if (pp->CodeOfPred) { pp->CodeOfPred = PtoOpAdjust(pp->CodeOfPred); - CleanClauses(pp->CodeOfPred, pp->CodeOfPred); + CleanClauses(pp->CodeOfPred, pp->CodeOfPred, pp); } } else { yamop *FirstC, *LastC; @@ -1495,12 +1468,12 @@ CleanCode(PredEntry *pp) #ifdef DEBUG_RESTORE2 YP_fprintf(errout, "at %lx Correcting clauses from %lx to %lx\n", *(OPCODE *) FirstC, FirstC, LastC); #endif - CleanClauses(FirstC, LastC); + CleanClauses(FirstC, LastC, pp); if (flag & (DynamicPredFlag|IndexedPredFlag)) { #ifdef DEBUG_RESTORE2 YP_fprintf(errout, "Correcting dynamic/indexed code\n"); #endif - RestoreClause(ClauseCodeToClause(pp->cs.p_code.TrueCodeOfPred), ASSEMBLING_INDEX); + RestoreClause(pp->cs.p_code.TrueCodeOfPred,pp, ASSEMBLING_INDEX); } } /* we are pointing at ourselves */ diff --git a/m4/Yatom.h.m4 b/m4/Yatom.h.m4 index 6e3af248c..0c1e27a5a 100644 --- a/m4/Yatom.h.m4 +++ b/m4/Yatom.h.m4 @@ -162,6 +162,7 @@ Inline(IsValProperty, PropFlags, int, flags, (flags == ValProperty) ) CodeOfPred holds the address of the correspondent C-function. */ typedef enum { + InUsePredFlag = 0x4000000L, /* count calls to pred */ CountPredFlag = 0x2000000L, /* count calls to pred */ HiddenPredFlag = 0x1000000L, /* invisible predicate */ CArgsPredFlag = 0x800000L, /* SWI-like C-interface pred. */ @@ -211,9 +212,10 @@ typedef struct pred_entry { unsigned int ArityOfPE; /* arity of property */ union { struct { - struct yami *TrueCodeOfPred; /* code address */ - struct yami *FirstClause; - struct yami *LastClause; + struct yami *TrueCodeOfPred; /* code address */ + struct yami *FirstClause; + struct yami *LastClause; + UInt NOfClauses; } p_code; CPredicate f_code; CmpPredicate d_code; @@ -229,7 +231,6 @@ typedef struct pred_entry { #endif /* TABLING */ SMALLUNSGN ModuleOfPred; /* module for this definition */ profile_data StatisticsForPred; /* enable profiling for predicate */ - SMALLUNSGN StateOfPred; /* actual state of predicate */ } PredEntry; #define PEProp ((PropFlags)(0x0000)) @@ -255,8 +256,7 @@ typedef enum { DBClMask = 0x0800, /* informs this is a data base structure */ LogUpdRuleMask= 0x0400, /* informs the code is for a log upd rule with env */ LogUpdMask = 0x0200, /* informs this is a logic update index. */ - StaticMask = 0x0100, /* dealing with static predicates */ - SpiedMask = 0x0080 /* this predicate is being spied */ + StaticMask = 0x0100 /* dealing with static predicates */ /* other flags belong to DB */ } dbentry_flags; @@ -289,7 +289,7 @@ typedef struct DB_STRUCT { Term Contents[MIN_ARRAY]; /* stored term */ } DBStruct; -#define DBStructFlagsToDBStruct(X) ((DBRef)((X) - (CELL) &(((DBRef) NIL)->Flags))) +#define DBStructFlagsToDBStruct(X) ((DBRef)((char *)(X) - (CELL) &(((DBRef) NIL)->Flags))) #if defined(YAPOR) || defined(THREADS) #define INIT_DBREF_COUNT(X) (X)->ref_count = 0 diff --git a/pl/arith.yap b/pl/arith.yap index 9ad782773..1c268003d 100644 --- a/pl/arith.yap +++ b/pl/arith.yap @@ -352,7 +352,6 @@ do_not_compile_expressions :- '$set_value'('$c_arith',[]). '$binary_op_as_integer'(gcd,16). '$binary_op_as_integer'(min,17). '$binary_op_as_integer'(max,18). -'$binary_op_as_integer'(atan2,19). %'$binary_op_as_integer'(gcdmult,28). /* Arithmetics */ diff --git a/pl/boot.yap b/pl/boot.yap index 4014a30c9..2eaf41483 100644 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -265,11 +265,11 @@ repeat :- '$repeat'. '$execute_command'(C,_,top) :- var(C), !, '$do_error'(instantiation_error,meta_call(C)). -'$execute_command'(end_of_file,_,_). '$execute_command'(C,_,top) :- number(C), !, '$do_error'(type_error(callable,C),meta_call(C)). '$execute_command'(R,_,top) :- db_reference(R), !, '$do_error'(type_error(callable,R),meta_call(R)). +'$execute_command'(end_of_file,_,_) :- !. '$execute_command'((:-G),_,Option) :- !, '$current_module'(M), '$process_directive'(G, Option, M), @@ -880,7 +880,7 @@ break :- '$get_value'('$break',BL), NBL is BL+1, '$csult'(V, _) :- var(V), !, '$do_error'(instantiation_error,consult(V)). -'$csult'([], _) :- !. +'$csult'([], _). '$csult'([-F|L], M) :- !, '$reconsult'(M:F), '$csult'(L, M). '$csult'([F|L], M) :- '$consult'(M:F), '$csult'(L, M).