Example #1
0
LLVMExecutionEngineRef
mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb)
{
  std::string Error;

  force_pass_linking ();

  LLVMInitializeX86Target ();
  LLVMInitializeX86TargetInfo ();

  llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "", false);

  mono_mm = new MonoJITMemoryManager ();
  mono_mm->alloc_cb = alloc_cb;

#if LLVM_MAJOR_VERSION == 2 && LLVM_MINOR_VERSION < 8
   DwarfExceptionHandling = true;
#else
   JITExceptionHandling = true;
#endif
  // PrettyStackTrace installs signal handlers which trip up libgc
  DisablePrettyStackTrace = true;

  ExecutionEngine *EE = ExecutionEngine::createJIT (unwrap (MP), &Error, mono_mm, CodeGenOpt::Default);
  if (!EE) {
	  errs () << "Unable to create LLVM ExecutionEngine: " << Error << "\n";
	  g_assert_not_reached ();
  }
  EE->InstallExceptionTableRegister (exception_cb);
  EE->RegisterJITEventListener (new MonoJITEventListener (emitted_cb));

  fpm = new FunctionPassManager (unwrap (MP));

  fpm->add(new TargetData(*EE->getTargetData()));
  /* Add a default set of passes */
  //createStandardFunctionPasses (fpm, 2);
  fpm->add(createInstructionCombiningPass());
  fpm->add(createReassociatePass());
  fpm->add(createGVNPass());
  fpm->add(createCFGSimplificationPass());

  /* The one used by opt is:
   * -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -basiccg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loopsimplify -domfrontier -loopsimplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loopsimplify -lcssa -iv-users -indvars -loop-deletion -loopsimplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify
   */

  /* Add passes specified by the env variable */
  /* Only the passes in force_pass_linking () can be used */
  for (unsigned i = 0; i < PassList.size(); ++i) {
      const PassInfo *PassInf = PassList[i];
      Pass *P = 0;

      if (PassInf->getNormalCtor())
		  P = PassInf->getNormalCtor()();
	  fpm->add (P);
  }

  return wrap(EE);
}
Example #2
0
LLVMExecutionEngineRef
mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb)
{
  std::string Error;

  LLVMInitializeX86Target ();
  LLVMInitializeX86TargetInfo ();

  llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "", false);

  mono_mm = new MonoJITMemoryManager ();
  mono_mm->alloc_cb = alloc_cb;
  mono_mm->emitted_cb = emitted_cb;

  DwarfExceptionHandling = true;
  // PrettyStackTrace installs signal handlers which trip up libgc
  DisablePrettyStackTrace = true;

  ExecutionEngine *EE = ExecutionEngine::createJIT (unwrap (MP), &Error, mono_mm, CodeGenOpt::Default);
  if (!EE) {
	  errs () << "Unable to create LLVM ExecutionEngine: " << Error << "\n";
	  g_assert_not_reached ();
  }
  EE->InstallExceptionTableRegister (exception_cb);
  EE->RegisterJITEventListener (new MonoJITEventListener ());

  fpm = new FunctionPassManager (unwrap (MP));

  fpm->add(new TargetData(*EE->getTargetData()));
  /* Add a random set of passes */
  /* Make this run-time configurable */
  fpm->add(createInstructionCombiningPass());
  fpm->add(createReassociatePass());
  fpm->add(createGVNPass());
  fpm->add(createCFGSimplificationPass());

  /* Add passes specified by the env variable */
  /* FIXME: This can only add passes which are linked in, thus are already used */
  for (unsigned i = 0; i < PassList.size(); ++i) {
      const PassInfo *PassInf = PassList[i];
      Pass *P = 0;

      if (PassInf->getNormalCtor())
		  P = PassInf->getNormalCtor()();
	  if (dynamic_cast<MachineFunctionPass*>(P) != 0) {
		  errs () << PassInf->getPassName () << " is a machine function pass.\n";
	  } else {
		  fpm->add (P);
	  }
  }

  return wrap(EE);
}
Example #3
0
int
main()
{
	Module*          module = new Module("interactive");
	ExecutionEngine* engine = ExecutionEngine::create(module);
	
	CEnv cenv(module, engine->getTargetData());

	repl(cenv, engine);

	std::cout << "Generated code:" << endl;
	module->dump();

	return 0;
}
Example #4
0
 main_func_type jit_engine::compile(const ast::Program &prog) {
     llvm::LLVMContext &c=llvm::getGlobalContext();
     llvm::Module *m=new llvm::Module("brainfuck", c);
     brainfuck::codegen(*m, prog);
     //m->dump();
     
     std::string ErrStr;
     ExecutionEngine *TheExecutionEngine = EngineBuilder(m).setErrorStr(&ErrStr).create();
     if (!TheExecutionEngine) {
         fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
         exit(1);
     }
     Function *f_main=m->getFunction("main");
     
     // Optimize, target dependant
     if(optimization_level_>0)
     {
         FunctionPassManager OurFPM(m);
         
         // Set up the optimizer pipeline.  Start with registering info about how the
         // target lays out data structures.
         OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
         // Provide basic AliasAnalysis support for GVN.
         OurFPM.add(createBasicAliasAnalysisPass());
         // Do simple "peephole" optimizations and bit-twiddling optzns.
         OurFPM.add(createInstructionCombiningPass());
         // Reassociate expressions.
         OurFPM.add(createReassociatePass());
         // Eliminate Common SubExpressions.
         OurFPM.add(createGVNPass());
         // Simplify the control flow graph (deleting unreachable blocks, etc).
         OurFPM.add(createCFGSimplificationPass());
         //OurFPM.add(createLoopSimplifyPass());
         //OurFPM.add(createBlockPlacementPass());
         //OurFPM.add(createConstantPropagationPass());
         
         OurFPM.doInitialization();
      
         OurFPM.run(*f_main);
     }
     
     //m->dump();
     
     void *rp=TheExecutionEngine->getPointerToFunction(f_main);
     main_func_type fp=reinterpret_cast<main_func_type>(rp);
     return fp;
 }
