/************************************************************************* * * * 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: $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 deterministic 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_TRACED_ABSMI_C 1 // #ifndef _NATIVE #define HAS_CACHE_REGS 1 #include "absmi.h" #include "heapgc.h" #include "cut_c.h" Int traced_absmi(void); #ifndef PUSH_X /* 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; ->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: #if !USE_THREADED_CODE switch (opcode) { #endif #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(RESOURCE_ERROR_TRAIL,"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 // move instructions to separate file // so that they are easier to analyse. #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 #if _NATIVE default: saveregs(); Yap_Error(SYSTEM_ERROR_INTERNAL, MkIntegerTerm(opcode), "trying to execute invalid YAAM instruction %d", opcode); setregs(); FAIL(); } #endif } return (0); } #endif /* YAP_JIT */