2014-07-13 05:30:14 +01:00
|
|
|
/*************************************************************************
|
|
|
|
* *
|
|
|
|
* Extension for YAP Prolog *
|
|
|
|
* *
|
|
|
|
* Copyright G.S.Oliveira, A.F.Silva and Universidade Estadual de Maringá *
|
|
|
|
* *
|
|
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
|
|
* *
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
|
|
|
* File: jit_transformpreds.c *
|
|
|
|
* comments: JIT Compiler Optimizations predicates *
|
|
|
|
* *
|
|
|
|
* Last rev: 2013-10-18 *
|
|
|
|
*************************************************************************/
|
|
|
|
|
2015-01-18 02:46:03 +00:00
|
|
|
#include "jit_predicates.hpp"
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
#define N_TRANSFORM_PASSES 69
|
|
|
|
|
|
|
|
// Disable one (passed by argument) LLVM transform pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_disable_transform_pass( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable one (passed by argument) LLVM transform pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_transform_pass( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable one (passed by argument) LLVM transform pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_enable_transform_pass( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable a list (passed by argument) of LLVM transform passes
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_transform_passes( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable all available LLVM transform passes
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_enable_all_transform_passes( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Disable all available LLVM transform passes
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_disable_all_transform_passes( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable n LLVM transform passes (randomly)
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_n_transform_passes( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable a transform level
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_transform_level( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Max element of Argument Promotion Pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_argument_promotion_max_elements( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Threshold of Scalar Repl Aggregates Pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_scalar_replace_aggregates_threshold( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Threshold of Loop Unroll Pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_loop_unroll_threshold( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Threshold of Function Inlining Pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_inline_threshold( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Eliminates (or not) only debugging information on Strip Symbols Pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_strip_symbols_pass_type( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Optimizes (or not) for size on Loop Unswitch Pass
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_loop_unswitch_optimize_for_size( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Default value of 'max elements on Argument Promotion Pass *
|
|
|
|
* 'threshold of Scalar Repl Aggregates Pass *
|
|
|
|
* 'threshold of Loop Unroll Pass *
|
|
|
|
* 'threshold of Function Inlining Pass *
|
|
|
|
* 'Strip Symbols Pass *
|
|
|
|
* 'Loop Unswitch Pass *
|
|
|
|
*/
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_default_optimization_args( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Same as 'p_default_optimization_args'
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_reset_optimization_args( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable IPO by LLVM
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_enable_unit_at_time( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable libcalls simplification by LLVM
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_enable_simplify_libcalls( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Disable IPO by LLVM
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_disable_unit_at_time( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Disable libcalls simplification by LLVM
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_disable_simplify_libcalls( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable (or not) link-time optimization
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_link_time_opt1( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Same as 'p_link_time_opt1', but accepts 3 arguments: *
|
|
|
|
* 1 -- Should I apply this opt? *
|
|
|
|
* 2 -- Should I run internalize? *
|
|
|
|
* 3 -- Should I run inliner? *
|
|
|
|
*/
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_link_time_opt3( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Enable link-time optimization. Same as 'link_time_opt(true)'
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_enable_link_time_opt( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Same as 'p_enable_link_time_opt', but accepts 2 arguments: *
|
|
|
|
* 1 -- Should I run internalize? *
|
|
|
|
* 2 -- Should I run inliner? *
|
|
|
|
*/
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_enable_link_time_opt2( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Disable link-time optimization.
|
2015-01-18 02:46:03 +00:00
|
|
|
static Int p_disable_link_time_opt( USES_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
|
2015-01-18 01:32:13 +00:00
|
|
|
|
2014-07-13 05:30:14 +01:00
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_disable_transform_pass( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// First: stores what transform pass should be disabled
|
|
|
|
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
enumTransformPasses f;
|
|
|
|
// valid values for ARG1 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
Int v = IntOfTerm(t);
|
|
|
|
if (v < 0 || v >= N_TRANSFORM_PASSES) {
|
|
|
|
// value passed by argument is out of known range
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
f = (enumTransformPasses)v;
|
|
|
|
}
|
|
|
|
else if (IsAtomTerm(t)) {
|
|
|
|
// ARG1 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
if (strcmp(str, "ALL") == 0) {
|
|
|
|
// atom is 'all' -- this will disable all passes
|
|
|
|
if (ExpEnv.transform_struc.act_tr) free(ExpEnv.transform_struc.act_tr);
|
|
|
|
ExpEnv.transform_struc.act_tr = NULL;
|
|
|
|
ExpEnv.transform_struc.n = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Detects one pass according to 'str' -- store it
|
|
|
|
if (strcmp(str, "AGGRESSIVEDCE") == 0 || strcmp(str, "ADCE") == 0) f = t_createAggressiveDCEPass;
|
|
|
|
else if (strcmp(str, "ARGUMENTPROMOTION") == 0 || strcmp(str, "ARGPROMOTION") == 0) f = t_createArgumentPromotionPass;
|
|
|
|
else if (strcmp(str, "BBVECTORIZE") == 0) f = t_createBBVectorizePass;
|
|
|
|
else if (strcmp(str, "BLOCKEXTRACTOR") == 0 || strcmp(str, "EXTRACTBLOCKS") == 0) f = t_createBlockExtractorPass;
|
|
|
|
else if (strcmp(str, "BLOCKPLACEMENT") == 0) f = t_createBlockPlacementPass;
|
|
|
|
else if (strcmp(str, "BREAKCRITICALEDGES") == 0 || strcmp(str, "BREAKCRITEDGES") == 0) f = t_createBreakCriticalEdgesPass;
|
|
|
|
else if (strcmp(str, "CFGSIMPLIFICATION") == 0 || strcmp(str, "SIMPLIFYCFG") == 0) f = t_createCFGSimplificationPass;
|
|
|
|
else if (strcmp(str, "CODEGENPREPARE") == 0) f = t_createCodeGenPreparePass;
|
|
|
|
else if (strcmp(str, "CONSTANTMERGE") == 0 || strcmp(str, "CONSTMERGE") == 0) f = t_createConstantMergePass;
|
|
|
|
else if (strcmp(str, "CONSTANTPROPAGATION") == 0 || strcmp(str, "CONSTPROP") == 0) f = t_createConstantPropagationPass;
|
|
|
|
else if (strcmp(str, "CORRELATEDVALUEPROPAGATION") == 0 || strcmp(str, "CORRELATEDPROPAGATION") == 0) f = t_createCorrelatedValuePropagationPass;
|
|
|
|
else if (strcmp(str, "DEADARGELIMINATION") == 0 || strcmp(str, "DEADARGELIM") == 0) f = t_createDeadArgEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADARGHACKING") == 0 || strcmp(str, "DEADARGHAX0R") == 0) f = t_createDeadArgHackingPass;
|
|
|
|
else if (strcmp(str, "DEADCODEELIMINATION") == 0 || strcmp(str, "DCE") == 0) f = t_createDeadCodeEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADINSTELIMINATION") == 0 || strcmp(str, "DIE") == 0) f = t_createDeadInstEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADSTOREELIMINATION") == 0 || strcmp(str, "DSE") == 0) f = t_createDeadStoreEliminationPass;
|
|
|
|
else if (strcmp(str, "DEMOTEREGISTERTOMEMORY") == 0 || strcmp(str, "REG2MEM") == 0) f = t_createDemoteRegisterToMemoryPass;
|
|
|
|
else if (strcmp(str, "EARLYCSE") == 0) f = t_createEarlyCSEPass;
|
|
|
|
else if (strcmp(str, "FUNCTIONATTRS") == 0) f = t_createFunctionAttrsPass;
|
|
|
|
else if (strcmp(str, "FUNCTIONINLINING") == 0 || strcmp(str, "INLINE") == 0) f = t_createFunctionInliningPass;
|
|
|
|
else if (strcmp(str, "GLOBALDCE") == 0) f = t_createGlobalDCEPass;
|
|
|
|
else if (strcmp(str, "GLOBALOPTIMIZER") == 0 || strcmp(str, "GLOBALOPT") == 0) f = t_createGlobalOptimizerPass;
|
|
|
|
else if (strcmp(str, "GVEXTRACTION") == 0) f = t_createGVExtractionPass;
|
|
|
|
else if (strcmp(str, "GVN") == 0) f = t_createGVNPass;
|
|
|
|
else if (strcmp(str, "INDVARSIMPLIFY") == 0 || strcmp(str, "INDVARS") == 0) f = t_createIndVarSimplifyPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONCOMBINING") == 0 || strcmp(str, "INSTCOMBINE") == 0) f = t_createInstructionCombiningPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONNAMER") == 0 || strcmp(str, "INSTNAMER") == 0) f = t_createInstructionNamerPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONSIMPLIFIER") == 0 || strcmp(str, "INSTSIMPLIFY") == 0) f = t_createInstructionSimplifierPass;
|
|
|
|
else if (strcmp(str, "INTERNALIZE") == 0) f = t_createInternalizePass;
|
|
|
|
else if (strcmp(str, "IPCONSTANTPROPAGATION") == 0 || strcmp(str, "IPCONSTPROP") == 0) f = t_createIPConstantPropagationPass;
|
|
|
|
else if (strcmp(str, "IPSCCP") == 0) f = t_createIPSCCPPass;
|
|
|
|
else if (strcmp(str, "JUMPTHREADING") == 0) f = t_createJumpThreadingPass;
|
|
|
|
else if (strcmp(str, "LCSSA") == 0) f = t_createLCSSAPass;
|
|
|
|
else if (strcmp(str, "LICM") == 0) f = t_createLICMPass;
|
|
|
|
else if (strcmp(str, "LOOPDELETION") == 0) f = t_createLoopDeletionPass;
|
|
|
|
else if (strcmp(str, "LOOPEXTRACTOR") == 0 || strcmp(str, "LOOPEXTRACT") == 0) f = t_createLoopExtractorPass;
|
|
|
|
else if (strcmp(str, "LOOPIDIOM") == 0) f = t_createLoopIdiomPass;
|
|
|
|
else if (strcmp(str, "LOOPINSTSIMPLIFY") == 0) f = t_createLoopInstSimplifyPass;
|
|
|
|
else if (strcmp(str, "LOOPROTATE") == 0) f = t_createLoopRotatePass;
|
|
|
|
else if (strcmp(str, "LOOPSIMPLIFY") == 0) f = t_createLoopSimplifyPass;
|
|
|
|
else if (strcmp(str, "LOOPSTRENGTHREDUCE") == 0 || strcmp(str, "LOOPREDUCE") == 0) f = t_createLoopStrengthReducePass;
|
|
|
|
else if (strcmp(str, "LOOPUNROLL") == 0) f = t_createLoopUnrollPass;
|
|
|
|
else if (strcmp(str, "LOOPUNSWITCH") == 0) f = t_createLoopUnswitchPass;
|
|
|
|
else if (strcmp(str, "LOWERATOMIC") == 0) f = t_createLowerAtomicPass;
|
|
|
|
else if (strcmp(str, "LOWEREXPECTINTRINSIC") == 0 || strcmp(str, "LOWEREXPECT") == 0) f = t_createLowerExpectIntrinsicPass;
|
|
|
|
else if (strcmp(str, "LOWERINVOKE") == 0) f = t_createLowerInvokePass;
|
|
|
|
else if (strcmp(str, "LOWERSWITCH") == 0) f = t_createLowerSwitchPass;
|
|
|
|
else if (strcmp(str, "MEMCPYOPT") == 0) f = t_createMemCpyOptPass;
|
|
|
|
else if (strcmp(str, "MERGEFUNCTIONS") == 0 || strcmp(str, "MERGEFUNC") == 0) f = t_createMergeFunctionsPass;
|
|
|
|
else if (strcmp(str, "OBJCARCAPELIM") == 0) f = t_createObjCARCAPElimPass;
|
|
|
|
else if (strcmp(str, "OBJCARCCONTRACT") == 0) f = t_createObjCARCContractPass;
|
|
|
|
else if (strcmp(str, "OBJCARCEXPAND") == 0) f = t_createObjCARCExpandPass;
|
|
|
|
else if (strcmp(str, "OBJCARCOPT") == 0 || strcmp(str, "OBJCARC") == 0) f = t_createObjCARCOptPass;
|
|
|
|
else if (strcmp(str, "PARTIALINLINING") == 0 || strcmp(str, "PARTIALINLINER") == 0) f = t_createPartialInliningPass;
|
|
|
|
else if (strcmp(str, "PROMOTEMEMORYTOREGISTER") == 0 || strcmp(str, "MEM2REG") == 0) f = t_createPromoteMemoryToRegisterPass;
|
|
|
|
else if (strcmp(str, "PRUNEEH") == 0) f = t_createPruneEHPass;
|
|
|
|
else if (strcmp(str, "REASSOCIATE") == 0) f = t_createReassociatePass;
|
|
|
|
else if (strcmp(str, "SCALARREPLAGGREGATES") == 0 || strcmp(str, "SCALARREPL") == 0) f = t_createScalarReplAggregatesPass;
|
|
|
|
else if (strcmp(str, "SCCP") == 0) f = t_createSCCPPass;
|
|
|
|
else if (strcmp(str, "SIMPLIFYLIBCALLS") == 0) f = t_createSimplifyLibCallsPass;
|
|
|
|
else if (strcmp(str, "SINGLELOOPEXTRACTOR") == 0 || strcmp(str, "LOOPEXTRACTSINGLE") == 0) f = t_createSingleLoopExtractorPass;
|
|
|
|
else if (strcmp(str, "SINKING") == 0 || strcmp(str, "SINK") == 0) f = t_createSinkingPass;
|
|
|
|
else if (strcmp(str, "STRIPDEADDEBUGINFO") == 0) f = t_createStripDeadDebugInfoPass;
|
|
|
|
else if (strcmp(str, "STRIPDEADPROTOTYPES") == 0) f = t_createStripDeadPrototypesPass;
|
|
|
|
else if (strcmp(str, "STRIPDEBUGDECLARE") == 0) f = t_createStripDebugDeclarePass;
|
|
|
|
else if (strcmp(str, "STRIPNONDEBUGSYMBOLS") == 0) f = t_createStripNonDebugSymbolsPass;
|
|
|
|
else if (strcmp(str, "STRIPSYMBOLS") == 0 || strcmp(str, "STRIP") == 0) f = t_createStripSymbolsPass;
|
|
|
|
else if (strcmp(str, "TAILCALLELIMINATION") == 0 || strcmp(str, "TAILCALLELIM") == 0) f = t_createTailCallEliminationPass;
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Transform pass");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Second: creates a new list with all transform on 'ExpEnv.analysis_struc.act_tr' but that transform stored on first step
|
|
|
|
enumTransformPasses *tmplist = NULL;
|
|
|
|
COUNT tmpn = 0;
|
|
|
|
int i = 0;
|
|
|
|
while (i < ExpEnv.transform_struc.n) {
|
|
|
|
if (ExpEnv.transform_struc.act_tr[i] != f) {
|
|
|
|
tmpn += 1;
|
|
|
|
tmplist = (enumTransformPasses*)realloc(tmplist, tmpn*sizeof(enumTransformPasses));
|
|
|
|
tmplist[tmpn-1] = ExpEnv.transform_struc.act_tr[i];
|
|
|
|
}
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Third: makes 'ExpEnv.analysis_struc.act_tr' to point to new list created on second step
|
|
|
|
free(ExpEnv.transform_struc.act_tr);
|
|
|
|
ExpEnv.transform_struc.n = tmpn;
|
|
|
|
ExpEnv.transform_struc.act_tr = tmplist;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_transform_pass( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// First: disables analysis pass (if be active)
|
2015-01-18 02:46:03 +00:00
|
|
|
p_disable_transform_pass( PASS_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
|
|
|
|
// Second: valids argument and inserts new transform pass
|
|
|
|
// valid values for ARG1 are 'integer' and 'atom'
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
Int v;
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
v = IntOfTerm(t);
|
|
|
|
if (v < 0 || v >= N_TRANSFORM_PASSES) {
|
|
|
|
// value passed by argument is out of known range
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// creates a new slot in 'ExpEnv.analysis_struc.act_tr' and appends the pass in it
|
|
|
|
ExpEnv.transform_struc.n += 1;
|
|
|
|
ExpEnv.transform_struc.act_tr = (enumTransformPasses*)
|
|
|
|
realloc(ExpEnv.transform_struc.act_tr, ExpEnv.transform_struc.n * sizeof(enumTransformPasses));
|
|
|
|
ExpEnv.transform_struc.act_tr[ExpEnv.transform_struc.n-1] = (enumTransformPasses)v;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (IsAtomTerm(t)) {
|
|
|
|
// ARG1 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detects one pass according to 'str'
|
|
|
|
if (strcmp(str, "AGGRESSIVEDCE") == 0 || strcmp(str, "ADCE") == 0) v = t_createAggressiveDCEPass;
|
|
|
|
else if (strcmp(str, "ARGUMENTPROMOTION") == 0 || strcmp(str, "ARGPROMOTION") == 0) v = t_createArgumentPromotionPass;
|
|
|
|
else if (strcmp(str, "BBVECTORIZE") == 0) v = t_createBBVectorizePass;
|
|
|
|
else if (strcmp(str, "BLOCKEXTRACTOR") == 0 || strcmp(str, "EXTRACTBLOCKS") == 0) v = t_createBlockExtractorPass;
|
|
|
|
else if (strcmp(str, "BLOCKPLACEMENT") == 0) v = t_createBlockPlacementPass;
|
|
|
|
else if (strcmp(str, "BREAKCRITICALEDGES") == 0 || strcmp(str, "BREAKCRITEDGES") == 0) v = t_createBreakCriticalEdgesPass;
|
|
|
|
else if (strcmp(str, "CFGSIMPLIFICATION") == 0 || strcmp(str, "SIMPLIFYCFG") == 0) v = t_createCFGSimplificationPass;
|
|
|
|
else if (strcmp(str, "CODEGENPREPARE") == 0) v = t_createCodeGenPreparePass;
|
|
|
|
else if (strcmp(str, "CONSTANTMERGE") == 0 || strcmp(str, "CONSTMERGE") == 0) v = t_createConstantMergePass;
|
|
|
|
else if (strcmp(str, "CONSTANTPROPAGATION") == 0 || strcmp(str, "CONSTPROP") == 0) v = t_createConstantPropagationPass;
|
|
|
|
else if (strcmp(str, "CORRELATEDVALUEPROPAGATION") == 0 || strcmp(str, "CORRELATEDPROPAGATION") == 0) v = t_createCorrelatedValuePropagationPass;
|
|
|
|
else if (strcmp(str, "DEADARGELIMINATION") == 0 || strcmp(str, "DEADARGELIM") == 0) v = t_createDeadArgEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADARGHACKING") == 0 || strcmp(str, "DEADARGHAX0R") == 0) v = t_createDeadArgHackingPass;
|
|
|
|
else if (strcmp(str, "DEADCODEELIMINATION") == 0 || strcmp(str, "DCE") == 0) v = t_createDeadCodeEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADINSTELIMINATION") == 0 || strcmp(str, "DIE") == 0) v = t_createDeadInstEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADSTOREELIMINATION") == 0 || strcmp(str, "DSE") == 0) v = t_createDeadStoreEliminationPass;
|
|
|
|
else if (strcmp(str, "DEMOTEREGISTERTOMEMORY") == 0 || strcmp(str, "REG2MEM") == 0) v = t_createDemoteRegisterToMemoryPass;
|
|
|
|
else if (strcmp(str, "EARLYCSE") == 0) v = t_createEarlyCSEPass;
|
|
|
|
else if (strcmp(str, "FUNCTIONATTRS") == 0) v = t_createFunctionAttrsPass;
|
|
|
|
else if (strcmp(str, "FUNCTIONINLINING") == 0 || strcmp(str, "INLINE") == 0) v = t_createFunctionInliningPass;
|
|
|
|
else if (strcmp(str, "GLOBALDCE") == 0) v = t_createGlobalDCEPass;
|
|
|
|
else if (strcmp(str, "GLOBALOPTIMIZER") == 0 || strcmp(str, "GLOBALOPT") == 0) v = t_createGlobalOptimizerPass;
|
|
|
|
else if (strcmp(str, "GVEXTRACTION") == 0) v = t_createGVExtractionPass;
|
|
|
|
else if (strcmp(str, "GVN") == 0) v = t_createGVNPass;
|
|
|
|
else if (strcmp(str, "INDVARSIMPLIFY") == 0 || strcmp(str, "INDVARS") == 0) v = t_createIndVarSimplifyPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONCOMBINING") == 0 || strcmp(str, "INSTCOMBINE") == 0) v = t_createInstructionCombiningPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONNAMER") == 0 || strcmp(str, "INSTNAMER") == 0) v = t_createInstructionNamerPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONSIMPLIFIER") == 0 || strcmp(str, "INSTSIMPLIFY") == 0) v = t_createInstructionSimplifierPass;
|
|
|
|
else if (strcmp(str, "INTERNALIZE") == 0) v = t_createInternalizePass;
|
|
|
|
else if (strcmp(str, "IPCONSTANTPROPAGATION") == 0 || strcmp(str, "IPCONSTPROP") == 0) v = t_createIPConstantPropagationPass;
|
|
|
|
else if (strcmp(str, "IPSCCP") == 0) v = t_createIPSCCPPass;
|
|
|
|
else if (strcmp(str, "JUMPTHREADING") == 0) v = t_createJumpThreadingPass;
|
|
|
|
else if (strcmp(str, "LCSSA") == 0) v = t_createLCSSAPass;
|
|
|
|
else if (strcmp(str, "LICM") == 0) v = t_createLICMPass;
|
|
|
|
else if (strcmp(str, "LOOPDELETION") == 0) v = t_createLoopDeletionPass;
|
|
|
|
else if (strcmp(str, "LOOPEXTRACTOR") == 0 || strcmp(str, "LOOPEXTRACT") == 0) v = t_createLoopExtractorPass;
|
|
|
|
else if (strcmp(str, "LOOPIDIOM") == 0) v = t_createLoopIdiomPass;
|
|
|
|
else if (strcmp(str, "LOOPINSTSIMPLIFY") == 0) v = t_createLoopInstSimplifyPass;
|
|
|
|
else if (strcmp(str, "LOOPROTATE") == 0) v = t_createLoopRotatePass;
|
|
|
|
else if (strcmp(str, "LOOPSIMPLIFY") == 0) v = t_createLoopSimplifyPass;
|
|
|
|
else if (strcmp(str, "LOOPSTRENGTHREDUCE") == 0 || strcmp(str, "LOOPREDUCE") == 0) v = t_createLoopStrengthReducePass;
|
|
|
|
else if (strcmp(str, "LOOPUNROLL") == 0) v = t_createLoopUnrollPass;
|
|
|
|
else if (strcmp(str, "LOOPUNSWITCH") == 0) v = t_createLoopUnswitchPass;
|
|
|
|
else if (strcmp(str, "LOWERATOMIC") == 0) v = t_createLowerAtomicPass;
|
|
|
|
else if (strcmp(str, "LOWEREXPECTINTRINSIC") == 0 || strcmp(str, "LOWEREXPECT") == 0) v = t_createLowerExpectIntrinsicPass;
|
|
|
|
else if (strcmp(str, "LOWERINVOKE") == 0) v = t_createLowerInvokePass;
|
|
|
|
else if (strcmp(str, "LOWERSWITCH") == 0) v = t_createLowerSwitchPass;
|
|
|
|
else if (strcmp(str, "MEMCPYOPT") == 0) v = t_createMemCpyOptPass;
|
|
|
|
else if (strcmp(str, "MERGEFUNCTIONS") == 0 || strcmp(str, "MERGEFUNC") == 0) v = t_createMergeFunctionsPass;
|
|
|
|
else if (strcmp(str, "OBJCARCAPELIM") == 0) v = t_createObjCARCAPElimPass;
|
|
|
|
else if (strcmp(str, "OBJCARCCONTRACT") == 0) v = t_createObjCARCContractPass;
|
|
|
|
else if (strcmp(str, "OBJCARCEXPAND") == 0) v = t_createObjCARCExpandPass;
|
|
|
|
else if (strcmp(str, "OBJCARCOPT") == 0 || strcmp(str, "OBJCARC") == 0) v = t_createObjCARCOptPass;
|
|
|
|
else if (strcmp(str, "PARTIALINLINING") == 0 || strcmp(str, "PARTIALINLINER") == 0) v = t_createPartialInliningPass;
|
|
|
|
else if (strcmp(str, "PROMOTEMEMORYTOREGISTER") == 0 || strcmp(str, "MEM2REG") == 0) v = t_createPromoteMemoryToRegisterPass;
|
|
|
|
else if (strcmp(str, "PRUNEEH") == 0) v = t_createPruneEHPass;
|
|
|
|
else if (strcmp(str, "REASSOCIATE") == 0) v = t_createReassociatePass;
|
|
|
|
else if (strcmp(str, "SCALARREPLAGGREGATES") == 0 || strcmp(str, "SCALARREPL") == 0) v = t_createScalarReplAggregatesPass;
|
|
|
|
else if (strcmp(str, "SCCP") == 0) v = t_createSCCPPass;
|
|
|
|
else if (strcmp(str, "SIMPLIFYLIBCALLS") == 0) v = t_createSimplifyLibCallsPass;
|
|
|
|
else if (strcmp(str, "SINGLELOOPEXTRACTOR") == 0 || strcmp(str, "LOOPEXTRACTSINGLE") == 0) v = t_createSingleLoopExtractorPass;
|
|
|
|
else if (strcmp(str, "SINKING") == 0 || strcmp(str, "SINK") == 0) v = t_createSinkingPass;
|
|
|
|
else if (strcmp(str, "STRIPDEADDEBUGINFO") == 0) v = t_createStripDeadDebugInfoPass;
|
|
|
|
else if (strcmp(str, "STRIPDEADPROTOTYPES") == 0) v = t_createStripDeadPrototypesPass;
|
|
|
|
else if (strcmp(str, "STRIPDEBUGDECLARE") == 0) v = t_createStripDebugDeclarePass;
|
|
|
|
else if (strcmp(str, "STRIPNONDEBUGSYMBOLS") == 0) v = t_createStripNonDebugSymbolsPass;
|
|
|
|
else if (strcmp(str, "STRIPSYMBOLS") == 0 || strcmp(str, "STRIP") == 0) v = t_createStripSymbolsPass;
|
|
|
|
else if (strcmp(str, "TAILCALLELIMINATION") == 0 || strcmp(str, "TAILCALLELIM") == 0) v = t_createTailCallEliminationPass;
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// creates a new slot in 'ExpEnv.analysis_struc.act_tr' and appends the pass in it
|
|
|
|
ExpEnv.transform_struc.n += 1;
|
|
|
|
ExpEnv.transform_struc.act_tr = (enumTransformPasses*)
|
|
|
|
realloc(ExpEnv.transform_struc.act_tr, ExpEnv.transform_struc.n * sizeof(enumTransformPasses));
|
|
|
|
ExpEnv.transform_struc.act_tr[ExpEnv.transform_struc.n-1] = v;
|
|
|
|
ExpEnv.transform_struc.optlevel = -1; // using this, optlevel won't be used
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Transform pass");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_enable_transform_pass( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
2015-01-18 02:46:03 +00:00
|
|
|
return p_transform_pass( PASS_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_transform_passes( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// valid values for ARG1 are 'atom' and 'list (pair)'
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
if (IsAtomTerm(t)) {
|
|
|
|
// ARG1 is atom
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// If ARG1 is atom, 'all' is the only valid value
|
|
|
|
if (strcmp(str, "ALL") == 0) {
|
|
|
|
// First: disables all transform passes
|
|
|
|
free(ExpEnv.transform_struc.act_tr);
|
|
|
|
ExpEnv.transform_struc.act_tr = NULL;
|
|
|
|
ExpEnv.transform_struc.n = 0;
|
|
|
|
|
|
|
|
// Second, insert all transform passes on 'ExpEnv.analysis_struc.act_tr'
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < N_TRANSFORM_PASSES; i++) {
|
|
|
|
ExpEnv.transform_struc.n += 1;
|
|
|
|
ExpEnv.transform_struc.act_tr = (enumTransformPasses*)realloc(ExpEnv.transform_struc.act_tr, ExpEnv.transform_struc.n * sizeof(enumTransformPasses));
|
|
|
|
ExpEnv.transform_struc.act_tr[ExpEnv.transform_struc.n-1] = i;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
// value passed by argument is out of known range (ARG1 differs of 'all')
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else if (IsPairTerm(t)) {
|
|
|
|
// ARG1 is list
|
|
|
|
// First: disables all transform passes
|
|
|
|
if (ExpEnv.transform_struc.act_tr) free(ExpEnv.transform_struc.act_tr);
|
|
|
|
ExpEnv.transform_struc.act_tr = NULL;
|
|
|
|
ExpEnv.transform_struc.n = 0;
|
|
|
|
|
|
|
|
// Second: scrolls over the list treating each element individually
|
|
|
|
Term u = HeadOfTermCell(t); // get head of list 't'
|
|
|
|
u = Deref(u);
|
|
|
|
while (1) {
|
|
|
|
Int v;
|
|
|
|
enumTransformPasses w;
|
|
|
|
|
|
|
|
// valid values for head are 'integer' and 'atom' (the list can contain both)
|
|
|
|
if (IsIntTerm(u)) {
|
|
|
|
// head is integer
|
|
|
|
v = IntOfTerm(u);
|
|
|
|
if (v < 0 || v >= N_TRANSFORM_PASSES) {
|
|
|
|
// head's value is out of known range
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,u,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// insert transform pass defined by 'head' on 'ExpEnv.analysis_struc.act_tr'
|
|
|
|
ExpEnv.transform_struc.n += 1;
|
|
|
|
ExpEnv.transform_struc.act_tr = (enumTransformPasses*)realloc(ExpEnv.transform_struc.act_tr, ExpEnv.transform_struc.n * sizeof(enumTransformPasses));
|
|
|
|
ExpEnv.transform_struc.act_tr[ExpEnv.transform_struc.n-1] = (enumTransformPasses)v;
|
|
|
|
}
|
|
|
|
else if (IsAtomTerm(u)) {
|
|
|
|
// head is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(u))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(u)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detects one pass according to 'str'
|
|
|
|
if (strcmp(str, "AGGRESSIVEDCE") == 0 || strcmp(str, "ADCE") == 0) w = t_createAggressiveDCEPass;
|
|
|
|
else if (strcmp(str, "ARGUMENTPROMOTION") == 0 || strcmp(str, "ARGPROMOTION") == 0) w = t_createArgumentPromotionPass;
|
|
|
|
else if (strcmp(str, "BBVECTORIZE") == 0) w = t_createBBVectorizePass;
|
|
|
|
else if (strcmp(str, "BLOCKEXTRACTOR") == 0 || strcmp(str, "EXTRACTBLOCKS") == 0) w = t_createBlockExtractorPass;
|
|
|
|
else if (strcmp(str, "BLOCKPLACEMENT") == 0) w = t_createBlockPlacementPass;
|
|
|
|
else if (strcmp(str, "BREAKCRITICALEDGES") == 0 || strcmp(str, "BREAKCRITEDGES") == 0) w = t_createBreakCriticalEdgesPass;
|
|
|
|
else if (strcmp(str, "CFGSIMPLIFICATION") == 0 || strcmp(str, "SIMPLIFYCFG") == 0) w = t_createCFGSimplificationPass;
|
|
|
|
else if (strcmp(str, "CODEGENPREPARE") == 0) w = t_createCodeGenPreparePass;
|
|
|
|
else if (strcmp(str, "CONSTANTMERGE") == 0 || strcmp(str, "CONSTMERGE") == 0) w = t_createConstantMergePass;
|
|
|
|
else if (strcmp(str, "CONSTANTPROPAGATION") == 0 || strcmp(str, "CONSTPROP") == 0) w = t_createConstantPropagationPass;
|
|
|
|
else if (strcmp(str, "CORRELATEDVALUEPROPAGATION") == 0 || strcmp(str, "CORRELATEDPROPAGATION") == 0) w = t_createCorrelatedValuePropagationPass;
|
|
|
|
else if (strcmp(str, "DEADARGELIMINATION") == 0 || strcmp(str, "DEADARGELIM") == 0) w = t_createDeadArgEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADARGHACKING") == 0 || strcmp(str, "DEADARGHAX0R") == 0) w = t_createDeadArgHackingPass;
|
|
|
|
else if (strcmp(str, "DEADCODEELIMINATION") == 0 || strcmp(str, "DCE") == 0) w = t_createDeadCodeEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADINSTELIMINATION") == 0 || strcmp(str, "DIE") == 0) w = t_createDeadInstEliminationPass;
|
|
|
|
else if (strcmp(str, "DEADSTOREELIMINATION") == 0 || strcmp(str, "DSE") == 0) w = t_createDeadStoreEliminationPass;
|
|
|
|
else if (strcmp(str, "DEMOTEREGISTERTOMEMORY") == 0 || strcmp(str, "REG2MEM") == 0) w = t_createDemoteRegisterToMemoryPass;
|
|
|
|
else if (strcmp(str, "EARLYCSE") == 0) w = t_createEarlyCSEPass;
|
|
|
|
else if (strcmp(str, "FUNCTIONATTRS") == 0) w = t_createFunctionAttrsPass;
|
|
|
|
else if (strcmp(str, "FUNCTIONINLINING") == 0 || strcmp(str, "INLINE") == 0) w = t_createFunctionInliningPass;
|
|
|
|
else if (strcmp(str, "GLOBALDCE") == 0) w = t_createGlobalDCEPass;
|
|
|
|
else if (strcmp(str, "GLOBALOPTIMIZER") == 0 || strcmp(str, "GLOBALOPT") == 0) w = t_createGlobalOptimizerPass;
|
|
|
|
else if (strcmp(str, "GVEXTRACTION") == 0) w = t_createGVExtractionPass;
|
|
|
|
else if (strcmp(str, "GVN") == 0) w = t_createGVNPass;
|
|
|
|
else if (strcmp(str, "INDVARSIMPLIFY") == 0 || strcmp(str, "INDVARS") == 0) w = t_createIndVarSimplifyPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONCOMBINING") == 0 || strcmp(str, "INSTCOMBINE") == 0) w = t_createInstructionCombiningPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONNAMER") == 0 || strcmp(str, "INSTNAMER") == 0) w = t_createInstructionNamerPass;
|
|
|
|
else if (strcmp(str, "INSTRUCTIONSIMPLIFIER") == 0 || strcmp(str, "INSTSIMPLIFY") == 0) w = t_createInstructionSimplifierPass;
|
|
|
|
else if (strcmp(str, "INTERNALIZE") == 0) w = t_createInternalizePass;
|
|
|
|
else if (strcmp(str, "IPCONSTANTPROPAGATION") == 0 || strcmp(str, "IPCONSTPROP") == 0) w = t_createIPConstantPropagationPass;
|
|
|
|
else if (strcmp(str, "IPSCCP") == 0) w = t_createIPSCCPPass;
|
|
|
|
else if (strcmp(str, "JUMPTHREADING") == 0) w = t_createJumpThreadingPass;
|
|
|
|
else if (strcmp(str, "LCSSA") == 0) w = t_createLCSSAPass;
|
|
|
|
else if (strcmp(str, "LICM") == 0) w = t_createLICMPass;
|
|
|
|
else if (strcmp(str, "LOOPDELETION") == 0) w = t_createLoopDeletionPass;
|
|
|
|
else if (strcmp(str, "LOOPEXTRACTOR") == 0 || strcmp(str, "LOOPEXTRACT") == 0) w = t_createLoopExtractorPass;
|
|
|
|
else if (strcmp(str, "LOOPIDIOM") == 0) w = t_createLoopIdiomPass;
|
|
|
|
else if (strcmp(str, "LOOPINSTSIMPLIFY") == 0) w = t_createLoopInstSimplifyPass;
|
|
|
|
else if (strcmp(str, "LOOPROTATE") == 0) w = t_createLoopRotatePass;
|
|
|
|
else if (strcmp(str, "LOOPSIMPLIFY") == 0) w = t_createLoopSimplifyPass;
|
|
|
|
else if (strcmp(str, "LOOPSTRENGTHREDUCE") == 0 || strcmp(str, "LOOPREDUCE") == 0) w = t_createLoopStrengthReducePass;
|
|
|
|
else if (strcmp(str, "LOOPUNROLL") == 0) w = t_createLoopUnrollPass;
|
|
|
|
else if (strcmp(str, "LOOPUNSWITCH") == 0) w = t_createLoopUnswitchPass;
|
|
|
|
else if (strcmp(str, "LOWERATOMIC") == 0) w = t_createLowerAtomicPass;
|
|
|
|
else if (strcmp(str, "LOWEREXPECTINTRINSIC") == 0 || strcmp(str, "LOWEREXPECT") == 0) w = t_createLowerExpectIntrinsicPass;
|
|
|
|
else if (strcmp(str, "LOWERINVOKE") == 0) w = t_createLowerInvokePass;
|
|
|
|
else if (strcmp(str, "LOWERSWITCH") == 0) w = t_createLowerSwitchPass;
|
|
|
|
else if (strcmp(str, "MEMCPYOPT") == 0) w = t_createMemCpyOptPass;
|
|
|
|
else if (strcmp(str, "MERGEFUNCTIONS") == 0 || strcmp(str, "MERGEFUNC") == 0) w = t_createMergeFunctionsPass;
|
|
|
|
else if (strcmp(str, "OBJCARCAPELIM") == 0) w = t_createObjCARCAPElimPass;
|
|
|
|
else if (strcmp(str, "OBJCARCCONTRACT") == 0) w = t_createObjCARCContractPass;
|
|
|
|
else if (strcmp(str, "OBJCARCEXPAND") == 0) w = t_createObjCARCExpandPass;
|
|
|
|
else if (strcmp(str, "OBJCARCOPT") == 0 || strcmp(str, "OBJCARC") == 0) w = t_createObjCARCOptPass;
|
|
|
|
else if (strcmp(str, "PARTIALINLINING") == 0 || strcmp(str, "PARTIALINLINER") == 0) w = t_createPartialInliningPass;
|
|
|
|
else if (strcmp(str, "PROMOTEMEMORYTOREGISTER") == 0 || strcmp(str, "MEM2REG") == 0) w = t_createPromoteMemoryToRegisterPass;
|
|
|
|
else if (strcmp(str, "PRUNEEH") == 0) w = t_createPruneEHPass;
|
|
|
|
else if (strcmp(str, "REASSOCIATE") == 0) w = t_createReassociatePass;
|
|
|
|
else if (strcmp(str, "SCALARREPLAGGREGATES") == 0 || strcmp(str, "SCALARREPL") == 0) w = t_createScalarReplAggregatesPass;
|
|
|
|
else if (strcmp(str, "SCCP") == 0) w = t_createSCCPPass;
|
|
|
|
else if (strcmp(str, "SIMPLIFYLIBCALLS") == 0) w = t_createSimplifyLibCallsPass;
|
|
|
|
else if (strcmp(str, "SINGLELOOPEXTRACTOR") == 0 || strcmp(str, "LOOPEXTRACTSINGLE") == 0) w = t_createSingleLoopExtractorPass;
|
|
|
|
else if (strcmp(str, "SINKING") == 0 || strcmp(str, "SINK") == 0) w = t_createSinkingPass;
|
|
|
|
else if (strcmp(str, "STRIPDEADDEBUGINFO") == 0) w = t_createStripDeadDebugInfoPass;
|
|
|
|
else if (strcmp(str, "STRIPDEADPROTOTYPES") == 0) w = t_createStripDeadPrototypesPass;
|
|
|
|
else if (strcmp(str, "STRIPDEBUGDECLARE") == 0) w = t_createStripDebugDeclarePass;
|
|
|
|
else if (strcmp(str, "STRIPNONDEBUGSYMBOLS") == 0) w = t_createStripNonDebugSymbolsPass;
|
|
|
|
else if (strcmp(str, "STRIPSYMBOLS") == 0 || strcmp(str, "STRIP") == 0) w = t_createStripSymbolsPass;
|
|
|
|
else if (strcmp(str, "TAILCALLELIMINATION") == 0 || strcmp(str, "TAILCALLELIM") == 0) w = t_createTailCallEliminationPass;
|
|
|
|
else {
|
|
|
|
// head's value is out of known range
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,u,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// insert transform pass defined by 'head' on 'ExpEnv.analysis_struc.act_tr'
|
|
|
|
ExpEnv.transform_struc.n += 1;
|
|
|
|
ExpEnv.transform_struc.act_tr = (enumTransformPasses*)realloc(ExpEnv.transform_struc.act_tr, ExpEnv.transform_struc.n * sizeof(enumTransformPasses));
|
|
|
|
ExpEnv.transform_struc.act_tr[ExpEnv.transform_struc.n-1] = w;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// head's value is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Transform pass");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// here, 'u' is the current head of list (just been treated) and 't' is our list itself
|
|
|
|
t = TailOfTermCell(t); // 't' is now our list without 'u' (tail of 't')
|
|
|
|
t = Deref(t);
|
|
|
|
if (IsAtomTerm(t)) break; // if 't' is an empty list (which is treated as atom by Prolog), we finish the loop
|
|
|
|
u = HeadOfTermCell(t); // else, 'u' is now next head which will be treated
|
|
|
|
u = Deref(u);
|
|
|
|
}
|
|
|
|
ExpEnv.transform_struc.optlevel = -1; // using this, optlevel won't be used
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Transform pass");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_enable_all_transform_passes( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Same as 'transform_passes(all)'
|
|
|
|
// First, disable all analysis passes
|
|
|
|
if (ExpEnv.transform_struc.act_tr) free(ExpEnv.transform_struc.act_tr);
|
|
|
|
ExpEnv.transform_struc.act_tr = NULL;
|
|
|
|
ExpEnv.transform_struc.n = 0;
|
|
|
|
// Second, insert all transform passes
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < N_TRANSFORM_PASSES; i++) {
|
|
|
|
ExpEnv.transform_struc.n += 1;
|
|
|
|
ExpEnv.transform_struc.act_tr = (enumTransformPasses*)
|
|
|
|
realloc(ExpEnv.transform_struc.act_tr, ExpEnv.transform_struc.n * sizeof(enumTransformPasses));
|
|
|
|
ExpEnv.transform_struc.act_tr[ExpEnv.transform_struc.n-1] = (enumTransformPasses)i;
|
|
|
|
}
|
|
|
|
ExpEnv.transform_struc.optlevel = -1; // using this, optlevel won't be used
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_disable_all_transform_passes( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Just empty 'ExpEnv.analysis_struc.act_tr'
|
|
|
|
if (ExpEnv.transform_struc.act_tr) free(ExpEnv.transform_struc.act_tr);
|
|
|
|
ExpEnv.transform_struc.act_tr = NULL;
|
|
|
|
ExpEnv.transform_struc.n = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_n_transform_passes( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// valid value for ARG1 is just 'integer' (number of transform passes added randomly)
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
Int n = IntOfTerm(t);
|
|
|
|
if (n < 0 || n >= N_TRANSFORM_PASSES) {
|
|
|
|
// value passed by argument is out of known range
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// First: disables all transform passes
|
|
|
|
free(ExpEnv.transform_struc.act_tr);
|
|
|
|
ExpEnv.transform_struc.act_tr = NULL;
|
|
|
|
ExpEnv.transform_struc.n = 0;
|
|
|
|
|
|
|
|
/* Second: adds n transform passes randomly */
|
|
|
|
srand (time(NULL));
|
|
|
|
while (ExpEnv.transform_struc.n < n) {
|
|
|
|
CELL v = rand() % (n);
|
|
|
|
if (
|
|
|
|
((enumTransformPasses)v == t_createBlockExtractorPass) ||
|
|
|
|
((enumTransformPasses)v == t_createDeadArgHackingPass) ||
|
|
|
|
((enumTransformPasses)v == t_createGVExtractionPass) ||
|
|
|
|
((enumTransformPasses)v == t_createLoopExtractorPass) ||
|
|
|
|
((enumTransformPasses)v == t_createStripDeadDebugInfoPass) ||
|
|
|
|
((enumTransformPasses)v == t_createStripDeadPrototypesPass) ||
|
|
|
|
((enumTransformPasses)v == t_createStripDebugDeclarePass) ||
|
|
|
|
((enumTransformPasses)v == t_createStripNonDebugSymbolsPass) ||
|
|
|
|
((enumTransformPasses)v == t_createStripSymbolsPass)
|
|
|
|
) {
|
|
|
|
// I can't add these passes (they are used just for debugging)
|
|
|
|
n -= 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
COUNT i = 0;
|
|
|
|
|
|
|
|
/* I must ensure all steps are different from one another */
|
|
|
|
while (i < ExpEnv.transform_struc.n) {
|
|
|
|
if (ExpEnv.transform_struc.act_tr[i] == (enumTransformPasses)v) break;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (i == ExpEnv.transform_struc.n) {
|
|
|
|
/***/
|
|
|
|
|
|
|
|
// If pass is not specific for debugging and not yet added so I add it */
|
|
|
|
ExpEnv.transform_struc.n += 1;
|
|
|
|
ExpEnv.transform_struc.act_tr = (enumTransformPasses*)
|
|
|
|
realloc(ExpEnv.transform_struc.act_tr, ExpEnv.transform_struc.n*sizeof(enumTransformPasses));
|
|
|
|
ExpEnv.transform_struc.act_tr[ExpEnv.transform_struc.n-1] = (enumTransformPasses)v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ExpEnv.transform_struc.optlevel = -1; // using this, optlevel won't be used
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"N transform passes");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_transform_level( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 is just 'integer'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
Int lvl = IntOfTerm(t);
|
|
|
|
if (lvl < -1 || lvl > 3) {
|
|
|
|
// value passed by argument is out of known range (valid values are: 0, 1, 2, and 3)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
ExpEnv.transform_struc.optlevel = lvl; // if 'transform_pass' or similars are used before, they won't be considered
|
|
|
|
|
|
|
|
/* Setting function inlining threshold (for createFunctionInliningPass) -- level 0 does not apply this */
|
|
|
|
if (ExpEnv.transform_struc.optlevel == 3)
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = 225;
|
|
|
|
else if (ExpEnv.transform_struc.optlevel == 2)
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = 100;
|
|
|
|
else
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = 40;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Transform level");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_argument_promotion_max_elements( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 is just 'integer'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
Int v = IntOfTerm(t);
|
|
|
|
#if SIZEOF_INT_P==4
|
|
|
|
if (v < 0 || v > 0xffffffff) { // 32 bits
|
|
|
|
#else /* SIZEOF_INT_P==8 */
|
|
|
|
if (v < 0 || v > 0x1999999999999999) { // 64 bits
|
|
|
|
#endif
|
|
|
|
// value passed by argument is out of known range (max value is machine-dependent)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// Setting max elements for Argument Promotion Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.arg_promotion_max_elements = v;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Argument Promotion Max Elements");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_scalar_replace_aggregates_threshold( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 is just 'integer'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
Int v = IntOfTerm(t);
|
|
|
|
if (v < -1 || v > 0xffff) {
|
|
|
|
// value passed by argument is out of known range (max value is 65535)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// Setting threshold for Scalar Repl Aggregates Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.scalar_replace_aggregates_threshold = v;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Scalar Replace Aggregates Threshold");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_loop_unroll_threshold( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 is just 'integer'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
Int v = IntOfTerm(t);
|
|
|
|
if (v < -1 || v > 0xffff) {
|
|
|
|
// value passed by argument is out of known range (max value is 65535)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// Setting threshold for Loop Unroll Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.loop_unroll_threshold = v;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Loop Unroll Threshold");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_inline_threshold( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 is just 'integer'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
Int v = IntOfTerm(t);
|
|
|
|
if (v < -1 || v > 0xffff) {
|
|
|
|
// value passed by argument is out of known range (max value is 65535)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// Setting threshold for Function Inlining Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = v;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Inline Threshold");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_strip_symbols_pass_type( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid values for ARG1 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
// Setting Strip Symbols Pass condition. '0' is false; Any other value is true
|
|
|
|
ExpEnv.transform_struc.opt_args.strip_symbols_pass_type = IntOfTerm(t);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (IsAtomTerm(t)) {
|
|
|
|
// ARG1 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) ExpEnv.transform_struc.opt_args.strip_symbols_pass_type = 0;
|
|
|
|
else if (strcmp(str, "TRUE") == 0) ExpEnv.transform_struc.opt_args.strip_symbols_pass_type = 1;
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Strip Symbols Pass Type");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_loop_unswitch_optimize_for_size( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid values for ARG1 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
// Setting Loop Unswitch Pass condition. '0' is false; Any other value is true
|
|
|
|
ExpEnv.transform_struc.opt_args.loop_unswitch_optimize_for_size = IntOfTerm(t);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (IsAtomTerm(t)) {
|
|
|
|
// ARG1 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) ExpEnv.transform_struc.opt_args.loop_unswitch_optimize_for_size = 0;
|
|
|
|
else if (strcmp(str, "TRUE") == 0) ExpEnv.transform_struc.opt_args.loop_unswitch_optimize_for_size = 1;
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Loop Unswitch Optimize for Size");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_default_optimization_args( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
/* resetting arguments used in some passes */
|
|
|
|
ExpEnv.transform_struc.opt_args.arg_promotion_max_elements = 3; // Argument Promotion Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.strip_symbols_pass_type = 0; // Strip Symbols Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.scalar_replace_aggregates_threshold = -1; // Scalar Repl Aggregates Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.loop_unswitch_optimize_for_size = 0; // Loop Unswitch Pass
|
|
|
|
ExpEnv.transform_struc.opt_args.loop_unroll_threshold = -1; // Loop Unroll Pass
|
|
|
|
|
|
|
|
// Function Inlining Pass (according current 'optlevel')
|
|
|
|
if (ExpEnv.transform_struc.optlevel == 3)
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = 225;
|
|
|
|
else if (ExpEnv.transform_struc.optlevel == 2)
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = 100;
|
|
|
|
else if (ExpEnv.transform_struc.optlevel == 1)
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = 40;
|
|
|
|
else // 0
|
|
|
|
ExpEnv.transform_struc.opt_args.inline_threshold = 0;
|
|
|
|
/***/
|
|
|
|
|
|
|
|
// Link-time optimization
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = 0;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = 0;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_reset_optimization_args( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Same as 'p_default_optimization_args'
|
2015-01-18 02:46:03 +00:00
|
|
|
p_default_optimization_args( PASS_REGS1 );
|
2014-07-13 05:30:14 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_enable_unit_at_time( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Enable IPO
|
|
|
|
ExpEnv.transform_struc.unit_at_time_enabled = 1;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_enable_simplify_libcalls( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Enable libcalls simplification
|
|
|
|
ExpEnv.transform_struc.simplify_libcalls_enabled = 1;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_disable_unit_at_time( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Disable IPO
|
|
|
|
ExpEnv.transform_struc.unit_at_time_enabled = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_disable_simplify_libcalls( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Disable libcalls simplification
|
|
|
|
ExpEnv.transform_struc.simplify_libcalls_enabled = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_link_time_opt1( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// 'ARG1' is integer
|
|
|
|
// enabling link-time optimization ('internalize' = 1 and 'runinliner' = 0 are default)
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = IntOfTerm(t);
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = 1;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (IsAtomTerm(t)) {
|
|
|
|
// 'ARG1' is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) {
|
|
|
|
// disabling link-time optimization ('internalize' and 'runinliner' does not work if 'enabled' = 0)
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = 0;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = 0;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = 0;
|
|
|
|
}
|
|
|
|
else if (strcmp(str, "TRUE") == 0) {
|
|
|
|
// enabling link-time optimization ('internalize' = 1 and 'runinliner' = 0 are default)
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = 1;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = 1;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Link-time optimization");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_link_time_opt3( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(t) || IsAtomTerm(t)) {
|
|
|
|
Term u = Deref(ARG2);
|
|
|
|
// valid value for ARG2 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(u) || IsAtomTerm(u)) {
|
|
|
|
Term v = Deref(ARG3);
|
|
|
|
// valid value for ARG3 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(v) || IsAtomTerm(v)) {
|
|
|
|
|
|
|
|
/* setting 1st argument (link-time optimization itself) */
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = IntOfTerm(t);
|
|
|
|
}
|
|
|
|
else /* atom */ {
|
|
|
|
// ARG1 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) ExpEnv.transform_struc.link_time_opt.enabled = 0; // disabling link-time opt
|
|
|
|
else if (strcmp(str, "TRUE") == 0) ExpEnv.transform_struc.link_time_opt.enabled = 1; // enabling link-time opt
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setting 2nd argument (internalize) */
|
|
|
|
if (IsIntTerm(u)) {
|
|
|
|
// ARG2 is integer
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = IntOfTerm(u);
|
|
|
|
}
|
|
|
|
else /* atom */ {
|
|
|
|
// ARG2 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(u))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(u)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) ExpEnv.transform_struc.link_time_opt.internalize = 0; // disabling internalize
|
|
|
|
else if (strcmp(str, "TRUE") == 0) ExpEnv.transform_struc.link_time_opt.internalize = 1; // enabling internalize
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,u,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setting 3rd argument (runinliner) */
|
|
|
|
if (IsIntTerm(v)) {
|
|
|
|
// ARG3 is integer
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = IntOfTerm(v);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else /* atom */ {
|
|
|
|
// ARG3 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(v))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(v)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) ExpEnv.transform_struc.link_time_opt.runinliner = 0; // disabling runinliner
|
|
|
|
else if (strcmp(str, "TRUE") == 0) ExpEnv.transform_struc.link_time_opt.runinliner = 1; // enabling runinliner
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,v,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG3 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Link-time optimization (3rd arg)");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG2 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Link-time optimization (2nd arg)");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Link-time optimization (1st arg)");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_enable_link_time_opt( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
// Same as 'link_time_opt(true)'
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = 1;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = 1;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_enable_link_time_opt2( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Term t = Deref(ARG1);
|
|
|
|
// valid value for ARG1 are 'integer' and 'atom'
|
|
|
|
if (IsIntTerm(t) || IsAtomTerm(t)) {
|
|
|
|
// valid value for ARG2 are 'integer' and 'atom'
|
|
|
|
Term u = Deref(ARG2);
|
|
|
|
if (IsIntTerm(u) || IsAtomTerm(u)) {
|
|
|
|
|
|
|
|
/* setting 1st argument (internalize) */
|
|
|
|
if (IsIntTerm(t)) {
|
|
|
|
// ARG1 is integer
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = IntOfTerm(t);
|
|
|
|
}
|
|
|
|
else /* atom */ {
|
|
|
|
// ARG1 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(t))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(t)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) ExpEnv.transform_struc.link_time_opt.internalize = 0; // disabling internalize
|
|
|
|
else if (strcmp(str, "TRUE") == 0) ExpEnv.transform_struc.link_time_opt.internalize = 1; // enabling internalize
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,t,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setting 2nd argument (runinliner) */
|
|
|
|
if (IsIntTerm(u)) {
|
|
|
|
// ARG2 is integer
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = IntOfTerm(u);
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = 1;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else /* atom */ {
|
|
|
|
// ARG2 is atom
|
|
|
|
int i = 0, j = 0;
|
|
|
|
char *tmp;
|
|
|
|
// gets string from atom and stores it on 'str'
|
|
|
|
char *str = (char*)malloc(YAP_AtomNameLength(AtomOfTerm(u))*sizeof(char));
|
|
|
|
strcpy(str, AtomName(AtomOfTerm(u)));
|
|
|
|
// Makes upper characters of 'str' (for comparison)
|
|
|
|
UPPER_ENTRY(str);
|
|
|
|
|
|
|
|
// Detecting value according to 'str'
|
|
|
|
if (strcmp(str, "FALSE") == 0) ExpEnv.transform_struc.link_time_opt.runinliner = 0; // disabling runinliner
|
|
|
|
else if (strcmp(str, "TRUE") == 0) ExpEnv.transform_struc.link_time_opt.runinliner = 1; // enabling runinliner
|
|
|
|
else {
|
|
|
|
// value passed by argument is out of known range (only 'true' or 'false' are allowed)
|
|
|
|
Yap_Error(OUT_OF_KNOWNRANGE_ERROR,u,"");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = 1; // enabling link-time opt
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG2 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Link-time optimization (2nd arg)");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// ARG1 is not an integer or atom
|
|
|
|
Yap_NilError(INVALID_PARAMETER_TYPE_ERROR,"Link-time optimization (1st arg)");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2015-01-18 02:46:03 +00:00
|
|
|
p_disable_link_time_opt( USES_REGS1 )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
ExpEnv.transform_struc.link_time_opt.enabled = 0;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.internalize = 0;
|
|
|
|
ExpEnv.transform_struc.link_time_opt.runinliner = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
|
|
|
|
void
|
2015-01-18 01:32:13 +00:00
|
|
|
Yap_InitJitTransformPreds( void )
|
2014-07-13 05:30:14 +01:00
|
|
|
{
|
|
|
|
Yap_InitCPred("disable_transform_pass", 1, p_disable_transform_pass, SafePredFlag);
|
|
|
|
Yap_InitCPred("transform_pass", 1, p_transform_pass, SafePredFlag);
|
|
|
|
Yap_InitCPred("enable_transform_pass", 1, p_enable_transform_pass, SafePredFlag);
|
|
|
|
Yap_InitCPred("transform_passes", 1, p_transform_passes, SafePredFlag);
|
|
|
|
Yap_InitCPred("enable_all_transform_passes", 0, p_enable_all_transform_passes, SafePredFlag);
|
|
|
|
Yap_InitCPred("disable_all_transform_passes", 1, p_disable_all_transform_passes, SafePredFlag);
|
|
|
|
Yap_InitCPred("n_transform_passes", 1, p_n_transform_passes, SafePredFlag);
|
|
|
|
Yap_InitCPred("transform_level", 1, p_transform_level, SafePredFlag);
|
|
|
|
Yap_InitCPred("argument_promotion_max_elements", 1, p_argument_promotion_max_elements, SafePredFlag);
|
|
|
|
Yap_InitCPred("scalar_replace_aggregates_threshold", 1, p_scalar_replace_aggregates_threshold, SafePredFlag);
|
|
|
|
Yap_InitCPred("loop_unroll_threshold", 1, p_loop_unroll_threshold, SafePredFlag);
|
|
|
|
Yap_InitCPred("inline_threshold", 1, p_inline_threshold, SafePredFlag);
|
|
|
|
Yap_InitCPred("strip_symbols_pass_type", 1, p_strip_symbols_pass_type, SafePredFlag);
|
|
|
|
Yap_InitCPred("loop_unswitch_optimize_for_size", 1, p_loop_unswitch_optimize_for_size, SafePredFlag);
|
|
|
|
Yap_InitCPred("default_optimization_args", 0, p_default_optimization_args, SafePredFlag);
|
|
|
|
Yap_InitCPred("reset_optimization_args", 0, p_reset_optimization_args, SafePredFlag);
|
|
|
|
Yap_InitCPred("enable_unit_at_time", 0, p_enable_unit_at_time, SafePredFlag);
|
|
|
|
Yap_InitCPred("enable_simplify_libcalls", 0, p_enable_simplify_libcalls, SafePredFlag);
|
|
|
|
Yap_InitCPred("disable_unit_at_time", 0, p_disable_unit_at_time, SafePredFlag);
|
|
|
|
Yap_InitCPred("disable_simplify_libcalls", 0, p_disable_simplify_libcalls, SafePredFlag);
|
|
|
|
Yap_InitCPred("link_time_opt", 1, p_link_time_opt1, SafePredFlag);
|
|
|
|
Yap_InitCPred("link_time_opt", 3, p_link_time_opt3, SafePredFlag);
|
|
|
|
Yap_InitCPred("enable_link_time_opt", 0, p_enable_link_time_opt, SafePredFlag);
|
|
|
|
Yap_InitCPred("enable_link_time_opt", 2, p_enable_link_time_opt2, SafePredFlag);
|
|
|
|
Yap_InitCPred("disable_link_time_opt", 0, p_disable_link_time_opt, SafePredFlag);
|
|
|
|
}
|