Exemple #1
0
void Cache::preload(llvm::ExecutionEngine& _ee, std::unordered_map<std::string, uint64_t>& _funcCache)
{
	Guard g{x_cacheMutex};

	// Disable listener
	auto listener = g_listener;
	g_listener = nullptr;

	auto cachePath = getVersionedCacheDir();
	std::error_code err;
	for (auto it = llvm::sys::fs::directory_iterator{cachePath, err}; it != decltype(it){}; it.increment(err))
	{
		auto name = it->path().substr(cachePath.size() + 1);
		if (auto module = getObject(name))
		{
			DLOG(cache) << "Preload: " << name << "\n";
			_ee.addModule(std::move(module));
			auto addr = _ee.getFunctionAddress(name);
			assert(addr);
			_funcCache[std::move(name)] = addr;
		}
	}

	g_listener = listener;
}
Exemple #2
0
void JITtedFunctionCollector::UnregisterFunctionMapping(llvm::ExecutionEngine &engine)
{
   std::vector<llvm::Function *>::reverse_iterator it;

   for (it=m_vec_functions.rbegin(); it < m_vec_functions.rend(); it++) {
      llvm::Function *ff = (llvm::Function *)*it;
      //BB std::cerr << "JITtedFunctionCollector::UnregisterFunctionMapping: updateGlobalMapping("
      //BB          << ff->getName().data() << ", 0); Global @" << engine.getPointerToGlobalIfAvailable(ff) << std::endl;
      engine.freeMachineCodeForFunction(ff);
      engine.updateGlobalMapping(ff, 0);
      //BB std::cerr << "Global after delete @" << engine.getPointerToGlobalIfAvailable(ff) << std::endl;
   }
   m_vec_functions.clear(); 
}
bool ExternalDispatcherImpl::runProtectedCall(Function *f, uint64_t *args) {
  struct sigaction segvAction, segvActionOld;
  bool res;

  if (!f)
    return false;

  std::vector<GenericValue> gvArgs;
  gTheArgsP = args;

  segvAction.sa_handler = 0;
  memset(&segvAction.sa_mask, 0, sizeof(segvAction.sa_mask));
  segvAction.sa_flags = SA_SIGINFO;
  segvAction.sa_sigaction = ::sigsegv_handler;
  sigaction(SIGSEGV, &segvAction, &segvActionOld);

  if (setjmp(escapeCallJmpBuf)) {
    res = false;
  } else {
    errno = lastErrno;
    executionEngine->runFunction(f, gvArgs);
    // Explicitly acquire errno information
    lastErrno = errno;
    res = true;
  }

  sigaction(SIGSEGV, &segvActionOld, 0);
  return res;
}
void
IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
{
    for (AllocationRecord &record : m_records)
    {
        if (record.m_process_address == LLDB_INVALID_ADDRESS)
            continue;

        if (record.m_section_id == eSectionIDInvalid)
            continue;

        engine.mapSectionAddress((void*)record.m_host_address, record.m_process_address);
    }

    // Trigger re-application of relocations.
    engine.finalizeObject();
}
void
RecordingMemoryManager::ReportAllocations (llvm::ExecutionEngine &engine)
{
    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
            ai != ae;
            ++ai)
    {
        if (!ai->m_allocated)
            continue;

        engine.mapSectionAddress((void*)ai->m_local_start, ai->m_remote_start);
    }
}
bool ExternalDispatcherImpl::executeCall(Function *f, Instruction *i,
                                         uint64_t *args) {
  dispatchers_ty::iterator it = dispatchers.find(i);
  if (it != dispatchers.end()) {
    // Code already JIT'ed for this
    return runProtectedCall(it->second, args);
  }

  // Code for this not JIT'ed. Do this now.
  Function *dispatcher;
#ifdef WINDOWS
  std::map<std::string, void *>::iterator it2 =
      preboundFunctions.find(f->getName());

  if (it2 != preboundFunctions.end()) {
    // only bind once
    if (it2->second) {
      executionEngine->addGlobalMapping(f, it2->second);
      it2->second = 0;
    }
  }
#endif

  Module *dispatchModule = NULL;
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
  // The MCJIT generates whole modules at a time so for every call that we
  // haven't made before we need to create a new Module.
  dispatchModule = new Module(getFreshModuleID(), ctx);
#else
  dispatchModule = this->singleDispatchModule;
#endif
  dispatcher = createDispatcher(f, i, dispatchModule);
  dispatchers.insert(std::make_pair(i, dispatcher));

// Force the JIT execution engine to go ahead and build the function. This
// ensures that any errors or assertions in the compilation process will
// trigger crashes instead of being caught as aborts in the external
// function.
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
  if (dispatcher) {
    // The dispatchModule is now ready so tell MCJIT to generate the code for
    // it.
    auto dispatchModuleUniq = std::unique_ptr<Module>(dispatchModule);
    executionEngine->addModule(
        std::move(dispatchModuleUniq)); // MCJIT takes ownership
    // Force code generation
    uint64_t fnAddr =
        executionEngine->getFunctionAddress(dispatcher->getName());
    executionEngine->finalizeObject();
    assert(fnAddr && "failed to get function address");
    (void)fnAddr;
  } else {
    // MCJIT didn't take ownership of the module so delete it.
    delete dispatchModule;
  }
#else
  if (dispatcher) {
    // Old JIT works on a function at a time so compile the function.
    executionEngine->recompileAndRelinkFunction(dispatcher);
  }
#endif
  return runProtectedCall(dispatcher, args);
}
Exemple #7
0
void Simulator::Simulate()
{
  llvm::SMDiagnostic error;
  //std::unique_ptr<llvm::Module> M = llvm::ParseIRFile("Behavior.bc", error, context);
  //MyModule = M.get();
  MyModule = llvm::ParseIRFile("Behavior.bc", error, context);
  string err_str;
/*
    OwningPtr<MemoryBuffer> result;
    MemoryBuffer *mb;
    llvm::error_code ec = MemoryBuffer::getFile("Behavior.bc", result);
    mb = result.take();
    err_str = ec.message();
    if (!mb) {
      error() <<"Cannot open \"" <<bitcode_file() <<"\": " <<err_str <<endl;
      exit(1);
    }
    MyModule = llvm::ParseBitcodeFile(mb,context,&err_str);
    if (!MyModule) {
      error() <<"Failed to load module from bitcode file: " <<err_str <<endl;
      exit(1);
    }
    delete mb;
*/
/*
    for (llvm::Module::iterator f = MyModule->begin(), ef = MyModule->end(); f!=ef; ++f) 
    {
      f->addFnAttr(Attributes::AlwaysInline);
    }
*/
    for (int32_t i = 0; i < (int32_t)OPCODE::INVALID; i++) {
      OPCODE op = (OPCODE) i;
      llvm::Function *func = MyModule->getFunction(GetFuncName(op));
      func->addFnAttr(llvm::Attribute::AlwaysInline);
      OpFunctionMap[op] = func; 
    }
    test_type = MyModule->getFunction("test")->getFunctionType();


    std::string ErrStr;
    passManager = new llvm::PassManager();
    passManager->add(llvm::createAlwaysInlinerPass());
    fPassManager = new llvm::FunctionPassManager(MyModule);
    //fPassManager->add(new DataLayout(*EE->getDataLayout()));
    //fPassManager->add(new DataLayout(*EE->getDataLayout()));
    fPassManager->add(llvm::createGVNPass());
    fPassManager->add(llvm::createInstructionCombiningPass());
    fPassManager->add(llvm::createCFGSimplificationPass());
    fPassManager->add(llvm::createDeadStoreEliminationPass());

/*
    llvm::EngineBuilder builder(MyModule);
    builder.setErrorStr(&ErrStr);
    builder.setEngineKind(llvm::EngineKind::JIT);
    builder.setOptLevel(llvm::CodeGenOpt::Default); // None/Less/Default/Aggressive
    //llvm::TargetOptions options;
    //options.JITExceptionHandling = 1;
    //builder.setTargetOptions(options);
    EE = builder.create();
*/
  //StringRef MCPU = llvm::sys::getHostCPUName()
  EE = llvm::EngineBuilder(MyModule).create(); 
/*
    EE =
      llvm::EngineBuilder(std::move(M))
          .setErrorStr(&ErrStr)
          .setMCJITMemoryManager(llvm::make_unique<llvm::SectionMemoryManager>())
          .create();
*/
/*
    EE = llvm::EngineBuilder(M)
                .setErrorStr(&ErrStr)
                .setMCJITMemoryManager(llvm::SectionMemoryManager())
                .create();
    EE = llvm::EngineBuilder(std::move(M)).setErrorStr(&ErrStr).create();

*/
    if (!EE) {
      fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
      exit(1);
    }
    EE->DisableLazyCompilation(true);


/*
    //atexit(llvm_shutdown);  // Call llvm_shutdown() on exit.
    //llvm::EngineBuilder builder(MyModule);
    llvm::EngineBuilder builder(std::move(M));
    //llvm::EngineBuilder builder(MyModule);
    builder.setErrorStr(&err_str);
    builder.setEngineKind(llvm::EngineKind::JIT);
    builder.setOptLevel(llvm::CodeGenOpt::Default); // None/Less/Default/Aggressive
    //TargetOptions options;
    //options.JITExceptionHandling = 1;
    //builder.setTargetOptions(options);
    EE = builder.create();
    if (!EE) {
      std::cout <<"failed to create execution engine: " <<err_str <<"\n";
      exit(1);
    }
*/
/*
    //MyModule->dump();
    EE = llvm::EngineBuilder(std::move(M)).create();
*/
    //string ErrStr;
    //EE = llvm::EngineBuilder(std::move(M)).setErrorStr(&ErrStr).setMCPU("i386").create();


  //context = llvm::getGlobalContext();
  int32_t index = 0;
  Blocks = new HostBlock[1000];
  int32_t block_index = 0;
  while(index < total_inst) {

    Blocks[block_index].pc = index;  
    ostringstream f_name;
    f_name << "func";
    f_name << block_index;
    //string f_name = string("func");// + string(index);
/*
    llvm::Function *func =
      llvm::cast<llvm::Function>(MyModule->getOrInsertFunction(f_name.str(), 
            llvm::Type::getVoidTy(context), (llvm::Type *)0));
*/
  // Make the function type:  double(double,double) etc.
    //std::vector<Type*> Doubles(Args.size(),
    //                         Type::getDoubleTy(getGlobalContext()));
    llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), false);
    llvm::Function *func = llvm::Function::Create(FT, 
                                                  llvm::Function::ExternalLinkage,
                                                  f_name.str(),
                                                  MyModule);

