petabricks::CodeGenerator::CodeGenerator(const StreamTreePtr& root, const TrainingDepsPtr& cg)
  : _contCounter(0), _indent(0), _cg(cg)
{
  if(!_cg) _cg = new TrainingDeps();
  _odefines = root->add(new StreamTree("defines"));
  _oheaders = root->add(new StreamTree("headers"));
  _bcur     = root->add(new StreamTree("top"));
  _ocur = _bcur->add(new StreamTree("main"));
}
Exemple #2
0
 void write() {
   std::ofstream of(_cpp.c_str());
   of << headertxtcpp;
   of << "/* Compile with: \n"
      <<  _gcccmd << "\n"
      << " */\n";
   _code->writeTo(of);
   of.flush();
   of.close();
 }
Exemple #3
0
int main( int argc, const char ** argv){

  /*
  #ifdef HAVE_OPENCL
  OpenCLUtil::init();
  OpenCLUtil::printDeviceList();
  OpenCLUtil::deinit();
  exit(-1);
  #endif
  */

  // READ COMMAND LINE:

  OutputCodeList ccfiles;

  jalib::JArgs args(argc, argv);
  std::vector<std::string> inputs;
  if(args.needHelp())
    std::cerr << "OPTIONS:" << std::endl;
  
  thePbPreprocessor="\""PYTHON"\" \"" +
                    jalib::Filesystem::FindHelperUtility("preprocessor.py")
                    +"\"";

  args.param("input",      inputs).help("input file to compile (*.pbcc)");
  args.param("output",     theOutputBin).help("output binary to be produced");
  args.param("outputinfo", theOutputInfo).help("output *.info file to be produced");
  args.param("outputobj",  theObjectFile).help("output *.o file to be produced");
  args.param("runtimedir", theRuntimeDir).help("directory where petabricks.h may be found");
  args.param("libdir",     theLibDir).help("directory where libpbruntime.a may be found");
  args.param("preproc",    thePbPreprocessor).help("program to use as preprocessor");
  args.param("compile",    shouldCompile).help("disable the compilation step");
  args.param("link",       shouldLink).help("disable the linking step");
  args.param("main",       theMainName).help("transform name to use as program entry point");
  args.param("hardcode",   theHardcodedConfig).help("a config file containing tunables to set to hardcoded values");
  args.param("jobs",       theNJobs).help("number of gcc processes to call at once");

  if(args.param("version").help("print out version number and exit") ){
    std::cerr << PACKAGE " compiler (pbc) v" VERSION " " REVISION_LONG << std::endl;
    return 1;
  }

  args.finishParsing(inputs);

  if(inputs.empty() || args.needHelp()){
    std::cerr << "\n" PACKAGE " compiler (pbc) v" VERSION " " REVISION_SHORT << std::endl;
    std::cerr << "USAGE: " << argv[0] << " [OPTIONS] filename.pbcc" << std::endl;
    std::cerr << "run `" << argv[0] << " --help` for options" << std::endl;
    return 1;
  }

  JASSERT(inputs.size()==1)(inputs.size()).Text("expected exactly one input file");
  theInput = inputs.front();
  if(theRuntimeDir.empty()) theRuntimeDir = jalib::Filesystem::Dirname(jalib::Filesystem::FindHelperUtility("runtime/petabricks.h"));
  if(theLibDir    .empty()) theLibDir     = jalib::Filesystem::Dirname(jalib::Filesystem::FindHelperUtility("libpbruntime.a"));
  if(theOutputBin .empty()) theOutputBin  = jalib::Filesystem::Basename(theInput);
  if(theObjDir.empty())     theObjDir     = theOutputBin + ".obj";
  if(theOutputInfo.empty()) theOutputInfo = theOutputBin + ".info";
  if(theObjectFile.empty()) theObjectFile = theOutputBin + ".o";
  
  
  int rv = mkdir(theObjDir.c_str(), 0755);
  if(rv!=0 && errno==EEXIST)
    rv=0, errno=0;
  JASSERT(rv==0)(theObjDir).Text("failed to create objdir");
  
  if(!theHardcodedConfig.empty())
    CodeGenerator::theHardcodedTunables() = jalib::JTunableManager::loadRaw(theHardcodedConfig);

  JASSERT(jalib::Filesystem::FileExists(theInput))(theInput)
    .Text("input file does not exist");

  // PARSE:

  TransformListPtr t = parsePbFile(theInput.c_str());

  // COMPILE:

  for(TransformList::iterator i=t->begin(); i!=t->end(); ++i){
    (*i)->initialize();
    #ifdef DEBUG
    (*i)->print(std::cout);
    #endif
  }

  for(TransformList::iterator i=t->begin(); i!=t->end(); ++i){
    (*i)->compile();
  }

  findMainTransform(t);

  // CODEGEN:
  StreamTreePtr header = new StreamTree("header");
  StreamTreePtr prefix = header->add(new StreamTree("prefix"));
  CodeGenerator o(header, NULL);
  
  for(TransformList::iterator i=t->begin(); i!=t->end(); ++i){
    ccfiles.push_back(OutputCode((*i)->name(), o));
    (*i)->generateCode(o);
  }

  // generate misc files:
  o.cg().beginGlobal();
#ifdef SINGLE_SEQ_CUTOFF
  o.createTunable(true, "system.cutoff.sequential", "sequentialcutoff", 64);
#endif
  o.cg().endGlobal();
  ccfiles.push_back(OutputCode(GENMISC, o));
  o.outputTunables(o.os());
  o.comment("A hook called by PetabricksRuntime");
  o.beginFunc("petabricks::PetabricksRuntime::Main*", "petabricksMainTransform");
  o.write("return "+theMainName+"_main::instance();");
  o.endFunc();
  o.comment("A hook called by PetabricksRuntime");
  o.beginFunc( "petabricks::PetabricksRuntime::Main*"
             , "petabricksFindTransform"
             , std::vector<std::string>(1, "const std::string& name"));
  for(TransformList::iterator i=t->begin(); i!=t->end(); ++i){
    (*i)->registerMainInterface(o);
  }
  o.write("return NULL;");
  o.endFunc();
  
  // generate common header file:
  *prefix << headertxth;
  *prefix << "namespace { \n";
  *prefix << CodeGenerator::theFilePrefix().str();
  *prefix << "} \n";
  o.outputTunableHeaders(*prefix);
  ccfiles.writeHeader(header);

  // dump .info file:
  std::ofstream infofile(theOutputInfo.c_str());
  o.cg().dumpTo(infofile);
  infofile.flush();
  infofile.close();


  char olddir[1024];
  memset(olddir, 0, sizeof olddir);
  JASSERT(olddir==getcwd(olddir, sizeof olddir - 1));
  JASSERT(chdir(theObjDir.c_str())==0)(theObjDir);
  
  ccfiles.writeMakefile();
  
  // COMPILE AND LINK:
  if(shouldCompile)
    ccfiles.compile();
  else
    ccfiles.write();

  if(shouldLink) {
    ccfiles.link();
    JASSERT(chdir(olddir)==0)(olddir);
    JASSERT(rename((theObjDir+"/"BIN_TMPFILE).c_str(), theOutputBin.c_str())==0)
      (theObjDir+"/"BIN_TMPFILE)(theOutputBin);
  }else{
    JASSERT(chdir(olddir)==0)(olddir);
  }


#ifdef DEBUG
  MAXIMA.sanityCheck();
#endif

  JTRACE("done")(theInput)(theOutputInfo)(theObjDir)(theOutputBin);
  return 0;
}
Exemple #4
0
 void writeHeader(const StreamTreePtr& h) {
   std::ofstream of((theObjDir+"/"GENHEADER).c_str());
   h->writeTo(of);
   of.flush();
   of.close();
 }