Commit f8283fb1 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Reenable type speculation

parent b0555285
......@@ -74,10 +74,7 @@ static BoxedClass* simpleCallSpeculation(AST_Call* node, CompilerType* rtn_type,
if (node->func->type == AST_TYPE::Name && ast_cast<AST_Name>(node->func)->id.s() == "xrange")
return xrange_cls;
// if (node->func->type == AST_TYPE::Attribute && ast_cast<AST_Attribute>(node->func)->attr == "dot")
// return float_cls;
return NULL;
return predictClassFor(node);
}
typedef llvm::DenseMap<InternedString, CompilerType*> TypeMap;
......@@ -115,10 +112,6 @@ private:
assert(old_type);
assert(speculation != TypeAnalysis::NONE);
if (VERBOSITY() >= 3)
printf("Would maybe try to speculate but deopt is currently broken\n");
return old_type;
if (speculated_cls != NULL && speculated_cls->is_constant) {
ConcreteCompilerType* speculated_type = unboxedType(typeFromClass(speculated_cls));
if (VERBOSITY() >= 2) {
......
......@@ -1754,8 +1754,8 @@ Box* astInterpretFunctionEval(CLFunction* clfunc, Box* globals, Box* boxedLocals
return v.o ? v.o : None;
}
Box* astInterpretFrom(CLFunction* clfunc, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
FrameStackState frame_state) {
Box* astInterpretDeopt(CLFunction* clfunc, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
FrameStackState frame_state) {
assert(clfunc);
assert(enclosing_stmt);
assert(frame_state.locals);
......
......@@ -75,8 +75,8 @@ void setupInterpreter();
Box* astInterpretFunction(CLFunction* f, int nargs, Box* closure, Box* generator, Box* globals, Box* arg1, Box* arg2,
Box* arg3, Box** args);
Box* astInterpretFunctionEval(CLFunction* cf, Box* globals, Box* boxedLocals);
Box* astInterpretFrom(CLFunction* cf, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
FrameStackState frame_state);
Box* astInterpretDeopt(CLFunction* cf, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
FrameStackState frame_state);
AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr);
Box* getGlobalsForInterpretedFrame(void* frame_ptr);
......
......@@ -670,6 +670,7 @@ void CompiledFunction::speculationFailed() {
CLFunction* cl = this->clfunc;
assert(cl);
assert(this != cl->always_use_version);
bool found = false;
for (int i = 0; i < clfunc->versions.size(); i++) {
......@@ -681,6 +682,17 @@ void CompiledFunction::speculationFailed() {
}
}
if (!found) {
for (auto it = clfunc->osr_versions.begin(); it != clfunc->osr_versions.end(); ++it) {
if (it->second == this) {
clfunc->osr_versions.erase(it);
this->dependent_callsites.invalidateAll();
found = true;
break;
}
}
}
if (!found) {
for (int i = 0; i < clfunc->versions.size(); i++) {
printf("%p\n", clfunc->versions[i]);
......
......@@ -30,6 +30,7 @@ class TypeRecorder;
// (I think most compilers pass "this" as the argument 0 and then shift the rest of the
// arguments, but I'd rather not depend on that behavior since I can't find where that's
// specified.)
// The return value of this function is 'obj' for ease of use.
extern "C" Box* recordType(TypeRecorder* recorder, Box* obj);
class TypeRecorder {
private:
......
......@@ -426,9 +426,11 @@ static bool inGeneratorEntry(unw_word_t ip) {
return ((unw_word_t)generatorEntry < ip && ip <= generator_entry_end);
}
static bool inDeopt(unw_word_t ip) {
static unw_word_t deopt_end = getFunctionEnd((unw_word_t)deopt);
return ((unw_word_t)deopt < ip && ip <= deopt_end);
static bool isDeopt(unw_word_t ip) {
// Check for astInterpretDeopt() instead of deopt(), since deopt() will do some
// unwinding and we don't want it to skip things.
static unw_word_t deopt_end = getFunctionEnd((unw_word_t)astInterpretDeopt);
return ((unw_word_t)astInterpretDeopt < ip && ip <= deopt_end);
}
......@@ -626,7 +628,7 @@ void unwindingThroughFrame(PythonUnwindSession* unwind_session, unw_cursor_t* cu
unw_word_t bp = get_cursor_bp(cursor);
PythonFrameIteratorImpl frame_iter;
if (inDeopt(ip)) {
if (isDeopt(ip)) {
assert(!unwind_session->shouldSkipFrame());
unwind_session->setShouldSkipNextFrame(true);
} else if (frameIsPythonFrame(ip, bp, cursor, &frame_iter)) {
......@@ -667,7 +669,7 @@ template <typename Func> void unwindPythonStack(Func func) {
bool stop_unwinding = false;
PythonFrameIteratorImpl frame_iter;
if (inDeopt(ip)) {
if (isDeopt(ip)) {
assert(!unwind_session->shouldSkipFrame());
unwind_session->setShouldSkipNextFrame(true);
} else if (frameIsPythonFrame(ip, bp, &cursor, &frame_iter)) {
......
......@@ -347,8 +347,9 @@ public:
compiled->clfunc = this;
if (compiled->entry_descriptor == NULL) {
if (versions.size() == 0 && compiled->effort == EffortLevel::MAXIMAL && compiled->spec->accepts_all_inputs
&& compiled->spec->boxed_return_value)
bool could_have_speculations = (source.get() != NULL);
if (!could_have_speculations && versions.size() == 0 && compiled->effort == EffortLevel::MAXIMAL
&& compiled->spec->accepts_all_inputs && compiled->spec->boxed_return_value)
always_use_version = compiled;
assert(compiled->spec->arg_types.size() == paramspec.totalReceived());
......
......@@ -169,14 +169,6 @@ extern "C" Box* deopt(AST_expr* expr, Box* value) {
static StatCounter num_deopt("num_deopt");
num_deopt.log();
printf("Deopt!\n");
print_ast(expr);
printf("\n");
dump(value);
printf("\n");
RELEASE_ASSERT(0, "deopt is currently broken...");
auto deopt_state = getDeoptState();
// Should we only do this selectively?
......@@ -189,7 +181,7 @@ extern "C" Box* deopt(AST_expr* expr, Box* value) {
deopt_state.frame_state.frame_info->exc.value = NULL;
}
return astInterpretFrom(deopt_state.cf->clfunc, expr, deopt_state.current_stmt, value, deopt_state.frame_state);
return astInterpretDeopt(deopt_state.cf->clfunc, expr, deopt_state.current_stmt, value, deopt_state.frame_state);
}
extern "C" bool softspace(Box* b, bool newval) {
......
# skip-if: '-O' in EXTRA_JIT_ARGS
# expected: statfail
# statcheck: 4 <= noninit_count('num_deopt') < 50
# statcheck: 1 <= stats["num_osr_exits"] <= 2
......
# skip-if: '-O' in EXTRA_JIT_ARGS
# expected: statfail
# statcheck: 4 <= noninit_count('num_deopt') < 50
# statcheck: 1 <= stats["num_osr_exits"] <= 2
......
# skip-if: '-O' in EXTRA_JIT_ARGS
# expected: statfail
# statcheck: 4 <= noninit_count('num_deopt') < 50
# statcheck: 1 <= stats["num_osr_exits"] <= 2
......
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