Commit 22b48e18 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #1172 from kmod/jit_time

Try to reduce JIT time for the LLVM tier
parents 7fd2c60c 31333266
......@@ -332,7 +332,7 @@ endmacro()
# tests testname directory arguments
add_pyston_test(defaults tests --order-by-mtime -t50)
# XXX: reenable
# add_pyston_test(force_llvm tests -a=-n -a=-X -t50)
add_pyston_test(force_llvm tests -a=-n -a=-X -t50)
if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
add_pyston_test(max_compilation_tier tests -a=-O -a=-X -t50)
endif()
......
def f(l):
if l[0] > l[1]: l[0], l[1] = l[1], l[0]
if l[0] > l[2]: l[0], l[2] = l[2], l[0]
if l[0] > l[3]: l[0], l[3] = l[3], l[0]
if l[0] > l[4]: l[0], l[4] = l[4], l[0]
if l[0] > l[5]: l[0], l[5] = l[5], l[0]
if l[0] > l[6]: l[0], l[6] = l[6], l[0]
if l[0] > l[7]: l[0], l[7] = l[7], l[0]
if l[0] > l[8]: l[0], l[8] = l[8], l[0]
if l[0] > l[9]: l[0], l[9] = l[9], l[0]
if l[0] > l[10]: l[0], l[10] = l[10], l[0]
if l[0] > l[11]: l[0], l[11] = l[11], l[0]
if l[0] > l[12]: l[0], l[12] = l[12], l[0]
if l[0] > l[13]: l[0], l[13] = l[13], l[0]
if l[0] > l[14]: l[0], l[14] = l[14], l[0]
if l[0] > l[15]: l[0], l[15] = l[15], l[0]
if l[0] > l[16]: l[0], l[16] = l[16], l[0]
if l[0] > l[17]: l[0], l[17] = l[17], l[0]
if l[0] > l[18]: l[0], l[18] = l[18], l[0]
if l[0] > l[19]: l[0], l[19] = l[19], l[0]
if l[1] > l[2]: l[1], l[2] = l[2], l[1]
if l[1] > l[3]: l[1], l[3] = l[3], l[1]
if l[1] > l[4]: l[1], l[4] = l[4], l[1]
if l[1] > l[5]: l[1], l[5] = l[5], l[1]
if l[1] > l[6]: l[1], l[6] = l[6], l[1]
if l[1] > l[7]: l[1], l[7] = l[7], l[1]
if l[1] > l[8]: l[1], l[8] = l[8], l[1]
if l[1] > l[9]: l[1], l[9] = l[9], l[1]
if l[1] > l[10]: l[1], l[10] = l[10], l[1]
if l[1] > l[11]: l[1], l[11] = l[11], l[1]
if l[1] > l[12]: l[1], l[12] = l[12], l[1]
if l[1] > l[13]: l[1], l[13] = l[13], l[1]
if l[1] > l[14]: l[1], l[14] = l[14], l[1]
if l[1] > l[15]: l[1], l[15] = l[15], l[1]
if l[1] > l[16]: l[1], l[16] = l[16], l[1]
if l[1] > l[17]: l[1], l[17] = l[17], l[1]
if l[1] > l[18]: l[1], l[18] = l[18], l[1]
if l[1] > l[19]: l[1], l[19] = l[19], l[1]
if l[2] > l[3]: l[2], l[3] = l[3], l[2]
if l[2] > l[4]: l[2], l[4] = l[4], l[2]
if l[2] > l[5]: l[2], l[5] = l[5], l[2]
if l[2] > l[6]: l[2], l[6] = l[6], l[2]
if l[2] > l[7]: l[2], l[7] = l[7], l[2]
if l[2] > l[8]: l[2], l[8] = l[8], l[2]
if l[2] > l[9]: l[2], l[9] = l[9], l[2]
if l[2] > l[10]: l[2], l[10] = l[10], l[2]
if l[2] > l[11]: l[2], l[11] = l[11], l[2]
if l[2] > l[12]: l[2], l[12] = l[12], l[2]
if l[2] > l[13]: l[2], l[13] = l[13], l[2]
if l[2] > l[14]: l[2], l[14] = l[14], l[2]
if l[2] > l[15]: l[2], l[15] = l[15], l[2]
if l[2] > l[16]: l[2], l[16] = l[16], l[2]
if l[2] > l[17]: l[2], l[17] = l[17], l[2]
if l[2] > l[18]: l[2], l[18] = l[18], l[2]
if l[2] > l[19]: l[2], l[19] = l[19], l[2]
if l[3] > l[4]: l[3], l[4] = l[4], l[3]
if l[3] > l[5]: l[3], l[5] = l[5], l[3]
if l[3] > l[6]: l[3], l[6] = l[6], l[3]
if l[3] > l[7]: l[3], l[7] = l[7], l[3]
if l[3] > l[8]: l[3], l[8] = l[8], l[3]
if l[3] > l[9]: l[3], l[9] = l[9], l[3]
if l[3] > l[10]: l[3], l[10] = l[10], l[3]
if l[3] > l[11]: l[3], l[11] = l[11], l[3]
if l[3] > l[12]: l[3], l[12] = l[12], l[3]
if l[3] > l[13]: l[3], l[13] = l[13], l[3]
if l[3] > l[14]: l[3], l[14] = l[14], l[3]
if l[3] > l[15]: l[3], l[15] = l[15], l[3]
if l[3] > l[16]: l[3], l[16] = l[16], l[3]
if l[3] > l[17]: l[3], l[17] = l[17], l[3]
if l[3] > l[18]: l[3], l[18] = l[18], l[3]
if l[3] > l[19]: l[3], l[19] = l[19], l[3]
if l[4] > l[5]: l[4], l[5] = l[5], l[4]
if l[4] > l[6]: l[4], l[6] = l[6], l[4]
if l[4] > l[7]: l[4], l[7] = l[7], l[4]
if l[4] > l[8]: l[4], l[8] = l[8], l[4]
if l[4] > l[9]: l[4], l[9] = l[9], l[4]
if l[4] > l[10]: l[4], l[10] = l[10], l[4]
if l[4] > l[11]: l[4], l[11] = l[11], l[4]
if l[4] > l[12]: l[4], l[12] = l[12], l[4]
if l[4] > l[13]: l[4], l[13] = l[13], l[4]
if l[4] > l[14]: l[4], l[14] = l[14], l[4]
if l[4] > l[15]: l[4], l[15] = l[15], l[4]
if l[4] > l[16]: l[4], l[16] = l[16], l[4]
if l[4] > l[17]: l[4], l[17] = l[17], l[4]
if l[4] > l[18]: l[4], l[18] = l[18], l[4]
if l[4] > l[19]: l[4], l[19] = l[19], l[4]
if l[5] > l[6]: l[5], l[6] = l[6], l[5]
if l[5] > l[7]: l[5], l[7] = l[7], l[5]
if l[5] > l[8]: l[5], l[8] = l[8], l[5]
if l[5] > l[9]: l[5], l[9] = l[9], l[5]
if l[5] > l[10]: l[5], l[10] = l[10], l[5]
if l[5] > l[11]: l[5], l[11] = l[11], l[5]
if l[5] > l[12]: l[5], l[12] = l[12], l[5]
if l[5] > l[13]: l[5], l[13] = l[13], l[5]
if l[5] > l[14]: l[5], l[14] = l[14], l[5]
if l[5] > l[15]: l[5], l[15] = l[15], l[5]
if l[5] > l[16]: l[5], l[16] = l[16], l[5]
if l[5] > l[17]: l[5], l[17] = l[17], l[5]
if l[5] > l[18]: l[5], l[18] = l[18], l[5]
if l[5] > l[19]: l[5], l[19] = l[19], l[5]
if l[6] > l[7]: l[6], l[7] = l[7], l[6]
if l[6] > l[8]: l[6], l[8] = l[8], l[6]
if l[6] > l[9]: l[6], l[9] = l[9], l[6]
if l[6] > l[10]: l[6], l[10] = l[10], l[6]
if l[6] > l[11]: l[6], l[11] = l[11], l[6]
if l[6] > l[12]: l[6], l[12] = l[12], l[6]
if l[6] > l[13]: l[6], l[13] = l[13], l[6]
if l[6] > l[14]: l[6], l[14] = l[14], l[6]
if l[6] > l[15]: l[6], l[15] = l[15], l[6]
if l[6] > l[16]: l[6], l[16] = l[16], l[6]
if l[6] > l[17]: l[6], l[17] = l[17], l[6]
if l[6] > l[18]: l[6], l[18] = l[18], l[6]
if l[6] > l[19]: l[6], l[19] = l[19], l[6]
if l[7] > l[8]: l[7], l[8] = l[8], l[7]
if l[7] > l[9]: l[7], l[9] = l[9], l[7]
if l[7] > l[10]: l[7], l[10] = l[10], l[7]
if l[7] > l[11]: l[7], l[11] = l[11], l[7]
if l[7] > l[12]: l[7], l[12] = l[12], l[7]
if l[7] > l[13]: l[7], l[13] = l[13], l[7]
if l[7] > l[14]: l[7], l[14] = l[14], l[7]
if l[7] > l[15]: l[7], l[15] = l[15], l[7]
if l[7] > l[16]: l[7], l[16] = l[16], l[7]
if l[7] > l[17]: l[7], l[17] = l[17], l[7]
if l[7] > l[18]: l[7], l[18] = l[18], l[7]
if l[7] > l[19]: l[7], l[19] = l[19], l[7]
if l[8] > l[9]: l[8], l[9] = l[9], l[8]
if l[8] > l[10]: l[8], l[10] = l[10], l[8]
if l[8] > l[11]: l[8], l[11] = l[11], l[8]
if l[8] > l[12]: l[8], l[12] = l[12], l[8]
if l[8] > l[13]: l[8], l[13] = l[13], l[8]
if l[8] > l[14]: l[8], l[14] = l[14], l[8]
if l[8] > l[15]: l[8], l[15] = l[15], l[8]
if l[8] > l[16]: l[8], l[16] = l[16], l[8]
if l[8] > l[17]: l[8], l[17] = l[17], l[8]
if l[8] > l[18]: l[8], l[18] = l[18], l[8]
if l[8] > l[19]: l[8], l[19] = l[19], l[8]
if l[9] > l[10]: l[9], l[10] = l[10], l[9]
if l[9] > l[11]: l[9], l[11] = l[11], l[9]
if l[9] > l[12]: l[9], l[12] = l[12], l[9]
if l[9] > l[13]: l[9], l[13] = l[13], l[9]
if l[9] > l[14]: l[9], l[14] = l[14], l[9]
if l[9] > l[15]: l[9], l[15] = l[15], l[9]
if l[9] > l[16]: l[9], l[16] = l[16], l[9]
if l[9] > l[17]: l[9], l[17] = l[17], l[9]
if l[9] > l[18]: l[9], l[18] = l[18], l[9]
if l[9] > l[19]: l[9], l[19] = l[19], l[9]
if l[10] > l[11]: l[10], l[11] = l[11], l[10]
if l[10] > l[12]: l[10], l[12] = l[12], l[10]
if l[10] > l[13]: l[10], l[13] = l[13], l[10]
if l[10] > l[14]: l[10], l[14] = l[14], l[10]
if l[10] > l[15]: l[10], l[15] = l[15], l[10]
if l[10] > l[16]: l[10], l[16] = l[16], l[10]
if l[10] > l[17]: l[10], l[17] = l[17], l[10]
if l[10] > l[18]: l[10], l[18] = l[18], l[10]
if l[10] > l[19]: l[10], l[19] = l[19], l[10]
if l[11] > l[12]: l[11], l[12] = l[12], l[11]
if l[11] > l[13]: l[11], l[13] = l[13], l[11]
if l[11] > l[14]: l[11], l[14] = l[14], l[11]
if l[11] > l[15]: l[11], l[15] = l[15], l[11]
if l[11] > l[16]: l[11], l[16] = l[16], l[11]
if l[11] > l[17]: l[11], l[17] = l[17], l[11]
if l[11] > l[18]: l[11], l[18] = l[18], l[11]
if l[11] > l[19]: l[11], l[19] = l[19], l[11]
if l[12] > l[13]: l[12], l[13] = l[13], l[12]
if l[12] > l[14]: l[12], l[14] = l[14], l[12]
if l[12] > l[15]: l[12], l[15] = l[15], l[12]
if l[12] > l[16]: l[12], l[16] = l[16], l[12]
if l[12] > l[17]: l[12], l[17] = l[17], l[12]
if l[12] > l[18]: l[12], l[18] = l[18], l[12]
if l[12] > l[19]: l[12], l[19] = l[19], l[12]
if l[13] > l[14]: l[13], l[14] = l[14], l[13]
if l[13] > l[15]: l[13], l[15] = l[15], l[13]
if l[13] > l[16]: l[13], l[16] = l[16], l[13]
if l[13] > l[17]: l[13], l[17] = l[17], l[13]
if l[13] > l[18]: l[13], l[18] = l[18], l[13]
if l[13] > l[19]: l[13], l[19] = l[19], l[13]
if l[14] > l[15]: l[14], l[15] = l[15], l[14]
if l[14] > l[16]: l[14], l[16] = l[16], l[14]
if l[14] > l[17]: l[14], l[17] = l[17], l[14]
if l[14] > l[18]: l[14], l[18] = l[18], l[14]
if l[14] > l[19]: l[14], l[19] = l[19], l[14]
if l[15] > l[16]: l[15], l[16] = l[16], l[15]
if l[15] > l[17]: l[15], l[17] = l[17], l[15]
if l[15] > l[18]: l[15], l[18] = l[18], l[15]
if l[15] > l[19]: l[15], l[19] = l[19], l[15]
if l[16] > l[17]: l[16], l[17] = l[17], l[16]
if l[16] > l[18]: l[16], l[18] = l[18], l[16]
if l[16] > l[19]: l[16], l[19] = l[19], l[16]
if l[17] > l[18]: l[17], l[18] = l[18], l[17]
if l[17] > l[19]: l[17], l[19] = l[19], l[17]
if l[18] > l[19]: l[18], l[19] = l[19], l[18]
return l
print f([3, 12, 16, 8, 17, 6, 13, 0, 4, 15, 1, 14, 11, 18, 10, 5, 9, 7, 2, 19])
print f([2, 6, 11, 4, 7, 18, 19, 10, 15, 13, 3, 0, 17, 5, 8, 1, 14, 9, 16, 12])
print f([6, 12, 10, 7, 19, 15, 14, 5, 16, 1, 4, 11, 13, 2, 18, 9, 0, 3, 17, 8])
print f([1, 17, 13, 8, 9, 19, 18, 6, 5, 10, 12, 14, 2, 15, 0, 4, 11, 16, 7, 3])
print f([4, 7, 8, 6, 16, 10, 0, 5, 1, 3, 19, 2, 15, 12, 17, 11, 13, 18, 14, 9])
print f([14, 16, 11, 12, 5, 0, 10, 3, 1, 8, 17, 13, 4, 19, 9, 15, 6, 2, 7, 18])
print f([0, 3, 14, 9, 19, 13, 1, 7, 4, 17, 8, 16, 10, 5, 12, 6, 15, 11, 2, 18])
print f([17, 19, 3, 13, 15, 6, 16, 4, 0, 18, 8, 1, 9, 11, 2, 12, 7, 10, 5, 14])
print f([19, 5, 15, 1, 8, 2, 3, 12, 6, 14, 17, 7, 13, 10, 4, 18, 11, 9, 16, 0])
print f([13, 10, 11, 17, 19, 12, 14, 7, 5, 9, 2, 4, 18, 8, 6, 3, 16, 15, 0, 1])
import itertools
import sys
N = 5
if len(sys.argv) > 1:
N = int(sys.argv[1])
print "def f(l):"
for i in xrange(N):
for j in xrange(i + 1, N):
print " if l[%d] > l[%d]: l[%d], l[%d] = l[%d], l[%d]" % (i, j, i, j, j, i)
print " return l"
import random
for i in xrange(10):
l = range(N)
random.shuffle(l)
print "print f(%s)" % (l,)
......@@ -52,28 +52,17 @@ private:
}
};
llvm::DenseSet<AST_Name*> kills;
llvm::DenseMap<InternedString, AST_Name*> last_uses;
llvm::DenseMap<InternedString, Status> statuses;
LivenessAnalysis* analysis;
void _doLoad(InternedString name, AST_Name* node) {
Status& status = statuses[name];
status.addUsage(Status::USED);
last_uses[name] = node;
}
void _doStore(InternedString name) {
Status& status = statuses[name];
status.addUsage(Status::DEFINED);
auto it = last_uses.find(name);
if (it != last_uses.end()) {
kills.insert(it->second);
last_uses.erase(it);
}
}
Status::Usage getStatusFirst(InternedString name) const {
......@@ -90,22 +79,7 @@ public:
bool firstIsDef(InternedString name) const { return getStatusFirst(name) == Status::DEFINED; }
bool isKilledAt(AST_Name* node, bool is_live_at_end) const {
if (kills.count(node))
return true;
// If it's not live at the end, then the last use is a kill
// even though we weren't able to determine that in a single
// pass
if (!is_live_at_end) {
auto it = last_uses.find(node->id);
if (it != last_uses.end() && node == it->second)
return true;
}
return false;
}
bool isKilledAt(AST_Name* node, bool is_live_at_end) { return node->is_kill; }
bool visit_classdef(AST_ClassDef* node) {
......
......@@ -1691,7 +1691,6 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
bool is_live = true;
if (node->is_kill) {
is_live = false;
assert(!source_info->getLiveness()->isLiveAtEnd(node->id, current_block));
} else if (node->lookup_type == ScopeInfo::VarScopeType::FAST)
is_live = source_info->getLiveness()->isLiveAtEnd(node->id, current_block);
......
......@@ -1008,6 +1008,8 @@ CompiledFunction* doCompile(FunctionMetadata* md, SourceInfo* source, ParamNames
assert((entry_descriptor != NULL) + (spec != NULL) == 1);
md->calculateNumVRegs();
if (VERBOSITY("irgen") >= 2)
source->cfg->print();
......
......@@ -1881,13 +1881,9 @@ private:
}
template <typename GetLLVMValCB>
void _setVRegIfUserVisible(InternedString name, GetLLVMValCB get_llvm_val_cb, CompilerVariable* prev,
void _setVRegIfUserVisible(int vreg, GetLLVMValCB get_llvm_val_cb, CompilerVariable* prev,
bool potentially_undefined) {
auto cfg = irstate->getSourceInfo()->cfg;
if (!cfg->hasVregsAssigned())
irstate->getMD()->calculateNumVRegs();
assert(cfg->sym_vreg_map.count(name));
int vreg = cfg->sym_vreg_map[name];
assert(vreg >= 0);
if (vreg < cfg->sym_vreg_map_user_visible.size()) {
......@@ -1908,13 +1904,12 @@ private:
}
// only updates symbol_table if we're *not* setting a global
void _doSet(InternedString name, CompilerVariable* val, const UnwindInfo& unw_info) {
void _doSet(int vreg, InternedString name, ScopeInfo::VarScopeType vst, CompilerVariable* val,
const UnwindInfo& unw_info) {
assert(name.s() != "None");
assert(name.s() != FRAME_INFO_PTR_NAME);
assert(val->getType()->isUsable());
auto scope_info = irstate->getScopeInfo();
ScopeInfo::VarScopeType vst = scope_info->getScopeTypeOfName(name);
assert(vst != ScopeInfo::VarScopeType::DEREF);
if (vst == ScopeInfo::VarScopeType::GLOBAL) {
......@@ -1949,7 +1944,7 @@ private:
bool maybe_was_undefined = _popFake(defined_name, true);
if (vst == ScopeInfo::VarScopeType::CLOSURE) {
size_t offset = scope_info->getClosureOffset(name);
size_t offset = irstate->getScopeInfo()->getClosureOffset(name);
// This is basically `closure->elts[offset] = val;`
CompilerVariable* closure = symbol_table[internString(CREATED_CLOSURE_NAME)];
......@@ -1967,10 +1962,19 @@ private:
}
auto&& get_llvm_val = [&]() { return val->makeConverted(emitter, UNKNOWN)->getValue(); };
_setVRegIfUserVisible(name, get_llvm_val, prev, maybe_was_undefined);
_setVRegIfUserVisible(vreg, get_llvm_val, prev, maybe_was_undefined);
}
}
void _doSet(AST_Name* name, CompilerVariable* val, const UnwindInfo& unw_info) {
auto scope_info = irstate->getScopeInfo();
auto vst = name->lookup_type;
if (vst == ScopeInfo::VarScopeType::UNKNOWN)
vst = scope_info->getScopeTypeOfName(name->id);
assert(vst != ScopeInfo::VarScopeType::DEREF);
_doSet(name->vreg, name->id, vst, val, unw_info);
}
void _doSetattr(AST_Attribute* target, CompilerVariable* val, const UnwindInfo& unw_info) {
CompilerVariable* t = evalExpr(target->value, unw_info);
t->setattr(emitter, getEmptyOpInfo(unw_info), target->attr.getBox(), val);
......@@ -2028,7 +2032,7 @@ private:
_doSetattr(ast_cast<AST_Attribute>(target), val, unw_info);
break;
case AST_TYPE::Name:
_doSet(ast_cast<AST_Name>(target)->id, val, unw_info);
_doSet(ast_cast<AST_Name>(target), val, unw_info);
break;
case AST_TYPE::Subscript:
_doSetitem(ast_cast<AST_Subscript>(target), val, unw_info);
......@@ -2164,7 +2168,7 @@ private:
InternedString defined_name = getIsDefinedName(target->id);
ConcreteCompilerVariable* is_defined_var = static_cast<ConcreteCompilerVariable*>(_getFake(defined_name, true));
_setVRegIfUserVisible(target->id, []() { return getNullPtr(g.llvm_value_type_ptr); }, prev,
_setVRegIfUserVisible(target->vreg, []() { return getNullPtr(g.llvm_value_type_ptr); }, prev,
(bool)is_defined_var);
if (symbol_table.count(target->id) == 0) {
......@@ -2599,7 +2603,14 @@ private:
void loadArgument(InternedString name, ConcreteCompilerType* t, llvm::Value* v, const UnwindInfo& unw_info) {
assert(name.s() != FRAME_INFO_PTR_NAME);
CompilerVariable* var = unboxVar(t, v);
_doSet(name, var, unw_info);
auto cfg = irstate->getSourceInfo()->cfg;
auto vst = irstate->getScopeInfo()->getScopeTypeOfName(name);
int vreg = -1;
if (vst == ScopeInfo::VarScopeType::FAST || vst == ScopeInfo::VarScopeType::CLOSURE) {
assert(cfg->sym_vreg_map.count(name));
vreg = cfg->sym_vreg_map[name];
}
_doSet(vreg, name, vst, var, unw_info);
}
void loadArgument(AST_expr* name, ConcreteCompilerType* t, llvm::Value* v, const UnwindInfo& unw_info) {
......
......@@ -373,20 +373,25 @@ void addCXXFixup(llvm::Instruction* inst, const llvm::SmallVector<llvm::Tracking
call->replaceAllUsesWith(new_invoke);
call->eraseFromParent();
llvm::Value* exc_type, *exc_value, *exc_traceback;
std::tie(exc_type, exc_value, exc_traceback) = createLandingpad(fixup_block);
llvm::IRBuilder<true> builder(fixup_block);
llvm::SmallVector<llvm::Value*, 4> decref_args;
decref_args.push_back(getConstantInt(to_decref.size(), g.i32));
decref_args.append(to_decref.begin(), to_decref.end());
builder.CreateCall(g.funcs.xdecrefAll, decref_args);
auto rethrow = builder.CreateCall3(g.funcs.rawReraise, exc_type, exc_value, exc_traceback);
static llvm::Function* _personality_func = g.stdlib_module->getFunction("__gxx_personality_v0");
assert(_personality_func);
llvm::Value* personality_func
= g.cur_module->getOrInsertFunction(_personality_func->getName(), _personality_func->getFunctionType());
assert(personality_func);
static llvm::Type* lp_type = llvm::StructType::create(std::vector<llvm::Type*>{ g.i8_ptr, g.i64 });
assert(lp_type);
llvm::LandingPadInst* landing_pad = builder.CreateLandingPad(lp_type, personality_func, 1);
landing_pad->addClause(getNullPtr(g.i8_ptr));
llvm::SmallVector<llvm::Value*, 4> call_args;
llvm::Value* cxaexc_pointer = builder.CreateExtractValue(landing_pad, { 0 });
call_args.push_back(cxaexc_pointer);
call_args.push_back(getConstantInt(to_decref.size(), g.i32));
call_args.append(to_decref.begin(), to_decref.end());
builder.CreateCall(g.funcs.xdecrefAndRethrow, call_args);
builder.CreateUnreachable();
// new_invoke->getParent()->getParent()->dump();
}
// TODO: this should be cleaned up and moved to src/core/
......
......@@ -324,7 +324,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(reraiseCapiExcAsCxx);
GET(deopt);
GET(checkRefs);
GET(xdecrefAll);
GET(xdecrefAndRethrow);
GET(div_float_float);
GET(floordiv_float_float);
......
......@@ -55,7 +55,7 @@ struct GlobalFuncs {
llvm::Value* raise0, *raise0_capi, *raise3, *raise3_capi, *rawReraise;
llvm::Value* PyErr_Fetch, *PyErr_NormalizeException, *PyErr_Restore, *caughtCapiException, *reraiseCapiExcAsCxx;
llvm::Value* deopt;
llvm::Value* checkRefs, *xdecrefAll;
llvm::Value* checkRefs, *xdecrefAndRethrow;
llvm::Value* div_float_float, *floordiv_float_float, *mod_float_float, *pow_float_float;
......
This diff is collapsed.
......@@ -120,6 +120,7 @@ public:
class SourceInfo;
CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body);
void printCFG(CFG* cfg);
}
#endif
......@@ -70,9 +70,9 @@ public:
const char* c_str() const;
bool operator==(InternedString rhs) const {
assert(this->_str || this->pool == invalidPool());
assert(rhs._str || rhs.pool == invalidPool());
assert(this->pool == rhs.pool || this->pool == invalidPool() || rhs.pool == invalidPool());
// assert(this->_str || this->pool == invalidPool());
// assert(rhs._str || rhs.pool == invalidPool());
// assert(this->pool == rhs.pool || this->pool == invalidPool() || rhs.pool == invalidPool());
return this->_str == rhs._str;
}
......
......@@ -140,7 +140,7 @@ void force() {
FORCE(reraiseCapiExcAsCxx);
FORCE(deopt);
FORCE(checkRefs);
FORCE(xdecrefAll);
FORCE(xdecrefAndRethrow);
FORCE(div_i64_i64);
FORCE(mod_i64_i64);
......
......@@ -118,7 +118,10 @@ static inline Box* callattrInternal3(Box* obj, BoxedString* attr, LookupScope sc
return callattrInternal<S, rewritable>(obj, attr, scope, rewrite_args, argspec, arg1, arg2, arg3, NULL, NULL);
}
extern "C" void xdecrefAll(int num, ...) {
extern "C" void* __cxa_begin_catch(void*);
extern "C" void xdecrefAndRethrow(void* cxa_ptr, int num, ...) {
ExcInfo e = *(ExcInfo*)__cxa_begin_catch(cxa_ptr);
va_list va;
va_start(va, num);
......@@ -128,6 +131,8 @@ extern "C" void xdecrefAll(int num, ...) {
}
va_end(va);
rawReraise(e.type, e.value, e.traceback);
}
extern "C" Box* deopt(AST_expr* expr, Box* value) {
......
......@@ -231,6 +231,6 @@ extern "C" void boxedLocalsDel(Box* boxedLocals, BoxedString* attr);
extern "C" void checkRefs(Box* b); // asserts that b has >= 0 refs
extern "C" Box* assertAlive(Box* b); // asserts that b has > 0 refs, and returns b
extern "C" void xdecrefAll(int num, ...);
extern "C" void xdecrefAndRethrow(void* cxa_ptr, int num_decref, ...);
}
#endif
......@@ -1683,6 +1683,12 @@ static void functionSetDefaults(Box* b, Box* v, void*) {
// and leave this assert.
RELEASE_ASSERT(func->can_change_defaults, "trying to change the defaults on a non-defaults-changable function.");
// Changing defaults of builtins would be very scary. Python functions are safe since they
// store their arguments into their symbol table, but builtin functions are free to let them
// stay borrowed. If a builtin function has changable defaults, and it can call into arbitrary
// user code, then it could call something that changes its own defaults, and all of a sudden
// one of its arguments gets deallocated from under it.
if (v == None)
v = NULL;
else if (v && !PyTuple_Check(v)) {
......
# expected: fail
# - we have an extra evaluation of __nonzero__ at the end
class A(object):
def __init__(self, n):
print "init", n
self.n = n
def __lt__(self, rhs):
print "lt", self.n, rhs.n
return self
def __nonzero__(self):
print "nonzero", self.n
return True
def __repr__(self):
return "<A (%d)>" % self.n
print A(1) < A(2) < A(3)
......@@ -70,3 +70,9 @@ print type(C.__new__), type(C.__dict__['__new__'])
C.__new__.__defaults__ = (1,)
print type(C())
def f(a=1, b=2, c=3):
print a, b, c, type(a), type(b), type(c)
f.func_defaults = (a + 3, b + 3, c + 3)
for i in xrange(1000):
f()
# fail-if: '-n' in EXTRA_JIT_ARGS or '-O' in EXTRA_JIT_ARGS
class C(object):
def next(self):
return 1
def __del__(self):
print "del"
class D(object):
def __iter__(self):
return C()
def f():
for i in D():
print i
break
for i in xrange(100):
print
f()
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