1216 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1216 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*************************************************************************
 | 
						|
*									 *
 | 
						|
*	 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                               		 *
 | 
						|
*************************************************************************/
 | 
						|
 | 
						|
#define JIT_CODE 1
 | 
						|
 | 
						|
#include "jit_predicates.hpp"
 | 
						|
 | 
						|
#define N_TRANSFORM_PASSES 69
 | 
						|
 | 
						|
// Disable one (passed by argument) LLVM transform pass
 | 
						|
static Int  p_disable_transform_pass( USES_REGS1 );
 | 
						|
 | 
						|
// Enable one (passed by argument) LLVM transform pass
 | 
						|
static Int  p_transform_pass( USES_REGS1 );
 | 
						|
 | 
						|
// Enable one (passed by argument) LLVM transform pass
 | 
						|
static Int  p_enable_transform_pass( USES_REGS1 );
 | 
						|
 | 
						|
// Enable a list (passed by argument) of LLVM transform passes
 | 
						|
static Int  p_transform_passes( USES_REGS1 );
 | 
						|
 | 
						|
// Enable all available LLVM transform passes
 | 
						|
static Int  p_enable_all_transform_passes( USES_REGS1 );
 | 
						|
 | 
						|
// Disable all available LLVM transform passes
 | 
						|
static Int  p_disable_all_transform_passes( USES_REGS1 );
 | 
						|
 | 
						|
// Enable n LLVM transform passes (randomly)
 | 
						|
static Int  p_n_transform_passes( USES_REGS1 );
 | 
						|
 | 
						|
// Enable a transform level
 | 
						|
static Int  p_transform_level( USES_REGS1 );
 | 
						|
 | 
						|
// Max element of Argument Promotion Pass
 | 
						|
static Int  p_argument_promotion_max_elements( USES_REGS1 );
 | 
						|
 | 
						|
// Threshold of Scalar Repl Aggregates Pass
 | 
						|
static Int  p_scalar_replace_aggregates_threshold( USES_REGS1 );
 | 
						|
 | 
						|
// Threshold of Loop Unroll Pass
 | 
						|
static Int  p_loop_unroll_threshold( USES_REGS1 );
 | 
						|
 | 
						|
// Threshold of Function Inlining Pass
 | 
						|
static Int  p_inline_threshold( USES_REGS1 );
 | 
						|
 | 
						|
// Eliminates (or not) only debugging information on Strip Symbols Pass
 | 
						|
static Int  p_strip_symbols_pass_type( USES_REGS1 );
 | 
						|
 | 
						|
// Optimizes (or not) for size on Loop Unswitch Pass
 | 
						|
static Int  p_loop_unswitch_optimize_for_size( USES_REGS1 );
 | 
						|
 | 
						|
/*
 | 
						|
 * 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 *
 | 
						|
*/
 | 
						|
static Int  p_default_optimization_args( USES_REGS1 );
 | 
						|
 | 
						|
// Same as 'p_default_optimization_args'
 | 
						|
static Int  p_reset_optimization_args( USES_REGS1 );
 | 
						|
 | 
						|
// Enable IPO by LLVM
 | 
						|
static Int  p_enable_unit_at_time( USES_REGS1 );
 | 
						|
 | 
						|
// Enable libcalls simplification by LLVM
 | 
						|
static Int  p_enable_simplify_libcalls( USES_REGS1 );
 | 
						|
 | 
						|
// Disable IPO by LLVM
 | 
						|
static Int  p_disable_unit_at_time( USES_REGS1 );
 | 
						|
 | 
						|
// Disable libcalls simplification by LLVM
 | 
						|
static Int  p_disable_simplify_libcalls( USES_REGS1 );
 | 
						|
 | 
						|
// Enable (or not) link-time optimization
 | 
						|
static Int  p_link_time_opt1( USES_REGS1 );
 | 
						|
 | 
						|
/*
 | 
						|
 * 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?                         *
 | 
						|
*/
 | 
						|