//Function *F = Function::Create(FT, Function::ExternalLinkage, FnName, M);
    // Add a basic block to the function. As before, it automatically inserts
    // because of the last argument.
    llvm::BasicBlock *BB = llvm::BasicBlock::Create(context, "EntryBlock", func);

    // Create a basic block builder with default parameters.  The builder will
    // automatically append instructions to the basic block `BB'.
    IRB.SetInsertPoint(BB);
    llvm::Function *sim_func; 
    CInst *inst; 
    int b_size = 0;
    do {
        inst = &instructions[index];
        llvm::Value *dst = IRB.getInt32(inst->dst_reg);
        llvm::Value *src0 = IRB.getInt32(inst->src0_reg);
        llvm::Value *src1 = IRB.getInt32(inst->src1_reg);
        sim_func = OpFunctionMap[inst->opcode];
        llvm::Value *oprnds[] = {dst, src0, src1};
        llvm::ArrayRef <llvm::Value *> ref(oprnds, 3);
        IRB.CreateCall(sim_func, ref);
        index++;
        b_size++;
        //cout << "Index " << index << endl;
    //} while(b_size < 10 || inst->opcode != OPCODE::JMP);
    } while(b_size < 10  && index < total_inst);
    IRB.CreateRetVoid();  
    passManager->run(*MyModule); 
    fPassManager->run(*func);
    EE->finalizeObject();
    //std::vector<llvm::GenericValue> noargs;
    //std::cout << "calling " << f_name.str() << endl;
    //EE->runFunction(func, noargs);
    //Blocks[block_index].func_ptr = reinterpret_cast<HostFunction>(EE->getPointerToFunction(func));
    Blocks[block_index].func_ptr = (void *)(EE->getPointerToFunction(func));
    //Blocks[block_index].func_ptr = reinterpret_cast<decltype(HostFunction())>(EE->getPointerToNamedFunction(f_name.str()));
    //(Blocks[block_index].func_ptr)(); 
    block_index++;
    //cout << "BlockIndex " << block_index << endl;
  }
  total_blocks = block_index;
  MyModule->dump();
/*
  cout << "calling add32" << endl;
  void (*add32)(int32_t, int32_t, int32_t) = 
    reinterpret_cast<void (*)(int32_t, int32_t, int32_t)>(EE->getFunctionAddress("add32")); 
  add32(0, 2, 3);
*/
/*
  void (*func0)() = 
    reinterpret_cast<void (*)()>(EE->getFunctionAddress("func1")); 
  func0();
*/
/*
  struct timeval tp;
  gettimeofday(&tp, NULL);
  long int start = tp.tv_sec * 1000 + tp.tv_usec / 1000;
  for (int32_t i = 0; i < 100; i++) {
    for (int32_t j = 0 ; j < total_blocks; j++) {
      ((HostFunction)(Blocks[j].func_ptr))();
    }
  }
  gettimeofday(&tp, NULL);
  long int end = tp.tv_sec * 1000 + tp.tv_usec / 1000;
  cout << "Time = " << end - start << endl; 
*/
}