// optimise.h -- interface to aggressive optimiser		-*- C++ -*-
// 
// Author: Ian.Piumarta@INRIA.Fr
//
// Last edited: 2000-11-10 08:22:10 by piumarta on emilia.rd.wdi.disney.com
// 
// BUGS:
// 
//    The optimiser functions should be renamed from "genWhatever()" to
//    "optWhatever()" so that the optimiser and dumb codegen can
//    cohabit peacefully.  (When the more violent optimisations are
//    enabled it is essential that a given method can be recompiled if
//    ever the original optimisation assumptions are invalidated --
//    e.g. when a Context is modified explicitly from Smalltalk -- and
//    this should be FAST, without regard for output code quality.
//    Alternatively, the optimiser could be parameterised to apply only
//    those optimisations that are "safe" in a given situation.)


#ifndef _j_optimise_h
#define _j_optimise_h


#include "archdep.h"


class NativeMethod;


extern void opt_initialise(void);
extern void opt_dumpStack(void);

extern void genReset(void);
extern void genFinalise(int pass);

extern void genBlockEntry(void);
extern void genBlockExit(void);
extern void genRecombine(int stackDepth, bool followsBlock);

extern void genPrologue(NativeMethod *nMeth, bool ctxFlag);
extern void genBlockActivate(NativeMethod *nMeth, size_t nArgs);

extern void genPop(void);
extern void genDup(void);

extern void genLdSelf(bool blockFlag, bool tagFlag);
extern void genLdTrue(void);
extern void genLdFalse(void);
extern void genLdNil(void);

extern void genLdInt(int val);

extern void genLdThisContext(bool blockFlag);

extern void genLdLit(int idx, bool blockFlag);

extern void genLdInst(int idx, bool blockFlag, bool ctxFlag);
extern void genStInst(int idx, bool blockFlag, bool ctxFlag);
extern void genPopInst(int idx, bool blockFlag, bool ctxFlag);
extern void genLdTemp(int idx, bool blockFlag);
extern void genStTemp(int idx, bool blockFlag);
extern void genLdLitInd(int idx, bool blockFlag);
extern void genStLitInd(int idx, bool blockFlag);

extern void genJmp(insn *dst);
extern void genJmpF(insn *dst);
extern void genJmpT(insn *dst);

extern void genSuper(int sidx, int narg);
extern void genSend(int sidx, int narg);
extern void genSpecial(int sidx, int narg);

extern void genRemoteRetTop(void);
extern void genLocalRetTop(void);

extern void genAdd(int pass);
extern void genSubtract(int pass);
extern bool genLessThan(int pass, int jump= 0, insn *dest= 0, insn *next= 0, bool squash= false);
extern bool genGreaterThan(int pass, int jump= 0, insn *dest= 0, insn *next= 0, bool squash= false);
extern bool genLessOrEqual(int pass, int jump= 0, insn *dest= 0, insn *next= 0, bool squash= false);
extern bool genGreaterOrEqual(int pass, int jump= 0, insn *dest= 0, insn *next= 0, bool squash= false);
extern bool genEqual(int pass, int jump= 0, insn *dest= 0, insn *next= 0, bool squash= false);
extern bool genNotEqual(int pass, int jump= 0, insn *dest= 0, insn *next= 0, bool squash= false);
extern void genMultiply(int pass);
extern void genDivide(int pass);
extern void genMod(int pass);
extern void genMakePoint(void);
extern void genBitShift(void);
extern void genDiv(int pass);
extern void genBitAnd(int pass);
extern void genBitOr(int pass);

extern void genAt(void);
extern void genAtPut(void);
extern void genSize(void);
extern void genNext(void);
extern void genNextPut(void);
extern void genAtEnd(void);
extern bool genEquivalent(int jump= 0, const insn *dest= 0, const insn *next= 0,
			  bool squash= false, bool invert= false);
extern void genClass(void);
extern void genLambda(size_t startPC, size_t nArgs, bool blockFlag);
extern void genBlockCopy(int startPC, bool blockFlag);
extern void genValue(void);
extern void genValueWithArg(void);
extern void genDo(void);
extern void genNew(void);
extern void genNewWithArg(void);
extern void genPointX(void);
extern void genPointY(void);


#endif // _j_optimise_h
