Commit dbe78661 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #651 from undingen/inc_jit_rewriter2

Add a new JIT tier which is tightly coupled to the AST Interpreter
parents 1ef88c12 5358470c
...@@ -34,6 +34,7 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS} ...@@ -34,6 +34,7 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS}
capi/object.cpp capi/object.cpp
capi/typeobject.cpp capi/typeobject.cpp
codegen/ast_interpreter.cpp codegen/ast_interpreter.cpp
codegen/baseline_jit.cpp
codegen/codegen.cpp codegen/codegen.cpp
codegen/compvars.cpp codegen/compvars.cpp
codegen/entry.cpp codegen/entry.cpp
......
...@@ -109,7 +109,6 @@ void ICSlotRewrite::commit(CommitHook* hook) { ...@@ -109,7 +109,6 @@ void ICSlotRewrite::commit(CommitHook* hook) {
if (!do_commit) if (!do_commit)
return; return;
assert(assembler->isExactlyFull());
assert(!assembler->hasFailed()); assert(!assembler->hasFailed());
for (int i = 0; i < dependencies.size(); i++) { for (int i = 0; i < dependencies.size(); i++) {
......
...@@ -62,9 +62,8 @@ private: ...@@ -62,9 +62,8 @@ private:
ICSlotInfo* ic_entry; ICSlotInfo* ic_entry;
ICSlotRewrite(ICInfo* ic, const char* debug_name);
public: public:
ICSlotRewrite(ICInfo* ic, const char* debug_name);
~ICSlotRewrite(); ~ICSlotRewrite();
assembler::Assembler* getAssembler() { return assembler; } assembler::Assembler* getAssembler() { return assembler; }
......
...@@ -958,7 +958,7 @@ void Rewriter::_call(RewriterVar* result, bool has_side_effects, void* func_addr ...@@ -958,7 +958,7 @@ void Rewriter::_call(RewriterVar* result, bool has_side_effects, void* func_addr
assembler->callq(r); assembler->callq(r);
} else { } else {
assembler->call(assembler::Immediate(offset)); assembler->call(assembler::Immediate(offset));
assert(asm_address == (uint64_t)assembler->curInstPointer()); assert(assembler->hasFailed() || asm_address == (uint64_t)assembler->curInstPointer());
} }
assert(vars_by_location.count(assembler::RAX) == 0); assert(vars_by_location.count(assembler::RAX) == 0);
......
This diff is collapsed.
...@@ -25,6 +25,7 @@ class GCVisitor; ...@@ -25,6 +25,7 @@ class GCVisitor;
class AST_expr; class AST_expr;
class AST_stmt; class AST_stmt;
class AST_Jump;
class Box; class Box;
class BoxedClosure; class BoxedClosure;
class BoxedDict; class BoxedDict;
...@@ -33,6 +34,43 @@ struct LineInfo; ...@@ -33,6 +34,43 @@ struct LineInfo;
extern const void* interpreter_instr_addr; extern const void* interpreter_instr_addr;
struct ASTInterpreterJitInterface {
static int getCurrentBlockOffset();
static int getCurrentInstOffset();
static Box* derefHelper(void* interp, InternedString s);
static Box* doOSRHelper(void* interp, AST_Jump* node);
static Box* getBoxedLocalHelper(void* interp, BoxedString* s);
static Box* getBoxedLocalsHelper(void* interp);
static Box* getLocalHelper(void* interp, InternedString id);
static Box* landingpadHelper(void* interp);
static Box* setExcInfoHelper(void* interp, Box* type, Box* value, Box* traceback);
static Box* uncacheExcInfoHelper(void* interp);
static Box* yieldHelper(void* interp, Box* val);
static void setItemNameHelper(void* interp, Box* str, Box* val);
static void setLocalClosureHelper(void* interp, InternedString id, Box* v);
static void setLocalHelper(void* interp, InternedString id, Box* v);
};
class RewriterVar;
struct Value {
union {
bool b;
int64_t n;
double d;
Box* o;
};
RewriterVar* var;
operator RewriterVar*() { return var; }
Value() : o(0), var(0) {}
Value(bool b, RewriterVar* var) : b(b), var(var) {}
Value(int64_t n, RewriterVar* var) : n(n), var(var) {}
Value(double d, RewriterVar* var) : d(d), var(var) {}
Value(Box* o, RewriterVar* var) : o(o), var(var) {}
};
void setupInterpreter(); void setupInterpreter();
Box* astInterpretFunction(CompiledFunction* f, int nargs, Box* closure, Box* generator, Box* globals, Box* arg1, Box* astInterpretFunction(CompiledFunction* f, int nargs, Box* closure, Box* generator, Box* globals, Box* arg1,
Box* arg2, Box* arg3, Box** args); Box* arg2, Box* arg3, Box** args);
......
This diff is collapsed.
This diff is collapsed.
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "llvm/Object/ObjectFile.h" #include "llvm/Object/ObjectFile.h"
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "analysis/function_analysis.h"
#include "analysis/scoping_analysis.h" #include "analysis/scoping_analysis.h"
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "core/ast.h" #include "core/ast.h"
...@@ -62,6 +63,10 @@ SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags fut ...@@ -62,6 +63,10 @@ SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags fut
} }
} }
SourceInfo::~SourceInfo() {
// TODO: release memory..
}
void FunctionAddressRegistry::registerFunction(const std::string& name, void* addr, int length, void FunctionAddressRegistry::registerFunction(const std::string& name, void* addr, int length,
llvm::Function* llvm_func) { llvm::Function* llvm_func) {
assert(addr); assert(addr);
......
...@@ -544,9 +544,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -544,9 +544,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
emitter->getBuilder()->CreateStore(new_call_count, call_count_ptr); emitter->getBuilder()->CreateStore(new_call_count, call_count_ptr);
int reopt_threshold; int reopt_threshold;
if (effort == EffortLevel::MINIMAL) if (effort == EffortLevel::MODERATE)
reopt_threshold = REOPT_THRESHOLD_BASELINE;
else if (effort == EffortLevel::MODERATE)
reopt_threshold = REOPT_THRESHOLD_T2; reopt_threshold = REOPT_THRESHOLD_T2;
else else
RELEASE_ASSERT(0, "Unknown effort: %d", (int)effort); RELEASE_ASSERT(0, "Unknown effort: %d", (int)effort);
...@@ -1059,15 +1057,15 @@ CompiledFunction* doCompile(SourceInfo* source, ParamNames* param_names, const O ...@@ -1059,15 +1057,15 @@ CompiledFunction* doCompile(SourceInfo* source, ParamNames* param_names, const O
computeBlockSetClosure(blocks); computeBlockSetClosure(blocks);
} }
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(source->cfg); LivenessAnalysis* liveness = source->getLiveness();
std::unique_ptr<PhiAnalysis> phis; std::unique_ptr<PhiAnalysis> phis;
if (entry_descriptor) if (entry_descriptor)
phis = computeRequiredPhis(entry_descriptor, liveness.get(), source->getScopeInfo()); phis = computeRequiredPhis(entry_descriptor, liveness, source->getScopeInfo());
else else
phis = computeRequiredPhis(*param_names, source->cfg, liveness.get(), source->getScopeInfo()); phis = computeRequiredPhis(*param_names, source->cfg, liveness, source->getScopeInfo());
IRGenState irstate(cf, source, std::move(liveness), std::move(phis), param_names, getGCBuilder(), dbg_funcinfo); IRGenState irstate(cf, source, std::move(phis), param_names, getGCBuilder(), dbg_funcinfo);
emitBBs(&irstate, types, entry_descriptor, blocks); emitBBs(&irstate, types, entry_descriptor, blocks);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "analysis/scoping_analysis.h" #include "analysis/scoping_analysis.h"
#include "asm_writing/icinfo.h" #include "asm_writing/icinfo.h"
#include "codegen/ast_interpreter.h" #include "codegen/ast_interpreter.h"
#include "codegen/baseline_jit.h"
#include "codegen/codegen.h" #include "codegen/codegen.h"
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "codegen/irgen.h" #include "codegen/irgen.h"
...@@ -120,6 +121,12 @@ ScopeInfo* SourceInfo::getScopeInfo() { ...@@ -120,6 +121,12 @@ ScopeInfo* SourceInfo::getScopeInfo() {
return scoping->getScopeInfoForNode(ast); return scoping->getScopeInfoForNode(ast);
} }
LivenessAnalysis* SourceInfo::getLiveness() {
if (!liveness_info)
liveness_info = computeLivenessInfo(cfg);
return liveness_info.get();
}
EffortLevel initialEffort() { EffortLevel initialEffort() {
if (FORCE_INTERPRETER) if (FORCE_INTERPRETER)
return EffortLevel::INTERPRETED; return EffortLevel::INTERPRETED;
...@@ -127,7 +134,7 @@ EffortLevel initialEffort() { ...@@ -127,7 +134,7 @@ EffortLevel initialEffort() {
return EffortLevel::MAXIMAL; return EffortLevel::MAXIMAL;
if (ENABLE_INTERPRETER) if (ENABLE_INTERPRETER)
return EffortLevel::INTERPRETED; return EffortLevel::INTERPRETED;
return EffortLevel::MINIMAL; return EffortLevel::MODERATE;
} }
static void compileIR(CompiledFunction* cf, EffortLevel effort) { static void compileIR(CompiledFunction* cf, EffortLevel effort) {
...@@ -270,13 +277,6 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -270,13 +277,6 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
num_compiles.log(); num_compiles.log();
break; break;
} }
case EffortLevel::MINIMAL: {
static StatCounter us_compiling("us_compiling_1_minimal");
us_compiling.log(us);
static StatCounter num_compiles("num_compiles_1_minimal");
num_compiles.log();
break;
}
case EffortLevel::MODERATE: { case EffortLevel::MODERATE: {
static StatCounter us_compiling("us_compiling_2_moderate"); static StatCounter us_compiling("us_compiling_2_moderate");
us_compiling.log(us); us_compiling.log(us);
...@@ -742,6 +742,21 @@ void CompiledFunction::speculationFailed() { ...@@ -742,6 +742,21 @@ void CompiledFunction::speculationFailed() {
} }
} }
CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization* spec, bool is_interpreted, void* code,
EffortLevel effort, const OSREntryDescriptor* entry_descriptor)
: clfunc(NULL),
func(func),
spec(spec),
entry_descriptor(entry_descriptor),
is_interpreted(is_interpreted),
code(code),
effort(effort),
times_called(0),
times_speculation_failed(0),
location_map(nullptr) {
assert((spec != NULL) + (entry_descriptor != NULL) == 1);
}
ConcreteCompilerType* CompiledFunction::getReturnType() { ConcreteCompilerType* CompiledFunction::getReturnType() {
if (spec) if (spec)
return spec->rtn_type; return spec->rtn_type;
...@@ -803,7 +818,7 @@ CompiledFunction* compilePartialFuncInternal(OSRExit* exit) { ...@@ -803,7 +818,7 @@ CompiledFunction* compilePartialFuncInternal(OSRExit* exit) {
assert(exit->parent_cf->clfunc); assert(exit->parent_cf->clfunc);
CompiledFunction*& new_cf = exit->parent_cf->clfunc->osr_versions[exit->entry]; CompiledFunction*& new_cf = exit->parent_cf->clfunc->osr_versions[exit->entry];
if (new_cf == NULL) { if (new_cf == NULL) {
EffortLevel new_effort = exit->parent_cf->effort == EffortLevel::INTERPRETED ? EffortLevel::MINIMAL EffortLevel new_effort = exit->parent_cf->effort == EffortLevel::INTERPRETED ? EffortLevel::MODERATE
: EffortLevel::MAXIMAL; : EffortLevel::MAXIMAL;
CompiledFunction* compiled = compileFunction(exit->parent_cf->clfunc, NULL, new_effort, exit->entry); CompiledFunction* compiled = compileFunction(exit->parent_cf->clfunc, NULL, new_effort, exit->entry);
assert(compiled == new_cf); assert(compiled == new_cf);
...@@ -830,8 +845,6 @@ extern "C" CompiledFunction* reoptCompiledFuncInternal(CompiledFunction* cf) { ...@@ -830,8 +845,6 @@ extern "C" CompiledFunction* reoptCompiledFuncInternal(CompiledFunction* cf) {
EffortLevel new_effort; EffortLevel new_effort;
if (cf->effort == EffortLevel::INTERPRETED) if (cf->effort == EffortLevel::INTERPRETED)
new_effort = EffortLevel::MINIMAL;
else if (cf->effort == EffortLevel::MINIMAL)
new_effort = EffortLevel::MODERATE; new_effort = EffortLevel::MODERATE;
else if (cf->effort == EffortLevel::MODERATE) else if (cf->effort == EffortLevel::MODERATE)
new_effort = EffortLevel::MAXIMAL; new_effort = EffortLevel::MAXIMAL;
......
...@@ -42,12 +42,10 @@ extern "C" void dumpLLVM(llvm::Value* v) { ...@@ -42,12 +42,10 @@ extern "C" void dumpLLVM(llvm::Value* v) {
v->dump(); v->dump();
} }
IRGenState::IRGenState(CompiledFunction* cf, SourceInfo* source_info, std::unique_ptr<LivenessAnalysis> liveness, IRGenState::IRGenState(CompiledFunction* cf, SourceInfo* source_info, std::unique_ptr<PhiAnalysis> phis,
std::unique_ptr<PhiAnalysis> phis, ParamNames* param_names, GCBuilder* gc, ParamNames* param_names, GCBuilder* gc, llvm::MDNode* func_dbg_info)
llvm::MDNode* func_dbg_info)
: cf(cf), : cf(cf),
source_info(source_info), source_info(source_info),
liveness(std::move(liveness)),
phis(std::move(phis)), phis(std::move(phis)),
param_names(param_names), param_names(param_names),
gc(gc), gc(gc),
...@@ -426,13 +424,22 @@ IREmitter* createIREmitter(IRGenState* irstate, llvm::BasicBlock*& curblock, IRG ...@@ -426,13 +424,22 @@ IREmitter* createIREmitter(IRGenState* irstate, llvm::BasicBlock*& curblock, IRG
} }
static std::unordered_map<AST_expr*, std::vector<BoxedString*>*> made_keyword_storage; static std::unordered_map<AST_expr*, std::vector<BoxedString*>*> made_keyword_storage;
static std::vector<BoxedString*>* getKeywordNameStorage(AST_Call* node) { std::vector<BoxedString*>* getKeywordNameStorage(AST_Call* node) {
auto it = made_keyword_storage.find(node); auto it = made_keyword_storage.find(node);
if (it != made_keyword_storage.end()) if (it != made_keyword_storage.end())
return it->second; return it->second;
auto rtn = new std::vector<BoxedString*>(); auto rtn = new std::vector<BoxedString*>();
made_keyword_storage.insert(it, std::make_pair(node, rtn)); made_keyword_storage.insert(it, std::make_pair(node, rtn));
// Only add the keywords to the array the first time, since
// the later times we will hit the cache which will have the
// keyword names already populated:
if (!rtn->size()) {
for (auto kw : node->keywords)
rtn->push_back(kw->arg.getBox());
}
return rtn; return rtn;
} }
...@@ -833,22 +840,10 @@ private: ...@@ -833,22 +840,10 @@ private:
} }
std::vector<CompilerVariable*> args; std::vector<CompilerVariable*> args;
std::vector<BoxedString*>* keyword_names; std::vector<BoxedString*>* keyword_names = NULL;
if (node->keywords.size()) { if (node->keywords.size())
keyword_names = getKeywordNameStorage(node); keyword_names = getKeywordNameStorage(node);
// Only add the keywords to the array the first time, since
// the later times we will hit the cache which will have the
// keyword names already populated:
if (!keyword_names->size()) {
for (auto kw : node->keywords) {
keyword_names->push_back(kw->arg.getBox());
}
}
} else {
keyword_names = NULL;
}
for (int i = 0; i < node->args.size(); i++) { for (int i = 0; i < node->args.size(); i++) {
CompilerVariable* a = evalExpr(node->args[i], unw_info); CompilerVariable* a = evalExpr(node->args[i], unw_info);
args.push_back(a); args.push_back(a);
...@@ -1887,6 +1882,7 @@ private: ...@@ -1887,6 +1882,7 @@ private:
static BoxedString* space_str = static_cast<BoxedString*>(PyString_InternFromString(" ")); static BoxedString* space_str = static_cast<BoxedString*>(PyString_InternFromString(" "));
// TODO: why are we inline-generating all this code instead of just emitting a call to some runtime function? // TODO: why are we inline-generating all this code instead of just emitting a call to some runtime function?
// (=printHelper())
int nvals = node->values.size(); int nvals = node->values.size();
for (int i = 0; i < nvals; i++) { for (int i = 0; i < nvals; i++) {
CompilerVariable* var = evalExpr(node->values[i], unw_info); CompilerVariable* var = evalExpr(node->values[i], unw_info);
...@@ -2027,9 +2023,7 @@ private: ...@@ -2027,9 +2023,7 @@ private:
auto effort = irstate->getEffortLevel(); auto effort = irstate->getEffortLevel();
int osr_threshold; int osr_threshold;
if (effort == EffortLevel::MINIMAL) if (effort == EffortLevel::MODERATE)
osr_threshold = OSR_THRESHOLD_BASELINE;
else if (effort == EffortLevel::MODERATE)
osr_threshold = OSR_THRESHOLD_T2; osr_threshold = OSR_THRESHOLD_T2;
else else
RELEASE_ASSERT(0, "Unknown effort: %d", (int)effort); RELEASE_ASSERT(0, "Unknown effort: %d", (int)effort);
......
...@@ -56,7 +56,6 @@ class IRGenState { ...@@ -56,7 +56,6 @@ class IRGenState {
private: private:
CompiledFunction* cf; CompiledFunction* cf;
SourceInfo* source_info; SourceInfo* source_info;
std::unique_ptr<LivenessAnalysis> liveness;
std::unique_ptr<PhiAnalysis> phis; std::unique_ptr<PhiAnalysis> phis;
ParamNames* param_names; ParamNames* param_names;
GCBuilder* gc; GCBuilder* gc;
...@@ -70,8 +69,8 @@ private: ...@@ -70,8 +69,8 @@ private:
public: public:
IRGenState(CompiledFunction* cf, SourceInfo* source_info, std::unique_ptr<LivenessAnalysis> liveness, IRGenState(CompiledFunction* cf, SourceInfo* source_info, std::unique_ptr<PhiAnalysis> phis,
std::unique_ptr<PhiAnalysis> phis, ParamNames* param_names, GCBuilder* gc, llvm::MDNode* func_dbg_info); ParamNames* param_names, GCBuilder* gc, llvm::MDNode* func_dbg_info);
~IRGenState(); ~IRGenState();
CompiledFunction* getCurFunction() { return cf; } CompiledFunction* getCurFunction() { return cf; }
...@@ -90,7 +89,7 @@ public: ...@@ -90,7 +89,7 @@ public:
SourceInfo* getSourceInfo() { return source_info; } SourceInfo* getSourceInfo() { return source_info; }
LivenessAnalysis* getLiveness() { return liveness.get(); } LivenessAnalysis* getLiveness() { return source_info->getLiveness(); }
PhiAnalysis* getPhis() { return phis.get(); } PhiAnalysis* getPhis() { return phis.get(); }
ScopeInfo* getScopeInfo(); ScopeInfo* getScopeInfo();
...@@ -133,11 +132,13 @@ public: ...@@ -133,11 +132,13 @@ public:
}; };
class IREmitter; class IREmitter;
class AST_Call;
IREmitter* createIREmitter(IRGenState* irstate, llvm::BasicBlock*& curblock, IRGenerator* irgenerator = NULL); IREmitter* createIREmitter(IRGenState* irstate, llvm::BasicBlock*& curblock, IRGenerator* irgenerator = NULL);
IRGenerator* createIRGenerator(IRGenState* irstate, std::unordered_map<CFGBlock*, llvm::BasicBlock*>& entry_blocks, IRGenerator* createIRGenerator(IRGenState* irstate, std::unordered_map<CFGBlock*, llvm::BasicBlock*>& entry_blocks,
CFGBlock* myblock, TypeAnalysis* types); CFGBlock* myblock, TypeAnalysis* types);
CLFunction* wrapFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body, SourceInfo* source); CLFunction* wrapFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body, SourceInfo* source);
std::vector<BoxedString*>* getKeywordNameStorage(AST_Call* node);
} }
#endif #endif
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
namespace pyston { namespace pyston {
class AST_stmt; class AST_stmt;
class Box;
class CFG; class CFG;
class CFGBlock { class CFGBlock {
...@@ -43,6 +44,12 @@ private: ...@@ -43,6 +44,12 @@ private:
CFG* cfg; CFG* cfg;
public: public:
// Baseline JIT helper fields:
// contains address to the start of the code of this basic block
void* code;
// contains the address of the entry function
std::pair<CFGBlock*, Box*>(*entry_code)(void* interpeter, CFGBlock* block);
std::vector<AST_stmt*> body; std::vector<AST_stmt*> body;
std::vector<CFGBlock*> predecessors, successors; std::vector<CFGBlock*> predecessors, successors;
int idx; // index in the CFG int idx; // index in the CFG
...@@ -50,7 +57,7 @@ public: ...@@ -50,7 +57,7 @@ public:
typedef std::vector<AST_stmt*>::iterator iterator; typedef std::vector<AST_stmt*>::iterator iterator;
CFGBlock(CFG* cfg, int idx) : cfg(cfg), idx(idx), info(NULL) {} CFGBlock(CFG* cfg, int idx) : cfg(cfg), code(NULL), entry_code(NULL), idx(idx), info(NULL) {}
void connectTo(CFGBlock* successor, bool allow_backedge = false); void connectTo(CFGBlock* successor, bool allow_backedge = false);
void unconnectFrom(CFGBlock* successor); void unconnectFrom(CFGBlock* successor);
......
...@@ -39,15 +39,16 @@ bool DUMPJIT = false; ...@@ -39,15 +39,16 @@ bool DUMPJIT = false;
bool TRAP = false; bool TRAP = false;
bool USE_STRIPPED_STDLIB = true; // always true bool USE_STRIPPED_STDLIB = true; // always true
bool ENABLE_INTERPRETER = true; bool ENABLE_INTERPRETER = true;
bool ENABLE_BASELINEJIT = true;
bool ENABLE_PYPA_PARSER = true; bool ENABLE_PYPA_PARSER = true;
bool USE_REGALLOC_BASIC = true; bool USE_REGALLOC_BASIC = true;
bool PAUSE_AT_ABORT = false; bool PAUSE_AT_ABORT = false;
bool ENABLE_TRACEBACKS = true; bool ENABLE_TRACEBACKS = true;
int OSR_THRESHOLD_INTERPRETER = 500; int OSR_THRESHOLD_INTERPRETER = 25;
int REOPT_THRESHOLD_INTERPRETER = 200; int REOPT_THRESHOLD_INTERPRETER = 25;
int OSR_THRESHOLD_BASELINE = 10000; int OSR_THRESHOLD_BASELINE = 2500;
int REOPT_THRESHOLD_BASELINE = 250; int REOPT_THRESHOLD_BASELINE = 1000;
int OSR_THRESHOLD_T2 = 10000; int OSR_THRESHOLD_T2 = 10000;
int REOPT_THRESHOLD_T2 = 10000; int REOPT_THRESHOLD_T2 = 10000;
int SPECULATION_THRESHOLD = 100; int SPECULATION_THRESHOLD = 100;
......
...@@ -38,8 +38,8 @@ extern int SPECULATION_THRESHOLD; ...@@ -38,8 +38,8 @@ extern int SPECULATION_THRESHOLD;
extern int MAX_OBJECT_CACHE_ENTRIES; extern int MAX_OBJECT_CACHE_ENTRIES;
extern bool SHOW_DISASM, FORCE_INTERPRETER, FORCE_OPTIMIZE, PROFILE, DUMPJIT, TRAP, USE_STRIPPED_STDLIB, extern bool SHOW_DISASM, FORCE_INTERPRETER, FORCE_OPTIMIZE, PROFILE, DUMPJIT, TRAP, USE_STRIPPED_STDLIB,
CONTINUE_AFTER_FATAL, ENABLE_INTERPRETER, ENABLE_PYPA_PARSER, USE_REGALLOC_BASIC, PAUSE_AT_ABORT, ENABLE_TRACEBACKS, CONTINUE_AFTER_FATAL, ENABLE_INTERPRETER, ENABLE_BASELINEJIT, ENABLE_PYPA_PARSER, USE_REGALLOC_BASIC,
ASSEMBLY_LOGGING; PAUSE_AT_ABORT, ENABLE_TRACEBACKS, ASSEMBLY_LOGGING;
extern bool ENABLE_ICS, ENABLE_ICGENERICS, ENABLE_ICGETITEMS, ENABLE_ICSETITEMS, ENABLE_ICDELITEMS, ENABLE_ICBINEXPS, extern bool ENABLE_ICS, ENABLE_ICGENERICS, ENABLE_ICGETITEMS, ENABLE_ICSETITEMS, ENABLE_ICDELITEMS, ENABLE_ICBINEXPS,
ENABLE_ICNONZEROS, ENABLE_ICCALLSITES, ENABLE_ICSETATTRS, ENABLE_ICGETATTRS, ENALBE_ICDELATTRS, ENABLE_ICGETGLOBALS, ENABLE_ICNONZEROS, ENABLE_ICCALLSITES, ENABLE_ICSETATTRS, ENABLE_ICGETATTRS, ENALBE_ICDELATTRS, ENABLE_ICGETGLOBALS,
......
...@@ -65,7 +65,6 @@ using gc::GCVisitor; ...@@ -65,7 +65,6 @@ using gc::GCVisitor;
enum class EffortLevel { enum class EffortLevel {
INTERPRETED = 0, INTERPRETED = 0,
MINIMAL = 1,
MODERATE = 2, MODERATE = 2,
MAXIMAL = 3, MAXIMAL = 3,
}; };
...@@ -221,6 +220,7 @@ class BoxedClosure; ...@@ -221,6 +220,7 @@ class BoxedClosure;
class BoxedGenerator; class BoxedGenerator;
class ICInfo; class ICInfo;
class LocationMap; class LocationMap;
class JitCodeBlock;
struct CompiledFunction { struct CompiledFunction {
private: private:
...@@ -249,21 +249,10 @@ public: ...@@ -249,21 +249,10 @@ public:
LocationMap* location_map; // only meaningful if this is a compiled frame LocationMap* location_map; // only meaningful if this is a compiled frame
std::vector<ICInfo*> ics; std::vector<ICInfo*> ics;
std::vector<std::unique_ptr<JitCodeBlock>> code_blocks;
CompiledFunction(llvm::Function* func, FunctionSpecialization* spec, bool is_interpreted, void* code, CompiledFunction(llvm::Function* func, FunctionSpecialization* spec, bool is_interpreted, void* code,
EffortLevel effort, const OSREntryDescriptor* entry_descriptor) EffortLevel effort, const OSREntryDescriptor* entry_descriptor);
: clfunc(NULL),
func(func),
spec(spec),
entry_descriptor(entry_descriptor),
is_interpreted(is_interpreted),
code(code),
effort(effort),
times_called(0),
times_speculation_failed(0),
location_map(nullptr) {
assert((spec != NULL) + (entry_descriptor != NULL) == 1);
}
ConcreteCompilerType* getReturnType(); ConcreteCompilerType* getReturnType();
...@@ -282,6 +271,7 @@ typedef int FutureFlags; ...@@ -282,6 +271,7 @@ typedef int FutureFlags;
class BoxedModule; class BoxedModule;
class ScopeInfo; class ScopeInfo;
class InternedStringPool; class InternedStringPool;
class LivenessAnalysis;
class SourceInfo { class SourceInfo {
public: public:
BoxedModule* parent_module; BoxedModule* parent_module;
...@@ -295,6 +285,7 @@ public: ...@@ -295,6 +285,7 @@ public:
InternedStringPool& getInternedStrings(); InternedStringPool& getInternedStrings();
ScopeInfo* getScopeInfo(); ScopeInfo* getScopeInfo();
LivenessAnalysis* getLiveness();
// TODO we're currently copying the body of the AST into here, since lambdas don't really have a statement-based // TODO we're currently copying the body of the AST into here, since lambdas don't really have a statement-based
// body and we have to create one. Ideally, we'd be able to avoid the space duplication for non-lambdas. // body and we have to create one. Ideally, we'd be able to avoid the space duplication for non-lambdas.
...@@ -307,6 +298,10 @@ public: ...@@ -307,6 +298,10 @@ public:
SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags future_flags, AST* ast, SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags future_flags, AST* ast,
std::vector<AST_stmt*> body, std::string fn); std::vector<AST_stmt*> body, std::string fn);
~SourceInfo();
private:
std::unique_ptr<LivenessAnalysis> liveness_info;
}; };
typedef std::vector<CompiledFunction*> FunctionList; typedef std::vector<CompiledFunction*> FunctionList;
......
...@@ -226,6 +226,28 @@ extern "C" bool softspace(Box* b, bool newval) { ...@@ -226,6 +226,28 @@ extern "C" bool softspace(Box* b, bool newval) {
return r; return r;
} }
extern "C" void printHelper(Box* dest, Box* var, bool nl) {
static BoxedString* write_str = static_cast<BoxedString*>(PyString_InternFromString("write"));
static BoxedString* newline_str = static_cast<BoxedString*>(PyString_InternFromString("\n"));
static BoxedString* space_str = static_cast<BoxedString*>(PyString_InternFromString(" "));
if (var) {
// begin code for handling of softspace
bool new_softspace = !nl;
if (softspace(dest, new_softspace))
callattrInternal(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), space_str, 0, 0, 0, 0);
Box* str_or_unicode_var = (var->cls == unicode_cls) ? var : str(var);
callattrInternal(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), str_or_unicode_var, 0, 0, 0, 0);
}
if (nl) {
callattrInternal(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), newline_str, 0, 0, 0, 0);
if (!var)
softspace(dest, false);
}
}
extern "C" void my_assert(bool b) { extern "C" void my_assert(bool b) {
assert(b); assert(b);
} }
......
...@@ -48,6 +48,7 @@ BoxedModule* getCurrentModule(); ...@@ -48,6 +48,7 @@ BoxedModule* getCurrentModule();
// TODO sort this // TODO sort this
extern "C" bool softspace(Box* b, bool newval); extern "C" bool softspace(Box* b, bool newval);
extern "C" void printHelper(Box* dest, Box* var, bool nl);
extern "C" void my_assert(bool b); extern "C" void my_assert(bool b);
extern "C" Box* getattr(Box* obj, BoxedString* attr); extern "C" Box* getattr(Box* obj, BoxedString* attr);
extern "C" Box* getattrMaybeNonstring(Box* obj, Box* attr); extern "C" Box* getattrMaybeNonstring(Box* obj, Box* attr);
......
...@@ -578,6 +578,23 @@ public: ...@@ -578,6 +578,23 @@ public:
rtn->elts[2] = elt2; rtn->elts[2] = elt2;
return rtn; return rtn;
} }
static BoxedTuple* create4(Box* elt0, Box* elt1, Box* elt2, Box* elt3) {
BoxedTuple* rtn = new (4) BoxedTuple(4);
rtn->elts[0] = elt0;
rtn->elts[1] = elt1;
rtn->elts[2] = elt2;
rtn->elts[3] = elt3;
return rtn;
}
static BoxedTuple* create5(Box* elt0, Box* elt1, Box* elt2, Box* elt3, Box* elt4) {
BoxedTuple* rtn = new (5) BoxedTuple(5);
rtn->elts[0] = elt0;
rtn->elts[1] = elt1;
rtn->elts[2] = elt2;
rtn->elts[3] = elt3;
rtn->elts[4] = elt4;
return rtn;
}
static BoxedTuple* create(std::initializer_list<Box*> members) { return new (members.size()) BoxedTuple(members); } static BoxedTuple* create(std::initializer_list<Box*> members) { return new (members.size()) BoxedTuple(members); }
static BoxedTuple* create(int64_t size, BoxedClass* cls) { static BoxedTuple* create(int64_t size, BoxedClass* cls) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment