view test/conv1.c @ 725:3f1f6c0610c1

goto with enviornment syntax changed.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 20 Aug 2009 16:39:02 +0900
parents 6b7372e17970
children 07dce42b67af
line wrap: on
line source

#include "stdio.h"

static int loop;
#define __environment _CbC_environment
#define __return _CbC_return

#if 1 // def __micro_c__
#define CC_ONLY 0
#else
#define CC_ONLY 1
#endif

/* classical function call case (0) */

f0(int i) {
    int k,j;
    k = 3+i;
    j = g0(i+3);
    return k+4+j;
}

g0(int i) {
    return h0(i+4)+i;
}

h0(int i) {
    return i+4;
}

#if !CC_ONLY

/* straight conversion case (1) */

typedef char *stack;

struct cont_interface { // General Return Continuation
    __code (*ret)();
};

__code f(int i,stack sp) {
    int k,j;
    k = 3+i;
    goto f_g0(i,k,sp);
}

struct f_g0_interface {  // Specialized Return Continuation
    __code (*ret)();
    int i_,k_,j_;
};

__code f_g1(int j,stack sp);

__code f_g0(int i,int k,stack sp) { // Caller
    struct f_g0_interface *c = 
	(struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface));

    c->ret = f_g1;
    c->k_ = k;
    c->i_ = i;

    goto g(i+3,sp);
}

__code f_g1(int j,stack sp) {  // Continuation 
    struct f_g0_interface *c = (struct f_g0_interface *)sp;
    int k = c->k_;
    sp+=sizeof(struct f_g0_interface);
    c = (struct f_g0_interface *)sp;
    goto (c->ret)(k+4+j,sp);
}

__code g_h1(int j,stack sp);

__code g(int i,stack sp) { // Caller
    struct f_g0_interface *c = 
	(struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface));

    c->ret = g_h1;
    c->i_ = i;

    goto h(i+3,sp);
}

__code g_h1(int j,stack sp) {  // Continuation 
    struct f_g0_interface *c = (struct f_g0_interface *)sp;
    int i = c->i_;
    sp+=sizeof(struct f_g0_interface);
    c = (struct f_g0_interface *)sp;
    goto (c->ret)(j+i,sp);
}

__code h(int i,stack sp) {
    struct f_g0_interface *c = (struct f_g0_interface *)sp;
    goto (c->ret)(i+4,sp);
}

struct main_continuation { // General Return Continuation
    __code (*ret)();
    __code (*main_ret)();
    void *env;
};

__code main_return(int i,stack sp) {
    if (loop-->0)
	goto f(233,sp);
    printf("#0103:%d\n",i);
    goto (( (struct main_continuation *)sp)->main_ret)(0,
           ((struct main_continuation *)sp)->env);
}

/* little optimzation without stack continuation (2) */

__code f2(int i,char *sp) {
    int k,j;
    k = 3+i;
    goto g2(i,k,i+3,sp);
}

__code g2(int i,int k,int j,char *sp) {
    j = j+4;
    goto h2(i,k+4+j,sp);
}

__code h2_1(int i,int k,int j,char *sp) {
    goto main_return2(i+j,sp);
}

__code h2(int i,int k,char *sp) {
    goto h2_1(i,k,i+4,sp);
}

__code main_return2(int i,stack sp) {
    if (loop-->0)
	goto f2(233,sp);
    printf("#0132:%d\n",i);
    goto (( (struct main_continuation *)sp)->main_ret)(0,
           ((struct main_continuation *)sp)->env);
}

/* little optimizaed case (3) */

__code f2_1(int i,char *sp) {
    int k,j;
    k = 3+i;
    goto g2_1(k,i+3,sp);
}

__code g2_1(int k,int i,char *sp) {
    goto h2_11(k,i+4,sp);
}

__code f2_0_1(int k,int j,char *sp);
__code h2_1_1(int i,int k,int j,char *sp) {
    goto f2_0_1(k,i+j,sp);
}

__code h2_11(int i,int k,char *sp) {
    goto h2_1_1(i,k,i+4,sp);
}

__code f2_0_1(int k,int j,char *sp) {
    goto (( (struct cont_interface *)sp)->ret)(k+4+j,sp);
}

__code main_return2_1(int i,stack sp) {
    if (loop-->0)
        goto f2_1(233,sp);
    printf("#0165:%d\n",i);
    goto (( (struct main_continuation *)sp)->main_ret)(0,
           ((struct main_continuation *)sp)->env);
}

#define STACK_SIZE 2048
char main_stack[STACK_SIZE];
#define stack_last (main_stack+STACK_SIZE)

#endif

#define LOOP_COUNT 10000000

main(int ac,char *av[])
{
#if !CC_ONLY
    struct main_continuation *cont;
    stack sp = stack_last;
#endif
    int sw;
    int j;
    if (ac==2) sw = atoi(av[1]);
    else sw=3;

    if (sw==0) {
	for(loop=0;loop<LOOP_COUNT;loop++) {
	   j = f0(233);
	}
	printf("#0193:%d\n",j);
#if !CC_ONLY
    } else if (sw==1) {
	loop = LOOP_COUNT;
	sp -= sizeof(*cont);
	cont = (struct main_continuation *)sp;
	cont->ret = main_return;
	cont->main_ret = __return;
	cont->env = __environment;
	goto f(233,sp);
    } else if (sw==2) {
	loop = LOOP_COUNT;
	sp -= sizeof(*cont);
	cont = (struct main_continuation *)sp;
	cont->ret = main_return2;
	cont->main_ret = __return;
	cont->env = __environment;
	goto f2(233,sp);
    } else if (sw==3) {
	loop = LOOP_COUNT;
	sp -= sizeof(*cont);
	cont = (struct main_continuation *)sp;
	cont->ret = main_return2_1;
	cont->main_ret = __return;
	cont->env = __environment;
	goto f2_1(233,sp);
#endif
    }
return 0;
}

/* end */