Beispiel #1
0
void Codegen::createPasses() {

    llvm::TargetMachine *tm = targetMachine();
//    llvm::DataLayout *dl = new llvm::DataLayout(&llvmModule());

    modulePasses = new llvm::PassManager();
//     modulePasses->add(dl);
    functionPasses = new llvm::FunctionPassManager(&llvmModule());
//    functionPasses->add(dl);

    tm->addAnalysisPasses(*modulePasses);
    tm->addAnalysisPasses(*functionPasses);

    llvm::PassManagerBuilder pmBuilder;
    pmBuilder.OptLevel = options.optLevel;

    llvm::Triple targetTriple(llvmModule().getTargetTriple());
    pmBuilder.LibraryInfo = new llvm::TargetLibraryInfo(targetTriple);

    if (nativeEnabled()) {
        codegenPasses = new llvm::PassManager();
//        codegenPasses->add(dl);
        //codegenPasses->add(pmBuilder.LibraryInfo);
        tm->addAnalysisPasses(*codegenPasses);
    }

    unsigned inlineThreshold = 225;
    if (options.optLevel > 2) {
        inlineThreshold = 275;
        modulePasses->add(llvm::createStripSymbolsPass(true));
    }
    pmBuilder.Inliner = llvm::createFunctionInliningPass(inlineThreshold);
    pmBuilder.populateFunctionPassManager(*functionPasses);
    pmBuilder.populateModulePassManager(*modulePasses);
}
bool RSCompiler::beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM) {
  // Add a pass to internalize the symbols that don't need to have global
  // visibility.
  RSScript &script = static_cast<RSScript &>(pScript);
  const RSInfo *info = script.getInfo();

  // The vector contains the symbols that should not be internalized.
  std::vector<const char *> export_symbols;

  // Special RS functions should always be global symbols.
  const char **special_functions = RSExecutable::SpecialFunctionNames;
  while (*special_functions != NULL) {
    export_symbols.push_back(*special_functions);
    special_functions++;
  }

  // Visibility of symbols appeared in rs_export_var and rs_export_func should
  // also be preserved.
  const RSInfo::ExportVarNameListTy &export_vars = info->getExportVarNames();
  const RSInfo::ExportFuncNameListTy &export_funcs = info->getExportFuncNames();

  for (RSInfo::ExportVarNameListTy::const_iterator
           export_var_iter = export_vars.begin(),
           export_var_end = export_vars.end();
       export_var_iter != export_var_end; export_var_iter++) {
    export_symbols.push_back(*export_var_iter);
  }

  for (RSInfo::ExportFuncNameListTy::const_iterator
           export_func_iter = export_funcs.begin(),
           export_func_end = export_funcs.end();
       export_func_iter != export_func_end; export_func_iter++) {
    export_symbols.push_back(*export_func_iter);
  }

  // Expanded foreach functions should not be internalized, too.
  const RSInfo::ExportForeachFuncListTy &export_foreach_func =
      info->getExportForeachFuncs();
  std::vector<std::string> expanded_foreach_funcs;
  for (RSInfo::ExportForeachFuncListTy::const_iterator
           foreach_func_iter = export_foreach_func.begin(),
           foreach_func_end = export_foreach_func.end();
       foreach_func_iter != foreach_func_end; foreach_func_iter++) {
    std::string name(foreach_func_iter->first);
    expanded_foreach_funcs.push_back(name.append(".expand"));
  }

  // Need to wait until ForEachExpandList is fully populated to fill in
  // exported symbols.
  for (size_t i = 0; i < expanded_foreach_funcs.size(); i++) {
    export_symbols.push_back(expanded_foreach_funcs[i].c_str());
  }

  pPM.add(llvm::createInternalizePass(export_symbols));

  return true;
}
Beispiel #3
0
void Codegen::emitCode(llvm::raw_ostream *os) {
    llvm::formatted_raw_ostream formattedOS;

    createPasses();

    llvm::TargetMachine::CodeGenFileType cgft = llvm::TargetMachine::CGFT_AssemblyFile;
    switch (options.type) {
    case codegen::LLVM:
        formattedOS.setStream(*os, llvm::formatted_raw_ostream::PRESERVE_STREAM);
        modulePasses->add(llvm::createPrintModulePass(*os));
        break;
    case codegen::BC:
        modulePasses->add(llvm::createBitcodeWriterPass(*os));
        break;
    case codegen::ASM:
        break;
    case codegen::OBJ:
        cgft = llvm::TargetMachine::CGFT_ObjectFile;
        break;
    default:
        // screem
        break;
    }

    functionPasses->doInitialization();
    for (llvm::Module::iterator I = llvmModule().begin(),
            E = llvmModule().end(); I != E; ++I)
        if (!I->isDeclaration())
            functionPasses->run(*I);
    functionPasses->doFinalization();

    modulePasses->run(llvmModule());

    if (codegenPasses) {
        formattedOS.setStream(*os, llvm::formatted_raw_ostream::PRESERVE_STREAM);
        if (targetMachine()->addPassesToEmitFile(*codegenPasses, formattedOS, cgft)) {
            std::cout << "pass fail";
        }
        codegenPasses->run(llvmModule());
    }
}
Beispiel #4
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; 
*/
}