Exemple #1
0
static inline void DumpScopeWithDeps(BlockScopeRawPtr scope) {
  assert(scope->is(BlockScope::FunctionScope) ||
         scope->is(BlockScope::ClassScope));
  DumpScope(scope, "");
  const BlockScopeRawPtrFlagsVec &ordered = scope->getOrderedUsers();
  for (BlockScopeRawPtrFlagsVec::const_iterator it = ordered.begin(),
       end = ordered.end(); it != end; ++it) {
    BlockScopeRawPtrFlagsVec::value_type pf = *it;
    auto prefix = folly::to<string>("    (", pf->second, ") ");
    DumpScope(pf->first, prefix.c_str());
  }
}
Exemple #2
0
void DumpScopeInfo(             // DUMP INFORMATION FOR SCOPE
    SCOPE scope )               // - starting scope
{
    DumpScope( scope );
    RingWalk( ScopeFriends( scope ), &dumpFriend );
    RingWalk( ScopeInherits( scope ), &dumpBaseClass );
}
Exemple #3
0
void DumpScope(SymbolScope *scope, std::ofstream &dump)
{
    char buffer[100];
    
    for(std::map<std::string, Symbol *>::iterator it = scope->GetSymbolTable()->begin(); it != scope->GetSymbolTable()->end(); ++it)
    {
        Symbol *symbol = it->second;
        if (typeid(*(symbol->DeclType)) == typeid(FunctionType) || scope->GetScopeKind() == SymbolScope::Global)
        {
            sprintf(buffer, "%0llX\t%s", (long long)symbol->Address, symbol->Name.c_str());
            dump << buffer << std::endl;
        }
    }

    for(std::vector<SymbolScope *>::iterator it = scope->GetChildScopes()->begin(); it != scope->GetChildScopes()->end(); ++it)
    {
        SymbolScope *cs = *it;
        DumpScope(cs, dump);
    }
}
Exemple #4
0
static void dump_scope_defn(    // DUMP SCOPE, GIVEN A SCOPE_DEFN
    void *_defn )               // - scope definition
{
    SCOPE_DEFN *defn = _defn;
    DumpScope( defn->defn );
}
Exemple #5
0
void
AnalysisResult::processScopesParallel(const char *id,
                                      void *context /* = NULL */) {
  BlockScopeRawPtrQueue scopes;
  getScopesSet(scopes);

#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
  std::cout << "processScopesParallel(" << id << "): "
    << scopes.size() << " scopes" << std::endl;
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */

  DepthFirstVisitor<When, OptVisitor> dfv(
    OptVisitor<When>(shared_from_this(), scopes.size()));

  bool first = true;
  bool again;
  dfv.data().start();
  do {

#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
    std::cout << "-----------------------------------" << std::endl;
    AnalysisResult::s_NumDoJobCalls         = 0;
    AnalysisResult::s_NumForceRerunGlobal   = 0;
    AnalysisResult::s_NumReactivateGlobal   = 0;
    AnalysisResult::s_NumForceRerunUseKinds = 0;
    AnalysisResult::s_NumReactivateUseKinds = 0;

    AnalysisResult::s_DoJobUniqueScopes.clear();
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */

#ifdef HPHP_INSTRUMENT_TYPE_INF
    assert(RescheduleException::s_NumReschedules          == 0);
    assert(RescheduleException::s_NumForceRerunSelfCaller == 0);
    assert(RescheduleException::s_NumRetTypesChanged      == 0);
    assert(BaseTryLock::s_LockProfileMap.empty());
#endif /* HPHP_INSTRUMENT_TYPE_INF */

    BlockScopeRawPtrQueue enqueued;
    again = dfv.visitParallel(scopes, first, enqueued);
    preWaitCallback<When>(first, scopes, context);

#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
    {
      std::cout << "Enqueued " << enqueued.size() <<
        " scopes in visitParallel()" << std::endl;
      if (enqueued.size() < 100) {
        for (BlockScopeRawPtrQueue::const_iterator it = enqueued.begin();
             it != enqueued.end(); ++it) {
          DumpScopeWithDeps(*it);
        }
      }
      Timer timer(Timer::WallTime, "dfv.wait()");
      dfv.data().wait();
    }
#else
    dfv.data().wait();
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */

    assert(!dfv.data().getQueuedJobs());
    assert(!dfv.data().getActiveWorker());

#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
    std::cout << "Number of doJob() calls: "
      << AnalysisResult::s_NumDoJobCalls << std::endl;
    std::cout << "Number of scopes which got doJob() called: "
      << AnalysisResult::s_DoJobUniqueScopes.size() << std::endl;
    std::vector<BIPair> v(
        AnalysisResult::s_DoJobUniqueScopes.begin(),
        AnalysisResult::s_DoJobUniqueScopes.end());
    if (!v.empty()) {
      sort(v.begin(), v.end(), BIPairCmp());
      std::vector<BIPair>::const_iterator end =
        v.size() > 20 ? v.begin() + 20 : v.end();
      for (std::vector<BIPair>::const_iterator it = v.begin();
          it != end; ++it) {
        auto prefix = folly::to<string>((*it).second, " times: ");
        DumpScope((*it).first, prefix.c_str());
      }
      std::cout << "Number of global force reruns: "
        << AnalysisResult::s_NumForceRerunGlobal << std::endl;
      std::cout << "Number of global reactivates: "
        << AnalysisResult::s_NumReactivateGlobal << std::endl;
      std::cout << "Number of use kind force reruns: "
        << AnalysisResult::s_NumForceRerunUseKinds << std::endl;
      std::cout << "Number of use kind reactivates: "
        << AnalysisResult::s_NumReactivateUseKinds << std::endl;
    }
    int numWaiting = CountScopesWaiting(scopes);
    std::cout << "Number of waiting scopes: " << numWaiting << std::endl;
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */

    again = postWaitCallback<When>(first, again, scopes, context);
    first = false;
  } while (again);
  dfv.data().stop();

  for (BlockScopeRawPtrQueue::iterator
       it = scopes.begin(), end = scopes.end();
       it != end; ++it) {
    assert((*it)->getMark() == BlockScope::MarkProcessed);
    assert((*it)->getNumDepsToWaitFor() == 0);
    assert(!(*it)->needsReschedule());
    assert((*it)->rescheduleFlags() == 0);
  }
}
Exemple #6
0
int main(int argc, char **argv)
{
    bool codeTypeDefined = false;

    CompilationContext *context = CompilationContext::GetInstance();
    
    context->TextStart =  0x400000000;
    context->DataStart =  0x400004000;
    context->RDataStart = 0x400008000;
    
    //NOTE: Currently, all global variables are put in the bss section and are NOT initialized with zeros, the data/rdata is not used.
    context->BssStart =   0x440000000;

    // NOTE: default targe code type
    // Only CODE_TYPE_I0 is supported
    CompilationContext::GetInstance()->CodeType = CODE_TYPE_I0;
    codeTypeDefined = true;
    
    for(int i = 1; i < argc; i++)
    {
        if(strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0)
        {
			if (argv[i + 1] != NULL && *argv[i + 1] != '-') {
            	CompilationContext::GetInstance()->OutputFile = argv[++i];
			} else {
				CompilationContext::GetInstance()->OutputFile = "a.bin";
			}
        }
        else if( (strcmp(argv[i], "--debug") == 0) || (strcmp(argv[i], "-g") == 0) )
        {
            CompilationContext::GetInstance()->Debug = true;
        }
        /*
        else if (strcmp(argv[i], "--i0") == 0)
        {
            if (codeTypeDefined) {
                printf("--i0 and --disa can not be used at the same time.\n"
                        "Specify one code type only.\n");
                return -1;
            }
            CompilationContext::GetInstance()->CodeType = CODE_TYPE_I0;
            codeTypeDefined = true;
        }
        else if (strcmp(argv[i], "--disa") == 0)
        {
            if (codeTypeDefined) {
                printf("--i0 and --disa can not be used at the same time.\n"
                        "Specify one code type only.\n");
                return -11;
            }

            CompilationContext::GetInstance()->CodeType = CODE_TYPE_DISA;
            codeTypeDefined = true;
        }
        */
        else if ( (strcmp(argv[i], "--help") == 0) || strcmp(argv[i], "-h") == 0 )
        {
            print_usage(argv[0]);
            return 0;
        }
        else
        {
            CompilationContext::GetInstance()->InputFiles.push_back(argv[i]);
        }
    }

    ILProgram *il = NULL;

    std::vector<std::string> &inputFiles = CompilationContext::GetInstance()->InputFiles;
    
    if(inputFiles.size() == 0)
    {
        print_usage(argv[0]);
        return 0;
    }
    else if(inputFiles.size() != 1)
    {
        //FIXME: Multiple input files
        assert("Not implemented: multiple input files.");
    }

    for(std::vector<std::string>::iterator it = inputFiles.begin(); it != inputFiles.end(); ++it)
    {
        std::string inputFile = CompilationContext::GetInstance()->InputFiles.front();
        std::string fileExt = inputFile.substr(inputFile.find_last_of(".") + 1);
        if(fileExt == "c")
        {
            
            char tmpFileName[255];
            sprintf(tmpFileName, "%s.tmp", inputFile.c_str());
            
            // tmpnam(tmpFileName);
            printf("temp file is: %s\n", tmpFileName);
            
            context->CurrentFileName = inputFile;
            
            std::string cmdline = "gcc -E " + inputFile + " -o " + tmpFileName;
            if(system(cmdline.c_str()) != 0)
            {
               return -1; 
            }
 
            if(CompilationContext::GetInstance()->Debug)
            {
                printf("--------------------------------------\n");
                printf("parsing...\n");
            }

            CSourceParser *frontend = new CSourceParser();
            frontend->Parse(tmpFileName);

            // Note: leave tmpFile for user to check
            // remove(tmpFileName);
  
            if(CompilationContext::GetInstance()->Debug)
            {
                printf("--------------------------------------\n");
                printf("ConstantPropagation...\n");
            }
           
            ConstantPropagation *constantPropagation = new ConstantPropagation();
            context->CodeDom->Accept(constantPropagation);
  
            if(CompilationContext::GetInstance()->Debug)
            {
                printf("--------------------------------------\n");
                printf("ConstantPropagation...\n");
            }
             
            TypeDeduction *typeDeduction = new TypeDeduction();
            context->CodeDom->Accept(typeDeduction);

            if(CompilationContext::GetInstance()->Debug)
            {
                printf("--------------------------------------\n");
                printf("codeDom Dump:\n");
                ExpressionTreeDumper *codeDomDump = new ExpressionTreeDumper();
               
                context->CodeDom->Accept(codeDomDump);
            }

            ILGenerator *ilgen = new ILGenerator();
            context->CodeDom->Accept(ilgen);

            il = ilgen->GetILProgram();
        }
    }

    if(il == NULL)
    {
        return -1;
    }


    if(CompilationContext::GetInstance()->Debug && il != NULL)
    {
        std::string baseFileName = CompilationContext::GetInstance()->OutputFile;
        int pos = baseFileName.find_last_of(".");
        if(pos != -1)
        {
            baseFileName = baseFileName.substr(0, pos) + ".il";
        }

        std::ofstream ildump(baseFileName.c_str());
        for(std::vector<ILClass *>::iterator cit = il->Claases.begin(); cit != il->Claases.end(); ++cit)
        {
            ILClass *c = *cit;

            ildump << "class " <<  c->ClassSymbol->Name << std::endl << "{" << std::endl;

            for(std::vector<ILFunction *>::iterator fit = c->Functions.begin(); fit != c->Functions.end(); ++fit)
            {
                ILFunction *f = *fit;
                ildump << "    function " <<  f->FunctionSymbol->Name << std::endl << "    {" << std::endl;
                for(std::vector<IL>::iterator iit = f->Body.begin(); iit != f->Body.end(); ++iit)
                {
                    IL &il = *iit;
                    if(il.Opcode == IL::Label)
                    {
                        ildump << "        " << il.ToString() << std::endl;
                    }
                    else
                    {
                        ildump << "            " << il.ToString() << std::endl;
                    }
                }
                ildump << "    }" << std::endl;
            }
            ildump << "}" << std::endl;
        }

        ildump.close();
    }

    context->IL = il;

    // TODO: Optimize the IL
    ILOptimizer *ilopt = NULL;

    ilopt = new ILOptimizer();
    
    context->IL = ilopt->Optimize(il);
    
    // print optimized IL
    il = context->IL;
    if(CompilationContext::GetInstance()->Debug && il != NULL)
    {
        printf("--------------------------------------\n");
        printf("Optimized IL:\n");
        std::string baseFileName = CompilationContext::GetInstance()->OutputFile;
        int pos = baseFileName.find_last_of(".");
        if(pos != -1)
        {
            baseFileName = baseFileName.substr(0, pos) + ".opt.il";
        }

        std::ofstream ildump(baseFileName.c_str());
        for(std::vector<ILClass *>::iterator cit = il->Claases.begin(); cit != il->Claases.end(); ++cit)
        {
            ILClass *c = *cit;

            ildump << "class " <<  c->ClassSymbol->Name << std::endl << "{" << std::endl;

            for(std::vector<ILFunction *>::iterator fit = c->Functions.begin(); fit != c->Functions.end(); ++fit)
            {
                ILFunction *f = *fit;
                ildump << "    function " <<  f->FunctionSymbol->Name << std::endl << "    {" << std::endl;
                for(std::vector<IL>::iterator iit = f->Body.begin(); iit != f->Body.end(); ++iit)
                {
                    IL &il = *iit;
                    if(il.Opcode == IL::Label)
                    {
                        ildump << "        " << il.ToString() << std::endl;
                    }
                    else
                    {
                        ildump << "            " << il.ToString() << std::endl;
                    }
                }
                ildump << "    }" << std::endl;
            }
            ildump << "}" << std::endl;
        }

        ildump.close();
    }

    CodeGenerator *codegen = NULL;
    //Generate assembly code from IL
    /* if (CompilationContext::GetInstance()->CodeType == CODE_TYPE_DISA) {
        //Generate DISA assembly code from IL
        codegen = new DisaCodeGenerator();
        } else */
    if (CompilationContext::GetInstance()->CodeType == CODE_TYPE_I0) {
        codegen = new I0CodeGenerator();
    } else {
        printf("Error: unsupported CodeType.\n");
        return -1;
    }

    codegen->Generate(context->IL);


    for(std::vector<std::string>::iterator it = inputFiles.begin(); it != inputFiles.end(); ++it)
    {
        std::string inputFile = context->InputFiles.front();
        std::string fileExt = inputFile.substr(inputFile.find_last_of(".") + 1);
        if(fileExt == "s")
        {
            SourceParser *parser = NULL;
            /* if (CompilationContext::GetInstance()->CodeType == CODE_TYPE_DISA) {
                parser = new DisaAssemblyParser();
            } else
            */
            {
                // TODO: support i0 assembly
                printf(".s file is not supported for i0.\n");
                return -1;
            }
            parser->Parse(inputFile);
        }
    }

    if(context->Debug)
    {
        std::string baseFileName = CompilationContext::GetInstance()->OutputFile;
        std::string dumpFileName, mapFileName;
        int pos = baseFileName.find_last_of(".");
        if(pos != -1)
        {
            baseFileName = baseFileName.substr(0, pos);
        }

        dumpFileName = baseFileName + ".objdump";
        mapFileName = baseFileName + ".map";

        std::ofstream objdump(dumpFileName.c_str());

        int64_t currentText = context->TextStart;
        for(std::vector<TargetInstruction *>::iterator iit = context->Target->Code.begin(); iit != context->Target->Code.end(); ++iit)
        {
            TargetInstruction *inst = *iit;
            char buffer[32];
            sprintf(buffer, "%0llX> \t", (long long)currentText);
            objdump << buffer << inst->ToString().c_str() << std::endl;
            currentText += inst->GetLength();
        }
        objdump.close();


        std::ofstream mapdump(mapFileName.c_str());
        DumpScope(SymbolScope::GetRootScope(), mapdump);
    }
    
    printf("Maximum stack frame size: 0x%llX\n", (long long )(context->MaxStackFrame));
    
    // TODO: Optimize the assembly code
    TargetOptimizer *targetOpt = NULL;


    char *textBuf = new char[0x100000];
    int64_t textSize = 0;
    for(std::vector<TargetInstruction *>::iterator it = context->Target->Code.begin(); it != context->Target->Code.end(); ++it)
    {
        TargetInstruction *inst = *it;
        inst->Encode(&textBuf[textSize]);
        textSize += inst->GetLength();
    }

    // Write the binary into file
    std::string outputFile = CompilationContext::GetInstance()->OutputFile;
    BinaryWriter *binwt = new FlatFileWriter();

    std::vector<SectionInfo> sections;
    SectionInfo textSection;
    textSection.Name = ".text";
    textSection.RawData = textBuf;
    textSection.RawDataSize = textSize;
    textSection.VirtualBase = context->TextStart;
    textSection.VirtualSize = textSize;
    sections.push_back(textSection);

    binwt->WriteBinaryFile(context->OutputFile, &sections, context->TextStart);

    return 0;

}