static Int  p_link_time_opt3( USES_REGS1 );
 | 
						|
 | 
						|
// Enable link-time optimization. Same as 'link_time_opt(true)'
 | 
						|
static Int  p_enable_link_time_opt( USES_REGS1 );
 | 
						|
 | 
						|
/*
 | 
						|
 * Same as 'p_enable_link_time_opt', but accepts 2 arguments: *
 | 
						|
 *   1 -- Should I run internalize?                     *
 | 
						|
 *   2 -- Should I run inliner?                         *
 | 
						|
*/
 | 
						|
static Int  p_enable_link_time_opt2( USES_REGS1 );
 | 
						|
 | 
						|
// Disable link-time optimization.
 | 
						|
static Int  p_disable_link_time_opt( USES_REGS1 );
 | 
						|
 | 
						|
#pragma GCC diagnostic push
 | 
						|
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
 | 
						|
 | 
						|
static Int
 | 
						|
p_disable_transform_pass( USES_REGS1 )
 | 
						|
{
 | 
						|
  // 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
 | 
						|
p_transform_pass( USES_REGS1 )
 | 
						|
{
 | 
						|
  // First: disables analysis pass (if be active)
 | 
						|
  p_disable_transform_pass( PASS_REGS1 );
 | 
						|
 | 
						|
  // 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
 | 
						|
p_enable_transform_pass( USES_REGS1 )
 | 
						|
{
 | 
						|
  return p_transform_pass( PASS_REGS1 );
 | 
						|
}
 | 
						|
 | 
						|
static Int
 | 
						|
p_transform_passes( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_enable_all_transform_passes( USES_REGS1 )
 | 
						|
{
 | 
						|
  // 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
 | 
						|
p_disable_all_transform_passes( USES_REGS1 )
 | 
						|
{
 | 
						|
  // 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
 | 
						|
p_n_transform_passes( USES_REGS1 )
 | 
						|
{
 | 
						|
  // 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
 | 
						|
p_transform_level( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_argument_promotion_max_elements( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_scalar_replace_aggregates_threshold( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_loop_unroll_threshold( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_inline_threshold( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_strip_symbols_pass_type( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_loop_unswitch_optimize_for_size( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_default_optimization_args( USES_REGS1 )
 | 
						|
{
 | 
						|
  /* 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
 | 
						|
p_reset_optimization_args( USES_REGS1 )
 | 
						|
{
 | 
						|
  // Same as 'p_default_optimization_args'
 | 
						|
  p_default_optimization_args( PASS_REGS1 );
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Int
 | 
						|
p_enable_unit_at_time( USES_REGS1 )
 | 
						|
{
 | 
						|
  // Enable IPO
 | 
						|
  ExpEnv.transform_struc.unit_at_time_enabled = 1;
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Int
 | 
						|
p_enable_simplify_libcalls( USES_REGS1 )
 | 
						|
{
 | 
						|
  // Enable libcalls simplification
 | 
						|
  ExpEnv.transform_struc.simplify_libcalls_enabled = 1;
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Int
 | 
						|
p_disable_unit_at_time( USES_REGS1 )
 | 
						|
{
 | 
						|
  // Disable IPO
 | 
						|
  ExpEnv.transform_struc.unit_at_time_enabled = 0;
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Int
 | 
						|
p_disable_simplify_libcalls( USES_REGS1 )
 | 
						|
{
 | 
						|
  // Disable libcalls simplification
 | 
						|
  ExpEnv.transform_struc.simplify_libcalls_enabled = 0;
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Int
 | 
						|
p_link_time_opt1( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_link_time_opt3( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_enable_link_time_opt( USES_REGS1 )
 | 
						|
{
 | 
						|
  // 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
 | 
						|
p_enable_link_time_opt2( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
p_disable_link_time_opt( USES_REGS1 )
 | 
						|
{
 | 
						|
  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
 | 
						|
Yap_InitJitTransformPreds( void )
 | 
						|
{
 | 
						|
  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);
 | 
						|
}
 |