269 lines
5.3 KiB
C
269 lines
5.3 KiB
C
/*************************************************************************
|
|
* *
|
|
* Yap Prolog *
|
|
* *
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
* *
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* File: jit_traced.c *
|
|
* comments: Portable abstract machine interpreter *
|
|
* Last rev: $Date: 2008-08-13 01:16:26 $,$Author: vsc $ *
|
|
* *
|
|
*************************************************************************/
|
|
|
|
|
|
/**
|
|
|
|
@file jit_traced.c
|
|
|
|
@defgroup JIT_Impl Just-In-Time Compiler Implementation
|
|
@ingroup
|
|
|
|
We next discuss several issues on trying to make Prolog programs run
|
|
fast in YAP. We assume two different programming styles:
|
|
|
|
+ Execution of <em>deterministic</em> programs ofte
|
|
n
|
|
boils down to a recursive loop of the form:
|
|
|
|
~~~~~
|
|
loop(Env) :-
|
|
do_something(Env,NewEnv),
|
|
loop(NewEnv).
|
|
~~~~~
|
|
*/
|
|
|
|
|
|
|
|
#if YAP_JIT
|
|
|
|
#define YAP_TRACED 1
|
|
#define IN_ABSMI_C 1
|
|
#define HAS_CACHE_REGS 1
|
|
|
|
#include "absmi.h"
|
|
#include "heapgc.h"
|
|
|
|
#include "cut_c.h"
|
|
|
|
Int traced_absmi(void);
|
|
|
|
#ifdef PUSH_X
|
|
#else
|
|
|
|
/* keep X as a global variable */
|
|
|
|
Term Yap_XREGS[MaxTemps]; /* 29 */
|
|
|
|
#endif
|
|
|
|
|
|
// #include "print_preg.h"
|
|
//#include "sprint_op.hpp"
|
|
//#include "print_op.hpp"
|
|
|
|
static Term
|
|
interrupt_pexecute( PredEntry *pen USES_REGS ) {
|
|
return 0;
|
|
}
|
|
|
|
#include "IsGround.h"
|
|
#include "yaam_macros.hpp"
|
|
#include "fprintblock.h"
|
|
|
|
#if YAP_DBG_PREDS
|
|
#include "debug_printers.h"
|
|
#endif
|
|
|
|
// ref to JIT compiler
|
|
JIT_Compiler *J;
|
|
|
|
|
|
extern NativeContext *NativeArea;
|
|
extern IntermediatecodeContext *IntermediatecodeArea;
|
|
|
|
extern CELL l;
|
|
|
|
CELL nnexec;
|
|
|
|
void shutdown_llvm(void);
|
|
|
|
short global;
|
|
yamop* HEADPREG;
|
|
CELL BLOCK;
|
|
CELL BLOCKADDRESS;
|
|
CELL FAILED;
|
|
|
|
#undef SHADOW_P
|
|
#undef SHADOW_CP
|
|
#undef SHADOW_HB
|
|
#undef SHADOW_Y
|
|
#undef SHADOW_S
|
|
|
|
#undef PREG
|
|
#define PREG P
|
|
|
|
#undef CPREG
|
|
#define CPREG CP
|
|
|
|
#undef SREG
|
|
#define SREG S
|
|
|
|
#undef YREG
|
|
#define YREG YENV
|
|
|
|
#undef setregs
|
|
#define setregs()
|
|
|
|
#undef saveregs
|
|
#define saveregs()
|
|
|
|
#include "arith2.h"
|
|
|
|
Int
|
|
traced_absmi(void)
|
|
{
|
|
CACHE_REGS
|
|
|
|
static void *OpAddress[] =
|
|
{
|
|
#define OPCODE(OP,TYPE) && OP
|
|
#include "YapOpcodes.h"
|
|
#undef OPCODE
|
|
};
|
|
|
|
/* The indexing register so that we will not destroy ARG1 without
|
|
* reason */
|
|
#define I_R (XREGS[0])
|
|
|
|
static void *control_labels[] = { &&fail, &&NoStackCut, &&NoStackCommitY, &&NoStackCutE, &&NoStackCutT, &&NoStackEither, &&NoStackExecute, &&NoStackCall, &&NoStackDExecute, &&NoStackDeallocate, &¬railleft, &&NoStackFail, &&NoStackCommitX };
|
|
|
|
#if YAP_STAT_PREDS
|
|
struct timeval timstart, timend;
|
|
struct rusage rustart, ruend;
|
|
#endif
|
|
curtrace = NULL;
|
|
curpreg = NULL;
|
|
globalcurblock = NULL;
|
|
ineedredefinedest = 0;
|
|
NativeArea = (NativeContext*)malloc(sizeof(NativeContext));
|
|
NativeArea->area.p = NULL;
|
|
NativeArea->area.ok = NULL;
|
|
NativeArea->area.pc = NULL;
|
|
#if YAP_STAT_PREDS
|
|
NativeArea->area.nrecomp = NULL;
|
|
NativeArea->area.compilation_time = NULL;
|
|
NativeArea->area.native_size_bytes = NULL;
|
|
NativeArea->area.trace_size_bytes = NULL;
|
|
NativeArea->success = NULL;
|
|
NativeArea->runs = NULL;
|
|
NativeArea->t_runs = NULL;
|
|
#endif
|
|
NativeArea->n = 0;
|
|
IntermediatecodeArea = (IntermediatecodeContext*)malloc(sizeof(IntermediatecodeContext));
|
|
IntermediatecodeArea->area.t = NULL;
|
|
IntermediatecodeArea->area.ok = NULL;
|
|
IntermediatecodeArea->area.isactive = NULL;
|
|
IntermediatecodeArea->area.lastblock = NULL;
|
|
#if YAP_STAT_PREDS
|
|
IntermediatecodeArea->area.profiling_time = NULL;
|
|
#endif
|
|
IntermediatecodeArea->n = 0;
|
|
nnexec = 0;
|
|
l = 0;
|
|
|
|
|
|
|
|
setregs();
|
|
|
|
CACHE_A1();
|
|
|
|
reset_absmi:
|
|
|
|
SP = SP0;
|
|
|
|
/* when we start we are not in write mode */
|
|
|
|
{
|
|
op_numbers opcode = _Ystop;
|
|
goto critical_lbl;
|
|
|
|
//nextop_write:
|
|
|
|
opcode = Yap_op_from_opcode( PREG->y_u.o.opcw );
|
|
goto op_switch;
|
|
|
|
|
|
// nextop:
|
|
|
|
opcode = Yap_op_from_opcode( PREG->opc );
|
|
|
|
op_switch:
|
|
|
|
|
|
switch (opcode) {
|
|
|
|
#if !OS_HANDLES_TR_OVERFLOW
|
|
notrailleft:
|
|
/* if we are within indexing code, the system may have to
|
|
* update a S */
|
|
{
|
|
CELL cut_b;
|
|
|
|
#ifdef SHADOW_S
|
|
S = SREG;
|
|
#endif
|
|
/* YREG was pointing to where we were going to build the
|
|
* next choice-point. The stack shifter will need to know this
|
|
* to move the local stack */
|
|
SET_ASP(YREG, E_CB*sizeof(CELL));
|
|
cut_b = LCL0-(CELL *)(ASP[E_CB]);
|
|
saveregs();
|
|
if(!Yap_growtrail (0, false)) {
|
|
Yap_NilError(OUT_OF_TRAIL_ERROR,"YAP failed to reserve %ld bytes in growtrail",sizeof(CELL) * K16);
|
|
setregs();
|
|
FAIL();
|
|
}
|
|
setregs();
|
|
#ifdef SHADOW_S
|
|
SREG = S;
|
|
#endif
|
|
if (SREG == ASP) {
|
|
SREG[E_CB] = (CELL)(LCL0-cut_b);
|
|
}
|
|
}
|
|
goto reset_absmi;
|
|
|
|
#endif /* OS_HANDLES_TR_OVERFLOW */
|
|
|
|
// move instructions to separate file
|
|
// so that they are easier to analyse.
|
|
#if YAP_JIT
|
|
#include "../C/traced_absmi_insts.h"
|
|
#if YAPOR
|
|
#include "../OPTYap/traced_or.insts.h"
|
|
#endif
|
|
#if TABLING
|
|
#include "../OPTYap/traced_tab.insts.h"
|
|
#include "../OPTYap/traced_tab.tries.insts.h"
|
|
#endif
|
|
#endif
|
|
|
|
default:
|
|
saveregs();
|
|
Yap_Error(SYSTEM_ERROR, MkIntegerTerm(opcode), "trying to execute invalid YAAM instruction %d", opcode);
|
|
setregs();
|
|
FAIL();
|
|
}
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
#endif /* YAP_JIT */
|
|
|