void compileAndRunModule(AST_Module* m, BoxedModule* bm) { Timer _t("for compileModule()"); ScopingAnalysis* scoping = runScopingAnalysis(m); SourceInfo* si = new SourceInfo(bm, scoping); si->cfg = computeCFG(AST_TYPE::Module, m->body); si->ast = m; si->liveness = computeLivenessInfo(si->cfg); si->phis = computeRequiredPhis(NULL, si->cfg, si->liveness, si->scoping->getScopeInfoForNode(si->ast)); CLFunction* cl_f = new CLFunction(si); EffortLevel::EffortLevel effort = initialEffort(); CompiledFunction* cf = compileFunction(cl_f, new FunctionSignature(VOID, &si->getArgNames(), 0, false, false), effort, NULL); assert(cf->clfunc->versions.size()); _t.end(); if (cf->is_interpreted) interpretFunction(cf->func, 0, NULL, NULL, NULL, NULL); else ((void (*)())cf->code)(); }
void compileAndRunModule(AST_Module* m, BoxedModule* bm) { CompiledFunction* cf; { // scope for limiting the locked region: LOCK_REGION(codegen_rwlock.asWrite()); Timer _t("for compileModule()"); bm->future_flags = getFutureFlags(m, bm->fn.c_str()); ScopingAnalysis* scoping = runScopingAnalysis(m); SourceInfo* si = new SourceInfo(bm, scoping, m, m->body); si->cfg = computeCFG(si, m->body); si->liveness = computeLivenessInfo(si->cfg); si->phis = computeRequiredPhis(si->arg_names, si->cfg, si->liveness, si->getScopeInfo()); CLFunction* cl_f = new CLFunction(0, 0, false, false, si); EffortLevel::EffortLevel effort = initialEffort(); cf = compileFunction(cl_f, new FunctionSpecialization(VOID), effort, NULL); assert(cf->clfunc->versions.size()); } if (cf->is_interpreted) interpretFunction(cf->func, 0, NULL, NULL, NULL, NULL, NULL, NULL); else ((void (*)())cf->code)(); }
CompiledFunction* compileModule(AST_Module *m, BoxedModule *bm) { Timer _t("for compileModule()"); ScopingAnalysis *scoping = runScopingAnalysis(m); SourceInfo *si = new SourceInfo(bm, scoping); si->cfg = computeCFG(AST_TYPE::Module, m->body); si->ast = m; si->liveness = computeLivenessInfo(si->cfg); si->phis = computeRequiredPhis(NULL, si->cfg, si->liveness, si->scoping->getScopeInfoForNode(si->ast)); CLFunction *cl_f = new CLFunction(si); EffortLevel::EffortLevel effort = initialEffort(); CompiledFunction *cf = _doCompile(cl_f, new FunctionSignature(VOID, false), effort, NULL); assert(cf->clfunc->versions.size()); return cf; }
CompiledFunction* resolveCLFunc(CLFunction *f, int64_t nargs, Box* arg1, Box* arg2, Box* arg3, Box** args) { static StatCounter slowpath_resolveclfunc("slowpath_resolveclfunc"); slowpath_resolveclfunc.log(); FunctionList &versions = f->versions; for (int i = 0; i < versions.size(); i++) { CompiledFunction *cf = versions[i]; FunctionSignature* sig = cf->sig; if (sig->rtn_type->llvmType() != g.llvm_value_type_ptr) continue; if ((!sig->is_vararg && sig->arg_types.size() != nargs) || (sig->is_vararg && nargs < sig->arg_types.size())) continue; int nsig_args = sig->arg_types.size(); if (nsig_args >= 1) { if (sig->arg_types[0]->isFitBy(arg1->cls)) { // pass } else { continue; } } if (nsig_args >= 2) { if (sig->arg_types[1]->isFitBy(arg2->cls)) { // pass } else { continue; } } if (nsig_args >= 3) { if (sig->arg_types[2]->isFitBy(arg3->cls)) { // pass } else { continue; } } bool bad = false; for (int j = 3; j < nsig_args; j++) { if (sig->arg_types[j]->isFitBy(args[j-3]->cls)) { // pass } else { bad = true; break; } } if (bad) continue; assert(cf); assert(!cf->entry_descriptor); assert(cf->is_interpreted == (cf->code == NULL)); return cf; } if (f->source == NULL) { printf("Error: couldn't find suitable function version and no source to recompile!\n"); printf("%ld args:", nargs); for (int i = 0; i < nargs; i++) { Box* firstargs[] = {arg1, arg2, arg3}; printf(" %s", getTypeName(firstargs[i])->c_str()); if (i == 3) { printf(" [and more]"); break; } } printf("\n"); for (int j = 0; j < f->versions.size(); j++) { std::string func_name = g.func_addr_registry.getFuncNameAtAddress(f->versions[j]->code, true); printf("Version %d, %s:", j, func_name.c_str()); FunctionSignature *sig = f->versions[j]->sig; for (int i = 0; i < sig->arg_types.size(); i++) { printf(" %s", sig->arg_types[i]->debugName().c_str()); } if (sig->is_vararg) printf(" *vararg"); printf("\n"); //printf(" @%p %s\n", f->versions[j]->code, func_name.c_str()); } abort(); } assert(f->source->getArgsAST()->vararg.size() == 0); bool is_vararg = false; std::vector<ConcreteCompilerType*> arg_types; if (nargs >= 1) { arg_types.push_back(typeFromClass(arg1->cls)); } if (nargs >= 2) { arg_types.push_back(typeFromClass(arg2->cls)); } if (nargs >= 3) { arg_types.push_back(typeFromClass(arg3->cls)); } for (int j = 3; j < nargs; j++) { arg_types.push_back(typeFromClass(args[j-3]->cls)); } FunctionSignature *sig = new FunctionSignature(UNKNOWN, arg_types, is_vararg); EffortLevel::EffortLevel new_effort = initialEffort(); CompiledFunction *cf = _doCompile(f, sig, new_effort, NULL); // this pushes the new CompiledVersion to the back of the version list assert(cf->is_interpreted == (cf->code == NULL)); return cf; }