922 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			922 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "JIT_Compiler.hpp"
 | 
						|
#include <unistd.h>
 | 
						|
#include <sys/wait.h>
 | 
						|
#include <fcntl.h>
 | 
						|
//using namespace std;
 | 
						|
//using namespace llvm;
 | 
						|
 | 
						|
#include <llvm/Pass.h>
 | 
						|
#include <llvm/PassAnalysisSupport.h>
 | 
						|
#include <llvm/PassInfo.h>
 | 
						|
#include <llvm/PassManager.h>
 | 
						|
#include <llvm/PassRegistry.h>
 | 
						|
#include <llvm/PassSupport.h>
 | 
						|
#include <llvm/Analysis/CallGraphSCCPass.h>
 | 
						|
#include <llvm/CodeGen/Passes.h>
 | 
						|
 | 
						|
#include "PassPrinters.hh"
 | 
						|
 | 
						|
#define FREE_ALLOCATED() \
 | 
						|
  free(buffer); \
 | 
						|
  free(p->y_u.J.jh->cmd); \
 | 
						|
  free(outputfilename); \
 | 
						|
  free(optoutputfilename); \
 | 
						|
  free(cmd1); \
 | 
						|
  free(cmd2);
 | 
						|
 | 
						|
#define ADD_PASS_ACCORDING_TO_KIND()		\
 | 
						|
	switch (Kind) { \
 | 
						|
        case PT_BasicBlock: \
 | 
						|
	  fprintf(stderr, "Oops -- basicblock printer\n"); \
 | 
						|
	  exit(1); \
 | 
						|
        case PT_Region: \
 | 
						|
	  Pass.add(new RegionPassPrinter(PInfo));	\
 | 
						|
          break; \
 | 
						|
        case PT_Loop: \
 | 
						|
          Pass.add(new LoopPassPrinter(PInfo)); \
 | 
						|
          break; \
 | 
						|
        case PT_Function: \
 | 
						|
          Pass.add(new FunctionPassPrinter(PInfo)); \
 | 
						|
          break; \
 | 
						|
        case PT_CallGraphSCC: \
 | 
						|
          Pass.add(new CallGraphSCCPassPrinter(PInfo)); \
 | 
						|
          break; \
 | 
						|
        default: \
 | 
						|
	  Pass.add(new ModulePassPrinter(PInfo));	\
 | 
						|
          break; \
 | 
						|
        }
 | 
						|
 | 
						|
#define TREAT_CASE_FOR(PASS) \
 | 
						|
	    PInfo = PassRegistry::getPassRegistry()->getPassInfo(PASS->getPassID()); \
 | 
						|
	    Kind = PASS->getPassKind(); \
 | 
						|
	    ADD_PASS_ACCORDING_TO_KIND();
 | 
						|
 | 
						|