Example #5
0
LLVMExecutionEngineRef
mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb)
{
  std::string Error;

  force_pass_linking ();

#ifdef TARGET_ARM
  LLVMInitializeARMTarget ();
  LLVMInitializeARMTargetInfo ();
  LLVMInitializeARMTargetMC ();
#else
  LLVMInitializeX86Target ();
  LLVMInitializeX86TargetInfo ();
  LLVMInitializeX86TargetMC ();
#endif

  mono_mm = new MonoJITMemoryManager ();
  mono_mm->alloc_cb = alloc_cb;
  mono_mm->dlsym_cb = dlsym_cb;

  //JITExceptionHandling = true;
  // PrettyStackTrace installs signal handlers which trip up libgc
  DisablePrettyStackTrace = true;

  /*
   * The Default code model doesn't seem to work on amd64,
   * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
   * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
   */

  TargetOptions opts;
  opts.JITExceptionHandling = 1;

  EngineBuilder b (unwrap (MP));
#ifdef TARGET_AMD64
  ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setCodeModel (CodeModel::Large).setAllocateGVsWithCode (true).create ();
#else
  ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).create ();
#endif
  g_assert (EE);

#if 0
  ExecutionEngine *EE = ExecutionEngine::createJIT (unwrap (MP), &Error, mono_mm, CodeGenOpt::Default, true, Reloc::Default, CodeModel::Large);
  if (!EE) {
	  errs () << "Unable to create LLVM ExecutionEngine: " << Error << "\n";
	  g_assert_not_reached ();
  }
