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")); }
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; }