void JIT_Compiler::analyze_module(llvm::Module* &M)
 | 
						|
{
 | 
						|
  PassManager Pass; // 'Pass' stores analysis passes to be applied
 | 
						|
  TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));
 | 
						|
 | 
						|
  const PassInfo *PInfo;
 | 
						|
  PassKind Kind;
 | 
						|
 | 
						|
  Pass.add(TLI); // First, I add on 'Pass' the Target Info of Module
 | 
						|
  Pass.add(new DataLayoutPass()); // Second, I must add Target Data on 'Pass'
 | 
						|
  for (int i = 0; i < ExpEnv.analysis_struc.n; i++) {
 | 
						|
    /*
 | 
						|
     * 'ExpEnv.analysis_struc.act_an' contains sorted analysis passes *
 | 
						|
     * 'ExpEnv.analysis_struc.act_an' is filled by analysis predicates *
 | 
						|
     * What must I do? *
 | 
						|
     *    1. Pass over 'ExpEnv.analysis_struc.act_an' (by previous 'for') *
 | 
						|
     *    2. For each unity within 'ExpEnv.analysis_struc.act_an' *
 | 
						|
     *        2.1. Check its type *
 | 
						|
     *        2.2. Add analysis pass on 'Pass' accordingly the type checked *
 | 
						|
    */
 | 
						|
    switch (ExpEnv.analysis_struc.act_an[i]) {
 | 
						|
    case e_createAAEvalPass:
 | 
						|
      TREAT_CASE_FOR(createAAEvalPass());
 | 
						|
      break;
 | 
						|
    case e_createBasicAliasAnalysisPass:
 | 
						|
      TREAT_CASE_FOR(createBasicAliasAnalysisPass());
 | 
						|
      break;
 | 
						|
    case e_createAliasAnalysisCounterPass:
 | 
						|
      TREAT_CASE_FOR(createAliasAnalysisCounterPass());
 | 
						|
      break;
 | 
						|
    case e_createGlobalsModRefPass:
 | 
						|
      TREAT_CASE_FOR(createGlobalsModRefPass());
 | 
						|
      break;
 | 
						|
    case e_createInstCountPass:
 | 
						|
      TREAT_CASE_FOR(createInstCountPass());
 | 
						|
      break;
 | 
						|
    case e_createIVUsersPass:
 | 
						|
      TREAT_CASE_FOR(createIVUsersPass());
 | 
						|
      break;
 | 
						|
    case e_createLazyValueInfoPass:
 | 
						|
      TREAT_CASE_FOR(createLazyValueInfoPass());
 | 
						|
      break;
 | 
						|
    //CHANGED FOR LLVM 3.5
 | 
						|
    case e_createLoopDependenceAnalysisPass:
 | 
						|
      TREAT_CASE_FOR(createDependenceAnalysisPass());
 | 
						|
      break;
 | 
						|
    case e_createLibCallAliasAnalysisPass:
 | 
						|
      TREAT_CASE_FOR(createLibCallAliasAnalysisPass(NULL));
 | 
						|
      break;
 | 
						|
    case e_createLintPass:
 | 
						|
      TREAT_CASE_FOR(createLintPass());
 | 
						|
      break;
 | 
						|
    case e_createMemDepPrinter:
 | 
						|
      TREAT_CASE_FOR(createMemDepPrinter());
 | 
						|
      break;
 | 
						|
    case e_createModuleDebugInfoPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createModuleDebugInfoPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createNoAAPass:
 | 
						|
      TREAT_CASE_FOR(createNoAAPass());
 | 
						|
      break;
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //case e_createNoPathProfileInfoPass:
 | 
						|
    //  TREAT_CASE_FOR(createNoPathProfileInfoPass());
 | 
						|
    //  break;
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //case e_createNoProfileInfoPass:
 | 
						|
    //  TREAT_CASE_FOR(createNoProfileInfoPass());
 | 
						|
    //  break;
 | 
						|
    case e_createObjCARCAliasAnalysisPass:
 | 
						|
      TREAT_CASE_FOR(createObjCARCAliasAnalysisPass());
 | 
						|
      break;
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //case e_createProfileEstimatorPass:
 | 
						|
    //  TREAT_CASE_FOR(createProfileEstimatorPass());
 | 
						|
    //  break;
 | 
						|
    //CHANGED FOR LLVM 3.5
 | 
						|
    case e_createProfileLoaderPass:
 | 
						|
      TREAT_CASE_FOR(createSampleProfileLoaderPass());
 | 
						|
      break;
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //case e_createProfileVerifierPass:
 | 
						|
    //  TREAT_CASE_FOR(createProfileVerifierPass());
 | 
						|
    //  break;
 | 
						|
    case e_createRegionInfoPass:
 | 
						|
      TREAT_CASE_FOR(createRegionInfoPass());
 | 
						|
      break;
 | 
						|
    case e_createScalarEvolutionAliasAnalysisPass:
 | 
						|
      TREAT_CASE_FOR(createScalarEvolutionAliasAnalysisPass());
 | 
						|
      break;
 | 
						|
    case e_createTypeBasedAliasAnalysisPass:
 | 
						|
      TREAT_CASE_FOR(createTypeBasedAliasAnalysisPass());
 | 
						|
      break;
 | 
						|
    //CHANGED FOR LLVM 3.5
 | 
						|
    case e_createDbgInfoPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createDebugInfoVerifierPass());
 | 
						|
      break;
 | 
						|
    case e_createCFGPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createCFGPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createCFGOnlyPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createCFGOnlyPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createDomPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createDomPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createDomOnlyPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createDomOnlyPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createPostDomPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createPostDomPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createPostDomOnlyPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createPostDomOnlyPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createRegionPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createRegionPrinterPass());
 | 
						|
      break;
 | 
						|
    case e_createRegionOnlyPrinterPass:
 | 
						|
      TREAT_CASE_FOR(createRegionOnlyPrinterPass());
 | 
						|
      break;
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //case e_createPathProfileLoaderPass:
 | 
						|
    //  TREAT_CASE_FOR(createPathProfileLoaderPass());
 | 
						|
    //  break;
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //case e_createPathProfileVerifierPass:
 | 
						|
    //  TREAT_CASE_FOR(createPathProfileVerifierPass());
 | 
						|
    //  break;
 | 
						|
    default:;
 | 
						|
    }
 | 
						|
  }
 | 
						|
   
 | 
						|
  /* if 'llvm::TimePassesIsEnabled' is 'true', llvm time passes are printed on 'shutdown_llvm()' (p_halt -- stdpreds.c) */
 | 
						|
  llvm::TimePassesIsEnabled = ExpEnv.analysis_struc.time_pass_enabled;
 | 
						|
  /* Use 'llvm::EnableStatistics()' so that llvm stats are printed on 'shutdown_llvm()' (p_halt -- stdpreds.c) */
 | 
						|
  if (ExpEnv.analysis_struc.stats_enabled) llvm::EnableStatistics();
 | 
						|
  
 | 
						|
  /*
 | 
						|
   * Here, I configure resulting analysis output -- default: stderr *
 | 
						|
   * Use analysis_output_file/1 to change *
 | 
						|
  */
 | 
						|
  if (strcmp(((char*)ExpEnv.analysis_struc.outfile), "STDERR")) { // print to file that is not stderr
 | 
						|
    int stderrcopy = dup(2); // stderr backup
 | 
						|
    if (strcmp(((char*)ExpEnv.analysis_struc.outfile), "STDOUT") == 0) { // print to stdout
 | 
						|
      dup2(1, 2); // 2 is stderr; 1 is stdout -- dup2(1,2) redirects stderr output to stdout
 | 
						|
      Pass.run(*M); // Run passes (results will be printed on stdout)
 | 
						|
      dup2(stderrcopy, 2); // Recovers stderr
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      int Outputfile = open(((char*)ExpEnv.analysis_struc.outfile), O_CREAT | O_TRUNC | O_WRONLY, 0777);
 | 
						|
      // Openning Output file, whose name is on 'ExpEnv.analysis_struc.outfile'
 | 
						|
      if (Outputfile < 0) {
 | 
						|
        fprintf(stderr, "Error:: I can not write analysis passes's output on %s...\n", ((char*)ExpEnv.analysis_struc.outfile));
 | 
						|
        fprintf(stderr, "        %s...\n", strerror(errno));
 | 
						|
        errno = 0;
 | 
						|
        exit(1);
 | 
						|
      }
 | 
						|
      dup2(Outputfile, 2); // 2 is stderr; Outputfile is any other file -- dup2(Outputfile,2) redirects stderr output to Outputfile
 | 
						|
      Pass.run(*M); // Run passes (results will be printed on Outputfile)
 | 
						|
      close(Outputfile);
 | 
						|
      dup2(stderrcopy, 2); // Recovers stderr
 | 
						|
    }
 | 
						|
    close(stderrcopy);
 | 
						|
  }
 | 
						|
  else // print to stderr
 | 
						|
    Pass.run(*M); // Run passes (results will be printed on stderr)
 | 
						|
}
 | 
						|
 | 
						|