#endif

  EE->InstallExceptionTableRegister (exception_cb);
  mono_event_listener = new MonoJITEventListener (emitted_cb);
  EE->RegisterJITEventListener (mono_event_listener);

  fpm = new FunctionPassManager (unwrap (MP));

  fpm->add(new TargetData(*EE->getTargetData()));

  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  //initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  //initializeInstrumentation(Registry);
  initializeTarget(Registry);

  llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "", false);

  if (PassList.size() > 0) {
	  /* Use the passes specified by the env variable */
	  /* Only the passes in force_pass_linking () can be used */
	  for (unsigned i = 0; i < PassList.size(); ++i) {
		  const PassInfo *PassInf = PassList[i];
		  Pass *P = 0;

		  if (PassInf->getNormalCtor())
			  P = PassInf->getNormalCtor()();
		  fpm->add (P);
	  }
  } else {
	  /* Use the same passes used by 'opt' by default, without the ipo passes */
	  const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -basiccg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify";
	  char **args;
	  int i;

	  args = g_strsplit (opts, " ", 1000);
	  for (i = 0; args [i]; i++)
		  ;
	  llvm::cl::ParseCommandLineOptions (i, args, "", false);
	  g_strfreev (args);

	  for (unsigned i = 0; i < PassList.size(); ++i) {
		  const PassInfo *PassInf = PassList[i];
		  Pass *P = 0;

		  if (PassInf->getNormalCtor())
			  P = PassInf->getNormalCtor()();
		  fpm->add (P);
	  }

	  /*
	  fpm->add(createInstructionCombiningPass());
	  fpm->add(createReassociatePass());
	  fpm->add(createGVNPass());
	  fpm->add(createCFGSimplificationPass());
	  */
  }

  return wrap(EE);
}
Example #6
0
LLVMExecutionEngineRef
mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb)
{
  std::string Error;

  force_pass_linking ();

  LLVMInitializeX86Target ();
  LLVMInitializeX86TargetInfo ();

  mono_mm = new MonoJITMemoryManager ();
  mono_mm->alloc_cb = alloc_cb;

#if LLVM_MAJOR_VERSION == 2 && LLVM_MINOR_VERSION < 8
   DwarfExceptionHandling = true;
#else
   JITExceptionHandling = true;
#endif
  // PrettyStackTrace installs signal handlers which trip up libgc
  DisablePrettyStackTrace = true;

  ExecutionEngine *EE = ExecutionEngine::createJIT (unwrap (MP), &Error, mono_mm, CodeGenOpt::Default);
  if (!EE) {
	  errs () << "Unable to create LLVM ExecutionEngine: " << Error << "\n";
	  g_assert_not_reached ();
  }
  EE->InstallExceptionTableRegister (exception_cb);
  mono_event_listener = new MonoJITEventListener (emitted_cb);
  EE->RegisterJITEventListener (mono_event_listener);

  fpm = new FunctionPassManager (unwrap (MP));

  fpm->add(new TargetData(*EE->getTargetData()));

#if LLVM_CHECK_VERSION(2, 9)
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  //initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  //initializeInstrumentation(Registry);
  initializeTarget(Registry);
#endif

  llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "", false);

  if (PassList.size() > 0) {
	  /* Use the passes specified by the env variable */
	  /* Only the passes in force_pass_linking () can be used */
	  for (unsigned i = 0; i < PassList.size(); ++i) {
		  const PassInfo *PassInf = PassList[i];
		  Pass *P = 0;

		  if (PassInf->getNormalCtor())
			  P = PassInf->getNormalCtor()();
		  fpm->add (P);
	  }
  } else {
	  /* Use the same passes used by 'opt' by default, without the ipo passes */
	  const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -basiccg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loopsimplify -domfrontier -loopsimplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loopsimplify -lcssa -iv-users -indvars -loop-deletion -loopsimplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify";
	  char **args;
	  int i;

	  args = g_strsplit (opts, " ", 1000);
	  for (i = 0; args [i]; i++)
		  ;
	  llvm::cl::ParseCommandLineOptions (i, args, "", false);
	  g_strfreev (args);

	  for (unsigned i = 0; i < PassList.size(); ++i) {
		  const PassInfo *PassInf = PassList[i];
		  Pass *P = 0;

		  if (PassInf->getNormalCtor())
			  P = PassInf->getNormalCtor()();
		  fpm->add (P);
	  }

	  /*
	  fpm->add(createInstructionCombiningPass());
	  fpm->add(createReassociatePass());
	  fpm->add(createGVNPass());
	  fpm->add(createCFGSimplificationPass());
	  */
  }

  return wrap(EE);
}
Example #7
0
int main(int argc, char* argv[])
{
   if(argc < 2)
   {
      cerr << "Usage: " << argv[0] << " bf_file" << endl;
      return -1;
   }
   ifstream sourceFile(argv[1]);
   string line, source;
   while(getline(sourceFile, line)) source += line;

   // Setup a module and engine for JIT-ing
   std::string error;
   InitializeNativeTarget();

   Module* module = new Module("bfcode", getGlobalContext());

   InitializeNativeTarget();
   LLVMLinkInJIT();
   ExecutionEngine *engine = EngineBuilder(module)
      .setErrorStr(&error)
      .setOptLevel(CodeGenOpt::Aggressive)
      .create();
   if(!engine)
   {
      cout << "No engine created: " << error << endl;
      return -1;
   }

   module->setDataLayout(engine->getTargetData()->getStringRepresentation());

   // Compile the BF to IR
   cout << "Parsing… " << flush;
   Function* func = makeFunc(module, source.c_str());
   cout << "done" << endl;

   {
       ofstream dst("out.ll");
       raw_os_ostream rawdst(dst);
       rawdst << *module;
   }

   // Run optimization passes
   cout << "Optimizing… " << flush;

   PassManagerBuilder PMBuilder;

   FunctionPassManager pm(module);
   PMBuilder.populateFunctionPassManager(pm);
   pm.add(new TargetData(*(engine->getTargetData())));
   pm.add(createVerifierPass());

   // Eliminate simple loops such as [>>++<<-]
   pm.add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
   pm.add(createLICMPass());                 // Hoist loop invariants
   pm.add(createPromoteMemoryToRegisterPass());
   pm.add(createIndVarSimplifyPass());       // Canonicalize indvars
   pm.add(createLoopDeletionPass());         // Delete dead loops
   pm.add(createConstantPropagationPass());  // Propagate constants
   pm.add(new CondProp);                     // Propagate conditionals

   // Simplify code
   for(int repeat=0; repeat < 3; repeat++)
   {
      pm.add(createPromoteMemoryToRegisterPass());
      pm.add(createGVNPass());                  // Remove redundancies
      pm.add(createSCCPPass());                 // Constant prop with SCCP
      pm.add(createLoopDeletionPass());
      pm.add(createLoopUnrollPass());
      pm.add(createCFGSimplificationPass());    // Merge & remove BBs
      pm.add(createInstructionCombiningPass());
      pm.add(createConstantPropagationPass());  // Propagate constants
      pm.add(createAggressiveDCEPass());        // Delete dead instructions
      pm.add(createCFGSimplificationPass());    // Merge & remove BBs
      pm.add(createDeadStoreEliminationPass()); // Delete dead stores
      pm.add(createMemCpyOptPass());            // Combine multiple stores into memset's
      //pm.add(new PutCharAggregatePass);
   }

   pm.add(createPromoteMemoryToRegisterPass());

   // Process
   foreach (Function& f, *module)
       if (!f.isDeclaration)
           pm.run(f);

   PassManager pmm;

   PMBuilder.populateModulePassManager(pmm);
   pmm.add(createConstantMergePass());
   pmm.add(createGlobalOptimizerPass());
   pmm.add(createGlobalDCEPass());
   pmm.add(createIPConstantPropagationPass());
   pmm.run(*module);

   foreach (Function& f, *module)
       if (!f.isDeclaration)
           pm.run(f);
   pmm.run(*module);

   cout << "done" << endl;

   {
       ofstream dst("optout.ll");
       raw_os_ostream rawdst(dst);
       rawdst << *module;
   }

   // Compile …
   cout << "Compiling…" << flush;
   int (*bf)() = (int (*)())engine->getPointerToFunction(func);
   cout << " done" << endl;

   // … and run!
   return bf();
}
Example #8
0
bool CompiledCondition::compile(){
	InitializeNativeTarget();
	// Assume we're on main thread...
	LLVMContext &context = getGlobalContext();

	// Initialize module
	Module* module = new Module("Compiled function", context);

	// Create exection engine
	ExecutionEngine* engine = EngineBuilder(module).create();

	/********** Generate code **********/

	//Get a type for representing an integer pointer
	//Maybe this should be unsigned integer pointer type...
	PointerType* integerPointerType = PointerType::get(IntegerType::get(module->getContext(), 32), 0);

	//Create function type, for our function, int*, int* -> bool
	vector<const Type*> paramType;
	paramType.push_back(integerPointerType);
	paramType.push_back(integerPointerType);
	FunctionType* functionType = FunctionType::get(IntegerType::get(module->getContext(), 8), paramType, false);

	//Declare new function
	Function* function = Function::Create(functionType, GlobalValue::ExternalLinkage, "evaluate", module);
	//Use C calling convention
	function->setCallingConv(CallingConv::C);	//TODO: Read documentation and reconsider this

	//Get arguments from function
	Function::arg_iterator args = function->arg_begin();
	Value* marking = args++;
	Value* valuation = args++;
	marking->setName("marking");
	valuation->setName("valuation");

	//Create function block
	BasicBlock* functionBlock = BasicBlock::Create(module->getContext(), "functionBlock", function, 0);

	//Generate code
	CodeGenerationContext codeGenContext(marking, valuation, functionBlock, context);
	Value* result = _cond->codegen(codeGenContext);

	//Zero extend the result, e.g. make it a 8 bit bool
	CastInst* retval = new ZExtInst(result, IntegerType::get(module->getContext(), 8), "retval", functionBlock);

	//Create a return instruction
	ReturnInst::Create(module->getContext(), retval, functionBlock);

	/********** Optimize and Compile **********/

	// Create function pass manager, to optimize query
	FunctionPassManager optimizer(module);
	optimizer.add(new TargetData(*engine->getTargetData()));
	optimizer.add(createBasicAliasAnalysisPass());
	optimizer.add(createInstructionCombiningPass());
	optimizer.add(createReassociatePass());
	optimizer.add(createGVNPass());
	optimizer.add(createCFGSimplificationPass());
	optimizer.doInitialization();

	// Verify function, errors written to stderr
	if(verifyFunction(*function))
		return false;

	// Optimize function
	optimizer.run(*function);

	// Compile the function
	_nativeFunction = (bool(*)(const MarkVal*, const VarVal*))engine->getPointerToFunction(function);

	return _nativeFunction != NULL;
}