171static char SccsId[] =
"%W% %G%";
177#include "YapCompile.h"
194 branch parent_branches[256];
210#ifdef TABLING_INNER_CUTS
230static int active_branch(
int,
int);
231static void c_var(Term, Int,
unsigned int,
unsigned int,
compiler_struct *);
232static void reset_vars(
Ventry *);
233static Term optimize_ce(Term,
unsigned int,
unsigned int,
compiler_struct *);
234static void c_arg(Int, Term,
unsigned int,
unsigned int,
compiler_struct *);
238static void c_bifun(basic_preds, Term, Term, Term, Term, Term,
243static bool usesvar(compiler_vm_op);
248static void clear_bvarray(
int, CELL *);
257static void c_optimize(
PInstr *);
259static void compile_sf_term(Term,
int);
263 cglobs->branch_pointer->id = id;
264 cglobs->branch_pointer->cm = cmvar;
265 cglobs->branch_pointer++;
269 cglobs->branch_pointer--;
270 return (cglobs->branch_pointer->id);
274#define is_tabled(pe) (pe->PredFlags & TabledPredFlag)
277static inline int active_branch(
int i,
int onbranch) {
280 return (i == onbranch);
289#define FAIL(M, T, E) \
291 LOCAL_Error_TYPE = T; \
296#define IsNewVar(v) ((CELL *)(v) >= H0 && (CELL *)(v) < LCL0)
299 (Addr(v) < cglobs->cint.freep0 || Addr(v) > cglobs->cint.freep)
304inline static void pop_code(
unsigned int level,
compiler_struct *cglobs) {
307 if (cglobs->cint.cpc->op == pop_op)
308 ++(cglobs->cint.cpc->rnd1);
310 Yap_emit(pop_op, One, Zero, &cglobs->cint);
315 branch *bp = cglobs->branch_pointer;
316 while (bp > cglobs->parent_branches) {
318 if (bp->cm != TermNil) {
319 c_var(bp->cm, patch_b_flag, 1, 0, cglobs);
324static int check_var(Term t,
unsigned int level, Int argno,
327 int flags,
new = FALSE;
331 v = (
Ventry *)Yap_AllocCMem(
sizeof(*v), &cglobs->cint);
335 v->SelfOfVE = (CELL)v;
338 *CellPtr(t) = (CELL)v;
339 v->KindOfVE = v->NoOfVE = Unassigned;
353 if (((level > 0 || cglobs->onhead) && cglobs->curbranch == 0) ||
354 argno == save_pair_flag || argno == save_appl_flag)
356 if ((level > 0 && cglobs->curbranch == 0) || argno == save_pair_flag ||
357 argno == save_appl_flag)
359 v->FlagsOfVE = flags;
360 v->BranchOfVE = cglobs->onbranch;
361 v->NextOfVE = cglobs->vtable;
363 v->AgeOfVE = v->FirstOfVE = cglobs->goalno;
367 v->FlagsOfVE |= NonVoid;
368 if (v->BranchOfVE > 0) {
369 if (!active_branch(v->BranchOfVE, cglobs->onbranch)) {
370 v->AgeOfVE = v->FirstOfVE = 1;
372 v->FlagsOfVE |= BranchVar;
374 switch (v->FirstOpForV->op) {
376 v->FirstOpForV->op = get_val_op;
379 v->FirstOpForV->op = unify_val_op;
381 case unify_last_var_op:
382 v->FirstOpForV->op = unify_last_val_op;
385 v->FirstOpForV->op = put_val_op;
388 v->FirstOpForV->op = write_val_op;
397 v->FlagsOfVE |= OnHeadFlag;
405 v->FirstOpForV = cglobs->cint.cpc;
407 v->LastOpForV = cglobs->cint.cpc;
410 v->FlagsOfVE |= OnLastGoal;
411 if (v->AgeOfVE < cglobs->goalno)
412 v->AgeOfVE = cglobs->goalno;
415static void c_var(Term t, Int argno,
unsigned int arity,
unsigned int level,
417 int new = check_var(Deref(t), level, argno, cglobs);
422 Yap_emit(save_b_op, t, Zero, &cglobs->cint);
425 Yap_emit(commit_b_op, t, Zero, &cglobs->cint);
426 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
427 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
429 case soft_cut_b_flag:
430 Yap_emit(soft_cut_b_op, t, Zero, &cglobs->cint);
431 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
432 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
435 Yap_emit(patch_b_op, t, 0, &cglobs->cint);
438 Yap_emit(save_pair_op, t, 0, &cglobs->cint);
441 Yap_emit(save_appl_op, t, 0, &cglobs->cint);
446 Yap_emit(f_var_op, t, (CELL)arity, &cglobs->cint);
448 Yap_emit(f_val_op, t, (CELL)arity, &cglobs->cint);
455 Yap_emit((cglobs->onhead ? unify_s_var_op : write_s_var_op), v, -argno,
458 Yap_emit((cglobs->onhead ? unify_s_val_op : write_s_val_op), v, -argno,
462 if (cglobs->onhead) {
463 cglobs->space_used++;
465 Yap_emit((
new ? (++cglobs->nvars, get_var_op) : get_val_op), t, argno,
469 (
new ? (++cglobs->nvars,
470 (argno == (Int)arity ? unify_last_var_op : unify_var_op))
471 : (argno == (Int)arity ? unify_last_val_op : unify_val_op)),
472 t, Zero, &cglobs->cint);
475 Yap_emit((
new ? (++cglobs->nvars, put_var_op) : put_val_op), t, argno,
478 Yap_emit((
new ? (++cglobs->nvars, write_var_op) : write_val_op), t,
479 Zero, &cglobs->cint);
482 tag_var(t,
new, cglobs);
486static void c_2vars(
int op, Term t1, Int argno1, Term t2, Int argno2,
487 CELL extra,
unsigned int arity,
unsigned int level,
489 int new1 = check_var((t1 = Deref(t1)), level, argno1, cglobs);
490 int new2 = check_var((t2 = Deref(t2)), level, argno2, cglobs);
494 Yap_emit_5ops(bccall_op, t1, argno1, t2, argno2, extra, &cglobs->cint);
499 tag_var(t1, new1, cglobs);
500 tag_var(t2, new2, cglobs);
503static void reset_vars(
Ventry *vtable) {
508 t = (CELL *)v->AdrsOfVE;
514static Term optimize_ce(Term t,
unsigned int arity,
unsigned int level,
525 if (IsApplTerm(t) &&( IsExtensionFunctor((f =FunctorOfTerm(t))) ||
528 || f == FunctorSoftCut
529 || f == FunctorComma))
533 HR = (CELL *)cglobs->cint.freep;
534 cmp = Yap_compare_terms(t, (p->TermOfCE));
547 if (cglobs->onbranch || level > 1) {
550 ++(cglobs->n_common_exps);
554 p->VarOfCE = MkVarTerm();
555 if (HR >= (CELL *)cglobs->cint.freep0) {
558 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
560 p->NextCE = cglobs->common_exps;
561 cglobs->common_exps = p;
563 c_var(p->VarOfCE, save_appl_flag, arity, level, cglobs);
564 else if (IsPairTerm(t))
565 c_var(p->VarOfCE, save_pair_flag, arity, level, cglobs);
570static void compile_sf_term(Term t,
int argno,
int level) {
572 CELL *p = ArgsOfSFTerm(t) - 1;
573 SFEntry *pe = RepSFProp(Yap_GetAProp(NameOfFunctor(f), SFProperty));
574 Term nullvalue = pe->NilValue;
577 Yap_emit((cglobs->onhead ? get_s_f_op : put_s_f_op), f, argno,
580 Yap_emit((cglobs->onhead ? unify_s_f_op : write_s_f_op), f, Zero,
583 while ((argno = *++p)) {
585 if (t != nullvalue) {
587 Yap_emit((cglobs->onhead ? unify_s_a_op : write_s_a_op), t, (CELL)argno,
589 else if (!IsVarTerm(t)) {
590 Yap_ThrowError(SYSTEM_ERROR_COMPILER, t,
"illegal argument of soft functor");
592 siglongjmp(cglobs->cint.CompilerBotch, COMPILER_ERR_BOTCH);
594 c_var(t, -argno, arity, level, cglobs);
599 Yap_emit((cglobs->onhead ? get_s_end_op : put_s_end_op), Zero, Zero,
602 Yap_emit((cglobs->onhead ? unify_s_end_op : write_s_end_op), Zero, Zero,
607inline static void c_args(Term app,
unsigned int level,
610 Functor f = FunctorOfTerm(app);
611 unsigned int Arity = ArityOfFunctor(f);
615 if (Arity >= MaxTemps) {
616 Yap_ThrowError( SYSTEM_ERROR_COMPILER, app,
"exceed maximum arity (%ud) of compiled goal", MaxTemps);
618 siglongjmp(cglobs->cint.CompilerBotch, COMPILER_ERR_BOTCH);
620 if (Arity > cglobs->max_args)
621 cglobs->max_args = Arity;
623 for (i = 1; i <= Arity; ++i)
624 c_arg(i, ArgOfTerm(i, app), Arity, level, cglobs);
627static int try_store_as_dbterm(Term t, Int argno,
unsigned int arity,
int level,
634 while ((g = Yap_SizeGroundTerm(t, TRUE)) < 0) {
636 Yap_ThrowError( SYSTEM_ERROR_COMPILER, g,
"exceeds maximum ground term depth");
638 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_AUX_BOTCH);
643 HR = CellPtr(cglobs->cint.freep);
644 if ((dbt = Yap_StoreTermInDB(t, -1)) == NULL) {
646 switch (LOCAL_Error_TYPE) {
647 case RESOURCE_ERROR_STACK:
648 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil,
"while optimising ground term");
649 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_STACK_BOTCH);
651 case RESOURCE_ERROR_TRAIL:
652 Yap_ThrowError(RESOURCE_ERROR_TRAIL, TermNil,
"while optimising ground term");
653 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TRAIL_BOTCH);
655 case RESOURCE_ERROR_HEAP:
656 Yap_ThrowError(RESOURCE_ERROR_HEAP, TermNil,
"while optimising ground term");
657 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_HEAP_BOTCH);
659 case RESOURCE_ERROR_AUXILIARY_STACK:
660 Yap_ThrowError(RESOURCE_ERROR_AUXILIARY_STACK, TermNil,
"while optimising ground term");
661 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_AUX_BOTCH);
664 Yap_ThrowError(LOCAL_Error_TYPE, TermNil,
"while optimising ground term");
670 Yap_emit((cglobs->onhead ? get_dbterm_op : put_dbterm_op), dbt->Entry,
671 argno, &cglobs->cint);
673 Yap_emit((cglobs->onhead ? (argno == (Int)arity ? unify_last_dbterm_op
676 dbt->Entry, Zero, &cglobs->cint);
680static void c_arg(Int argno, Term t,
unsigned int arity,
unsigned int level,
684 c_var(t, argno, arity, level, cglobs);
685 else if (IsAtomTerm(t)) {
687 Yap_emit((cglobs->onhead ? get_atom_op : put_atom_op), (CELL)t, argno,
690 Yap_emit((cglobs->onhead
691 ? (argno == (Int)arity ? unify_last_atom_op : unify_atom_op)
693 (CELL)t, Zero, &cglobs->cint);
694 }
else if (IsIntegerTerm(t) || IsFloatTerm(t) || IsBigIntTerm(t) ||
697 if (IsFloatTerm(t)) {
699 Yap_emit((cglobs->onhead ? get_float_op : put_float_op), t, argno,
702 Yap_emit((cglobs->onhead ? (argno == (Int)arity ? unify_last_float_op
705 t, Zero, &cglobs->cint);
706 }
else if (IsLongIntTerm(t)) {
708 Yap_emit((cglobs->onhead ? get_longint_op : put_longint_op), t, argno,
711 Yap_emit((cglobs->onhead
712 ? (argno == (Int)arity ? unify_last_longint_op
715 t, Zero, &cglobs->cint);
716 }
else if (IsStringTerm(t)) {
719 CELL l1 = ++cglobs->labelno;
720 CELL *src = RepAppl(t);
721 PInstr *ocpc = cglobs->cint.cpc, *OCodeStart = cglobs->cint.CodeStart;
722 Int sz = (3 + src[1]) *
sizeof(CELL);
726 cglobs->cint.cpc = cglobs->cint.icpc;
730 Yap_emit(label_op, l1, Zero, &cglobs->cint);
731 dest = Yap_emit_extra_size(blob_op, sz / CellSize, sz, &cglobs->cint);
734 memcpy(dest, src, sz);
737 cglobs->cint.icpc = cglobs->cint.cpc;
738 if (cglobs->cint.BlobsStart == NULL)
739 cglobs->cint.BlobsStart = cglobs->cint.CodeStart;
740 cglobs->cint.cpc = ocpc;
741 cglobs->cint.CodeStart = OCodeStart;
745 Yap_emit((cglobs->onhead ? get_string_op : put_string_op), l1, argno,
748 Yap_emit((cglobs->onhead ? (argno == (Int)arity ? unify_last_string_op
751 l1, Zero, &cglobs->cint);
756 CELL l1 = ++cglobs->labelno;
757 CELL *src = RepAppl(t);
758 PInstr *ocpc = cglobs->cint.cpc, *OCodeStart = cglobs->cint.CodeStart;
761 ((((
MP_INT *)(RepAppl(t) + 2))->_mp_alloc) *
sizeof(mp_limb_t));
765 cglobs->cint.cpc = cglobs->cint.icpc;
769 Yap_emit(label_op, l1, Zero, &cglobs->cint);
770 dest = Yap_emit_extra_size(blob_op, sz / CellSize, sz, &cglobs->cint);
773 memcpy(dest, src, sz);
776 cglobs->cint.icpc = cglobs->cint.cpc;
777 if (cglobs->cint.BlobsStart == NULL)
778 cglobs->cint.BlobsStart = cglobs->cint.CodeStart;
779 cglobs->cint.cpc = ocpc;
780 cglobs->cint.CodeStart = OCodeStart;
784 Yap_emit((cglobs->onhead ? get_bigint_op : put_bigint_op), l1, argno,
787 Yap_emit((cglobs->onhead ? (argno == (Int)arity ? unify_last_bigint_op
790 l1, Zero, &cglobs->cint);
796 Yap_emit((cglobs->onhead ? get_num_op : put_num_op), (CELL)t, argno,
799 Yap_emit((cglobs->onhead
800 ? (argno == (Int)arity ? unify_last_num_op : unify_num_op)
802 (CELL)t, Zero, &cglobs->cint);
803 }
else if (IsPairTerm(t)) {
804 cglobs->space_used += 2;
805 if (optimizer_on && level < 6) {
806#if !defined(THREADS) && !defined(YAPOR)
809 !(cglobs->cint.CurrentPred->PredFlags &
810 (DynamicPredFlag | LogUpdatePredFlag))) {
811 if (try_store_as_dbterm(t, argno, arity, level, cglobs))
815 t = optimize_ce(t, arity, level, cglobs);
817 c_var(t, argno, arity, level, cglobs);
822 Yap_emit((cglobs->onhead ? get_list_op : put_list_op), Zero, argno,
824 else if (argno == (Int)arity)
825 Yap_emit((cglobs->onhead ? unify_last_list_op : write_last_list_op), Zero,
826 Zero, &cglobs->cint);
828 Yap_emit((cglobs->onhead ? unify_list_op : write_list_op), Zero, Zero,
831 c_arg(1, HeadOfTerm(t), 2, level, cglobs);
832 if (argno == (Int)arity) {
837 c_arg(2, TailOfTerm(t), 2, level, cglobs);
839 if (argno != (Int)arity) {
840 pop_code(level, cglobs);
842 }
else if (IsRefTerm(t)) {
843 PELOCK(40, cglobs->cint.CurrentPred);
844 if (!(cglobs->cint.CurrentPred->PredFlags &
845 (DynamicPredFlag | LogUpdatePredFlag))) {
847 UNLOCK(cglobs->cint.CurrentPred->PELock);
848 FAIL(
"can not compile data base reference", TYPE_ERROR_CALLABLE, t);
850 UNLOCK(cglobs->cint.CurrentPred->PELock);
851 cglobs->hasdbrefs = TRUE;
853 Yap_emit((cglobs->onhead ? get_atom_op : put_atom_op), (CELL)t, argno,
856 Yap_emit((cglobs->onhead ? (argno == (Int)arity ? unify_last_atom_op
859 (CELL)t, Zero, &cglobs->cint);
865 compile_sf_term(t, argno);
871 if (!(cglobs->cint.CurrentPred->PredFlags &
872 (DynamicPredFlag | LogUpdatePredFlag))) {
873 if (try_store_as_dbterm(t, argno, arity, level, cglobs))
876 t = optimize_ce(t, arity, level, cglobs);
878 c_var(t, argno, arity, level, cglobs);
882 cglobs->space_used += 1 + arity;
884 Yap_emit((cglobs->onhead ? get_struct_op : put_struct_op),
885 (CELL)FunctorOfTerm(t), argno, &cglobs->cint);
886 else if (argno == (Int)arity)
887 Yap_emit((cglobs->onhead ? unify_last_struct_op : write_last_struct_op),
888 (CELL)FunctorOfTerm(t), Zero, &cglobs->cint);
890 Yap_emit((cglobs->onhead ? unify_struct_op : write_struct_op),
891 (CELL)FunctorOfTerm(t), Zero, &cglobs->cint);
893 c_args(t, level, cglobs);
895 if (argno != (Int)arity) {
896 pop_code(level, cglobs);
904 Yap_emit(nop_op, Zero, Zero, &cglobs->cint);
907 if (IsNonVarTerm(t1)) {
914 if (IsAtomicTerm(t1)) {
916 if (!IsAtomicTerm(t2) || !Yap_unify(t1, t2)) {
918 Yap_emit(fail_op, Zero, Zero, &cglobs->cint);
922 Yap_emit(nop_op, Zero, Zero, &cglobs->cint);
924 }
else if (IsPairTerm(t1)) {
926 if (!IsPairTerm(t2)) {
928 Yap_emit(fail_op, Zero, Zero, &cglobs->cint);
932 c_eq(HeadOfTerm(t1), HeadOfTerm(t2), cglobs);
933 c_eq(TailOfTerm(t1), TailOfTerm(t2), cglobs);
935 }
else if (IsRefTerm(t1)) {
939 Yap_emit(fail_op, Zero, Zero, &cglobs->cint);
943 Yap_emit(nop_op, Zero, Zero, &cglobs->cint);
950 if (!IsApplTerm(t2) || FunctorOfTerm(t2) != f) {
952 Yap_emit(fail_op, Zero, Zero, &cglobs->cint);
956 max = ArityOfFunctor(f);
957 for (i = 0; i < max; i++) {
958 c_eq(ArgOfTerm(i + 1, t1), ArgOfTerm(i + 1, t2), cglobs);
965 if (IsNewVar(t1) && !IsVarTerm(t2) &&
966 !(cglobs->cint.CurrentPred->PredFlags & TabledPredFlag)) {
969 v = --cglobs->tmpreg;
970 c_arg(v, t2, 0, 0, cglobs);
971 cglobs->onhead = TRUE;
972 c_var(t1, v, 0, 0, cglobs);
973 cglobs->onhead = FALSE;
976 c_var(t1, 0, 0, 0, cglobs);
977 cglobs->onhead = TRUE;
978 c_var(t2, 0, 0, 0, cglobs);
980 Int v = --cglobs->tmpreg;
981 c_var(t1, v, 0, 0, cglobs);
982 cglobs->onhead = TRUE;
983 c_arg(v, t2, 0, 0, cglobs);
985 cglobs->onhead = FALSE;
994 if (Op == _save_by) {
996 Term tn = MkVarTerm();
997 c_var(tn, save_b_flag, 1, 0, cglobs);
1000 c_var(t, save_b_flag, 1, 0, cglobs);
1016if (!IsVarTerm(t) || IsNewVar(t)) {
1017 Term tn = MkVarTerm();
1018 c_eq(t, tn, cglobs);
1022 c_var(t, commit_b_flag, 1, 0, cglobs);
1023 else if (Op == _soft_cut_by)
1024 c_var(t, soft_cut_b_flag, 1, 0, cglobs);
1026 c_var(t, f_flag, (
unsigned int)Op, 0, cglobs);
1059static void c_bifun(basic_preds Op, Term t1, Term t2, Term t3, Term Goal,
1065 if (IsVarTerm(t1)) {
1066 if (IsVarTerm(t2)) {
1068 Int v1 = --cglobs->tmpreg;
1070 Int v2 = --cglobs->tmpreg;
1072 Yap_emit(fetch_args_vv_op, Zero, Zero, &cglobs->cint);
1074 c_var(t1, v1, 0, 0, cglobs);
1075 c_var(t2, v2, 0, 0, cglobs);
1080 if (IsPrimitiveTerm(t2) || IsNumTerm(t2)) {
1081 Yap_emit(fail_op, Zero, Zero, &cglobs->cint);
1084 Term tn = MkVarTerm();
1085 Int v1 = --cglobs->tmpreg;
1086 Int v2 = --cglobs->tmpreg;
1088 c_eq(t2, tn, cglobs);
1089 Yap_emit(fetch_args_vv_op, Zero, Zero, &cglobs->cint);
1091 c_var(t1, v1, 0, 0, cglobs);
1092 c_var(tn, v2, 0, 0, cglobs);
1095 }
else if (IsIntegerTerm(t2)) {
1099 Yap_emit(fetch_args_vi_op, IntegerOfTerm(t2), 0L, &cglobs->cint);
1101 c_var(t1, v1, 0, 0, cglobs);
1106 Yap_bip_name(Op, s);
1107 Yap_do_warning(TYPE_ERROR_NUMBER, t2,
1108 "compiling %s/2 with output bound", s);
1114 if (IsVarTerm(t2)) {
1118 Yap_bip_name(Op, s);
1119 Yap_do_warning(INSTANTIATION_ERROR, t2,
"compiling %s/3", s);
1123 if (Op == _functor) {
1127 if (!IsIntegerTerm(t2)) {
1128 Yap_do_warning(TYPE_ERROR_INTEGER, t2,
"compiling functor/3", NULL);
1132 i2 = IntegerOfTerm(t2);
1135 Yap_do_warning(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2,
1136 "compiling functor/3", NULL);
1139 if (IsNumTerm(t1)) {
1142 c_goal(MkAtomTerm(AtomFalse), mod, cglobs);
1143 }
else if (!IsAtomTerm(t1)) {
1146 Yap_bip_name(Op, s);
1147 Yap_do_warning(TYPE_ERROR_ATOM, t2,
"compiling functor/3", NULL);
1151 c_eq(t1, t3, cglobs);
1156 if (t1 == TermDot && i2 == 2) {
1157 if (HR + 2 >= (CELL *)cglobs->cint.freep0) {
1159 save_machine_regs();
1160 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1163 RESET_VARIABLE(HR + 1);
1165 c_eq(AbsPair(HR - 2), t3, cglobs);
1166 }
else if (i2 < 256 && IsAtomTerm(t1)) {
1167 *HR++ = (CELL)Yap_MkFunctor(AtomOfTerm(t1), i2);
1168 for (i = 0; i < i2; i++) {
1169 if (HR >= (CELL *)cglobs->cint.freep0) {
1171 save_machine_regs();
1172 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1177 c_eq(AbsAppl(hi), t3, cglobs);
1180 Functor f = FunctorOfTerm(Goal);
1181 Prop p0 = PredPropByFunc(f, mod);
1182 if (EndOfPAEntr(p0)) {
1183 save_machine_regs();
1184 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_HEAP_BOTCH);
1186 c_args(Goal, 0, cglobs);
1187 Yap_emit(safe_call_op, (CELL)p0, Zero, &cglobs->cint);
1188 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
1189 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1193 }
else if (Op == _arg) {
1195 if (IsIntegerTerm(t1))
1196 i1 = IntegerOfTerm(t1);
1200 Yap_bip_name(Op, s);
1201 Yap_do_warning(TYPE_ERROR_INTEGER, t1,
"compiling %s/2", s);
1204 if (IsAtomicTerm(t2) ||
1205 (IsApplTerm(t2) && IsExtensionFunctor(FunctorOfTerm(t2)))) {
1208 Yap_bip_name(Op, s);
1209 Yap_do_warning(TYPE_ERROR_COMPOUND, t2,
"compiling %s/2", s);
1212 }
else if (IsApplTerm(t2)) {
1213 Functor f = FunctorOfTerm(t2);
1214 if (i1 < 1 || i1 > ArityOfFunctor(f)) {
1215 c_goal(MkAtomTerm(AtomFalse), mod, cglobs);
1217 c_eq(ArgOfTerm(i1, t2), t3, cglobs);
1220 }
else if (IsPairTerm(t2)) {
1223 c_eq(HeadOfTerm(t2), t3, cglobs);
1226 c_eq(TailOfTerm(t2), t3, cglobs);
1229 c_goal(MkAtomTerm(AtomFalse), mod, cglobs);
1236 Yap_bip_name(Op, s);
1237 Yap_do_warning(TYPE_ERROR_INTEGER, t2,
"compiling %s", s);
1241 if (Op == _functor) {
1242 if (!IsAtomicTerm(t1)) {
1245 Yap_bip_name(Op, s);
1246 Yap_do_warning(TYPE_ERROR_ATOM, t1,
"compiling %s", s);
1249 if (!IsVarTerm(t2)) {
1254 if (!IsIntegerTerm(t2)) {
1257 Yap_bip_name(Op, s);
1258 Yap_do_warning(TYPE_ERROR_INTEGER, t2,
"compiling %s" , s);
1261 arity = IntOfTerm(t2);
1264 Yap_emit(fail_op, Zero, Zero, &cglobs->cint);
1268 if (!IsAtomTerm(t1)) {
1271 Yap_bip_name(Op, s);
1272 Yap_do_warning(TYPE_ERROR_INTEGER, t1,
"compiling %s", s);
1275 if (HR + 1 + arity >= (CELL *)cglobs->cint.freep0) {
1277 save_machine_regs();
1278 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1281 *HR++ = (CELL)Yap_MkFunctor(AtomOfTerm(t1), arity);
1286 c_eq(tnew, t3, cglobs);
1289 c_eq(t1, t3, cglobs);
1295 Yap_emit(fetch_args_cv_op, t1, Zero, &cglobs->cint);
1297 c_var(t2, v1, 0, 0, cglobs);
1301 }
else if (IsIntegerTerm(t1)) {
1304 Yap_emit(fetch_args_iv_op, IntegerOfTerm(t1), 0L, &cglobs->cint);
1306 c_var(t2, v1, 0, 0, cglobs);
1311 Yap_bip_name(Op, s);
1312 Yap_do_warning(UNINSTANTIATION_ERROR, t1,
"compiling %s/2 with output bound", s);
1317 if (!IsVarTerm(t3)) {
1319 Term tmpvar = MkVarTerm();
1320 if (HR == (CELL *)cglobs->cint.freep0) {
1322 save_machine_regs();
1323 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1325 c_var(tmpvar, f_flag, (
unsigned int)Op, 0, cglobs);
1326 c_eq(tmpvar, t3, cglobs);
1330 Yap_bip_name(Op, s);
1331 Yap_do_warning(UNINSTANTIATION_ERROR, t1,
"compiling %s/2 with output bound", s);
1335 }
else if (IsNewVar(t3) && cglobs->curbranch == 0 &&
1336 cglobs->cint.CurrentPred->PredFlags & TabledPredFlag) {
1337 Term nv = MkVarTerm();
1338 c_var(nv, f_flag, (
unsigned int)Op, 0, cglobs);
1339 if (Op == _functor) {
1340 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
1341 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1345 c_eq(t3, nv, cglobs);
1348 cglobs->curbranch ==
1350 c_var(t3, f_flag, (
unsigned int)Op, 0, cglobs);
1351 if (Op == _functor) {
1352 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
1353 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1357 Yap_emit(f_0_op, 0, (
unsigned int)Op, &cglobs->cint);
1359 if (Op == _functor) {
1360 Yap_emit(empty_call_op, Zero, (
unsigned int)Op, &cglobs->cint);
1361 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1363 cglobs->onhead = TRUE;
1364 c_var(t3, 0, 0, 0, cglobs);
1365 cglobs->onhead = FALSE;
1369 c_goal(Yap_MkApplTerm(FunctorCall,1,&Goal), mod, cglobs);
1375 Term t1 = ArgOfTerm(1, Goal);
1376 Term t2 = ArgOfTerm(2, Goal);
1377 Term t3 = ArgOfTerm(3, Goal);
1379 if (IsVarTerm(t1) && IsNewVar(t1)) {
1380 c_bifun(_functor, t2, t3, t1, Goal, mod, cglobs);
1381 }
else if (IsNonVarTerm(t1)) {
1383 if (IsAtomicTerm(t1)) {
1384 c_eq(t1, t2, cglobs);
1385 c_eq(t3, MkIntTerm(0), cglobs);
1386 }
else if (IsApplTerm(t1)) {
1387 Functor f = FunctorOfTerm(t1);
1388 c_eq(t2, MkAtomTerm(NameOfFunctor(f)), cglobs);
1389 c_eq(t3, MkIntegerTerm(ArityOfFunctor(f)), cglobs);
1391 c_eq(t2, TermDot, cglobs);
1392 c_eq(t3, MkIntTerm(2), cglobs);
1394 }
else if (IsVarTerm(t2) && IsNewVar(t2) && IsVarTerm(t3) && IsNewVar(t3)) {
1395 Int v1 = --cglobs->tmpreg;
1396 Yap_emit(fetch_args_vi_op, Zero, Zero, &cglobs->cint);
1397 c_var(t1, v1, 0, 0, cglobs);
1398 c_var(t2, f_flag, (
unsigned int)_functor, 0, cglobs);
1399 c_var(t3, f_flag, (
unsigned int)_functor, 0, cglobs);
1401 Functor f = FunctorOfTerm(Goal);
1402 Prop p0 = PredPropByFunc(f, mod);
1404 if (EndOfPAEntr(p0)) {
1405 save_machine_regs();
1406 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_HEAP_BOTCH);
1409 Yap_emit(enter_profiling_op, (CELL)RepPredProp(p0), Zero, &cglobs->cint);
1411 Yap_emit(count_call_op, (CELL)RepPredProp(p0), Zero, &cglobs->cint);
1412 c_args(Goal, 0, cglobs);
1413 Yap_emit(safe_call_op, (CELL)p0, Zero, &cglobs->cint);
1414 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
1415 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1419static int IsTrueGoal(Term t) {
1422 if (IsApplTerm(t)) {
1424 if (f == FunctorModule) {
1425 return (IsTrueGoal(ArgOfTerm(2, t)));
1427 if (f == FunctorComma || f == FunctorOr || f == FunctorVBar ||
1428 f == FunctorArrow || f==FunctorSoftCut) {
1429 return (IsTrueGoal(ArgOfTerm(1, t)) && IsTrueGoal(ArgOfTerm(2, t)));
1433 return (t == MkAtomTerm(AtomTrue));
1437 special_label_op lab_op = IntOfTerm(ArgOfTerm(1, Goal));
1438 special_label_id lab_id = IntOfTerm(ArgOfTerm(2, Goal));
1442 case SPECIAL_LABEL_INIT:
1443 label_name = ++cglobs->labelno;
1445 case SPECIAL_LABEL_EXCEPTION:
1446 cglobs->cint.exception_handler = label_name;
1448 case SPECIAL_LABEL_SUCCESS:
1449 cglobs->cint.success_handler = label_name;
1451 case SPECIAL_LABEL_FAILURE:
1452 cglobs->cint.failure_handler = label_name;
1455 Yap_emit_3ops(label_ctl_op, lab_op, lab_id, label_name, &cglobs->cint);
1457 case SPECIAL_LABEL_SET:
1459 case SPECIAL_LABEL_EXCEPTION:
1460 Yap_emit(label_op, cglobs->cint.exception_handler, Zero, &cglobs->cint);
1462 case SPECIAL_LABEL_SUCCESS:
1463 Yap_emit(label_op, cglobs->cint.success_handler, Zero, &cglobs->cint);
1465 case SPECIAL_LABEL_FAILURE:
1466 Yap_emit(label_op, cglobs->cint.failure_handler, Zero, &cglobs->cint);
1469 case SPECIAL_LABEL_CLEAR:
1471 case SPECIAL_LABEL_EXCEPTION:
1472 cglobs->cint.exception_handler = 0L;
1474 case SPECIAL_LABEL_SUCCESS:
1475 cglobs->cint.success_handler = 0L;
1477 case SPECIAL_LABEL_FAILURE:
1478 cglobs->cint.failure_handler = 0L;
1489 Goal = Yap_YapStripModule(Goal, &mod);
1490 if (IsVarTerm(Goal)) {
1491 Goal = Yap_MkApplTerm(FunctorCall, 1, &Goal);
1492 }
else if (IsNumTerm(Goal)) {
1494 FAIL(
"goal can not be a number", TYPE_ERROR_CALLABLE, Goal);
1495 }
else if (IsRefTerm(Goal)) {
1497 Yap_ThrowError(TYPE_ERROR_CALLABLE, Goal,
"goal argument in static procedure can not be a data base reference");
1498 }
else if (IsPairTerm(Goal)) {
1499 Goal = Yap_MkApplTerm(FunctorCall, 1, &Goal);
1501 if (IsAtomTerm(Goal)) {
1502 Atom atom = AtomOfTerm(Goal);
1504 if (atom == AtomFail || atom == AtomFalse) {
1505 Yap_emit(fail_op, Zero, Zero, &cglobs->cint);
1507 }
else if (atom == AtomTrue || atom == AtomOtherwise) {
1508 if (cglobs->onlast) {
1509 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
1511 PELOCK(41, cglobs->cint.CurrentPred);
1512 if (is_tabled(cglobs->cint.CurrentPred))
1513 Yap_emit(table_new_answer_op, Zero,
1514 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
1517 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
1519 UNLOCK(cglobs->cint.CurrentPred->PELock);
1523 }
else if (atom == AtomCut) {
1525 Yap_emit(enter_profiling_op,
1526 (CELL)RepPredProp(PredPropByAtom(AtomCut, 0)), Zero,
1529 Yap_emit(count_call_op, (CELL)RepPredProp(PredPropByAtom(AtomCut, 0)),
1530 Zero, &cglobs->cint);
1531 if (cglobs->onlast) {
1533 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
1535 PELOCK(42, cglobs->cint.CurrentPred);
1536 if (is_tabled(cglobs->cint.CurrentPred)) {
1537 Yap_emit_3ops(cut_op, Zero, Zero, Zero, &cglobs->cint);
1539 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
1540 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1541 Yap_emit(table_new_answer_op, Zero,
1542 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
1546 Yap_emit_3ops(cutexit_op, Zero, Zero, Zero, &cglobs->cint);
1548 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
1549 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1550 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
1553 UNLOCK(cglobs->cint.CurrentPred->PELock);
1556 Yap_emit_3ops(cut_op, Zero, Zero, Zero, &cglobs->cint);
1558 Yap_emit(empty_call_op, Zero, Zero, &cglobs->cint);
1559 Yap_emit(restore_tmps_and_skip_op, Zero, Zero, &cglobs->cint);
1560 adjust_current_commits(cglobs);
1565 else if (atom == AtomRepeat) {
1566 CELL l1 = ++cglobs->labelno;
1567 CELL l2 = ++cglobs->labelno;
1570 cglobs->needs_env = TRUE;
1572 Yap_emit(enter_profiling_op,
1573 (CELL)RepPredProp(PredPropByAtom(AtomRepeat, 0)), Zero,
1576 Yap_emit(count_call_op,
1577 (CELL)RepPredProp(PredPropByAtom(AtomRepeat, 0)), Zero,
1579 cglobs->or_found = TRUE;
1580 push_branch(cglobs->onbranch, TermNil, cglobs);
1581 cglobs->curbranch++;
1582 cglobs->onbranch = cglobs->curbranch;
1583 Yap_emit_3ops(push_or_op, l1, Zero, Zero, &cglobs->cint);
1584 Yap_emit_3ops(either_op, l1, Zero, Zero, &cglobs->cint);
1585 Yap_emit(restore_tmps_op, Zero, Zero, &cglobs->cint);
1586 Yap_emit(jump_op, l2, Zero, &cglobs->cint);
1587 Yap_emit(label_op, l1, Zero, &cglobs->cint);
1588 Yap_emit(pushpop_or_op, Zero, Zero, &cglobs->cint);
1589 Yap_emit_3ops(orelse_op, l1, Zero, Zero, &cglobs->cint);
1590 Yap_emit(label_op, l2, Zero, &cglobs->cint);
1591 if (cglobs->onlast) {
1593 PELOCK(43, cglobs->cint.CurrentPred);
1594 if (is_tabled(cglobs->cint.CurrentPred)) {
1595 Yap_emit(table_new_answer_op, Zero,
1596 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
1599 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
1600 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
1603 UNLOCK(cglobs->cint.CurrentPred->PELock);
1608 cglobs->onbranch = pop_branch(cglobs);
1609 Yap_emit(pop_or_op, Zero, Zero, &cglobs->cint);
1614 p = RepPredProp(p0 = Yap_PredPropByAtomNonThreadLocal(atom, mod));
1615 if (EndOfPAEntr(p0)) {
1616 save_machine_regs();
1617 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_HEAP_BOTCH);
1621 Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint);
1623 Yap_emit(count_call_op, (CELL)p, Zero, &cglobs->cint);
1625 f = FunctorOfTerm(Goal);
1626 p = RepPredProp(p0 = Yap_PredPropByFunctorNonThreadLocal(f, mod));
1627 if (EndOfPAEntr(p0)) {
1628 save_machine_regs();
1629 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_HEAP_BOTCH);
1631 if (f == FunctorOr || f == FunctorVBar) {
1633 CELL l = ++cglobs->labelno;
1634 CELL
m = ++cglobs->labelno;
1635 int save = cglobs->onlast;
1636 int savegoalno = cglobs->goalno;
1639 int looking_at_commit = FALSE;
1640 int optimizing_commit = FALSE;
1642 int looking_at_soft_cut = FALSE;
1643 PInstr *FirstP = cglobs->cint.cpc, *savecpc, *savencpc;
1645 push_branch(cglobs->onbranch, TermNil, cglobs);
1646 ++cglobs->curbranch;
1647 cglobs->onbranch = cglobs->curbranch;
1648 cglobs->or_found = TRUE;
1650 arg = ArgOfTerm(1, Goal);
1652 IsApplTerm(arg) && FunctorOfTerm(arg) == FunctorArrow;
1653 looking_at_soft_cut =
1654 IsApplTerm(arg) && FunctorOfTerm(arg) == FunctorSoftCut;
1656 if (optimizing_commit) {
1657 Yap_emit(label_op, l, Zero, &cglobs->cint);
1658 l = ++cglobs->labelno;
1660 Yap_emit_3ops(push_or_op, l, Zero, Zero, &cglobs->cint);
1661 if (looking_at_commit && Yap_is_a_test_pred(ArgOfTerm(1, arg), mod)) {
1667 optimizing_commit = TRUE;
1668 Yap_emit_3ops(label_ctl_op, SPECIAL_LABEL_INIT,
1669 SPECIAL_LABEL_FAILURE, l, &cglobs->cint);
1671 optimizing_commit = FALSE;
1672 cglobs->needs_env = TRUE;
1673 Yap_emit_3ops(either_op, l, Zero, Zero, &cglobs->cint);
1674 Yap_emit(restore_tmps_op, Zero, Zero, &cglobs->cint);
1678 optimizing_commit =
false;
1679 Yap_emit(label_op, l, Zero, &cglobs->cint);
1680 Yap_emit(pushpop_or_op, Zero, Zero, &cglobs->cint);
1681 Yap_emit_3ops(orelse_op, l = ++cglobs->labelno, Zero, Zero,
1683 cglobs->needs_env = TRUE;
1689 if (looking_at_commit || looking_at_soft_cut) {
1690 if ((!optimizing_commit && !commitflag)) {
1699 int my_goalno = cglobs->goalno;
1701 cglobs->goalno = savegoalno;
1702 commitflag = cglobs->labelno;
1703 commitvar = MkVarTerm();
1704 if (HR == (CELL *)cglobs->cint.freep0) {
1706 save_machine_regs();
1707 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1709 savecpc = cglobs->cint.cpc;
1710 savencpc = FirstP->nextInst;
1711 cglobs->cint.cpc = FirstP;
1712 cglobs->onbranch = pop_branch(cglobs);
1713 c_var(commitvar, save_b_flag, 1, 0, cglobs);
1714 push_branch(cglobs->onbranch, commitvar, cglobs);
1715 cglobs->onbranch = cglobs->curbranch;
1716 cglobs->cint.cpc->nextInst = savencpc;
1717 cglobs->cint.cpc = savecpc;
1718 cglobs->goalno = my_goalno;
1720 save = cglobs->onlast;
1721 cglobs->onlast = FALSE;
1722 c_goal(ArgOfTerm(1, arg), mod, cglobs);
1723 if (!optimizing_commit) {
1724 if (looking_at_soft_cut)
1725 c_var((Term)commitvar, soft_cut_b_flag, 1, 0, cglobs);
1727 c_var((Term)commitvar, commit_b_flag, 1, 0, cglobs);
1729 Yap_emit_3ops(label_ctl_op, SPECIAL_LABEL_CLEAR,
1730 SPECIAL_LABEL_FAILURE, l, &cglobs->cint);
1732 cglobs->onlast = save;
1733 c_goal(ArgOfTerm(2, arg), mod, cglobs);
1736 c_goal(ArgOfTerm(1, Goal), mod, cglobs);
1738 if (!cglobs->onlast) {
1739 Yap_emit(jump_op,
m, Zero, &cglobs->cint);
1742 if (!optimizing_commit || !cglobs->onlast) {
1743 cglobs->goalno = savegoalno + 1;
1745 Goal = ArgOfTerm(2, Goal);
1746 ++cglobs->curbranch;
1747 cglobs->onbranch = cglobs->curbranch;
1748 }
while (IsNonVarTerm(Goal) && IsApplTerm(Goal) &&
1749 (FunctorOfTerm(Goal) == FunctorOr ||
1750 FunctorOfTerm(Goal) == FunctorVBar));
1751 Yap_emit(pushpop_or_op, Zero, Zero, &cglobs->cint);
1752 Yap_emit(label_op, l, Zero, &cglobs->cint);
1753 if (!optimizing_commit) {
1754 Yap_emit(orlast_op, Zero, Zero, &cglobs->cint);
1756 optimizing_commit = FALSE;
1758 c_goal(Goal, mod, cglobs);
1760 cglobs->onbranch = pop_branch(cglobs);
1761 if (!cglobs->onlast) {
1762 Yap_emit(label_op,
m, Zero, &cglobs->cint);
1763 if ((cglobs->onlast = save))
1764 c_goal(MkAtomTerm(AtomTrue), mod, cglobs);
1766 Yap_emit(pop_or_op, Zero, Zero, &cglobs->cint);
1768 }
else if (f == FunctorComma) {
1769 int save = cglobs->onlast;
1770 Term t2 = ArgOfTerm(2, Goal);
1772 cglobs->onlast = FALSE;
1773 c_goal(ArgOfTerm(1, Goal), mod, cglobs);
1774 cglobs->onlast = save;
1775 c_goal(t2, mod, cglobs);
1777 }
else if (f == FunctorNot || f == FunctorAltNot) {
1779 CELL label = (cglobs->labelno += 2);
1780 CELL end_label = (cglobs->labelno += 2);
1781 int save = cglobs->onlast;
1785 cglobs->needs_env = TRUE;
1786 commitvar = MkVarTerm();
1787 if (HR == (CELL *)cglobs->cint.freep0) {
1789 save_machine_regs();
1790 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1792 push_branch(cglobs->onbranch, commitvar, cglobs);
1793 ++cglobs->curbranch;
1794 cglobs->onbranch = cglobs->curbranch;
1795 cglobs->or_found = TRUE;
1796 cglobs->onlast = FALSE;
1797 c_var(commitvar, save_b_flag, 1, 0, cglobs);
1798 Yap_emit_3ops(push_or_op, label, Zero, Zero, &cglobs->cint);
1799 Yap_emit_3ops(either_op, label, Zero, Zero, &cglobs->cint);
1800 Yap_emit(restore_tmps_op, Zero, Zero, &cglobs->cint);
1801 c_goal(ArgOfTerm(1, Goal), mod, cglobs);
1802 c_var(commitvar, commit_b_flag, 1, 0, cglobs);
1803 cglobs->onlast = save;
1804 Yap_emit(fail_op, end_label, Zero, &cglobs->cint);
1805 Yap_emit(pushpop_or_op, Zero, Zero, &cglobs->cint);
1806 Yap_emit(label_op, label, Zero, &cglobs->cint);
1807 Yap_emit(orlast_op, Zero, Zero, &cglobs->cint);
1808 Yap_emit(label_op, end_label, Zero, &cglobs->cint);
1809 cglobs->onlast = save;
1811 cglobs->onbranch = pop_branch(cglobs);
1812 c_goal(MkAtomTerm(AtomTrue), mod, cglobs);
1814 Yap_emit(pop_or_op, Zero, Zero, &cglobs->cint);
1816 }
else if (f == FunctorArrow) {
1819 int save = cglobs->onlast;
1821 commitvar = MkVarTerm();
1822 if (HR == (CELL *)cglobs->cint.freep0) {
1824 save_machine_regs();
1825 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1827 cglobs->onlast = FALSE;
1828 c_var(commitvar, save_b_flag, 1, 0, cglobs);
1829 c_goal(ArgOfTerm(1, Goal), mod, cglobs);
1830 c_var(commitvar, commit_b_flag, 1, 0, cglobs);
1831 cglobs->onlast = save;
1832 c_goal(ArgOfTerm(2, Goal), mod, cglobs);
1834 }
else if (f == FunctorSoftCut) {
1836 int save = cglobs->onlast;
1837 cglobs->onlast = FALSE;
1838 c_goal(ArgOfTerm(1, Goal), mod, cglobs);
1839 cglobs->onlast = save;
1840 c_goal(ArgOfTerm(2, Goal), mod, cglobs);
1842 }
else if (f == FunctorEq) {
1844 Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint);
1846 Yap_emit(count_call_op, (CELL)p, Zero, &cglobs->cint);
1847 c_eq(ArgOfTerm(1, Goal), ArgOfTerm(2, Goal), cglobs);
1848 if (cglobs->onlast) {
1849 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
1851 PELOCK(44, cglobs->cint.CurrentPred);
1852 if (is_tabled(cglobs->cint.CurrentPred))
1853 Yap_emit(table_new_answer_op, Zero,
1854 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
1857 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
1859 UNLOCK(cglobs->cint.CurrentPred->PELock);
1863 }
else if (f == FunctorSafe) {
1866 v->FlagsOfVE |= SafeVar;
1868 }
else if (p->PredFlags & (AsmPredFlag)) {
1869 basic_preds op = p->PredFlags & 0x7f;
1871 Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint);
1873 Yap_emit(count_call_op, (CELL)p, Zero, &cglobs->cint);
1874 if (op >= _atom && op <= _primitive) {
1875 c_test(op, ArgOfTerm(1, Goal), cglobs);
1876 if (cglobs->onlast) {
1877 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
1879 PELOCK(45, cglobs->cint.CurrentPred);
1880 if (is_tabled(cglobs->cint.CurrentPred))
1881 Yap_emit(table_new_answer_op, Zero,
1882 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
1885 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
1887 UNLOCK(cglobs->cint.CurrentPred->PELock);
1891 }
else if (op >= _plus && op <= _functor) {
1893 Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint);
1895 Yap_emit(count_call_op, (CELL)p, Zero, &cglobs->cint);
1896 if (op == _functor) {
1897 c_functor(Goal, mod, cglobs);
1899 c_bifun(op, ArgOfTerm(1, Goal), ArgOfTerm(2, Goal),
1900 ArgOfTerm(3, Goal), Goal, mod, cglobs);
1902 if (cglobs->onlast) {
1903 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
1905 PELOCK(46, cglobs->cint.CurrentPred);
1906 if (is_tabled(cglobs->cint.CurrentPred))
1907 Yap_emit(table_new_answer_op, Zero,
1908 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
1911 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
1913 UNLOCK(cglobs->cint.CurrentPred->PELock);
1917 }
else if (op == _p_label_ctl) {
1918 emit_special_label(Goal, cglobs);
1921 c_args(Goal, 0, cglobs);
1925 else if (p->PredFlags & BinaryPredFlag && !EAM) {
1927 else if (p->PredFlags & BinaryPredFlag) {
1930 Term a1 = ArgOfTerm(1, Goal);
1932 if (IsVarTerm(a1) && !IsNewVar(a1)) {
1933 Term a2 = ArgOfTerm(2, Goal);
1934 if (IsVarTerm(a2) && !IsNewVar(a2)) {
1935 cglobs->current_p0 = p0;
1936 c_2vars(bt_flag, a1, 0, a2, 0, (CELL)p0, 0, 0, cglobs);
1938 Term t2 = MkVarTerm();
1940 if (HR == (CELL *)cglobs->cint.freep0) {
1942 save_machine_regs();
1943 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1945 cglobs->current_p0 = p0;
1946 c_eq(t2, a2, cglobs);
1947 c_2vars(bt_flag, a1, 0, t2, 0, (CELL)p0, 0, 0, cglobs);
1950 Term a2 = ArgOfTerm(2, Goal);
1951 Term t1 = MkVarTerm();
1953 if (HR == (CELL *)cglobs->cint.freep0) {
1955 save_machine_regs();
1956 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1958 c_eq(t1, a1, cglobs);
1960 if (IsVarTerm(a2) && !IsNewVar(a2)) {
1961 cglobs->current_p0 = p0;
1962 c_2vars(bt_flag, t1, 0, a2, 0, (CELL)p0, 0, 0, cglobs);
1964 Term t2 = MkVarTerm();
1966 if (HR == (CELL *)cglobs->cint.freep0) {
1968 save_machine_regs();
1969 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_TEMPS_BOTCH);
1971 c_eq(t2, a2, cglobs);
1972 cglobs->current_p0 = p0;
1973 c_2vars(bt_flag, t1, 0, t2, 0, (CELL)p0, 0, 0, cglobs);
1976 if (cglobs->onlast) {
1977 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
1979 PELOCK(47, cglobs->cint.CurrentPred);
1980 if (is_tabled(cglobs->cint.CurrentPred))
1981 Yap_emit(table_new_answer_op, Zero,
1982 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
1985 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
1987 UNLOCK(cglobs->cint.CurrentPred->PELock);
1993 Yap_emit(enter_profiling_op, (CELL)p, Zero, &cglobs->cint);
1995 Yap_emit(count_call_op, (CELL)p, Zero, &cglobs->cint);
1996 if (f == FunctorExecuteInMod) {
1998 c_arg(1, ArgOfTerm(1, Goal), 1, 0, cglobs);
2000 c_args(Goal, 0, cglobs);
2005 if (p->PredFlags & SafePredFlag
2008 && !(p->PredFlags & SyncPredFlag)
2011 Yap_emit(safe_call_op, (CELL)p0, Zero, &cglobs->cint);
2012 if (cglobs->onlast) {
2013 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
2015 PELOCK(48, cglobs->cint.CurrentPred);
2016 if (is_tabled(cglobs->cint.CurrentPred))
2017 Yap_emit(table_new_answer_op, Zero, cglobs->cint.CurrentPred->ArityOfPE,
2021 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
2023 UNLOCK(cglobs->cint.CurrentPred->PELock);
2028 (AsmPredFlag | ModuleTransparentPredFlag | UserCPredFlag)) ||
2029 p->FunctorOfPred == FunctorExecuteInMod) {
2031 if (p->PredFlags & SyncPredFlag)
2032 Yap_emit(sync_op, (CELL)p, (CELL)(p->ArityOfPE), &cglobs->cint);
2034 if (p->FunctorOfPred == FunctorExecuteInMod) {
2035 cglobs->needs_env = TRUE;
2036 Yap_emit_4ops(call_op, (CELL)p0, Zero, Zero, ArgOfTerm(2, Goal),
2039 cglobs->needs_env = TRUE;
2040 Yap_emit_3ops(call_op, (CELL)p0, Zero, Zero, &cglobs->cint);
2043 if (cglobs->onlast) {
2044 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
2045 cglobs->or_found = TRUE;
2047 PELOCK(49, cglobs->cint.CurrentPred);
2048 if (is_tabled(cglobs->cint.CurrentPred))
2049 Yap_emit(table_new_answer_op, Zero,
2050 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
2053 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
2055 UNLOCK(cglobs->cint.CurrentPred->PELock);
2059 if (cglobs->onlast) {
2060 Yap_emit(deallocate_op, Zero, Zero, &cglobs->cint);
2062 PELOCK(50, cglobs->cint.CurrentPred);
2063 if (is_tabled(cglobs->cint.CurrentPred)) {
2064 cglobs->needs_env = TRUE;
2065 Yap_emit_3ops(call_op, (CELL)p0, Zero, Zero, &cglobs->cint);
2066 Yap_emit(table_new_answer_op, Zero,
2067 cglobs->cint.CurrentPred->ArityOfPE, &cglobs->cint);
2070 Yap_emit(execute_op, (CELL)p0, Zero, &cglobs->cint);
2072 UNLOCK(cglobs->cint.CurrentPred->PELock);
2075 cglobs->needs_env = TRUE;
2076 Yap_emit_3ops(call_op, (CELL)p0, Zero, Zero, &cglobs->cint);
2079 if (!cglobs->onlast)
2085 cglobs->onhead = FALSE;
2086 cglobs->BodyStart = cglobs->cint.cpc;
2088 while (IsNonVarTerm(Body) && IsApplTerm(Body) &&
2089 FunctorOfTerm(Body) == FunctorComma) {
2090 Term t2 = ArgOfTerm(2, Body);
2091 if (!cglobs->cint.success_handler && IsTrueGoal(t2)) {
2095 Body = ArgOfTerm(1, Body);
2098 c_goal(ArgOfTerm(1, Body), mod, cglobs);
2102 Yap_emit(endgoal_op, Zero, Zero, &cglobs->cint);
2105 cglobs->onlast = TRUE;
2106 c_goal(Body, mod, cglobs);
2108 if (EAM && cglobs->goalno > 1) {
2109 if (cglobs->cint.cpc->op == procceed_op) {
2110 cglobs->cint.cpc->op = endgoal_op;
2111 Yap_emit(procceed_op, Zero, Zero, &cglobs->cint);
2113 Yap_emit(endgoal_op, Zero, Zero, &cglobs->cint);
2122 cglobs->onhead = TRUE;
2123 cglobs->onlast = FALSE;
2124 cglobs->curbranch = cglobs->onbranch = 0;
2125 cglobs->branch_pointer = cglobs->parent_branches;
2126 cglobs->space_used = 0;
2127 cglobs->space_op = NULL;
2128 if (IsAtomTerm(t)) {
2129 Yap_emit(name_op, (CELL)AtomOfTerm(t), Zero, &cglobs->cint);
2132 Yap_emit(run_op, Zero, (UInt)cglobs->cint.CurrentPred, &cglobs->cint);
2135 Yap_emit(ensure_space_op, Zero, Zero, &cglobs->cint);
2136 cglobs->space_op = cglobs->cint.cpc;
2139 f = FunctorOfTerm(t);
2140 Yap_emit(name_op, (CELL)NameOfFunctor(f), ArityOfFunctor(f), &cglobs->cint);
2143 Yap_emit(run_op, Zero, (UInt)cglobs->cint.CurrentPred, &cglobs->cint);
2146 if (Yap_ExecutionMode == MIXED_MODE_USER)
2147 Yap_emit(native_op, 0, 0, &cglobs->cint);
2148 Yap_emit(ensure_space_op, Zero, Zero, &cglobs->cint);
2149 cglobs->space_op = cglobs->cint.cpc;
2152 Yap_emit(run_op, Zero, (UInt)cglobs->cint.CurrentPred, &cglobs->cint);
2155 if (Yap_ExecutionMode == MIXED_MODE || Yap_ExecutionMode == COMPILED)
2157 Yap_emit(native_op, 0, 0, &cglobs->cint);
2160 if (Yap_ExecutionMode == MIXED_MODE)
2161 Yap_NilError(SYSTEM_ERROR_JIT_NOT_AVAILABLE,
"mixed");
2163 Yap_NilError(SYSTEM_ERROR_JIT_NOT_AVAILABLE,
"just compiled");
2166 c_args(t, 0, cglobs);
2169inline static bool usesvar(compiler_vm_op ic) {
2170 if (ic >= get_var_op && ic <= put_val_op)
2187 if (ic >= unify_s_var_op && ic <= write_s_val_op)
2190 return ((ic >= unify_var_op && ic <= write_val_op) ||
2191 (ic >= unify_last_var_op && ic <= unify_last_val_op));
2206inline static bool usesvar2(compiler_vm_op ic) {
return ic == bccall_op; }
2212#define LOCALISE_VOIDS 1
2214#ifdef LOCALISE_VOIDS
2221static void tag_use(
Ventry *v USES_REGS) {
2224 if (v->NoOfVE == Unassigned || v->KindOfVE != PermVar) {
2225 v->NoOfVE = PermVar | (LOCAL_nperm++);
2226 v->KindOfVE = PermVar;
2227 v->FlagsOfVE |= PermFlag;
2231 if (v->NoOfVE == Unassigned) {
2232 if ((v->AgeOfVE > 1 && (v->AgeOfVE > v->FirstOfVE)) ||
2233 v->KindOfVE == PermVar
2237 v->NoOfVE = PermVar | (LOCAL_nperm++);
2238 v->KindOfVE = PermVar;
2239 v->FlagsOfVE |= PermFlag;
2241 v->NoOfVE = v->KindOfVE = TempVar;
2250#ifdef LOCALISE_VOIDS
2262 while (pc != NULL) {
2263 PInstr *tpc = pc->nextInst;
2264#ifdef LOCALISE_VOIDS
2265 if (pc->op == put_var_op) {
2267 if (v->AgeOfVE == v->FirstOfVE &&
2268 !(v->FlagsOfVE & (GlobalVal | OnHeadFlag | OnLastGoal | NonVoid))) {
2269 EnvTmp *x = (
EnvTmp *)Yap_AllocCMem(
sizeof(*x), &cglobs->cint);
2276 if (pc->op == call_op || pc->op == either_op || pc->op == orelse_op ||
2277 pc->op == push_or_op) {
2278#ifdef LOCALISE_VOIDS
2279 pc->ops.opseqt[1] = (CELL)EnvTmps;
2291 PInstr *npc = pc->nextInst;
2294 uses_var = usesvar(pc->op);
2298 tag_use(v PASS_REGS);
2299 if (usesvar2(pc->op)) {
2301 tag_use(v2 PASS_REGS);
2304 }
else if (pc->op == empty_call_op) {
2305 pc->rnd2 = LOCAL_nperm;
2306 }
else if (pc->op == call_op || pc->op == either_op ||
2307 pc->op == orelse_op || pc->op == push_or_op) {
2308#ifdef LOCALISE_VOIDS
2309 EnvTmps = (
EnvTmp *)(pc->ops.opseqt[1]);
2311 Ventry *v = EnvTmps->Var;
2312 v->NoOfVE = PermVar | (LOCAL_nperm++);
2313 v->KindOfVE = PermVar;
2314 v->FlagsOfVE |= (PermFlag | SafeVar);
2315 EnvTmps = EnvTmps->Next;
2318 pc->rnd2 = LOCAL_nperm;
2319 }
else if (pc->op == cut_op || pc->op == cutexit_op ||
2320 pc->op == commit_b_op ||
2321 pc->op == soft_cut_b_op) {
2322 pc->rnd2 = LOCAL_nperm;
2326 }
while (pc != NULL);
2331 size_t sz =
sizeof(CELL) * (1 + nperm / (8 *
sizeof(CELL)));
2332 vinfo = (CELL *)Yap_AllocCMem(sz, &cglobs->cint);
2333 memset((
void *)vinfo, 0, sz);
2337static void clear_bvarray(
int var, CELL *bvarray
2343 int max = 8 *
sizeof(CELL);
2347 while (var >= max) {
2352 nbit = ((CELL)1 << var);
2354 if (*bvarray & nbit) {
2357 LOCAL_Error_TYPE = SYSTEM_ERROR_COMPILER;
2358 LOCAL_ErrorMessage =
"compiler internal error: variable initialized twice";
2359 save_machine_regs();
2360 siglongjmp(cglobs->cint.CompilerBotch, COMPILER_ERR_BOTCH);
2368static void add_bvarray_op(
PInstr *cp, CELL *bvarray,
int env_size,
2370 int i, size = env_size / (8 *
sizeof(CELL));
2373 dest = Yap_emit_extra_size(mark_initialized_pvars_op, (CELL)env_size,
2374 (size + 1) *
sizeof(CELL), &cglobs->cint);
2376 for (i = 0; i <= size; i++)
2377 *dest++ = *bvarray++;
2388#define MAX_DISJUNCTIONS (128*128*32)
2390static int bvindex = 0;
2393 if (bvindex == MAX_DISJUNCTIONS) {
2395 Yap_ThrowError(SYSTEM_ERROR_COMPILER, MkIntTerm(0),
"too many embedded disjunctions (max = %d)", MAX_DISJUNCTIONS);
2396 save_machine_regs();
2397 siglongjmp(cglobs->cint.CompilerBotch, COMPILER_ERR_BOTCH);
2400 bvstack[bvindex].lab = label;
2401 bvstack[bvindex].last = -1;
2403 bvstack[bvindex].pc = pcpc;
2407static void reset_bvmap(CELL *bvarray,
int nperm,
compiler_struct *cglobs) {
2408 int size, size1, env_size, i;
2411 if (bvarray == NULL)
2415 Yap_ThrowError(SYSTEM_ERROR_COMPILER, MkIntTerm(0),
"No disjunctions found, but reset d1sjunctions was called");
2416 save_machine_regs();
2417 siglongjmp(cglobs->cint.CompilerBotch, COMPILER_ERR_BOTCH);
2419 env_size = (bvstack[bvindex - 1].pc)->rnd1;
2420 size = env_size / (8 *
sizeof(CELL));
2421 size1 = nperm / (8 *
sizeof(CELL));
2422 source = (bvstack[bvindex - 1].pc)->arnds;
2423 for (i = 0; i <= size; i++)
2425 for (i = size + 1; i <= size1; i++)
2426 *bvarray++ = (CELL)(0);
2429static void pop_bvmap(CELL *bvarray,
int nperm,
compiler_struct *cglobs) {
2432 Yap_ThrowError(SYSTEM_ERROR_COMPILER, MkIntTerm(0),
"pop disjunctions called, but no disjunctions available");
2436 reset_bvmap(bvarray, nperm, cglobs);
2451 CELL *vstat = init_bvarray(LOCAL_nperm, cglobs);
2453 LOCAL_nperm *
sizeof(
UnsafeEntry), &cglobs->cint);
2455 PInstr *opc = cglobs->cint.cpc;
2456 PInstr *OldCodeStart = cglobs->cint.CodeStart;
2458 cglobs->cint.CodeStart = cglobs->cint.BlobsStart;
2459 cglobs->cint.cpc = cglobs->cint.icpc;
2461 bvstack = (
bventry *)Yap_AllocCMem(MAX_DISJUNCTIONS *
sizeof(
bventry),
2467 if ((v->FlagsOfVE & PermFlag) && !(v->FlagsOfVE & SafeVar)) {
2468 UnsafeStack[pending].p = pc;
2469 UnsafeStack[pending++].v = v;
2470 v->FlagsOfVE |= SafeVar;
2477 if ((v->FlagsOfVE & PermFlag && pc == v->FirstOpForV) ||
2478 (v3->FlagsOfVE & PermFlag && pc == v3->FirstOpForV)) {
2480 Yap_ThrowError(SYSTEM_ERROR_COMPILER,TermNil,
" comparison between two first instances of two variables.");
2481 save_machine_regs();
2482 siglongjmp(cglobs->cint.CompilerBotch, COMPILER_ERR_BOTCH);
2489 case unify_last_var_op:
2496 if (v->FlagsOfVE & PermFlag && pc == v->FirstOpForV) {
2499 clear_bvarray((v->NoOfVE & MaskVarAdrs), vstat
2508 Yap_emit(label_op, ++cglobs->labelno, Zero, &cglobs->cint);
2509 pc->ops.opseqt[1] = (CELL)cglobs->labelno;
2510 add_bvarray_op(pc, vstat, pc->rnd2, cglobs);
2511 push_bvmap((CELL)cglobs->labelno, cglobs->cint.cpc, cglobs);
2515 Yap_emit(label_op, ++cglobs->labelno, Zero, &cglobs->cint);
2516 pc->ops.opseqt[1] = (CELL)cglobs->labelno;
2517 add_bvarray_op(pc, vstat, pc->rnd2, cglobs);
2520 reset_bvmap(vstat, LOCAL_nperm, cglobs);
2521 goto reset_safe_map;
2523 Yap_emit(label_op, ++cglobs->labelno, Zero, &cglobs->cint);
2524 pc->ops.opseqt[1] = (CELL)cglobs->labelno;
2525 add_bvarray_op(pc, vstat, pc->rnd2, cglobs);
2528 pop_bvmap(vstat, LOCAL_nperm, cglobs);
2529 goto reset_safe_map;
2534 Yap_emit(label_op, ++cglobs->labelno, Zero, &cglobs->cint);
2535 pc->rnd1 = (CELL)cglobs->labelno;
2536 add_bvarray_op(pc, vstat, pc->rnd2, cglobs);
2542 Yap_emit(label_op, ++cglobs->labelno, Zero, &cglobs->cint);
2543 pc->rnd1 = (CELL)cglobs->labelno;
2544 add_bvarray_op(pc, vstat, pc->rnd2, cglobs);
2547 Yap_emit(label_op, ++cglobs->labelno, Zero, &cglobs->cint);
2548 pc->ops.opseqt[1] = (CELL)cglobs->labelno;
2549 add_bvarray_op(pc, vstat, pc->rnd2, cglobs);
2552 int n = pc->op == call_op ? pc->rnd2 : 0;
2556 Ventry *v = UnsafeStack[--pending].v;
2558 v->FlagsOfVE &= ~SafeVar;
2559 no = (v->NoOfVE) & MaskVarAdrs;
2561 UnsafeStack[pending].p->op = put_unsafe_op;
2569 cglobs->cint.icpc = cglobs->cint.cpc;
2570 cglobs->cint.cpc = opc;
2571 cglobs->cint.BlobsStart = cglobs->cint.CodeStart;
2572 cglobs->cint.CodeStart = OldCodeStart;
2582 cpc = cglobs->cint.CodeStart;
2583 while ((ic = cpc->op) != allocate_op) {
2587 case unify_last_var_op:
2589 case unify_s_var_op:
2593 ve = ((
Ventry *)cpc->rnd1);
2594 if ((ve->FlagsOfVE & PermFlag) == 0 && ve->RCountOfVE <= 1) {
2595 ve->NoOfVE = ve->KindOfVE = VoidVar;
2596 if (ic == get_var_op || ic == save_pair_op || ic == save_appl_op
2598 || ic == unify_s_var_op
2605 if (ic != get_var_op)
2612 case get_longint_op:
2617 cglobs->Uses[cpc->rnd2] = 1;
2620 cglobs->Uses[cpc->rnd2] = 1;
2621 cglobs->Uses[cpc->rnd4] = 1;
2625 cpc = cpc->nextInst;
2629static int checktemp(Int arg, Int rn, compiler_vm_op ic,
2633 Int Needed[MaxTemps];
2634 Int r, target1, target2;
2640 cglobs->vadr = vadr = (v->NoOfVE);
2641 cglobs->vreg = vreg = vadr & MaskVarAdrs;
2642 if (v->KindOfVE == PermVar || v->KindOfVE == VoidVar)
2644 if (v->RCountOfVE == 1)
2647 --cglobs->Uses[vreg];
2651 q = cglobs->cint.cpc;
2659 for (r = 0; r < cglobs->MaxCTemps; ++r)
2661 if (rn > 0 && (ic == get_var_op || ic == put_var_op)) {
2662 if (ic == put_var_op)
2666 target1 = cglobs->MaxCTemps;
2667 target2 = cglobs->MaxCTemps;
2668 n = v->RCountOfVE - 1;
2669 while (q != v->LastOpForV && (q = q->nextInst) != NIL) {
2672 else if ((usesvar(ic = q->op) && arg == q->rnd1) ||
2673 (ic == bccall_op && arg == q->rnd3) ) {
2676 if (ic == put_val_op) {
2677 if (target1 == cglobs->MaxCTemps && Needed[q->rnd2] == 0)
2679 else if (target1 != (r = q->rnd2)) {
2680 if (target2 == cglobs->MaxCTemps && Needed[r] == 0)
2682 else if (target2 > r && cglobs->Uses[r] == 0 && Needed[r] == 0)
2688 else if ((ic >= get_var_op && ic <= put_unsafe_op) || ic == get_s_f_op ||
2690 Needed[q->rnd2] = 1;
2692 else if (ic >= get_var_op && ic <= put_unsafe_op)
2693 Needed[q->rnd2] = 1;
2695 if ((ic == call_op || ic == safe_call_op) && n == 0)
2698 if (target2 < target1) {
2703 if (target1 == cglobs->MaxCTemps || cglobs->Uses[target1] || Needed[target1])
2704 if ((target1 = target2) == cglobs->MaxCTemps || cglobs->Uses[target1] ||
2706 target1 = cglobs->MaxCTemps;
2709 while (target1 && cglobs->Uses[target1] == 0 && Needed[target1] == 0);
2712 if (target1 == cglobs->MaxCTemps) {
2714 Yap_ThrowError(SYSTEM_ERROR_COMPILER,TermNil,
" maximum termporary limit MaxCTmps (%d) exceeded.", cglobs->MaxCTemps);
2715 save_machine_regs();
2716 siglongjmp(cglobs->cint.CompilerBotch, COMPILER_ERR_BOTCH);
2718 v->NoOfVE = cglobs->vadr = vadr = TempVar | target1;
2719 v->KindOfVE = TempVar;
2720 cglobs->Uses[cglobs->vreg = vreg = target1] = v->RCountOfVE - 1;
2726 cp = cglobs->Contents;
2727 for (r = 0; r < cglobs->MaxCTemps; ++r)
2728 if (*cp++ == (Term)vadr)
2730 cglobs->Contents[vreg] = vadr;
2734static Int checkreg(Int arg, Int rn, compiler_vm_op ic,
int var_arg,
2736 PInstr *p = cglobs->cint.cpc;
2744 vreg = (v->NoOfVE) & MaskVarAdrs;
2745 if (v->KindOfVE == PermVar)
2747 else if (vreg == 0) {
2748 checktemp(arg, rn, ic, cglobs);
2749 vreg = (v->NoOfVE) & MaskVarAdrs;
2750 ++cglobs->Uses[vreg];
2754 while (cglobs->Uses[vreg] != 0) {
2757 cglobs->Uses[vreg] = v->RCountOfVE;
2761 while (cglobs->Uses[vreg] != 0) {
2766 if (p->op >= get_var_op && p->op <= put_unsafe_op && p->rnd2 == rn)
2769 if (p->op == procceed_op || p->op == call_op || p->op == push_or_op ||
2770 p->op == pushpop_or_op)
2779 unsigned int size = AdjustSize((max | 7) / 8 + 1);
2781 CELL *dest = Yap_emit_extra_size(mark_live_regs_op, max, size, &cglobs->cint);
2784 for (i = 1; i <= max; i++) {
2786 if (i % (8 * CellSize) == 0) {
2791 if (cglobs->Contents[i]) {
2792 int j = i % (8 * CellSize);
2796 return ((CELL)dest);
2801 PInstr *savepc = cglobs->BodyStart->nextInst;
2802 register Ventry *v = cglobs->vtable;
2803 Int *up = cglobs->Uses;
2804 CELL *cop = cglobs->Contents;
2808 int needs_either = 0;
2810 rn_to_kill[0] = rn_to_kill[1] = 0;
2811 cglobs->cint.cpc = cglobs->BodyStart;
2817 if (!cglobs->is_a_fact) {
2819 if (v->FlagsOfVE & BranchVar) {
2820 v->AgeOfVE = v->FirstOfVE + 1;
2822 Yap_emit(put_var_op, (CELL)v, Zero, &cglobs->cint);
2823 v->FlagsOfVE &= ~GlobalVal;
2824 v->FirstOpForV = cglobs->cint.cpc;
2828 cglobs->cint.cpc->nextInst = savepc;
2831 if (cglobs->needs_env || EAM) {
2833 if (cglobs->needs_env) {
2836 AssignPerm(cglobs->cint.CodeStart, cglobs);
2840 CheckUnsafe(cglobs->cint.CodeStart, cglobs);
2842 if (cglobs->pbvars != LOCAL_nperm) {
2844 Yap_ThrowError(SYSTEM_ERROR_COMPILER,TermNil,
" inconsistent calculations for permanent variables %d != %d", cglobs->pbvars, LOCAL_nperm);
2845 save_machine_regs();
2846 siglongjmp(cglobs->cint.CompilerBotch, OUT_OF_HEAP_BOTCH);
2852 cglobs->MaxCTemps = cglobs->nvars + cglobs->max_args - cglobs->tmpreg +
2853 cglobs->n_common_exps + 2;
2854 if (cglobs->MaxCTemps >= MaxTemps)
2855 cglobs->MaxCTemps = MaxTemps;
2858 for (rn = 0; rn < cglobs->MaxCTemps; ++rn) {
2868 cglobs->cint.cpc = cglobs->cint.CodeStart;
2869 while (cglobs->cint.cpc) {
2870 compiler_vm_op ic = cglobs->cint.cpc->op;
2871 Int arg = cglobs->cint.cpc->rnd1;
2872 Int rn = cglobs->cint.cpc->rnd2;
2880#ifdef TABLING_INNER_CUTS
2883 cglobs->cut_mark->op = clause_with_cut_op;
2891 for (i = 1; i < cglobs->MaxCTemps; ++i) {
2892 if (cglobs->Contents[i])
2895 cglobs->cint.cpc->ops.opseqt[1] = max;
2900 if (!cglobs->needs_env) {
2901 cglobs->cint.cpc->op = nop_op;
2904 PELOCK(51, cglobs->cint.CurrentPred);
2905 if (is_tabled(cglobs->cint.CurrentPred))
2906 cglobs->cint.cpc->op = nop_op;
2909 if (cglobs->goalno == 1 && !cglobs->or_found && LOCAL_nperm == 0)
2910 cglobs->cint.cpc->op = nop_op;
2912 UNLOCK(cglobs->cint.CurrentPred->PELock);
2917 ic = (cglobs->cint.cpc->nextInst)->op;
2918 if (ic >= get_var_op && ic <= put_unsafe_op)
2919 cglobs->cint.cpc->op = nop_op;
2923 if (checktemp(arg, rn, ic, cglobs)) {
2925 if (cglobs->vreg == rn && !EAM)
2927 if (cglobs->vreg == rn)
2929 cglobs->cint.cpc->op = nop_op;
2931 if (!cglobs->Uses[rn])
2932 cglobs->Contents[rn] = cglobs->vadr;
2936 checktemp(arg, rn, ic, cglobs);
2937 if (!cglobs->Uses[rn])
2938 cglobs->Contents[rn] = cglobs->vadr;
2942 --cglobs->Uses[rn_to_kill[0]];
2943 rn_to_kill[1] = rn_to_kill[0] = 0;
2947 --cglobs->Uses[rn_to_kill[0]];
2948 rn_to_kill[1] = rn_to_kill[0] = 0;
2951 case unify_last_var_op:
2952 case unify_last_val_op:
2954 case unify_s_var_op:
2955 case unify_s_val_op:
2957 checktemp(arg, rn, ic, cglobs);
2960 checktemp(arg, rn, ic, cglobs);
2961 checktemp(cglobs->cint.cpc->rnd3, cglobs->cint.cpc->rnd4, ic, cglobs);
2966 case get_longint_op:
2974 if (!cglobs->Uses[rn])
2975 cglobs->Contents[rn] = arg;
2980 if (!cglobs->Uses[rn])
2981 cglobs->Contents[rn] = NIL;
2985 rn = checkreg(arg, rn, ic, TRUE, cglobs);
2986 checktemp(arg, rn, ic, cglobs);
2987 cglobs->Contents[rn] = cglobs->vadr;
2991 rn = checkreg(arg, rn, ic, TRUE, cglobs);
2992 checktemp(arg, rn, ic, cglobs);
2994 if (rn && cglobs->Contents[rn] == (Term)cglobs->vadr && !EAM)
2996 if (rn && cglobs->Contents[rn] == (Term)cglobs->vadr)
2999 cglobs->cint.cpc->op = nop_op;
3001 cglobs->Contents[rn] = cglobs->vadr;
3005 rn_to_kill[rn_kills] = rn;
3008 case fetch_args_cv_op:
3009 case fetch_args_vc_op:
3010 case fetch_args_iv_op:
3011 case fetch_args_vi_op:
3012 rn_to_kill[1] = rn_to_kill[0] = 0;
3013 if (cglobs->cint.cpc->nextInst &&
3014 cglobs->cint.cpc->nextInst->op == put_val_op &&
3015 cglobs->cint.cpc->nextInst->nextInst &&
3016 (cglobs->cint.cpc->nextInst->nextInst->op == f_var_op ||
3017 cglobs->cint.cpc->nextInst->nextInst->op == f_0_op))
3022 case write_s_var_op: {
3025 if ((ve->FlagsOfVE & PermFlag) == 0 && ve->RCountOfVE <= 1)
3026 cglobs->cint.cpc->op = nop_op;
3028 case write_s_val_op:
3032 checktemp(arg, rn, ic, cglobs);
3036 cglobs->Contents[rn] = arg;
3043 case put_longint_op:
3047 rn = checkreg(arg, rn, ic, FALSE, cglobs);
3048 if (cglobs->Contents[rn] == arg)
3049 cglobs->cint.cpc->op = nop_op;
3050 cglobs->Contents[rn] = arg;
3055 rn = checkreg(arg, rn, ic, FALSE, cglobs);
3056 cglobs->Contents[rn] = NIL;
3061#ifdef TABLING_INNER_CUTS
3062 cglobs->cut_mark->op = clause_with_cut_op;
3068 checktemp(arg, rn, ic, cglobs);
3084 cop = cglobs->Contents;
3085 for (rn = 1; rn < cglobs->MaxCTemps; ++rn) {
3086 *up++ = *cop++ = NIL;
3091 cop = cglobs->Contents;
3092 for (rn = 0; rn < cglobs->MaxCTemps; ++rn) {
3093 if (*cop != (TempVar | rn)) {
3094 *up++ = *cop++ = NIL;
3101 case restore_tmps_and_skip_op:
3102 case restore_tmps_op:
3109 PInstr *mycpc = cglobs->cint.cpc,
3110 *oldCodeStart = cglobs->cint.CodeStart;
3114 cglobs->cint.CodeStart = cglobs->cint.BlobsStart;
3115 cglobs->cint.cpc = cglobs->cint.icpc;
3117 for (i = 1; i < cglobs->MaxCTemps; ++i) {
3118 if (cglobs->Contents[i])
3121 Yap_emit(label_op, ++cglobs->labelno, Zero, &cglobs->cint);
3122 mycpc->rnd1 = cglobs->labelno;
3123 rn = copy_live_temps_bmap(max, cglobs);
3124 cglobs->cint.icpc = cglobs->cint.cpc;
3125 cglobs->cint.BlobsStart = cglobs->cint.CodeStart;
3126 cglobs->cint.cpc = mycpc;
3127 cglobs->cint.CodeStart = oldCodeStart;
3132 if (cglobs->cint.cpc->nextInst)
3133 cglobs->cint.cpc = cglobs->cint.cpc->nextInst;
3147 PInstr *initial = oldpc, *dealloc_founds[16];
3160 PInstr *where = initial->nextInst->nextInst;
3162 dealloc_founds[--d_founds]->op = nop_op;
3163 if (where == pc || oldpc == initial->nextInst)
3165 oldpc->nextInst = initial->nextInst;
3166 initial->nextInst->nextInst = pc;
3167 initial->nextInst = where;
3187 dealloc_founds[d_founds++] = pc;
3198static void c_optimize(
PInstr *pc) {
3207 while (pc != NULL) {
3208 PInstr *tpc = pc->nextInst;
3217 PInstr *npc = pc->nextInst;
3222 if (npc->op == f_0_op) {
3223 npc->rnd1 = pc->rnd1;
3232 if (ve->KindOfVE == TempVar) {
3233 UInt argno = ve->NoOfVE & MaskVarAdrs;
3234 if (argno && argno == pc->rnd2) {
3241 case save_pair_op: {
3242 Term ve = (Term)pc->rnd1;
3243 PInstr *npc = pc->nextInst;
3245 if (((
Ventry *)ve)->RCountOfVE <= 1)
3250 npc->op = save_pair_op;
3251 npc->rnd1 = (CELL)ve;
3254 case save_appl_op: {
3255 Term ve = (Term)pc->rnd1;
3256 PInstr *npc = pc->nextInst;
3258 if (((
Ventry *)ve)->RCountOfVE <= 1)
3263 npc->op = save_appl_op;
3264 npc->rnd1 = (CELL)ve;
3271 case unify_last_var_op:
3279 v = (
Ventry *)(pc->rnd1);
3280 if (v->KindOfVE == VoidVar && onTail) {
3287 v = (
Ventry *)(pc->rnd1);
3288 if (!(v->FlagsOfVE & GlobalVal))
3289 pc->op = unify_local_op;
3292 case unify_last_val_op:
3293 v = (
Ventry *)(pc->rnd1);
3294 if (!(v->FlagsOfVE & GlobalVal))
3295 pc->op = unify_last_local_op;
3299 v = (
Ventry *)(pc->rnd1);
3300 if (!(v->FlagsOfVE & GlobalVal))
3301 pc->op = write_local_op;
3305 if (FALSE && onTail == 1) {
3310 PInstr *p = pc->nextInst;
3312 while (p != NIL && p->op == nop_op)
3314 if (p != NIL && p->op == pop_op) {
3315 pc->rnd1 += p->rnd1;
3316 pc->nextInst = p->nextInst;
3323 case unify_last_atom_op:
3326 case unify_last_num_op:
3328 case unify_float_op:
3329 case unify_last_float_op:
3330 case write_float_op:
3331 case unify_longint_op:
3332 case unify_string_op:
3333 case unify_bigint_op:
3334 case unify_last_longint_op:
3335 case unify_last_string_op:
3336 case unify_last_bigint_op:
3337 case write_longint_op:
3338 case write_string_op:
3339 case write_bigint_op:
3342 case unify_struct_op:
3343 case write_struct_op:
3344 case write_unsafe_op:
3345 case unify_last_list_op:
3346 case write_last_list_op:
3347 case unify_last_struct_op:
3348 case write_last_struct_op:
3361 }
while (pc != NULL);
3364 while (pc != NULL) {
3365 if (pc->op == allocate_op) {
3366 push_allocate(pc, opc);
3374yamop *Yap_cclause(
volatile Term inp_clause, Int NOfArgs, Term mod,
3375 volatile Term src) {
3383 volatile int maxvnum = 512;
3390#ifdef TABLING_INNER_CUTS
3392 cglobs.cut_mark = &cglobs_cut_mark;
3396 if (LOCAL_ActiveError)
3397 LOCAL_Error_TYPE = YAP_NO_ERROR;
3398 if ((botch_why = sigsetjmp(cglobs.cint.CompilerBotch, 0))) {
3399 restore_machine_regs();
3400 reset_vars(cglobs.vtable);
3401 Yap_ReleaseCMem(&cglobs.cint);
3402 switch (botch_why) {
3403 case OUT_OF_STACK_BOTCH:
3406 Int osize = 2 *
sizeof(CELL) * (ASP - HR);
3410 YAPLeaveCriticalSection();
3412 LOCAL_Error_TYPE = RESOURCE_ERROR_STACK;
3414 if (osize > ASP - HR) {
3415 if (!Yap_growstack(2 *
sizeof(CELL) * (ASP - HR))) {
3416 LOCAL_Error_TYPE = RESOURCE_ERROR_STACK;
3419 YAPEnterCriticalSection();
3424 case OUT_OF_AUX_BOTCH:
3426 YAPLeaveCriticalSection();
3429 if (!Yap_ExpandPreAllocCodeSpace(LOCAL_Error_Size, NULL, TRUE)) {
3430 LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK;
3432 YAPEnterCriticalSection();
3436 case OUT_OF_TEMPS_BOTCH:
3438 if (maxvnum < 16 * 1024) {
3444 case OUT_OF_HEAP_BOTCH:
3448 YAPLeaveCriticalSection();
3449 if (!Yap_growheap(FALSE, LOCAL_Error_Size, NULL)) {
3450 LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP;
3453 YAPEnterCriticalSection();
3457 case OUT_OF_TRAIL_BOTCH:
3461 YAPLeaveCriticalSection();
3462 if (!Yap_growtrail(LOCAL_TrailTop - (ADDR)TR, FALSE)) {
3463 LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL;
3466 YAPEnterCriticalSection();
3474 my_clause = inp_clause;
3476 LOCAL_Error_TYPE = YAP_NO_ERROR;
3479 cglobs.cint.CodeStart = cglobs.cint.cpc = NULL;
3480 cglobs.cint.BlobsStart = cglobs.cint.icpc = NULL;
3481 cglobs.cint.dbterml = NULL;
3482 cglobs.cint.blks = NULL;
3483 cglobs.cint.label_offset = NULL;
3484 cglobs.cint.freep = cglobs.cint.freep0 =
3485 (
char *)(HR + maxvnum + (
sizeof(Int) /
sizeof(CELL)) * MaxTemps +
3487 cglobs.cint.success_handler = 0L;
3488 if (ASP <= CellPtr(cglobs.cint.freep) + 256) {
3489 cglobs.vtable = NULL;
3490 LOCAL_Error_Size = (256 + maxvnum) *
sizeof(CELL);
3491 save_machine_regs();
3492 siglongjmp(cglobs.cint.CompilerBotch, 3);
3494 cglobs.Uses = (Int *)(HR + maxvnum);
3496 (Term *)(HR + maxvnum + (
sizeof(Int) /
sizeof(CELL)) * MaxTemps);
3497 cglobs.curbranch = cglobs.onbranch = 0;
3498 cglobs.branch_pointer = cglobs.parent_branches;
3499 cglobs.or_found = FALSE;
3500 cglobs.max_args = 0;
3503 cglobs.needs_env = FALSE;
3508 cglobs.vtable = NULL;
3509 cglobs.common_exps = NULL;
3510 cglobs.n_common_exps = 0;
3511 cglobs.labelno = 0L;
3512 cglobs.is_a_fact = FALSE;
3513 cglobs.hasdbrefs = FALSE;
3514 if (IsVarTerm(my_clause)) {
3515 Yap_ThrowError(INSTANTIATION_ERROR, my_clause,
" clause is not bound");
3518 if (IsApplTerm(my_clause) && FunctorOfTerm(my_clause) == FunctorAssert) {
3519 head = ArgOfTerm(1, my_clause);
3520 body = ArgOfTerm(2, my_clause);
3522 head = my_clause, body = MkAtomTerm(AtomTrue);
3524 if (IsVarTerm(head) || IsPairTerm(head) || IsIntTerm(head) ||
3525 IsFloatTerm(head) || IsRefTerm(head)) {
3526 Yap_ThrowError(TYPE_ERROR_CALLABLE, head,
"clause head should be atom or compound term");
3529 head = Yap_YapStripModule(head, &mod);
3530 if (IsAtomTerm(head)) {
3531 Atom ap = AtomOfTerm(head);
3532 cglobs.cint.CurrentPred = RepPredProp(PredPropByAtom(ap, mod));
3534 Functor f = FunctorOfTerm(head);
3535 cglobs.cint.CurrentPred =
3536 RepPredProp(PredPropByFunc(f, mod));
3539 PELOCK(52, cglobs.cint.CurrentPred);
3540 if ((cglobs.cint.CurrentPred->PredFlags & ProfiledPredFlag) ||
3542 (cglobs.cint.CurrentPred->cs.p_code.FirstClause == NIL))) {
3545 }
else if ((cglobs.cint.CurrentPred->PredFlags & CountPredFlag) ||
3547 (cglobs.cint.CurrentPred->cs.p_code.FirstClause == NIL))) {
3554 UNLOCK(cglobs.cint.CurrentPred->PELock);
3556 cglobs.is_a_fact = (body == MkAtomTerm(AtomTrue));
3559 c_head(head, &cglobs);
3561 if (cglobs.is_a_fact && !cglobs.vtable) {
3563 PELOCK(53, cglobs.cint.CurrentPred);
3564 if (is_tabled(cglobs.cint.CurrentPred))
3565 Yap_emit(table_new_answer_op, Zero, cglobs.cint.CurrentPred->ArityOfPE,
3569 Yap_emit(procceed_op, Zero, Zero, &cglobs.cint);
3571 UNLOCK(cglobs.cint.CurrentPred->PELock);
3574 if (cglobs.cint.BlobsStart != NULL) {
3575 cglobs.cint.cpc->nextInst = cglobs.cint.BlobsStart;
3576 cglobs.cint.BlobsStart = NULL;
3578 if (LOCAL_ErrorMessage)
3581 if (cglobs.space_op)
3582 cglobs.space_op->rnd1 = cglobs.space_used;
3585 if (GLOBAL_Option[
'g' - 96])
3586 Yap_ShowCode(&cglobs.cint);
3589#ifdef TABLING_INNER_CUTS
3590 Yap_emit(nop_op, Zero, Zero, &cglobs.cint);
3591 cglobs.cut_mark->op = clause_with_cut_op;
3593 Yap_emit(allocate_op, Zero, Zero, &cglobs.cint);
3597 Yap_emit(body_op, Zero, Zero, &cglobs.cint);
3600 c_body(body, mod, &cglobs);
3603 if (cglobs.space_op)
3604 cglobs.space_op->rnd1 = cglobs.space_used;
3606 if (cglobs.cint.BlobsStart != NULL) {
3607 cglobs.cint.cpc->nextInst = cglobs.cint.BlobsStart;
3608 cglobs.cint.BlobsStart = NULL;
3611 reset_vars(cglobs.vtable);
3616 if (LOCAL_ErrorMessage)
3619 if (GLOBAL_Option[
'g' - 96])
3620 Yap_ShowCode(&cglobs.cint);
3625 if (cglobs.cint.BlobsStart != NULL) {
3626 cglobs.cint.cpc->nextInst = cglobs.cint.BlobsStart;
3627 cglobs.cint.BlobsStart = NULL;
3628 while (cglobs.cint.cpc->nextInst != NULL)
3629 cglobs.cint.cpc = cglobs.cint.cpc->nextInst;
3633 c_optimize(cglobs.cint.CodeStart);
3635 if (GLOBAL_Option[
'f' - 96])
3636 Yap_ShowCode(&cglobs.cint);
3644 codigo_eam(&cglobs);
3649 acode = Yap_assemble(ASSEMBLING_CLAUSE, src, cglobs.cint.CurrentPred,
3650 (cglobs.is_a_fact && !cglobs.hasdbrefs &&
3651 !(cglobs.cint.CurrentPred->PredFlags & TabledPredFlag)),
3652 &cglobs.cint, cglobs.labelno + 1);
3654 Yap_ReleaseCMem(&cglobs.cint);
3655 if (acode == NULL) {
3656 Yap_ThrowError(SYSTEM_ERROR_COMPILER,src,
"assembler did not generate code");
@ source
If true maintain the source for all clauses.
@ call_counting
Predicates compiled with this flag set maintain a counter on the numbers of proceduree calls and of r...