542 lines
28 KiB
C++
542 lines
28 KiB
C++
/*
|
|
* amijit.h
|
|
*
|
|
* Created on: Jan 9, 2015
|
|
* Author: vsc
|
|
*/
|
|
|
|
#ifndef AMIJIT_H_
|
|
#define AMIJIT_H_
|
|
|
|
#if YAP_JIT
|
|
/* Available LLVM (v. 3.1) Analysis Passes */
|
|
typedef enum {
|
|
e_createAAEvalPass, //Exhaustive Alias Analysis Precision Evaluator
|
|
e_createAliasAnalysisCounterPass, //Count Alias Analysis Query Responses
|
|
e_createBasicAliasAnalysisPass, //Basic Alias Analysis (stateless AA impl)
|
|
e_createCFGOnlyPrinterPass, //Print CFG of function to 'dot' file (with no function bodies)
|
|
e_createCFGPrinterPass, //Print CFG of function to 'dot' file
|
|
e_createDbgInfoPrinterPass, //Print debug info in human readable form
|
|
e_createDomOnlyPrinterPass, //Print dominance tree of function to 'dot' file (with no function bodies)
|
|
e_createDomPrinterPass, //Print dominance tree of function to 'dot' file
|
|
e_createGlobalsModRefPass, //Simple mod/ref analysis for globals
|
|
e_createInstCountPass, //Counts the various types of Instructions
|
|
e_createIVUsersPass, //Induction Variable Users
|
|
e_createLazyValueInfoPass, //Lazy Value Information Analysis
|
|
e_createLibCallAliasAnalysisPass, //LibCall Alias Analysis
|
|
e_createLintPass, //Statically lint-checks LLVM IR
|
|
e_createLoopDependenceAnalysisPass, //Loop Dependence Analysis
|
|
e_createMemDepPrinter, //Memory Dependence Analysis
|
|
e_createModuleDebugInfoPrinterPass, //Decodes module-level debug info
|
|
e_createNoAAPass, //No Alias Analysis (always returns 'may' alias)
|
|
e_createNoPathProfileInfoPass, //No Path Profile Information
|
|
e_createNoProfileInfoPass, //No Profile Information
|
|
e_createObjCARCAliasAnalysisPass, //ObjC-ARC-Based Alias Analysis
|
|
e_createPathProfileLoaderPass, //Loads information from a path profile dump file
|
|
e_createPathProfileVerifierPass, //Verifies path profiling information
|
|
e_createPostDomOnlyPrinterPass, //Print postdominance tree of function to 'dot' file (with no function bodies)
|
|
e_createPostDomPrinterPass, //Print postdominance tree of function to 'dot' file
|
|
e_createProfileEstimatorPass, //Estimate profiling information
|
|
e_createProfileLoaderPass, //Load profile information from llvmprof.out
|
|
e_createProfileVerifierPass, //Verify profiling information
|
|
e_createRegionInfoPass, //Detect single entry single exit regions
|
|
e_createRegionOnlyPrinterPass, //Print regions of function to 'dot' file (with no function bodies)
|
|
e_createRegionPrinterPass, //Print regions of function to 'dot' file
|
|
e_createScalarEvolutionAliasAnalysisPass, //ScalarEvolution-based Alias Analysis
|
|
e_createTypeBasedAliasAnalysisPass //Type-Based Alias Analysis
|
|
} enumAnalysisPasses;
|
|
|
|
/* Available LLVM (v. 3.1) Transform Passes */
|
|
typedef enum{
|
|
t_createAggressiveDCEPass, //This pass uses the SSA based Aggressive DCE algorithm
|
|
t_createArgumentPromotionPass, //Promotes "by reference" arguments to be passed by value if the number of elements passed is smaller or equal to maxElement
|
|
t_createBBVectorizePass, //A basic-block vectorization pass
|
|
t_createBlockExtractorPass, //Extracts all blocks (except those specified in the argument list) from the functions in the module
|
|
t_createBlockPlacementPass, //This pass reorders basic blocks in order to increase the number of fall-through conditional branches
|
|
t_createBreakCriticalEdgesPass, //Break all of the critical edges in the CFG by inserting a dummy basic block
|
|
t_createCFGSimplificationPass, //Merge basic blocks, eliminate unreachable blocks, simplify terminator instructions, etc...
|
|
t_createCodeGenPreparePass, //Prepares a function for instruction selection
|
|
t_createConstantMergePass, //Returns a new pass that merges duplicate global constants together into a single constant that is shared
|
|
t_createConstantPropagationPass, //A worklist driven constant propagation pass
|
|
t_createCorrelatedValuePropagationPass, //Propagate CFG-derived value information
|
|
t_createDeadArgEliminationPass, //This pass removes arguments from functions which are not used by the body of the function
|
|
t_createDeadArgHackingPass, //Same as DAE, but delete arguments of external functions as well
|
|
t_createDeadCodeEliminationPass, //This pass is more powerful than DeadInstElimination
|
|
t_createDeadInstEliminationPass, //Removes trivially dead instructions without modifying the CFG of the function
|
|
t_createDeadStoreEliminationPass, //Deletes stores that are post-dominated by must-aliased stores and are not loaded used between the stores
|
|
t_createDemoteRegisterToMemoryPass, //This pass is used to demote registers to memory references
|
|
t_createEarlyCSEPass, //This pass performs a simple and fast CSE pass over the dominator tree
|
|
t_createFunctionAttrsPass, //Discovers functions that do not access memory, or only read memory, and gives them the readnone/readonly attribute
|
|
t_createFunctionInliningPass,
|
|
t_createGlobalDCEPass, //This transform is designed to eliminate unreachable internal globals (functions or global variables)
|
|
t_createGlobalOptimizerPass, //Returns a new pass that optimizes non-address taken internal globals
|
|
t_createGVExtractionPass, //Deletes as much of the module as possible, except for the global values specified
|
|
t_createGVNPass, //Performs global value numbering and redundant load elimination cotemporaneously
|
|
t_createIndVarSimplifyPass, //Transform induction variables in a program to all use a single canonical induction variable per loop
|
|
t_createInstructionCombiningPass, //Combine instructions to form fewer, simple instructions
|
|
t_createInstructionNamerPass, //Give any unnamed non-void instructions "tmp" names
|
|
t_createInstructionSimplifierPass, //Remove redundant instructions
|
|
t_createInternalizePass, //Loops over all of the functions in the input module, internalizing all globals
|
|
t_createIPConstantPropagationPass, //Propagates constants from call sites into the bodies of functions
|
|
t_createIPSCCPPass, //Propagates constants from call sites into the bodies of functions, and keeps track of whether basic blocks are executable in the process
|
|
t_createJumpThreadingPass, //Thread control through mult-pred/multi-succ blocks where some preds always go to some succ
|
|
t_createLCSSAPass, //This pass inserts phi nodes at loop boundaries to simplify other loop optimizations
|
|
t_createLICMPass, //Loop invariant code motion and memory promotion pass
|
|
t_createLoopDeletionPass, //Performs DCE of non-infinite loops that it can prove are dead
|
|
t_createLoopExtractorPass, //Extracts all natural loops from the program into a function if it can
|
|
t_createLoopIdiomPass, //Recognizes and replaces idioms in loops
|
|
t_createLoopInstSimplifyPass, //Simplifies instructions in a loop's body
|
|
t_createLoopRotatePass, //Simple loop rotating pass
|
|
t_createLoopSimplifyPass, //Insert Pre-header blocks into the CFG for every function in the module
|
|
t_createLoopStrengthReducePass, //This pass is strength reduces GEP instructions that use a loop's canonical induction variable as one of their indices
|
|
t_createLoopUnrollPass, //Simple loop unrolling pass
|
|
t_createLoopUnswitchPass, //Simple loop unswitching pass
|
|
t_createLowerAtomicPass, //Lower atomic intrinsics to non-atomic form
|
|
t_createLowerExpectIntrinsicPass, //Removes llvm.expect intrinsics and creates "block_weights" metadata
|
|
t_createLowerInvokePass, //Converts invoke and unwind instructions to use sjlj exception handling mechanisms
|
|
t_createLowerSwitchPass, //Converts SwitchInst instructions into a sequence of chained binary branch instructions
|
|
t_createMemCpyOptPass, //Performs optimizations related to eliminating memcpy calls and/or combining multiple stores into memset's
|
|
t_createMergeFunctionsPass, //Discovers identical functions and collapses them
|
|
t_createObjCARCAPElimPass, //ObjC ARC autorelease pool elimination
|
|
t_createObjCARCContractPass, //Late ObjC ARC cleanups
|
|
t_createObjCARCExpandPass, //ObjC ARC preliminary simplifications
|
|
t_createObjCARCOptPass, //ObjC ARC optimization
|
|
t_createPartialInliningPass, //Inlines parts of functions
|
|
t_createPromoteMemoryToRegisterPass, //This pass is used to promote memory references to be register references
|
|
t_createPruneEHPass, //Return a new pass object which transforms invoke instructions into calls, if the callee can _no t_ unwind the stack
|
|
t_createReassociatePass, //This pass reassociates commutative expressions in an order that is designed to promote better constant propagation, GCSE, LICM, PRE...
|
|
t_createScalarReplAggregatesPass, //Break up alloca's of aggregates into multiple allocas if possible.
|
|
t_createSCCPPass, //Sparse conditional constant propagation
|
|
t_createSimplifyLibCallsPass, //Optimizes specific calls to specific well-known (library) functions
|
|
t_createSingleLoopExtractorPass, //Extracts one natural loop from the program into a function if it can
|
|
t_createSinkingPass, //Code Sinking
|
|
t_createStripDeadDebugInfoPass, //Removes unused symbols' debug info
|
|
t_createStripDeadPrototypesPass, //Removes any function declarations (prototypes) that are not used
|
|
t_createStripDebugDeclarePass, //Removes llvm.dbg.declare intrinsics
|
|
t_createStripNonDebugSymbolsPass, //Strips symbols from functions and modules
|
|
t_createStripSymbolsPass, //Removes symbols from functions and modules
|
|
t_createTailCallEliminationPass //Eliminates call instructions to the current function which occur immediately before return instructions
|
|
} enumTransformPasses;
|
|
|
|
/* Enumeration for points to verify module correctness */
|
|
typedef enum {
|
|
NOPOINT, // no point -- module will not be verified
|
|
BEFORE, // before optimize -- module will be verified before transform passes
|
|
AFTER, // after optimize -- module will be verified after transform passes
|
|
BOTH // both -- module will be verified both before and after transform passes
|
|
} enumPointToVerifiy;
|
|
|
|
/* Enumeration for available execution modes */
|
|
typedef enum {
|
|
JUST_INTERPRETED,
|
|
SMART_JIT,
|
|
CONTINUOUS_COMPILATION,
|
|
JUST_COMPILED
|
|
} enumExecModes;
|
|
|
|
/* Enumerations for available parameters for frequency measurement */
|
|
typedef enum{
|
|
NO_FREQ, // without frequency (used on 'JUST_INTERPRETED' and 'JUST_COMPILED' modes)
|
|
COUNTER, // unity counters
|
|
TIME // unity execution times
|
|
} enumFrequencyType;
|
|
|
|
/* Enumerations for types of clauses that can be head on traces */
|
|
typedef enum{
|
|
UNUSED, // not used
|
|
JUST_HOT, // enumFrequencyType associated to clause must reach threshold
|
|
HOT_AND_CALLEE, // JUST_HOT + clause must contain a callee opcode (fcall or call)
|
|
HOT_AND_GREATER, // JUST_HOT + clause size must be greater than others
|
|
HOT_AND_FEWER // JUST_HOT + clause's backtracks must be smaller than others
|
|
} enumMainClauseType;
|
|
|
|
/* Enumerations for available llvm registers allocators */
|
|
typedef enum{
|
|
REG_ALLOC_BASIC, // Basic
|
|
REG_ALLOC_FAST, // Fast
|
|
REG_ALLOC_GREEDY, // Greedy
|
|
REG_ALLOC_PBQP // PBQP
|
|
} enumRegAllocator;
|
|
|
|
#include <pthread.h> // for 'CONTINUOUS_COMPILATION' mode
|
|
|
|
/* Enumeration for points to apply debug predicates */
|
|
typedef enum{
|
|
NO_PLACE = 0, // no place
|
|
ON_INTERPRETER = 1, // on interpreted opcodes
|
|
ON_PROFILED_INTERPRETER = 2, // on profiled opcodes
|
|
ON_NATIVE = 4 // on native code
|
|
} enumPlace;
|
|
|
|
/* This struct is used by debug predicates --
|
|
usually associated to yaam opcode, basic blocks or clauses */
|
|
typedef struct printt_struc {
|
|
Int print; // Should I print?
|
|
CELL msg_before; // If I print, what message should come before?
|
|
CELL msg_after; // If I print, what message should come after?
|
|
} PrinttStruc;
|
|
|
|
|
|
/* This struct represents our experimental environment for YAP */
|
|
typedef struct environment {
|
|
// struct for analysis predicates -- all fields are modified by analysis predicates (JIT_AnalysisPreds.c)
|
|
struct {
|
|
CELL outfile; // Where will analysis results be printed?
|
|
Int stats_enabled; // Should llvm stats be printed on 'shutdown_llvm()'?
|
|
Int time_pass_enabled; // Should llvm time passes be printed on 'shutdown_llvm()'?
|
|
enumPointToVerifiy pointtoverifymodule; // What point of code will llvm modules be verified?
|
|
COUNT n; // Number of elements on 'act_an'
|
|
enumAnalysisPasses *act_an; // List of analysis passes
|
|
} analysis_struc;
|
|
|
|
// struct for transform predicates -- all fields are modified by transform predicates (JIT_TransformPreds.c)
|
|
struct {
|
|
Int optlevel; // Optimization level -- 'act_tr' only will be used if 'optlevel' is '-1'
|
|
COUNT n; // Number of elements on 'act_tr'
|
|
enumTransformPasses *act_tr; // List of transform passes
|
|
struct {
|
|
CELL arg_promotion_max_elements; // Max elements on 'Argument Promotion Pass'
|
|
CELL strip_symbols_pass_type; // Argument for 'Strip Symbols Pass' -- if true, only debugging information is removed from the module
|
|
CELL scalar_replace_aggregates_threshold; // Threshold for 'Scalar Repl Aggregates Pass'
|
|
CELL loop_unswitch_optimize_for_size; // Argument for 'Loop Unswitch Pass' -- Should I optimize for size?
|
|
CELL loop_unroll_threshold; // Threshold for 'Loop Unroll Pass'
|
|
CELL inline_threshold; // Threshold for 'Function Inlining Pass'
|
|
} opt_args;
|
|
Int unit_at_time_enabled; // Should I enable IPO?
|
|
Int simplify_libcalls_enabled; // Should I simplify libcalls?
|
|
struct {
|
|
Int enabled; // Should I enable link-time optimizations?
|
|
CELL internalize; // Should I run 'Internalize Pass' on link-time optimization?
|
|
CELL runinliner; // Should I run 'Inline Pass' on link-time optimization?
|
|
} link_time_opt;
|
|
} transform_struc;
|
|
|
|
// struct for codegen predicates -- all fields are modified by codegen predicates (JIT_CodegenPreds.c)
|
|
struct {
|
|
struct {
|
|
Int noframepointerelim; // Should I use frame pointer elimination opt?
|
|
Int lessprecisefpmadoption; // Should I allow to generate multiply add if the result is "less precise"?
|
|
Int noexcessfpprecision; // Should I enable excess fp precision?
|
|
Int unsafefpmath; // Should I allow to produce results that are "less precise" than IEEE allows?
|
|
Int honorsigndependentroundingfpmathoption; // Which rounding mode should I use?
|
|
Int usesoftfloat; // Should I use libcalls or FP instructions to treat floating point libraries?
|
|
Int jitexceptionhandling; // Should JIT emit exception handling info?
|
|
Int jitemitdebuginfo; // Should JIT emit debug information?
|
|
Int jitemitdebuginfotodisk; // Should JIT write debug information to disk?
|
|
Int guaranteedtailcallopt; // Should I perform tail call optimization on calls which use fastcc calling convention?
|
|
Int disabletailcalls; // Should I use tail calls?
|
|
Int fastisel; // Should I use 'fast-path instruction selection' to reduce compilation time? If 'yes' native code won't have best quality
|
|
Int floatabitype; /* 0 = Default, 1 = Soft, 2 = Hard */
|
|
} struc_targetopt;
|
|
struct {
|
|
Int engineoptlevel; /* 0 = None, 1 = Less, 2 = Default, 3 = Agressive */
|
|
Int relocmodel; /* 0 = Default, 1 = Static, 2 = PIC, 3 = DynamicNoPIC */
|
|
Int codemodel; /* 0 = Default, 1 = JITDefault, 2 = Small, 3 = Kernel, 4 = Medium, 5 = Large */
|
|
Int usemcjit; // Should I use MC-JIT implementation (experimental)?
|
|
enumRegAllocator regallocator; // Active register allocator (predicate register_allocator/1)
|
|
} struc_enginebuilder;
|
|
} codegen_struc;
|
|
|
|
// struct for configuration predicates -- all fields are modified by configuration predicates (JIT_ConfigPreds.c)
|
|
struct {
|
|
enumExecModes execution_mode; // Active execution mode
|
|
enumFrequencyType frequency_type; // Active frequency type
|
|
Float frequency_bound; // Bound to become clauses as hot
|
|
Float profiling_startp; // Bound to init monitoring and trace building
|
|
enumMainClauseType mainclause_ty; // Types of clauses that can be head on traces
|
|
COUNT ncores; // Number of cores on processor -- used to determine default 'compilation_threads' (compilation_threads = ncores - 1)
|
|
COUNT compilation_threads; // Number of compilation threads (used only if 'execution_mode' is 'CONTINUOUS_COMPILATION')
|
|
pthread_t* threaded_compiler_threads; // List of threads (size = 'compilation_threads'). Used by function 'pthread_create'. Used on 'CONTINUOUS_COMPILATION' mode
|
|
CELL* posthreads; // Used to determine which threads are free/busy
|
|
Int torecompile; // Should I recompile traces?
|
|
Int current_displacement; // Jump displacement to run yaam opcodes on absmi. Zero is the default value and will make standard yaam opcodes are executed. 'TOTAL_OF_OPCODES' is the value after any clause become critical and will make 'traced_' yaam opcodes are executed.
|
|
COUNT TOTAL_OF_OPCODES; // Total of yaam opcodes. I must determine this dynamically due to several '#define' statements. Used to determine 'current_displacement' after any clause become critical.
|
|
Int useonlypi; // Execute only 'traced_' yaam opcodes. Don't compile. WARNING: if you enable this field (predicate only_profiled_interpreter/0), the system performance will decrease considerably. Use only to determine the actual cost of running such opcodes.
|
|
} config_struc;
|
|
|
|
#if YAP_STAT_PREDS
|
|
// struct for statistic predicates -- all fields are modified by statistic predicates (JIT_StatisticPreds.c)
|
|
struct {
|
|
int papi_initialized; // Was PAPI initialized? Used on predicate 'statistics_jit/0' -- if 1, PAPI results will be emitted
|
|
int papi_eventset; // PAPI event set
|
|
long long *papi_values; // List of collected performance counter values
|
|
short *papi_valid_values; // List of performance counters that will be collected
|
|
int papi_event_type; // Type of event that will be collected -- 'papi_event_type' involves what performance counters will be within 'papi_valid_values'
|
|
} stats_struc;
|
|
#endif
|
|
|
|
#if YAP_DBG_PREDS
|
|
// struct for debug predicates -- all fields are modified by debug predicates (JIT_DebugPreds.c)
|
|
struct {
|
|
/* Here, one 'PrinttStruc' for each yaam opcode on 'YapAppliedOpcodes.h' */
|
|
#define OPCODE(OP,TYPE) \
|
|
PrinttStruc pyaam_##OP;
|
|
#include "YapAppliedOpcodes.h"
|
|
#undef OPCODE
|
|
|
|
/* Here, one 'PrinttStruc' for each basic block on 'AppliedBasicBlocks.h' */
|
|
#define BBLOCK(BB) \
|
|
PrinttStruc pbbs_##BB;
|
|
#include "Yap_AppliedBasicBlocks.h"
|
|
#undef BBLOCK
|
|
|
|
/* This 'PrinttStruc' inform system whether head-clauses on traces should be printed */
|
|
PrinttStruc pmainclause_on_head;
|
|
|
|
/* Fields to treat intermediate code */
|
|
struct{
|
|
Int print_to_std; // Should intermediate code be printed on std (stdout, stderr)? Default:: print_to_std = 0 (don't print to stdout nor stderr)
|
|
Int print_to_file; // Should intermediate code be printed on file? Default:: print_to_file = 0 (don't print to file)
|
|
CELL std_name; // if 'print_to_std' = 'yes', where should intermediate code be printed?
|
|
CELL file_name; // if 'print_to_file' = 'yes', what file should intermediate code be printed?
|
|
} pprint_intermediate;
|
|
|
|
/* Fields to treat llva code */
|
|
struct {
|
|
Int print_llva_before; // Should llva code be printed before optimizing module?
|
|
Int print_llva_after; // Shoud llva code be printed after optimizing module?
|
|
} pprint_llva;
|
|
|
|
/* Fields for predicate print_me/2 */
|
|
struct {
|
|
CELL interpreted_backtrack; // msg to print when backtrack on standard yaam opcodes occur
|
|
CELL profiled_interpreted_backtrack; // msg to print when backtrack on 'traced_' yaam opcodes occur
|
|
CELL native_backtrack; // msg to print when backtrack on native code occur
|
|
CELL interpreted_treat_heap; // msg to print when heap is treated on interpreter (standard and 'traced_' yaam opcodes)
|
|
CELL native_treat_heap; // msg to print when heap is treated on native code
|
|
CELL interpreted_treat_trail; // msg to print when trail is treated on interpreter (standard and 'traced_' yaam opcodes)
|
|
CELL native_treat_trail; // msg to print when trail is treated on native code
|
|
CELL criticals; // msg to print when any clause becomes critical
|
|
CELL at_compilation; // msg to print before compilation
|
|
CELL at_recompilation; // msg to print before recompilation
|
|
CELL nativerun_init; // msg to print when native code is about to be run
|
|
CELL nativerun_exit_by_success; // msg to print when native code exits by success, ie., basic block nonexistent in native code (allows rebuilding and recompilation of traces)
|
|
CELL nativerun_exit_by_fail; // msg to print when native code exits byfail, ie., exits to treat trail or heap (don't allow rebuilding and recompilation of traces)
|
|
} pprint_me;
|
|
|
|
/* Messages on all predicates */
|
|
struct {
|
|
Int info_msgs; // Should I allow info messages?
|
|
Int success_msgs; // Should I allow success messages?
|
|
Int warning_msgs; // Should I allow warning messages?
|
|
Int error_msgs; // Should I allow error messages?
|
|
} act_predicate_msgs;
|
|
|
|
/* Actions on all predicates */
|
|
struct {
|
|
Int exit_on_warning; // Should I exit when any warning occur?
|
|
Int disable_on_warning; // Shouldn't I adjust appropriate values when any warning occur (implies 'exit_on_warning' = 'false')
|
|
Int exit_on_error; // Should I exit when any error occur?
|
|
} act_predicate_actions;
|
|
} debug_struc;
|
|
#endif
|
|
|
|
} Environment;
|
|
|
|
/* Enumeration for types of basic blocks -- used on trace construction */
|
|
typedef enum block_try {
|
|
NONE, // untyped
|
|
SIMPLE_ENTRY, // first basic block of any yaam opcode
|
|
SIMPLE, // any other basic block of any yaam opcode
|
|
CONDITIONAL_HEADER, // basic block of any 'if' statement of any yaam opcode
|
|
MULTIPLE_DESTINY // basic block of many destinations (elementary block). Returns from native code to interpreter always will occur here
|
|
} BlockTy;
|
|
|
|
/* Struct to represent individual basic blocks within traces */
|
|
typedef struct blocks_context {
|
|
union {
|
|
/* Fields for SIMPLE_ENTRY blocks */
|
|
struct {
|
|
UInt id; // block identifier (Yap_BasicBlocks.h)
|
|
char *label_entry; // entry label -- destinations of jumps from others 'SIMPLE_ENTRY' or 'SIMPLE' blocks
|
|
char *label_destiny; // destiny label -- where should I jump after I run?
|
|
} eb;
|
|
|
|
/* Fields for SIMPLE blocks */
|
|
struct {
|
|
UInt id; // block identifier (Yap_BasicBlocks.h)
|
|
char *label_destiny; // destiny label -- where should I jump after I run?
|
|
} sb;
|
|
|
|
/* Fields for CONDITIONAL_HEADER blocks */
|
|
struct {
|
|
char *exp; // expression of 'if' statement
|
|
struct blocks_context *_if; // destination if 'exp' is true
|
|
struct blocks_context *_else; // destination if 'exp' is false
|
|
} kb;
|
|
|
|
/* Fields for MULTIPLE_DESTINY blocks */
|
|
struct {
|
|
UInt id; // block identifier (Yap_BasicBlocks.h)
|
|
COUNT nfaillabels; // number of destinations caused by backtrack on native code
|
|
struct {
|
|
UInt *p;
|
|
char **labels;
|
|
} faildestiny; // destinations caused by backtrack on native code
|
|
COUNT ndest; // number of destinations that not be backtrack
|
|
struct {
|
|
UInt *p;
|
|
char **labels;
|
|
} destiny; // destinations that not be backtrack
|
|
} mdb;
|
|
|
|
/* Fields for untyped blocks */
|
|
struct {
|
|
CELL header; // just for aiding after treating 'CONDITIONAL_HEADER' blocks
|
|
} xb;
|
|
} u;
|
|
BlockTy blockty; // Basic block type
|
|
CELL thisp; // Value of PREG. Inside traces, basic blocks are only different from each other if 'id' and 'blockty' are different
|
|
CELL prev; // Previous basic block
|
|
CELL next; // Next basic block
|
|
} BlocksContext;
|
|
|
|
/* Struct to represent fully traces */
|
|
typedef struct trace_context {
|
|
COUNT n; // number of basic blocks
|
|
CELL tracesize; // For statistics... list of size (bytes) of each trace
|
|
BlocksContext *bc; // basic blocks context
|
|
} TraceContext;
|
|
|
|
/* Struct to represent Intermediatecode Area */
|
|
typedef struct intermediatecode_context {
|
|
COUNT n; // Total of traces stored
|
|
struct {
|
|
TraceContext** t; // List of pointers to traces -- total of 'n'
|
|
COUNT* ok; // List of traces ok (traces constructed and compiled at least once)
|
|
COUNT* isactive; // List of active traces (traces under construction). Initialized to zero
|
|
BlocksContext** lastblock; // List of last block added on each trace
|
|
#if YAP_STAT_PREDS
|
|
double* profiling_time; // For statistics... list of profiling time of each trace
|
|
#endif
|
|
} area;
|
|
} IntermediatecodeContext;
|
|
|
|
/* Struct to represent Nativecode Area */
|
|
typedef struct native_context {
|
|
COUNT n; // Total of traces compiled (is not necessarily equal to 'IntermediatecodeContext.n')
|
|
struct {
|
|
void** p; // List of pointers to compiled codes -- total of 'n'
|
|
COUNT* ok; // List of compiled codes ok (traces constructed and compiled at least once)
|
|
CELL* pc; // List of first heads of each compiled code
|
|
#if YAP_STAT_PREDS
|
|
COUNT *nrecomp; // For statistics... number of recompilations of each compiled code (max '1' if recompilation is disabled)
|
|
double **compilation_time; // For statistics... list of compilation time of each compiled code on each recompilation
|
|
CELL **native_size_bytes; // For statistics... list of native size (bytes) of each compiled code on each recompilation
|
|
CELL **trace_size_bytes; // For statistics... list of trace size (bytes) of each trace on each recompilation
|
|
#endif
|
|
} area;
|
|
#if YAP_STAT_PREDS
|
|
COUNT *runs; // List of calls of each compiled code
|
|
double *t_runs; // List of execution time of each compiled code
|
|
COUNT *success; // List of exit by success of each compiled code
|
|
#endif
|
|
} NativeContext;
|
|
|
|
/*
|
|
* Control flags for managing intermediate code *
|
|
* from traces stored on Intermediatecode Area *
|
|
* Intermediatecode Area stores traces represented as *
|
|
* basic blocks sequence *
|
|
*/
|
|
typedef struct control_flags_context {
|
|
COUNT nemited;
|
|
char** emited_blocks;
|
|
short emit;
|
|
short leastonce;
|
|
char* clabel;
|
|
COUNT labelidx;
|
|
COUNT printlabel;
|
|
char** entries;
|
|
COUNT nentries;
|
|
} ControlFlagsContext;
|
|
|
|
|
|
/* Struct associated to 'jit_handler' opcode */
|
|
typedef struct jit_handl_context {
|
|
/* Main yaam opcode features -- used by predicate 'main_clause_ty/1' */
|
|
struct {
|
|
CELL isground; // Does clause whose head is this 'jit_handler' have calls ('fcall' or 'call' opcode)? If 'yes', isground is '0'. Used when 'main_clause_ty(hot_and_callee)'
|
|
CELL clausesize; // Is clause whose head is this 'jit_handler' greater than other clauses? Used when ''main_clause_ty(hot_and_greater)'
|
|
CELL backtrack_counter; // Does clause whose head is this 'jit_handler' have fewer backtracks on history than other clauses? Used when ''main_clause_ty(hot_and_fewer)'
|
|
} mf;
|
|
|
|
/* Frequency Instrumenters -- only one is used */
|
|
struct {
|
|
union {
|
|
COUNT c; // counter
|
|
CELL t; // time
|
|
} bcst; // balance, counter, crossover, time
|
|
} fi;
|
|
|
|
/* Reverse pointers to code areas ('Intermediatecode Area' and 'Native Area') */
|
|
struct {
|
|
COUNT taddress; // intermediatecode area
|
|
COUNT naddress; // native area
|
|
} caa;
|
|
|
|
/* Fields for aiding trace construction and compilation */
|
|
struct {
|
|
char *cmd; // Argument to program 'echo' (called by fork on JIT_Compiler.cpp). Its value is C code that represent traces that will be compiled. Its value is freed after compilation.
|
|
ControlFlagsContext* cf; // Pointer to ControlFlagsContext. Just used here.
|
|
} tcc;
|
|
|
|
/* Fields for managing JIT -- recompilation and threads */
|
|
struct {
|
|
CELL used_thread;
|
|
CELL torecomp;
|
|
}jitman;
|
|
} JitHandlContext;
|
|
|
|
extern void **Yap_ABSMI_ControlLabels;
|
|
|
|
#endif /* YAP_JIT */
|
|
|
|
|
|
|
|
#endif /* _AMIJIT_H_ */
|
|
#if YAP_JIT
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
|
|
|
|
typedef void *(*call_jitc_t)(struct JIT_Compiler*, yamop *);
|
|
|
|
void *call_JIT_Compiler(struct JIT_Compiler*, yamop *);
|
|
|
|
|
|
|
|
static void
|
|
initJit(void)
|
|
{
|
|
extern void shutdown_llvm(void);
|
|
extern call_jitc_t Yap_JITCall;
|
|
|
|
Yap_InitJitAnalysisPreds();
|
|
Yap_InitJitTransformPreds();
|
|
Yap_InitJitCodegenPreds();
|
|
Yap_InitJitConfigPreds();
|
|
#if YAP_STAT_PREDS
|
|
Yap_InitJitStatisticPreds();
|
|
#endif
|
|
#if YAP_DBG_PREDS
|
|
Yap_InitJitDebugPreds();
|
|
#endif
|
|
GLOBAL_JIT_finalizer = shutdown_llvm;
|
|
Yap_JITCall = call_JIT_Compiler;
|
|
Yap_llvmShutdown = llvm_shutdown;
|
|
Yap_ExpEnvP = &Yap_ExpEnv;;
|
|
|
|
}
|
|
|
|
// export JIT as DLL
|
|
void
|
|
init_jit(void) {
|
|
initJit();
|
|
}
|
|
|
|
Environment Yap_ExpEnv;
|
|
|
|
#pragma GCC diagnostic pop
|
|
#endif /* YAP_JIT */
|
|
|