* Hugs version 1.4, December 1997
*
* $RCSfile: codegen.c,v $
- * $Revision: 1.3 $
- * $Date: 1999/02/03 17:08:25 $
+ * $Revision: 1.8 $
+ * $Date: 1999/07/06 15:24:36 $
* ------------------------------------------------------------------------*/
#include "prelude.h"
#include "Assembler.h"
#include "link.h"
+#include "Rts.h" /* IF_DEBUG */
+#include "RtsFlags.h"
/* --------------------------------------------------------------------------
* Local function prototypes:
static AsmBCO cgAlts ( AsmSp root, AsmSp sp, List alts );
static void testPrimPats ( AsmBCO bco, AsmSp root, List pats, StgExpr e );
-static void cgPrimAlt ( AsmBCO bco, AsmSp root, List vs, StgExpr e );
+//static void cgPrimAlt ( AsmBCO bco, AsmSp root, List vs, StgExpr e );
static AsmBCO cgLambda ( StgExpr e );
static AsmBCO cgRhs ( StgRhs rhs );
static void beginTop ( StgVar v );
static void endTop ( StgVar v );
+static StgVar currentTop;
+
/* --------------------------------------------------------------------------
*
* ------------------------------------------------------------------------*/
+static Cell cptrFromName ( Name n )
+{
+ char buf[1000];
+ void* p;
+ Module m = name(n).mod;
+ Text mt = module(m).text;
+ sprintf(buf,"%s_%s_closure",
+ textToStr(mt), textToStr(name(n).text) );
+ p = lookupOTabName ( m, buf );
+ if (!p) {
+ ERRMSG(0) "Can't find object symbol %s", buf
+ EEND;
+ }
+ return mkCPtr(p);
+}
+
static Bool varHasClosure( StgVar v )
{
return asmObjectHasClosure((AsmClosure*)ptrOf(stgVarInfo(v)));
static Void pushVar( AsmBCO bco, StgVar v )
{
- Cell info = stgVarInfo(v);
- assert(isStgVar(v));
- if (isPtr(info)) {
- asmClosure(bco,ptrOf(info));
- } else if (isInt(info)) {
- asmVar(bco,intOf(info),repOf(v));
+ Cell info;
+
+ if (!(isStgVar(v) || isCPtr(v))) {
+ assert(isStgVar(v) || isCPtr(v));
+ }
+
+ if (isCPtr(v)) {
+ asmGHCClosure(bco, cptrOf(v));
} else {
- internal("pushVar");
- }
+ info = stgVarInfo(v);
+ if (isPtr(info)) {
+ asmClosure(bco,ptrOf(info));
+ } else if (isInt(info)) {
+ asmVar(bco,intOf(info),repOf(v));
+ } else {
+ internal("pushVar");
+ }
+ }
}
static Void pushAtom( AsmBCO bco, StgAtom e )
pushVar(bco,e);
break;
case NAME:
- pushVar(bco,name(e).stgVar);
+ if (nonNull(name(e).stgVar))
+ pushVar(bco,name(e).stgVar); else
+ pushVar(bco,cptrFromName(e));
break;
case CHARCELL:
asmConstChar(bco,charOf(e));
case INTCELL:
asmConstInt(bco,intOf(e));
break;
-#if BIGNUM_IS_INTEGER
case BIGCELL:
asmConstInteger(bco,bignumToString(e));
break;
-#elif BIGNUM_IS_INT64
- case BIGCELL:
- asmConstInt64(bco,bignumOf(e));
- break;
-#else
-#warning What is BIGNUM?
-#endif
case FLOATCELL:
#if 0
asmConstFloat(bco,e); /* ToDo: support both float and double! */
asmClosure(bco,asmStringObj(textToStr(textOf(e))));
#endif
break;
+ case CPTRCELL:
+ asmGHCClosure(bco,cptrOf(e));
+ break;
case PTRCELL:
asmConstAddr(bco,ptrOf(e));
break;
static AsmBCO cgAlts( AsmSp root, AsmSp sp, List alts )
{
- AsmBCO bco = asmBeginContinuation(sp);
+#ifdef CRUDE_PROFILING
+ AsmBCO bco = asmBeginContinuation(sp, currentTop + 1000000000);
+#else
+ AsmBCO bco = asmBeginContinuation(sp, alts);
+#endif
/* ppStgAlts(alts); */
for(; nonNull(alts); alts=tl(alts)) {
StgCaseAlt alt = hd(alts);
- StgPat pat = stgCaseAltPat(alt);
- StgExpr body = stgCaseAltBody(alt);
- if (isDefaultPat(pat)) {
- AsmSp begin = asmBeginAlt(bco);
- cgBind(bco,pat);
- cgExpr(bco,root,body);
+ if (isDefaultAlt(alt)) {
+ cgBind(bco,stgDefaultVar(alt));
+ cgExpr(bco,root,stgDefaultBody(alt));
asmEndContinuation(bco);
return bco; /* ignore any further alternatives */
} else {
- StgDiscr con = stgPatDiscr(pat);
- List vs = stgPatVars(pat);
+ StgDiscr con = stgCaseAltCon(alt);
+ List vs = stgCaseAltVars(alt);
AsmSp begin = asmBeginAlt(bco);
- AsmPc fix = asmTest(bco,stgDiscrTag(con)); /* ToDo: omit in single constructor types! */
- cgBind(bco,pat);
+ AsmPc fix = asmTest(bco,stgDiscrTag(con));
+ /* ToDo: omit in single constructor types! */
+ asmBind(bco,PTR_REP); /* Adjust simulated sp to acct for return value */
if (isBoxingCon(con)) {
setPos(hd(vs),asmUnbox(bco,boxingConRep(con)));
} else {
asmBeginUnpack(bco);
- map1Proc(cgBind,bco,rev(vs));
+ map1Proc(cgBind,bco,reverse(vs));
asmEndUnpack(bco);
}
- cgExpr(bco,root,body);
+ cgExpr(bco,root,stgCaseAltBody(alt));
asmEndAlt(bco,begin);
asmFixBranch(bco,fix);
}
if (isNull(pats)) {
cgExpr(bco,root,e);
} else {
- StgPrimPat pat = hd(pats);
+ StgVar pat = hd(pats);
if (isInt(stgVarBody(pat))) {
/* asmTestInt leaves stack unchanged - so no need to adjust it */
AsmPc tst = asmTestInt(bco,getPos(pat),intOf(stgVarBody(pat)));
}
}
+#if 0 /* appears to be unused */
static void cgPrimAlt( AsmBCO bco, AsmSp root, List vs, StgExpr e )
{
assert(0); /* ToDo: test for patterns */
map1Proc(cgBind,bco,vs); /* ToDo: are these in right order? */
cgExpr(bco,root,e);
}
+#endif
+
static AsmBCO cgLambda( StgExpr e )
{
- AsmBCO bco = asmBeginBCO();
+ AsmBCO bco = asmBeginBCO(e);
AsmSp root = asmBeginArgCheck(bco);
- map1Proc(cgBind,bco,rev(stgLambdaArgs(e)));
+ map1Proc(cgBind,bco,reverse(stgLambdaArgs(e)));
asmEndArgCheck(bco,root);
/* ppStgExpr(e); */
static AsmBCO cgRhs( StgRhs rhs )
{
- AsmBCO bco = asmBeginBCO( );
+ AsmBCO bco = asmBeginBCO(rhs );
AsmSp root = asmBeginArgCheck(bco);
asmEndArgCheck(bco,root);
return bco;
}
+
static Void cgExpr( AsmBCO bco, AsmSp root, StgExpr e )
{
+ //printf("cgExpr:");ppStgExpr(e);printf("\n");
switch (whatIs(e)) {
case LETREC:
{
/* No need to use return address or to Slide */
AsmSp beginPrim = asmBeginPrim(bco);
- map1Proc(pushAtom,bco,rev(stgPrimArgs(scrut)));
+ map1Proc(pushAtom,bco,reverse(stgPrimArgs(scrut)));
asmEndPrim(bco,(AsmPrim*)name(stgPrimOp(scrut)).primop,beginPrim);
for(; nonNull(alts); alts=tl(alts)) {
StgPrimAlt alt = hd(alts);
- List pats = stgPrimAltPats(alt);
+ List pats = stgPrimAltVars(alt);
StgExpr body = stgPrimAltBody(alt);
AsmSp altBegin = asmBeginAlt(bco);
- map1Proc(cgBind,bco,rev(pats));
+ map1Proc(cgBind,bco,reverse(pats));
testPrimPats(bco,root,pats,body);
asmEndAlt(bco,altBegin);
}
for(; nonNull(alts); alts=tl(alts)) {
StgPrimAlt alt = hd(alts);
- List pats = stgPrimAltPats(alt);
+ List pats = stgPrimAltVars(alt);
StgExpr body = stgPrimAltBody(alt);
AsmSp altBegin = asmBeginAlt(bco);
map1Proc(cgBind,bco,pats);
case STGAPP: /* Tail call */
{
AsmSp env = asmBeginEnter(bco);
- map1Proc(pushAtom,bco,rev(stgAppArgs(e)));
+ map1Proc(pushAtom,bco,reverse(stgAppArgs(e)));
pushAtom(bco,stgAppFun(e));
asmEndEnter(bco,env,root);
break;
case STGPRIM: /* Tail call again */
{
AsmSp beginPrim = asmBeginPrim(bco);
- map1Proc(pushAtom,bco,rev(stgPrimArgs(e)));
+ map1Proc(pushAtom,bco,reverse(stgPrimArgs(e)));
asmEndPrim(bco,(AsmPrim*)name(e).primop,beginPrim);
/* map1Proc(cgBind,bco,rs_vars); */
assert(0); /* asmReturn_retty(); */
}
}
+#define M_ITBLNAMES 35000
+
+void* itblNames[M_ITBLNAMES];
+int nItblNames = 0;
+
/* allocate space for top level variable
* any change requires a corresponding change in 'build'.
*/
pushAtom(bco,hd(args));
setPos(v,asmBox(bco,boxingConRep(con)));
} else {
- setPos(v,asmAllocCONSTR(bco,stgConInfo(con)));
+
+ void* vv = stgConInfo(con);
+ if (!(nItblNames < (M_ITBLNAMES-2)))
+ internal("alloc -- M_ITBLNAMES too small");
+ if (isName(con)) {
+ itblNames[nItblNames++] = vv;
+ itblNames[nItblNames++] = textToStr(name(con).text);
+ } else
+ if (isTuple(con)) {
+ char* cc = malloc(10);
+ assert(cc);
+ sprintf(cc, "Tuple%d", tupleOf(con) );
+ itblNames[nItblNames++] = vv;
+ itblNames[nItblNames++] = cc;
+ } else
+ assert ( /* cant identify constructor name */ 0 );
+
+ setPos(v,asmAllocCONSTR(bco, vv));
}
break;
}
- case STGAPP:
- setPos(v,asmAllocAP(bco,length(stgAppArgs(rhs))));
+ case STGAPP: {
+ Int totSizeW = 0;
+ List bs = stgAppArgs(rhs);
+ for (; nonNull(bs); bs=tl(bs)) {
+ if (isName(hd(bs))) {
+ totSizeW += 1;
+ } else {
+ ASSERT(whatIs(hd(bs))==STGVAR);
+ totSizeW += asmRepSizeW( charOf(stgVarRep(hd(bs))) );
+ }
+ }
+ setPos(v,asmAllocAP(bco,totSizeW));
+ //ORIGINALLY:setPos(v,asmAllocAP(bco,length(stgAppArgs(rhs))));
break;
+ }
case LAMBDA: /* optimisation */
setObj(v,cgLambda(rhs));
break;
{
StgRhs rhs = stgVarBody(v);
assert(isStgVar(v));
+
switch (whatIs(rhs)) {
case STGCON:
{
doNothing(); /* already done in alloc */
} else {
AsmSp start = asmBeginPack(bco);
- map1Proc(pushAtom,bco,rev(args));
+ map1Proc(pushAtom,bco,reverse(args));
asmEndPack(bco,getPos(v),start,stgConInfo(con));
}
return;
}
case STGAPP:
{
+ Bool itsaPAP;
StgVar fun = stgAppFun(rhs);
+ StgVar fun0 = fun;
List args = stgAppArgs(rhs);
if (isName(fun)) {
- fun = name(fun).stgVar;
+ if (nonNull(name(fun).stgVar))
+ fun = name(fun).stgVar; else
+ fun = cptrFromName(fun);
}
- if (nonNull(stgVarBody(fun))
- && whatIs(stgVarBody(fun)) == LAMBDA
- && length(stgLambdaArgs(stgVarBody(fun))) > length(args)) {
+
+ if (isCPtr(fun)) {
+ assert(isName(fun0));
+ itsaPAP = name(fun0).arity > length(args);
+fprintf ( stderr, "nativeCall: name %s, arity %d, args %d\n",
+ nameFromOPtr(cptrOf(fun)), name(fun0).arity, length(args) );
+ } else {
+ itsaPAP = FALSE;
+ if (nonNull(stgVarBody(fun))
+ && whatIs(stgVarBody(fun)) == LAMBDA
+ && length(stgLambdaArgs(stgVarBody(fun))) > length(args)
+ )
+ itsaPAP = TRUE;
+ }
+
+ if (itsaPAP) {
AsmSp start = asmBeginMkPAP(bco);
- map1Proc(pushAtom,bco,rev(args));
+ map1Proc(pushAtom,bco,reverse(args));
pushAtom(bco,fun);
asmEndMkPAP(bco,getPos(v),start); /* optimisation */
} else {
AsmSp start = asmBeginMkAP(bco);
- map1Proc(pushAtom,bco,rev(args));
+ map1Proc(pushAtom,bco,reverse(args));
pushAtom(bco,fun);
asmEndMkAP(bco,getPos(v),start);
}
* for each top level variable - this should be simpler!
* ------------------------------------------------------------------------*/
+#if 0 /* appears to be unused */
static void cgAddVar( AsmObject obj, StgAtom v )
{
if (isName(v)) {
assert(isStgVar(v));
asmAddPtr(obj,getObj(v));
}
+#endif
+
/* allocate AsmObject for top level variables
* any change requires a corresponding change in endTop
{
StgRhs rhs;
assert(isStgVar(v));
+ currentTop = v;
rhs = stgVarBody(v);
switch (whatIs(rhs)) {
case STGCON:
{
- List as = stgConArgs(rhs);
+ //List as = stgConArgs(rhs);
setObj(v,asmBeginCon(stgConInfo(stgConCon(rhs))));
break;
}
case LAMBDA:
- setObj(v,asmBeginBCO());
+#ifdef CRUDE_PROFILING
+ setObj(v,asmBeginBCO(currentTop));
+#else
+ setObj(v,asmBeginBCO(rhs));
+#endif
break;
default:
setObj(v,asmBeginCAF());
static void endTop( StgVar v )
{
StgRhs rhs = stgVarBody(v);
- ppStgRhs(rhs);
+ currentTop = v;
switch (whatIs(rhs)) {
case STGCON:
{
/* ToDo: merge this code with cgLambda */
AsmBCO bco = (AsmBCO)getObj(v);
AsmSp root = asmBeginArgCheck(bco);
- map1Proc(cgBind,bco,rev(stgLambdaArgs(rhs)));
+ map1Proc(cgBind,bco,reverse(stgLambdaArgs(rhs)));
asmEndArgCheck(bco,root);
cgExpr(bco,root,stgLambdaBody(rhs));
static void zap( StgVar v )
{
- stgVarBody(v) = NIL;
+ // ToDo: reinstate
+ // stgVarBody(v) = NIL;
}
/* external entry point */
Void cgBinds( List binds )
{
+ List b;
+ int i;
+
+#if 0
+ if (lastModule() != modulePrelude) {
+ printf("\n\ncgBinds: before ll\n\n" );
+ for (b=binds; nonNull(b); b=tl(b)) {
+ printStg ( stdout, hd(b) ); printf("\n\n");
+ }
+ }
+#endif
+
binds = liftBinds(binds);
- mapProc(beginTop,binds);
- mapProc(endTop,binds);
- mapProc(zap,binds);
+
+#if 0
+ if (lastModule() != modulePrelude) {
+ printf("\n\ncgBinds: after ll\n\n" );
+ for (b=binds; nonNull(b); b=tl(b)) {
+ printStg ( stdout, hd(b) ); printf("\n\n");
+ }
+ }
+#endif
+
+ for (b=binds,i=0; nonNull(b); b=tl(b),i++) {
+ beginTop(hd(b));
+ }
+
+ for (b=binds,i=0; nonNull(b); b=tl(b),i++) {
+ //printf("endTop %s\n", maybeName(hd(b)));
+ endTop(hd(b));
+ }
+
+ //mapProc(zap,binds);
}
/* --------------------------------------------------------------------------