void JIT_Compiler::optimize_module(llvm::Module* &M)
 | 
						|
{
 | 
						|
  if (ExpEnv.transform_struc.optlevel > -1) { /* Do I need to apply transform level? */
 | 
						|
    /* Yes, I do, so... */
 | 
						|
 | 
						|
    /* Initializes PassManager for Function */
 | 
						|
    std::shared_ptr<FunctionPassManager> FPM;
 | 
						|
    FPM.reset(new legacy::FunctionPassManager(M));
 | 
						|
    FPM->add(new DataLayoutPass());
 | 
						|
    PassManagerBuilder Builder; // aid to 'FPM' and 'MPM'
 | 
						|
	
 | 
						|
    /* Initializes PassManager for Function */
 | 
						|
    PassManager MPM;
 | 
						|
    TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));
 | 
						|
    MPM.add(TLI);
 | 
						|
    MPM.add(new DataLayoutPass());
 | 
						|
	
 | 
						|
    /* Populates 'Builder' */
 | 
						|
    Builder.OptLevel = ExpEnv.transform_struc.optlevel;
 | 
						|
    Builder.DisableUnitAtATime = !ExpEnv.transform_struc.unit_at_time_enabled;
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //Builder.DisableSimplifyLibCalls = !ExpEnv.transform_struc.simplify_libcalls_enabled;
 | 
						|
      /* inline and unrool only be enabled if 'ExpEnv.transform_struc.optlevel' > 0 */
 | 
						|
      if (ExpEnv.transform_struc.optlevel) Builder.Inliner =
 | 
						|
          createFunctionInliningPass(ExpEnv.transform_struc.opt_args.inline_threshold);
 | 
						|
      Builder.DisableUnrollLoops = (ExpEnv.transform_struc.optlevel == 0);
 | 
						|
      /***/
 | 
						|
    /***/
 | 
						|
 | 
						|
    /* Populates 'FPM' from 'Builder' */
 | 
						|
    Builder.populateFunctionPassManager(*FPM);
 | 
						|
    /* Populates 'MPM' from 'Builder' */
 | 
						|
    Builder.populateModulePassManager(MPM);
 | 
						|
    
 | 
						|
    /*
 | 
						|
     * Enabling link-time optimizations -- default is no *
 | 
						|
     * Use 'link_time_opt/1', 'link_time_opt/3', 'enable_link_time_opt/0', or 'enable_link_time_opt/2' to change *
 | 
						|
    */
 | 
						|
    if (ExpEnv.transform_struc.link_time_opt.enabled)
 | 
						|
      Builder.populateLTOPassManager(MPM /*,
 | 
						|
                                     (bool)ExpEnv.transform_struc.link_time_opt.internalize,
 | 
						|
                                     (bool)ExpEnv.transform_struc.link_time_opt.runinliner
 | 
						|
					 */);
 | 
						|
    /***/
 | 
						|
 | 
						|
    //set_regalloc_pass(MPM);
 | 
						|
 | 
						|
    /* Pass over all functions within Module and run passes */
 | 
						|
    FPM->doInitialization();
 | 
						|
    for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F)
 | 
						|
      FPM->run(*F);
 | 
						|
    FPM->doFinalization();
 | 
						|
    /***/
 | 
						|
 | 
						|
    MPM.run(*M); // Run passes on module
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    /* No, I need to apply transform passes accordingly transform predicates but transform_level/1 */
 | 
						|
    std::vector<GlobalValue*> GVvector; // 'createGVExtractionPass' argument
 | 
						|
    PassManager Pass; // 'Pass' stores transform passes to be applied
 | 
						|
    TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));
 | 
						|
    Pass.add(TLI); // First, I add on 'Pass' the Target Info of Module
 | 
						|
    Pass.add(new DataLayoutPass()); // Second, I must add Target Data on 'Pass'
 | 
						|
    for (int i = 0; i < ExpEnv.transform_struc.n; i++) {
 | 
						|
      /*
 | 
						|
       * 'ExpEnv.transform_struc.act_tr' contains sorted transform passes *
 | 
						|
       * 'ExpEnv.transform_struc.act_tr' is filled by transform predicates *
 | 
						|
       * What must I do? *
 | 
						|
       *    1. Pass over 'ExpEnv.transform_struc.act_tr' (by previous 'for') *
 | 
						|
       *    2. For each unity within 'ExpEnv.analysis_struc.act_an', add transform pass on 'Pass' *
 | 
						|
      */
 | 
						|
      switch (ExpEnv.transform_struc.act_tr[i]) {
 | 
						|
      case t_createAggressiveDCEPass:
 | 
						|
        Pass.add(createAggressiveDCEPass());
 | 
						|
	break;
 | 
						|
      case t_createArgumentPromotionPass:
 | 
						|
        Pass.add(createArgumentPromotionPass((Int)ExpEnv.transform_struc.opt_args.arg_promotion_max_elements));
 | 
						|
        break;
 | 
						|
      case t_createBBVectorizePass:
 | 
						|
        Pass.add(createBBVectorizePass());
 | 
						|
        break;
 | 
						|
      case t_createBlockExtractorPass:
 | 
						|
        Pass.add(createBlockExtractorPass());
 | 
						|
        break;
 | 
						|
      //NOT IN LLVM 3.5
 | 
						|
      //case t_createBlockPlacementPass:
 | 
						|
      //  Pass.add(createBlockPlacementPass());
 | 
						|
      //  break;
 | 
						|
      case t_createBreakCriticalEdgesPass:
 | 
						|
        Pass.add(createBreakCriticalEdgesPass());
 | 
						|
        break;
 | 
						|
      case t_createCFGSimplificationPass:
 | 
						|
        Pass.add(createCFGSimplificationPass());
 | 
						|
        break;
 | 
						|
      case t_createCodeGenPreparePass:
 | 
						|
        Pass.add(createCodeGenPreparePass());
 | 
						|
        break;
 | 
						|
      case t_createConstantMergePass:
 | 
						|
        Pass.add(createConstantMergePass());
 | 
						|
        break;
 | 
						|
      case t_createConstantPropagationPass:
 | 
						|
        Pass.add(createConstantPropagationPass());
 | 
						|
        break;
 | 
						|
      case t_createCorrelatedValuePropagationPass:
 | 
						|
        Pass.add(createCorrelatedValuePropagationPass());
 | 
						|
        break;
 | 
						|
      case t_createDeadArgEliminationPass:
 | 
						|
        Pass.add(createDeadArgEliminationPass());
 | 
						|
        break;
 | 
						|
      case t_createDeadArgHackingPass:
 | 
						|
        Pass.add(createDeadArgHackingPass());
 | 
						|
        break;
 | 
						|
      case t_createDeadCodeEliminationPass:
 | 
						|
        Pass.add(createDeadCodeEliminationPass());
 | 
						|
        break;
 | 
						|
      case t_createDeadInstEliminationPass:
 | 
						|
        Pass.add(createDeadInstEliminationPass());
 | 
						|
        break;
 | 
						|
      case t_createDeadStoreEliminationPass:
 | 
						|
        Pass.add(createDeadStoreEliminationPass());
 | 
						|
        break;
 | 
						|
      case t_createDemoteRegisterToMemoryPass:
 | 
						|
        Pass.add(createDemoteRegisterToMemoryPass());
 | 
						|
        break;
 | 
						|
      case t_createEarlyCSEPass:
 | 
						|
        Pass.add(createEarlyCSEPass());
 | 
						|
        break;
 | 
						|
      case t_createFunctionAttrsPass:
 | 
						|
        Pass.add(createFunctionAttrsPass());
 | 
						|
        break;
 | 
						|
      case t_createFunctionInliningPass:
 | 
						|
        Pass.add(createFunctionInliningPass(ExpEnv.transform_struc.opt_args.inline_threshold));
 | 
						|
        break;
 | 
						|
      case t_createGlobalDCEPass:
 | 
						|
        Pass.add(createGlobalDCEPass());
 | 
						|
        break;
 | 
						|
      case t_createGlobalOptimizerPass:
 | 
						|
        Pass.add(createGlobalOptimizerPass());
 | 
						|
        break;
 | 
						|
      case t_createGVExtractionPass:
 | 
						|
        Pass.add(createGVExtractionPass(GVvector));
 | 
						|
        break;
 | 
						|
      case t_createGVNPass:
 | 
						|
        Pass.add(createGVNPass());
 | 
						|
        break;
 | 
						|
      case t_createIndVarSimplifyPass:
 | 
						|
        Pass.add(createIndVarSimplifyPass());
 | 
						|
        break;
 | 
						|
      case t_createInstructionCombiningPass:
 | 
						|
        Pass.add(createInstructionCombiningPass());
 | 
						|
        break;
 | 
						|
      case t_createInstructionNamerPass:
 | 
						|
        Pass.add(createInstructionNamerPass());
 | 
						|
        break;
 | 
						|
      case t_createInstructionSimplifierPass:
 | 
						|
        Pass.add(createInstructionSimplifierPass());
 | 
						|
        break;
 | 
						|
      case t_createInternalizePass:
 | 
						|
        Pass.add(createInternalizePass());
 | 
						|
        break;
 | 
						|
      case t_createIPConstantPropagationPass:
 | 
						|
        Pass.add(createIPConstantPropagationPass());
 | 
						|
        break;
 | 
						|
      case t_createIPSCCPPass:
 | 
						|
        Pass.add(createIPSCCPPass());
 | 
						|
        break;
 | 
						|
      case t_createJumpThreadingPass:
 | 
						|
        Pass.add(createJumpThreadingPass());
 | 
						|
        break;
 | 
						|
      case t_createLCSSAPass:
 | 
						|
        Pass.add(createLCSSAPass());
 | 
						|
        break;
 | 
						|
      case t_createLICMPass:
 | 
						|
        Pass.add(createLICMPass());
 | 
						|
        break;
 | 
						|
      case t_createLoopDeletionPass:
 | 
						|
        Pass.add(createLoopDeletionPass());
 | 
						|
        break;
 | 
						|
      case t_createLoopExtractorPass:
 | 
						|
        Pass.add(createLoopExtractorPass());
 | 
						|
        break;
 | 
						|
      case t_createLoopIdiomPass:
 | 
						|
        Pass.add(createLoopIdiomPass());
 | 
						|
        break;
 | 
						|
      case t_createLoopInstSimplifyPass:
 | 
						|
        Pass.add(createLoopInstSimplifyPass());
 | 
						|
        break;
 | 
						|
      case t_createLoopRotatePass:
 | 
						|
        Pass.add(createLoopRotatePass());
 | 
						|
        break;
 | 
						|
      case t_createLoopSimplifyPass:
 | 
						|
        Pass.add(createLoopSimplifyPass());
 | 
						|
        break;
 | 
						|
      case t_createLoopStrengthReducePass:
 | 
						|
        Pass.add(createLoopStrengthReducePass());
 | 
						|
        break;
 | 
						|
      case t_createLoopUnrollPass:
 | 
						|
        Pass.add(createLoopUnrollPass((Int)ExpEnv.transform_struc.opt_args.loop_unroll_threshold));
 | 
						|
        break;
 | 
						|
      case t_createLoopUnswitchPass:
 | 
						|
        Pass.add(createLoopUnswitchPass((bool)ExpEnv.transform_struc.opt_args.loop_unswitch_optimize_for_size));
 | 
						|
        break;
 | 
						|
      case t_createLowerAtomicPass:
 | 
						|
        Pass.add(createLowerAtomicPass());
 | 
						|
        break;
 | 
						|
      case t_createLowerExpectIntrinsicPass:
 | 
						|
        Pass.add(createLowerExpectIntrinsicPass());
 | 
						|
        break;
 | 
						|
      case t_createLowerInvokePass:
 | 
						|
        Pass.add(createLowerInvokePass());
 | 
						|
        break;
 | 
						|
      case t_createLowerSwitchPass:
 | 
						|
        Pass.add(createLowerSwitchPass());
 | 
						|
        break;
 | 
						|
      case t_createMemCpyOptPass:
 | 
						|
        Pass.add(createMemCpyOptPass());
 | 
						|
        break;
 | 
						|
      case t_createMergeFunctionsPass:
 | 
						|
        Pass.add(createMergeFunctionsPass());
 | 
						|
        break;
 | 
						|
      case t_createObjCARCAPElimPass:
 | 
						|
        Pass.add(createObjCARCAPElimPass());
 | 
						|
        break;
 | 
						|
      case t_createObjCARCContractPass:
 | 
						|
        Pass.add(createObjCARCContractPass());
 | 
						|
        break;
 | 
						|
      case t_createObjCARCExpandPass:
 | 
						|
        Pass.add(createObjCARCExpandPass());
 | 
						|
        break;
 | 
						|
      case t_createObjCARCOptPass:
 | 
						|
        Pass.add(createObjCARCOptPass());
 | 
						|
        break;
 | 
						|
      case t_createPartialInliningPass:
 | 
						|
        Pass.add(createPartialInliningPass());
 | 
						|
        break;
 | 
						|
      case t_createPromoteMemoryToRegisterPass:
 | 
						|
        Pass.add(createPromoteMemoryToRegisterPass());
 | 
						|
        break;
 | 
						|
      case t_createPruneEHPass:
 | 
						|
        Pass.add(createPruneEHPass());
 | 
						|
        break;
 | 
						|
      case t_createReassociatePass:
 | 
						|
        Pass.add(createReassociatePass());
 | 
						|
        break;
 | 
						|
      case t_createScalarReplAggregatesPass:
 | 
						|
        Pass.add(createScalarReplAggregatesPass((Int)ExpEnv.transform_struc.opt_args.scalar_replace_aggregates_threshold));
 | 
						|
        break;
 | 
						|
      case t_createSCCPPass:
 | 
						|
        Pass.add(createSCCPPass());
 | 
						|
        break;
 | 
						|
      //NOT IN LLVM 3.5
 | 
						|
      //case t_createSimplifyLibCallsPass:
 | 
						|
      //  Pass.add(createSimplifyLibCallsPass());
 | 
						|
      //  break;
 | 
						|
      case t_createSingleLoopExtractorPass:
 | 
						|
        Pass.add(createSingleLoopExtractorPass());
 | 
						|
        break;
 | 
						|
      case t_createSinkingPass:
 | 
						|
        Pass.add(createSinkingPass());
 | 
						|
        break;
 | 
						|
      case t_createStripDeadDebugInfoPass:
 | 
						|
        Pass.add(createStripDeadDebugInfoPass());
 | 
						|
        break;
 | 
						|
      case t_createStripDeadPrototypesPass:
 | 
						|
        Pass.add(createStripDeadPrototypesPass());
 | 
						|
        break;
 | 
						|
      case t_createStripDebugDeclarePass:
 | 
						|
        Pass.add(createStripDebugDeclarePass());
 | 
						|
        break;
 | 
						|
      case t_createStripNonDebugSymbolsPass:
 | 
						|
        Pass.add(createStripNonDebugSymbolsPass());
 | 
						|
        break;
 | 
						|
      case t_createStripSymbolsPass:
 | 
						|
        Pass.add(createStripSymbolsPass((bool)ExpEnv.transform_struc.opt_args.strip_symbols_pass_type));
 | 
						|
        break;
 | 
						|
      case t_createTailCallEliminationPass:
 | 
						|
        Pass.add(createTailCallEliminationPass());
 | 
						|
        break;
 | 
						|
      default:;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    //set_regalloc_pass(Pass);
 | 
						|
    Pass.run(*M); // Run passes
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void JIT_Compiler::set_regalloc_pass(PassManager &PM) {
 | 
						|
  // 'ExpEnv.codegen_struc.struc_enginebuilder.regallocator' contains the active register allocator to be used
 | 
						|
  switch(ExpEnv.codegen_struc.struc_enginebuilder.regallocator) {
 | 
						|
  case REG_ALLOC_BASIC:
 | 
						|
    PM.add(createBasicRegisterAllocator());
 | 
						|
    break;
 | 
						|
  case REG_ALLOC_FAST:
 | 
						|
    PM.add(createFastRegisterAllocator());
 | 
						|
    break;
 | 
						|
  case REG_ALLOC_GREEDY:
 | 
						|
    PM.add(createGreedyRegisterAllocator());
 | 
						|
    break;
 | 
						|
  case REG_ALLOC_PBQP:
 | 
						|
    PM.add(createDefaultPBQPRegisterAllocator());
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void* JIT_Compiler::compile_all(LLVMContext* &Context, yamop* p)
 | 
						|
{
 | 
						|
  /* Init llvm code generation, analysis and transform passes */
 | 
						|
  InitializeNativeTarget();
 | 
						|
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
 | 
						|
  initializeCore(Registry);
 | 
						|
  initializeScalarOpts(Registry);
 | 
						|
  initializeVectorization(Registry);
 | 
						|
  initializeIPO(Registry);
 | 
						|
  initializeAnalysis(Registry);
 | 
						|
  initializeIPA(Registry);
 | 
						|
  initializeTransformUtils(Registry);
 | 
						|
  initializeInstCombine(Registry);
 | 
						|
  initializeInstrumentation(Registry);
 | 
						|
  initializeTarget(Registry);
 | 
						|
  sys::Process::PreventCoreFiles();
 | 
						|
 | 
						|
#pragma GCC diagnostic push
 | 
						|
#pragma GCC diagnostic ignored "-Wwrite-strings"
 | 
						|
  /* CLANG arguments */
 | 
						|
  char *clang_args[] =
 | 
						|
{
 | 
						|
    "clang", "-fomit-frame-pointer", "-O0",
 | 
						|
#if CUT_C
 | 
						|
    "-DCUT_C=1",
 | 
						|
#endif
 | 
						|
#if COROUTINING
 | 
						|
    "-DCOROUTINING=1",
 | 
						|
#endif
 | 
						|
#if RATIONAL_TREES
 | 
						|
    "-DRATIONAL_TREES=1",
 | 
						|
#endif
 | 
						|
#if DEBUG
 | 
						|
    "-DDEBUG=1",
 | 
						|
#endif
 | 
						|
#if DEPTH_LIMIT
 | 
						|
    "-DDEPTH_LIMIT=1",
 | 
						|
#endif
 | 
						|
#if YAP_DBG_PREDS
 | 
						|
    "-DYAP_DBG_PREDS=1",
 | 
						|
#endif
 | 
						|
#if YAP_STAT_PREDS
 | 
						|
    "-DYAP_STAT_PREDS=1",
 | 
						|
#endif
 | 
						|
#if TABLING
 | 
						|
    "-DTABLING=1",
 | 
						|
#endif
 | 
						|
#if _YAP_NOT_INSTALLED_
 | 
						|
    "-D_YAP_NOT_INSTALLED_=1",
 | 
						|
#endif
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
    "-DHAVE_CONFIG_H",
 | 
						|
#endif
 | 
						|
    "-DYAP_JIT", "-D_NATIVE=1", "-I.", "-I./H", "-I./include", "-I./os", "-I./OPTYap", "-I./BEAM", "-I./MYDDAS", "-I./HPP", "-xc", "-c", "-", "-o", "-", "-emit-llvm", NULL
 | 
						|
};
 | 
						|
#pragma GCC diagnostic pop
 | 
						|
  
 | 
						|
  std::string errStr;
 | 
						|
  error_code e;
 | 
						|
 | 
						|
  /* Pipe to communicate 'echo' with 'clang' */
 | 
						|
  int pipe1[2];
 | 
						|
  int pid_echo, pid_clang ;
 | 
						|
  
 | 
						|
  /* 'clang' out file */
 | 
						|
  char* outputfilename = (char*)malloc(33*sizeof(char));
 | 
						|
  sprintf(outputfilename, "%lx.bc", (CELL)p);
 | 
						|
  int Output = open(outputfilename, O_CREAT | O_RDWR, 0644);
 | 
						|
  
 | 
						|
  /* Creating pipes */
 | 
						|
  if (pipe(pipe1)<0) {
 | 
						|
    perror("      ERROR!!\n      ERROR") ;
 | 
						|
    exit(1);
 | 
						|
  }
 | 
						|
	
 | 
						|
  /* Calls echo. */
 | 
						|
  pid_echo = fork() ;
 | 
						|
  if (pid_echo < 0) {
 | 
						|
    perror("      ERROR!!\n      ERROR") ;
 | 
						|
    exit(1);
 | 
						|
  }
 | 
						|
  if (!pid_echo) {
 | 
						|
    /* Setting echo's output to 1st pipe */
 | 
						|
    dup2(pipe1[1], 1);
 | 
						|
	
 | 
						|
    /* Closing pipes */
 | 
						|
    close(pipe1[0]);
 | 
						|
    close(pipe1[1]);
 | 
						|
    
 | 
						|
    execlp("echo", "echo", p->y_u.J.jh->tcc.cmd, NULL);
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    /* Calls clang. */
 | 
						|
    pid_clang = fork() ;
 | 
						|
    if (pid_clang < 0) {
 | 
						|
      perror("      ERROR!!\n      ERROR") ;
 | 
						|
      exit(1);
 | 
						|
    }
 | 
						|
    if (!pid_clang) {
 | 
						|
      /* Setting clang's input from 1st pipe */
 | 
						|
      dup2(pipe1[0], 0) ;
 | 
						|
 | 
						|
      /* Setting clang's output to Output */
 | 
						|
      dup2(Output, 1) ;
 | 
						|
		  
 | 
						|
      /* Closing pipes */
 | 
						|
      close(pipe1[0]);
 | 
						|
      close(pipe1[1]);
 | 
						|
		  
 | 
						|
      execvp(*clang_args, clang_args);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /* Closing pipes */
 | 
						|
  close(pipe1[0]);
 | 
						|
  close(pipe1[1]);
 | 
						|
 | 
						|
  /* waiting for completion of processes */
 | 
						|
  int i;
 | 
						|
  int *status = NULL;
 | 
						|
  // 2 means two processes: 'echo' and 'clang'
 | 
						|
  for (i = 0; i < 2; i++) wait(status);
 | 
						|
  /***/
 | 
						|
  
 | 
						|
  /*
 | 
						|
   * At this point, the compiled code (O0) is on 'Output' *
 | 
						|
   * I need to read it to main memory *
 | 
						|
   * for this, I'll use 'MemoryBuffer::getOpenFile' *
 | 
						|
  */
 | 
						|
  lseek(Output, 0, SEEK_SET);
 | 
						|
  ErrorOr<std::unique_ptr<MemoryBuffer>> em = MemoryBuffer::getOpenFile(Output, outputfilename, -1);
 | 
						|
  e = em.getError();
 | 
						|
  if (e) {
 | 
						|
    errs() << "ERROR::Unable to MemoryBuffer from " << outputfilename << " -- " << e.message() << "\n";
 | 
						|
    exit(1);
 | 
						|
  }
 | 
						|
 | 
						|
  /*
 | 
						|
   * At this point, the compiled code (O0) is on main memory *
 | 
						|
   * I need to read it to Module *
 | 
						|
   * for this, I'll use 'parseBitcodeFile' *
 | 
						|
  */
 | 
						|
  ErrorOr<Module *> ModuleOrErr =
 | 
						|
    parseBitcodeFile(em.get()->getMemBufferRef(), *Context);
 | 
						|
 | 
						|
  std::unique_ptr<Module> M;
 | 
						|
  
 | 
						|
  if (std::error_code ec = ModuleOrErr.getError()) 
 | 
						|
    errs() <<  ec.message();
 | 
						|
  /* at last, get M */
 | 
						|
  M.reset(ModuleOrErr.get());
 | 
						|
  /*
 | 
						|
   * verify module correctness *
 | 
						|
   * predicates: *
 | 
						|
   *   enable_module_correctness/1 *
 | 
						|
   *   verify_module_before/0 *
 | 
						|
   *   verify_module_both/0 *
 | 
						|
  */
 | 
						|
  if (ExpEnv.analysis_struc.pointtoverifymodule == BEFORE || ExpEnv.analysis_struc.pointtoverifymodule == BOTH) {
 | 
						|
    if (verifyModule(*M)) {
 | 
						|
      errs() << "ERROR:: Module not built correctly!\n";
 | 
						|
      exit(1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /***/
 | 
						|
 | 
						|
#if YAP_DBG_PREDS
 | 
						|
  /* for debug... print module before optimizing it */
 | 
						|
  if (ExpEnv.debug_struc.pprint_llva.print_llva_before)
 | 
						|
    errs() << "Module before optimization::\n" << *Mod;
 | 
						|
#endif
 | 
						|
 | 
						|
  llvm::Module *Mod = M.get();
 | 
						|
  /* Analyze module -- analysis predicates */
 | 
						|
  analyze_module(Mod);
 | 
						|
  /* Optimize module -- transform predicates */
 | 
						|
  optimize_module(Mod);
 | 
						|
  
 | 
						|
  /* Computing size of optimized module */
 | 
						|
  {
 | 
						|
    std::error_code  ErrorInfo;
 | 
						|
    /* Open file 'tmp.bc' which will be filled by optimized Module */
 | 
						|
    std::unique_ptr<tool_output_file> Out;
 | 
						|
    Out.reset(new tool_output_file("tmp.bc", ErrorInfo, llvm::sys::fs::F_None));
 | 
						|
    if (ErrorInfo) {
 | 
						|
      errs() << ErrorInfo.message() << '\n';
 | 
						|
      exit(1);
 | 
						|
    }
 | 
						|
    /* 'createPrintModulePass(arg)' will print Module (now optimized) to on file represented by 'arg' */
 | 
						|
    PassManager Pass;
 | 
						|
    Pass.add(createPrintModulePass(Out->os()));
 | 
						|
    Pass.run(*M);
 | 
						|
    /* 'Out->keep()' will keep printed module to file and will close file */
 | 
						|
    Out->keep();
 | 
						|
	
 | 
						|
    /* Open file 'tmp.bc' */
 | 
						|
    int Outtmp = open("tmp.bc", O_CREAT | O_RDWR, 0644);
 | 
						|
#if YAP_STAT_PREDS
 | 
						|
    /* for statistics... compute file size and store value on 'NativeArea->area.native_size_bytes' */
 | 
						|
    NativeArea->area.native_size_bytes[p->y_u.jhc.jh->caa.naddress][NativeArea->area.nrecomp[p->y_u.jhc.jh->caa.naddress]-1] = lseek(Outtmp, 0, SEEK_END);
 | 
						|
#endif
 | 
						|
    close(Outtmp);
 | 
						|
    remove("tmp.bc");
 | 
						|
  }
 | 
						|
  /***/\
 | 
						|
  
 | 
						|
#if YAP_DBG_PREDS
 | 
						|
  /* for debug... print module after optimizing it */
 | 
						|
  if (ExpEnv.debug_struc.pprint_llva.print_llva_after)
 | 
						|
    errs() << "Module after optimization::\n" << *Mod;
 | 
						|
#endif
 | 
						|
	
 | 
						|
  /*
 | 
						|
   * verify module correctness *
 | 
						|
   * predicates: *
 | 
						|
   *   enable_module_correctness/0 *
 | 
						|
   *   enable_module_correctness/1 *
 | 
						|
   *   verify_module_after/0 *
 | 
						|
   *   verify_module_both/0 *
 | 
						|
  */
 | 
						|
  if (ExpEnv.analysis_struc.pointtoverifymodule == AFTER || ExpEnv.analysis_struc.pointtoverifymodule == BOTH) {
 | 
						|
    if (verifyModule(*Mod)) {
 | 
						|
      errs() << "ERROR:: Module not built correctly!\n";
 | 
						|
      exit(1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /***/
 | 
						|
  
 | 
						|
  // materializeAllPermanently -- Make sure all GlobalValues in this Module are fully read
 | 
						|
  error_code materialize_error = Mod->materializeAllPermanently();
 | 
						|
  if (materialize_error.value() != 0) {
 | 
						|
    errs() <<"Error:: bitcode didn't read correctly. -- " << materialize_error.message() << "\n";
 | 
						|
    exit(1);
 | 
						|
  }
 | 
						|
 | 
						|
  /* Creating EngineBuilder -- called 'builder' */
 | 
						|
  Function *EntryFn;
 | 
						|
   
 | 
						|
  llvm::CodeGenOpt::Level level;
 | 
						|
  switch(ExpEnv.codegen_struc.struc_enginebuilder.engineoptlevel) {
 | 
						|
    case 0:
 | 
						|
      level = CodeGenOpt::None;
 | 
						|
      break;
 | 
						|
    case 1:
 | 
						|
      level = CodeGenOpt::Less;
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      level = CodeGenOpt::Default;
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      level = CodeGenOpt::Aggressive;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  // codegen predicate 'relocmodel/1'
 | 
						|
  llvm::Reloc::Model relocmodel;
 | 
						|
  switch(ExpEnv.codegen_struc.struc_enginebuilder.relocmodel) {
 | 
						|
    case 0:
 | 
						|
      relocmodel = Reloc::Default;
 | 
						|
      break;
 | 
						|
    case 1:
 | 
						|
      relocmodel = Reloc::Static;
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      relocmodel = Reloc::PIC_;
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      relocmodel = Reloc::DynamicNoPIC;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  // codegen predicate 'codemodel/1'
 | 
						|
  llvm::CodeModel::Model codemodel;
 | 
						|
  switch(ExpEnv.codegen_struc.struc_enginebuilder.codemodel) {
 | 
						|
    case 0:
 | 
						|
      codemodel = CodeModel::Default;
 | 
						|
      break;
 | 
						|
    case 1:
 | 
						|
      codemodel = CodeModel::JITDefault;
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      codemodel = CodeModel::Small;
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      codemodel = CodeModel::Kernel;
 | 
						|
      break;
 | 
						|
    case 4:
 | 
						|
      codemodel = CodeModel::Medium;
 | 
						|
      break;
 | 
						|
    case 5:
 | 
						|
      codemodel = CodeModel::Large;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  // MCJIT is default from 3.6
 | 
						|
  // codegen predicates 'enable_mcjit/0' or 'disable_mcjit/0'
 | 
						|
  //  builder.setUseMCJIT((bool)ExpEnv.codegen_struc.struc_enginebuilder.usemcjit);
 | 
						|
  llvm::TargetOptions Options;
 | 
						|
  {
 | 
						|
    /* codegen predicates 'enable_framepointer_elimination/0' or 'disable_framepointer_elimination/0' */
 | 
						|
    Options.NoFramePointerElim = (bool)ExpEnv.codegen_struc.struc_targetopt.noframepointerelim;
 | 
						|
	//NOT IN LLVM 3.5
 | 
						|
    //Options.NoFramePointerElimNonLeaf = (bool)ExpEnv.codegen_struc.struc_targetopt.noframepointerelim;
 | 
						|
    /***/
 | 
						|
    // codegen predicates 'less_precise_fp_mad_option/0' or 'more_precise_fp_mad_option/0'
 | 
						|
    Options.LessPreciseFPMADOption = (bool)ExpEnv.codegen_struc.struc_targetopt.lessprecisefpmadoption;
 | 
						|
    // codegen predicates 'no_excess_fp_precision/0' or 'excess_fp_precision/0'
 | 
						|
    //NOT IN LLVM 3.5
 | 
						|
    //Options.NoExcessFPPrecision = (bool)ExpEnv.codegen_struc.struc_targetopt.noexcessfpprecision;
 | 
						|
    // codegen predicates 'unsafe_fp_math/0' or 'safe_fp_math/0'
 | 
						|
    Options.UnsafeFPMath = (bool)ExpEnv.codegen_struc.struc_targetopt.unsafefpmath;
 | 
						|
    // codegen predicates 'rounding_mode_dynamically_changed/0' or 'rounding_mode_not_changed/0'
 | 
						|
    Options.HonorSignDependentRoundingFPMathOption =
 | 
						|
        (bool)ExpEnv.codegen_struc.struc_targetopt.honorsigndependentroundingfpmathoption;
 | 
						|
    // codegen predicates 'no_use_soft_float/0' or 'use_soft_float/0'
 | 
						|
    Options.UseSoftFloat = (bool)ExpEnv.codegen_struc.struc_targetopt.usesoftfloat;
 | 
						|
    // codegen predicates 'enable_jit_exception_handling/0' or 'disable_jit_exception_handling/0'
 | 
						|
	//NOT IN LLVM 3.5
 | 
						|
    //Options.JITExceptionHandling = (bool)ExpEnv.codegen_struc.struc_targetopt.jitexceptionhandling;
 | 
						|
    // codegen predicates 'enable_jit_emit_debug_info/0' or 'disable_jit_emit_debug_info/0'
 | 
						|
    Options.JITEmitDebugInfo = (bool)ExpEnv.codegen_struc.struc_targetopt.jitemitdebuginfo;
 | 
						|
    // codegen predicates 'enable_jit_emit_debug_info_to_disk/0' or 'disable_jit_emit_debug_info_to_disk/0'
 | 
						|
    Options.JITEmitDebugInfoToDisk = (bool)ExpEnv.codegen_struc.struc_targetopt.jitemitdebuginfotodisk;
 | 
						|
    // codegen predicates 'guaranteed_tail_call_opt/0' or 'no_guaranteed_tail_call_opt/0'
 | 
						|
    Options.GuaranteedTailCallOpt = (bool)ExpEnv.codegen_struc.struc_targetopt.guaranteedtailcallopt;
 | 
						|
    // codegen predicates 'enable_tail_calls/0' or 'disable_tail_calls/0'
 | 
						|
    Options.DisableTailCalls = (bool)ExpEnv.codegen_struc.struc_targetopt.disabletailcalls;
 | 
						|
    // codegen predicates 'enable_fast_isel/0' or 'disable_fast_isel/0'
 | 
						|
    Options.EnableFastISel = (bool)ExpEnv.codegen_struc.struc_targetopt.fastisel;
 | 
						|
  }
 | 
						|
  // codegen predicates 'fp_abitype/1' or 'default_fp_abitype/0'
 | 
						|
  switch(ExpEnv.codegen_struc.struc_targetopt.floatabitype) {
 | 
						|
    case 0:
 | 
						|
      Options.FloatABIType = FloatABI::Default;
 | 
						|
      break;
 | 
						|
    case 1:
 | 
						|
      Options.FloatABIType = FloatABI::Soft;
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      Options.FloatABIType = FloatABI::Hard;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
   
 | 
						|
  // codegen predicate 'engine_opt_level/1'
 | 
						|
 | 
						|
  /* Creating ExecutionEngine from EngineBuilder (builder) */
 | 
						|
  ExecutionEngine *EE =
 | 
						|
    EngineBuilder(std::move(M))
 | 
						|
    .setErrorStr(&errStr)
 | 
						|
    .setOptLevel( level )
 | 
						|
    .setRelocationModel( relocmodel )
 | 
						|
    .setCodeModel( codemodel )
 | 
						|
    .setEngineKind(EngineKind::JIT)
 | 
						|
       .setTargetOptions(Options)
 | 
						|
       // check class in Kaleidoscope example.
 | 
						|
       //    .setMCJITMemoryManager(std::unique_ptr<HelpingMemoryManager>(
 | 
						|
       //								 new HelpingMemoryManager(this)))
 | 
						|
    .setMCJITMemoryManager(std::unique_ptr<SectionMemoryManager>(new SectionMemoryManager()))
 | 
						|
    .create();
 | 
						|
  if (!EE) {
 | 
						|
    if (!errStr.empty())
 | 
						|
      errs() << "Error creating Execution Engine: " << errStr << "\n";
 | 
						|
    else
 | 
						|
      errs() << "Unknown error creating Execution Engine!\n";
 | 
						|
    exit(1);
 | 
						|
  }
 | 
						|
  /***/
 | 
						|
 | 
						|
  // 'clause' is our function -- getting it from Module
 | 
						|
  EntryFn = Mod->getFunction("clause");
 | 
						|
  if (!EntryFn) {
 | 
						|
    /*
 | 
						|
     * Theoretically, every Module is correct, but *
 | 
						|
     * for some reason, llvm can not compile some of them *
 | 
						|
    */
 | 
						|
    close(Output);
 | 
						|
    remove(outputfilename);
 | 
						|
    free(p->y_u.J.jh->tcc.cmd);
 | 
						|
    free(outputfilename);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  /* Here, we know that Module was be successfully compiled, so... */
 | 
						|
  // 1. execute all of the static constructors or destructors for program
 | 
						|
  EE->runStaticConstructorsDestructors(false);
 | 
						|
  // global++; what is this?
 | 
						|
  close(Output);
 | 
						|
  remove(outputfilename);
 | 
						|
  free(p->y_u.J.jh->tcc.cmd);
 | 
						|
  free(outputfilename);
 | 
						|
  // 2. get native pointer from 'clause' (our function within Module) and return it
 | 
						|
  return EE->getPointerToFunction(EntryFn);
 | 
						|
}
 | 
						|
 | 
						|
void* JIT_Compiler::compile(yamop* p) {
 | 
						|
  /* LLVMContext must be declared here, otherwise LLVM will crash on x86_64 machines */
 | 
						|
  LLVMContext *Context = new LLVMContext();
 | 
						|
  return compile_all(Context, p);
 | 
						|
}
 |