Include new instruction execute_cpred to perform tail optimisation for

builtins. Required changes:
- be careful about creeping in deallocate: it may be followed by
something that is not a cut nor a proceed.
- include new instruction in absmi.c: it is a merge of execute and
call_cpred.
- change compiler to generate execute even for C builtins.
- be careful with dexecute: it may not be done if execute_op is a C
builtin.
- if we are in execute_cpred, the garbage collector cannot trust P:
instead it must look at CP to find out the size of the current
environment. The macro gc_P receives that information.
- We don't need to change CP if we do a meta-call from within
execute_cpred (and we in fact cannot). Check places where we do
meta-calls: exec, clause in cdmgr, and lu_recorded.
This commit is contained in:
Vítor Santos Costa
2008-08-28 04:43:00 +01:00
parent ff12e2bdbf
commit 17ba194c1e
21 changed files with 190 additions and 69 deletions

View File

@@ -1224,7 +1224,8 @@ a_p(op_numbers opcode, clause_info *clinfo, yamop *code_p, int pass_no, struct i
return a_e(op, code_p, pass_no);
}
}
if (Flags & CPredFlag) {
if (Flags & CPredFlag &&
opcode == _call) {
code_p = check_alloc(clinfo, code_p, pass_no, cip);
if (clinfo->commit_lab && (Flags & TestPredFlag)) {
if (pass_no) {
@@ -1307,6 +1308,10 @@ a_p(op_numbers opcode, clause_info *clinfo, yamop *code_p, int pass_no, struct i
else if (opcode == _execute ||
opcode == _dexecute) {
if (pass_no) {
if (opcode == _execute &&
(RepPredProp(fe)->PredFlags & CPredFlag)) {
code_p->opc = emit_op(_execute_cpred);
}
code_p->u.pp.p = RepPredProp(fe);
code_p->u.pp.p0 = clinfo->CurrentPred;
}
@@ -2112,13 +2117,14 @@ a_glist(int *do_not_optimise_uatomp, yamop *code_p, int pass_no, struct intermed
return a_r(cip->cpc->rnd2, _get_list, code_p, pass_no);
}
#define NEXTOPC (cip->cpc->nextInst)->op
#define NEXTOPC (cip->cpc->nextInst->op)
static yamop *
a_deallocate(clause_info *clinfo, yamop *code_p, int pass_no, struct intermediates *cip)
{
if (clinfo->alloc_found == 1) {
if (NEXTOPC == execute_op) {
if (NEXTOPC == execute_op &&
!(RepPredProp((Prop)(cip->cpc->nextInst->rnd1))->PredFlags & CPredFlag)) {
cip->cpc = cip->cpc->nextInst;
code_p = a_p(_dexecute, clinfo, code_p, pass_no, cip);
} else