Commit 9ef680bb authored by Marius Wachtler's avatar Marius Wachtler

AST & BST: remove unnecessary nodes and fields

parent aba408b8
......@@ -78,8 +78,6 @@ public:
bool isKilledAt(BST_Name* node, bool is_live_at_end) { return node->is_kill; }
bool visit_import(BST_Import* node) { RELEASE_ASSERT(0, "these should all get removed by the cfg"); }
bool visit_classdef(BST_ClassDef* node) {
for (auto e : node->bases)
e->accept(this);
......@@ -118,8 +116,6 @@ public:
}
return true;
}
bool visit_alias(BST_alias* node) { RELEASE_ASSERT(0, "these should be removed by the cfg"); }
};
LivenessAnalysis::LivenessAnalysis(CFG* cfg) : cfg(cfg), result_cache(cfg->getVRegInfo().getTotalNumOfVRegs()) {
......@@ -282,30 +278,27 @@ public:
virtual bool visit_assert(BST_Assert* node) { return true; }
virtual bool visit_branch(BST_Branch* node) { return true; }
virtual bool visit_expr(BST_Expr* node) { return true; }
virtual bool visit_global(BST_Global* node) { return true; }
virtual bool visit_invoke(BST_Invoke* node) { return false; }
virtual bool visit_jump(BST_Jump* node) { return true; }
virtual bool visit_pass(BST_Pass* node) { return true; }
virtual bool visit_print(BST_Print* node) { return true; }
virtual bool visit_raise(BST_Raise* node) { return true; }
virtual bool visit_return(BST_Return* node) { return true; }
virtual bool visit_delete(BST_Delete* node) {
for (auto t : node->targets) {
if (t->type == BST_TYPE::Name) {
BST_Name* name = bst_cast<BST_Name>(t);
if (name->lookup_type != ScopeInfo::VarScopeType::GLOBAL
&& name->lookup_type != ScopeInfo::VarScopeType::NAME) {
assert(name->vreg != -1);
state[name->vreg] = DefinednessAnalysis::Undefined;
} else
assert(name->vreg == -1);
} else {
// The CFG pass should reduce all deletes to the "basic" deletes on names/attributes/subscripts.
// If not, probably the best way to do this would be to just do a full BST traversal
// and look for BST_Name's with a ctx of Del
assert(t->type == BST_TYPE::Attribute || t->type == BST_TYPE::Subscript);
}
auto t = node->target;
if (t->type == BST_TYPE::Name) {
BST_Name* name = bst_cast<BST_Name>(t);
if (name->lookup_type != ScopeInfo::VarScopeType::GLOBAL
&& name->lookup_type != ScopeInfo::VarScopeType::NAME) {
assert(name->vreg != -1);
state[name->vreg] = DefinednessAnalysis::Undefined;
} else
assert(name->vreg == -1);
} else {
// The CFG pass should reduce all deletes to the "basic" deletes on names/attributes/subscripts.
// If not, probably the best way to do this would be to just do a full BST traversal
// and look for BST_Name's with a ctx of Del
assert(t->type == BST_TYPE::Attribute || t->type == BST_TYPE::Subscript);
}
return true;
}
......@@ -322,21 +315,8 @@ public:
return true;
}
virtual bool visit_alias(BST_alias* node) {
int vreg = node->name_vreg;
if (node->asname.s().size())
vreg = node->asname_vreg;
_doSet(vreg);
return true;
}
virtual bool visit_import(BST_Import* node) { return false; }
virtual bool visit_importfrom(BST_ImportFrom* node) { return false; }
virtual bool visit_assign(BST_Assign* node) {
for (int i = 0; i < node->targets.size(); i++) {
_doSet(node->targets[i]);
}
_doSet(node->target);
return true;
}
......
......@@ -606,8 +606,6 @@ public:
bool visit_while(AST_While* node) override { return false; }
bool visit_with(AST_With* node) override { return false; }
bool visit_yield(AST_Yield* node) override { return false; }
bool visit_branch(AST_Branch* node) override { return false; }
bool visit_jump(AST_Jump* node) override { return false; }
bool visit_delete(AST_Delete* node) override { return false; }
bool visit_global(AST_Global* node) override {
......
......@@ -297,21 +297,6 @@ private:
return rtn;
}
void* visit_boolop(BST_BoolOp* node) override {
int n = node->values.size();
CompilerType* rtn = NULL;
for (int i = 0; i < n; i++) {
CompilerType* t = getType(node->values[i]);
if (rtn == NULL)
rtn = t;
else if (rtn != t)
rtn = UNKNOWN;
}
return rtn;
}
void* visit_call(BST_Call* node) override {
CompilerType* func = getType(node->func);
......@@ -349,29 +334,24 @@ private:
}
void* visit_compare(BST_Compare* node) override {
if (node->ops.size() == 1) {
CompilerType* left = getType(node->left);
CompilerType* right = getType(node->comparators[0]);
AST_TYPE::AST_TYPE op_type = node->ops[0];
if (op_type == AST_TYPE::Is || op_type == AST_TYPE::IsNot || op_type == AST_TYPE::In
|| op_type == AST_TYPE::NotIn) {
assert(node->ops.size() == 1 && "I don't think this should happen");
return BOOL;
}
CompilerType* left = getType(node->left);
CompilerType* right = getType(node->comparator);
AST_TYPE::AST_TYPE op_type = node->op;
if (op_type == AST_TYPE::Is || op_type == AST_TYPE::IsNot || op_type == AST_TYPE::In
|| op_type == AST_TYPE::NotIn) {
return BOOL;
}
BoxedString* name = getOpName(node->ops[0]);
CompilerType* attr_type = left->getattrType(name, true);
BoxedString* name = getOpName(node->op);
CompilerType* attr_type = left->getattrType(name, true);
if (attr_type == UNDEF)
attr_type = UNKNOWN;
if (attr_type == UNDEF)
attr_type = UNKNOWN;
std::vector<CompilerType*> arg_types;
arg_types.push_back(right);
return attr_type->callType(ArgPassSpec(2), arg_types, NULL);
} else {
return UNKNOWN;
}
std::vector<CompilerType*> arg_types;
arg_types.push_back(right);
return attr_type->callType(ArgPassSpec(2), arg_types, NULL);
}
void* visit_dict(BST_Dict* node) override {
......@@ -541,9 +521,7 @@ private:
void visit_assign(BST_Assign* node) override {
CompilerType* t = getType(node->value);
for (int i = 0; i < node->targets.size(); i++) {
_doSet(node->targets[i], t);
}
_doSet(node->target, t);
}
void visit_branch(BST_Branch* node) override {
......@@ -569,27 +547,26 @@ private:
}
void visit_delete(BST_Delete* node) override {
for (BST_expr* target : node->targets) {
switch (target->type) {
case BST_TYPE::Subscript:
getType(bst_cast<BST_Subscript>(target)->value);
break;
case BST_TYPE::Attribute:
getType(bst_cast<BST_Attribute>(target)->value);
break;
case BST_TYPE::Name: {
auto name = bst_cast<BST_Name>(target);
assert(name->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
if (name->lookup_type == ScopeInfo::VarScopeType::FAST
|| name->lookup_type == ScopeInfo::VarScopeType::CLOSURE) {
sym_table[name->vreg] = NULL;
} else
assert(name->vreg == -1);
break;
}
default:
RELEASE_ASSERT(0, "%d", target->type);
BST_expr* target = node->target;
switch (target->type) {
case BST_TYPE::Subscript:
getType(bst_cast<BST_Subscript>(target)->value);
break;
case BST_TYPE::Attribute:
getType(bst_cast<BST_Attribute>(target)->value);
break;
case BST_TYPE::Name: {
auto name = bst_cast<BST_Name>(target);
assert(name->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
if (name->lookup_type == ScopeInfo::VarScopeType::FAST
|| name->lookup_type == ScopeInfo::VarScopeType::CLOSURE) {
sym_table[name->vreg] = NULL;
} else
assert(name->vreg == -1);
break;
}
default:
RELEASE_ASSERT(0, "%d", target->type);
}
}
......@@ -617,12 +594,6 @@ private:
return t;
}
void visit_global(BST_Global* node) override {}
void visit_import(BST_Import* node) override { assert(0 && "this should get removed by cfg"); }
void visit_importfrom(BST_ImportFrom* node) override { assert(0 && "this should get removed by cfg"); }
void visit_exec(BST_Exec* node) override {
getType(node->body);
if (node->globals)
......@@ -634,17 +605,13 @@ private:
void visit_invoke(BST_Invoke* node) override { node->stmt->accept_stmt(this); }
void visit_jump(BST_Jump* node) override {}
void visit_pass(BST_Pass* node) override {}
void visit_print(BST_Print* node) override {
if (node->dest)
getType(node->dest);
if (EXPAND_UNNEEDED) {
for (int i = 0; i < node->values.size(); i++) {
getType(node->values[i]);
}
}
if (EXPAND_UNNEEDED && node->value)
getType(node->value);
}
void visit_raise(BST_Raise* node) override {
......
......@@ -88,8 +88,6 @@ private:
Value visit_compare(BST_Compare* node);
Value visit_delete(BST_Delete* node);
Value visit_exec(BST_Exec* node);
Value visit_global(BST_Global* node);
Value visit_module(BST_Module* node);
Value visit_print(BST_Print* node);
Value visit_raise(BST_Raise* node);
Value visit_return(BST_Return* node);
......@@ -1055,10 +1053,6 @@ Value ASTInterpreter::visit_stmt(BST_stmt* node) {
throw e;
}
return rtn;
case BST_TYPE::Global:
rtn = visit_global((BST_Global*)node);
ASTInterpreterJitInterface::pendingCallsCheckHelper();
break;
// pseudo
case BST_TYPE::Branch:
......@@ -1308,111 +1302,98 @@ Value ASTInterpreter::visit_assert(BST_Assert* node) {
return Value();
}
Value ASTInterpreter::visit_global(BST_Global* node) {
#ifndef NDEBUG
for (auto name : node->names) {
assert(!getSymVRegMap().count(name));
}
#endif
return Value();
}
Value ASTInterpreter::visit_delete(BST_Delete* node) {
for (BST_expr* target_ : node->targets) {
switch (target_->type) {
case BST_TYPE::Subscript: {
BST_Subscript* sub = (BST_Subscript*)target_;
Value value = visit_expr(sub->value);
AUTO_DECREF(value.o);
bool is_slice = (sub->slice->type == BST_TYPE::Slice) && (((BST_Slice*)sub->slice)->step == NULL);
if (is_slice) {
BST_Slice* slice = (BST_Slice*)sub->slice;
Value lower = slice->lower ? visit_expr(slice->lower) : Value();
AUTO_XDECREF(lower.o);
Value upper = slice->upper ? visit_expr(slice->upper) : Value();
AUTO_XDECREF(upper.o);
assert(slice->step == NULL);
BST_expr* target_ = node->target;
switch (target_->type) {
case BST_TYPE::Subscript: {
BST_Subscript* sub = (BST_Subscript*)target_;
Value value = visit_expr(sub->value);
AUTO_DECREF(value.o);
bool is_slice = (sub->slice->type == BST_TYPE::Slice) && (((BST_Slice*)sub->slice)->step == NULL);
if (is_slice) {
BST_Slice* slice = (BST_Slice*)sub->slice;
Value lower = slice->lower ? visit_expr(slice->lower) : Value();
AUTO_XDECREF(lower.o);
Value upper = slice->upper ? visit_expr(slice->upper) : Value();
AUTO_XDECREF(upper.o);
assert(slice->step == NULL);
if (jit)
jit->emitAssignSlice(value, lower, upper, jit->imm(0ul));
assignSlice(value.o, lower.o, upper.o, NULL);
} else {
Value slice = visit_slice(sub->slice);
AUTO_DECREF(slice.o);
if (jit)
jit->emitDelItem(value, slice);
delitem(value.o, slice.o);
}
break;
if (jit)
jit->emitAssignSlice(value, lower, upper, jit->imm(0ul));
assignSlice(value.o, lower.o, upper.o, NULL);
} else {
Value slice = visit_slice(sub->slice);
AUTO_DECREF(slice.o);
if (jit)
jit->emitDelItem(value, slice);
delitem(value.o, slice.o);
}
case BST_TYPE::Attribute: {
BST_Attribute* attr = (BST_Attribute*)target_;
Value target = visit_expr(attr->value);
AUTO_DECREF(target.o);
BoxedString* str = attr->attr.getBox();
break;
}
case BST_TYPE::Attribute: {
BST_Attribute* attr = (BST_Attribute*)target_;
Value target = visit_expr(attr->value);
AUTO_DECREF(target.o);
BoxedString* str = attr->attr.getBox();
if (jit)
jit->emitDelAttr(target, str);
delattr(target.o, str);
break;
}
case BST_TYPE::Name: {
BST_Name* target = (BST_Name*)target_;
assert(target->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
ScopeInfo::VarScopeType vst = target->lookup_type;
if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (jit)
jit->emitDelAttr(target, str);
delattr(target.o, str);
jit->emitDelGlobal(target->id.getBox());
delGlobal(frame_info.globals, target->id.getBox());
break;
}
case BST_TYPE::Name: {
BST_Name* target = (BST_Name*)target_;
assert(target->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
} else if (vst == ScopeInfo::VarScopeType::NAME) {
if (jit)
jit->emitDelName(target->id);
ASTInterpreterJitInterface::delNameHelper(this, target->id);
} else {
assert(vst == ScopeInfo::VarScopeType::FAST);
ScopeInfo::VarScopeType vst = target->lookup_type;
if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (jit)
jit->emitDelGlobal(target->id.getBox());
delGlobal(frame_info.globals, target->id.getBox());
continue;
} else if (vst == ScopeInfo::VarScopeType::NAME) {
assert(getVRegInfo().getVReg(target->id) == target->vreg);
if (target->id.s()[0] == '#') {
assert(vregs[target->vreg] != NULL);
if (jit)
jit->emitDelName(target->id);
ASTInterpreterJitInterface::delNameHelper(this, target->id);
jit->emitKillTemporary(target);
} else {
assert(vst == ScopeInfo::VarScopeType::FAST);
assert(getVRegInfo().getVReg(target->id) == target->vreg);
if (target->id.s()[0] == '#') {
assert(vregs[target->vreg] != NULL);
if (jit)
jit->emitKillTemporary(target);
} else {
abortJITing();
if (vregs[target->vreg] == 0) {
assertNameDefined(0, target->id.c_str(), NameError, true /* local_var_msg */);
return Value();
}
abortJITing();
if (vregs[target->vreg] == 0) {
assertNameDefined(0, target->id.c_str(), NameError, true /* local_var_msg */);
return Value();
}
frame_info.num_vregs = std::max(frame_info.num_vregs, target->vreg + 1);
Py_DECREF(vregs[target->vreg]);
vregs[target->vreg] = NULL;
}
break;
frame_info.num_vregs = std::max(frame_info.num_vregs, target->vreg + 1);
Py_DECREF(vregs[target->vreg]);
vregs[target->vreg] = NULL;
}
default:
ASSERT(0, "Unsupported del target: %d", target_->type);
abort();
break;
}
default:
ASSERT(0, "Unsupported del target: %d", target_->type);
abort();
}
return Value();
}
Value ASTInterpreter::visit_assign(BST_Assign* node) {
assert(node->targets.size() == 1 && "cfg should have lowered it to a single target");
Value v = visit_expr(node->value);
doStore(node->targets[0], v);
doStore(node->target, v);
return Value();
}
Value ASTInterpreter::visit_print(BST_Print* node) {
assert(node->values.size() <= 1 && "cfg should have lowered it to 0 or 1 values");
Value dest = node->dest ? visit_expr(node->dest) : Value();
Value var = node->values.size() ? visit_expr(node->values[0]) : Value();
Value var = node->value ? visit_expr(node->value) : Value();
if (jit)
jit->emitPrint(dest, var, node->nl);
......@@ -1442,12 +1423,11 @@ Value ASTInterpreter::visit_exec(BST_Exec* node) {
}
Value ASTInterpreter::visit_compare(BST_Compare* node) {
RELEASE_ASSERT(node->comparators.size() == 1, "not implemented");
Value left = visit_expr(node->left);
AUTO_DECREF(left.o);
Value right = visit_expr(node->comparators[0]);
Value right = visit_expr(node->comparator);
AUTO_DECREF(right.o);
return doBinOp(node, left, right, node->ops[0], BinExpType::Compare);
return doBinOp(node, left, right, node->op, BinExpType::Compare);
}
Value ASTInterpreter::visit_expr(BST_expr* node) {
......@@ -2127,9 +2107,8 @@ extern "C" Box* astInterpretDeoptFromASM(BoxedCode* code, BST_expr* after_expr,
if (enclosing_stmt->type == BST_TYPE::Assign) {
auto asgn = bst_cast<BST_Assign>(enclosing_stmt);
RELEASE_ASSERT(asgn->value == after_expr, "%p %p", asgn->value, after_expr);
assert(asgn->targets.size() == 1);
assert(asgn->targets[0]->type == BST_TYPE::Name);
auto name = bst_cast<BST_Name>(asgn->targets[0]);
assert(asgn->target->type == BST_TYPE::Name);
auto name = bst_cast<BST_Name>(asgn->target);
assert(name->id.s()[0] == '#');
interpreter.addSymbol(name->vreg, expr_val, true);
break;
......
......@@ -727,13 +727,12 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
if (stmt->type == BST_TYPE::Assign) {
auto asgn = bst_cast<BST_Assign>(stmt);
assert(asgn->targets.size() == 1);
if (asgn->targets[0]->type == BST_TYPE::Name) {
auto asname = bst_cast<BST_Name>(asgn->targets[0]);
if (asgn->target->type == BST_TYPE::Name) {
auto asname = bst_cast<BST_Name>(asgn->target);
assert(asname->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
InternedString name = asname->id;
int vreg = bst_cast<BST_Name>(asgn->targets[0])->vreg;
int vreg = bst_cast<BST_Name>(asgn->target)->vreg;
assert(name.c_str()[0] == '#'); // it must be a temporary
// You might think I need to check whether `name' is being assigned globally or locally,
// since a global assign doesn't affect the symbol table. However, the CFG pass only
......
......@@ -1137,19 +1137,16 @@ private:
}
CompilerVariable* evalCompare(BST_Compare* node, const UnwindInfo& unw_info) {
RELEASE_ASSERT(node->ops.size() == 1, "");
CompilerVariable* left = evalExpr(node->left, unw_info);
CompilerVariable* right = evalExpr(node->comparators[0], unw_info);
CompilerVariable* right = evalExpr(node->comparator, unw_info);
assert(left);
assert(right);
if (node->ops[0] == AST_TYPE::Is || node->ops[0] == AST_TYPE::IsNot) {
return doIs(emitter, left, right, node->ops[0] == AST_TYPE::IsNot);
}
if (node->op == AST_TYPE::Is || node->op == AST_TYPE::IsNot)
return doIs(emitter, left, right, node->op == AST_TYPE::IsNot);
CompilerVariable* rtn = _evalBinExp(node, left, right, node->ops[0], Compare, unw_info);
CompilerVariable* rtn = _evalBinExp(node, left, right, node->op, Compare, unw_info);
return rtn;
}
......@@ -2084,27 +2081,24 @@ private:
void doAssign(BST_Assign* node, const UnwindInfo& unw_info) {
CompilerVariable* val = evalExpr(node->value, unw_info);
for (int i = 0; i < node->targets.size(); i++) {
_doSet(node->targets[i], val, unw_info);
}
_doSet(node->target, val, unw_info);
}
void doDelete(BST_Delete* node, const UnwindInfo& unw_info) {
for (BST_expr* target : node->targets) {
switch (target->type) {
case BST_TYPE::Subscript:
_doDelitem(static_cast<BST_Subscript*>(target), unw_info);
break;
case BST_TYPE::Attribute:
_doDelAttr(static_cast<BST_Attribute*>(target), unw_info);
break;
case BST_TYPE::Name:
_doDelName(static_cast<BST_Name*>(target), unw_info);
break;
default:
ASSERT(0, "Unsupported del target: %d", target->type);
abort();
}
BST_expr* target = node->target;
switch (target->type) {
case BST_TYPE::Subscript:
_doDelitem(static_cast<BST_Subscript*>(target), unw_info);
break;
case BST_TYPE::Attribute:
_doDelAttr(static_cast<BST_Attribute*>(target), unw_info);
break;
case BST_TYPE::Name:
_doDelName(static_cast<BST_Name*>(target), unw_info);
break;
default:
ASSERT(0, "Unsupported del target: %d", target->type);
abort();
}
}
......@@ -2237,11 +2231,10 @@ private:
}
assert(dest);
assert(node->values.size() <= 1);
ConcreteCompilerVariable* converted;
if (node->values.size() == 1) {
CompilerVariable* var = evalExpr(node->values[0], unw_info);
if (node->value) {
CompilerVariable* var = evalExpr(node->value, unw_info);
converted = var->makeConverted(emitter, var->getBoxType());
} else {
converted = new ConcreteCompilerVariable(UNKNOWN, getNullPtr(g.llvm_value_type_ptr));
......@@ -2561,15 +2554,6 @@ private:
if ((((BST_Expr*)node)->value)->type != BST_TYPE::Str)
doExpr(bst_cast<BST_Expr>(node), unw_info);
break;
// case BST_TYPE::If:
// doIf(bst_cast<BST_If>(node));
// break;
// case BST_TYPE::Import:
// doImport(bst_cast<BST_Import>(node), unw_info);
// break;
// case BST_TYPE::ImportFrom:
// doImportFrom(bst_cast<BST_ImportFrom>(node), unw_info);
// break;
case BST_TYPE::Global:
// Should have been handled already
break;
......
......@@ -887,28 +887,6 @@ void AST_Yield::accept(ASTVisitor* v) {
value->accept(v);
}
void AST_Branch::accept(ASTVisitor* v) {
bool skip = v->visit_branch(this);
if (skip)
return;
test->accept(v);
}
void AST_Branch::accept_stmt(ASTStmtVisitor* v) {
v->visit_branch(this);
}
void AST_Jump::accept(ASTVisitor* v) {
bool skip = v->visit_jump(this);
if (skip)
return;
}
void AST_Jump::accept_stmt(ASTStmtVisitor* v) {
v->visit_jump(this);
}
void AST_ClsAttribute::accept(ASTVisitor* v) {
bool skip = v->visit_clsattribute(this);
if (skip)
......@@ -917,22 +895,6 @@ void AST_ClsAttribute::accept(ASTVisitor* v) {
value->accept(v);
}
void AST_MakeFunction::accept(ASTVisitor* v) {
bool skip = v->visit_makefunction(this);
if (skip)
return;
function_def->accept(v);
}
void AST_MakeClass::accept(ASTVisitor* v) {
bool skip = v->visit_makeclass(this);
if (skip)
return;
class_def->accept(v);
}
void print_ast(AST* ast) {
ASTPrintVisitor v;
ast->accept(&v);
......@@ -1827,18 +1789,6 @@ bool ASTPrintVisitor::visit_yield(AST_Yield* node) {
return true;
}
bool ASTPrintVisitor::visit_branch(AST_Branch* node) {
stream << "if ";
node->test->accept(this);
stream << " goto " << node->iftrue->idx << " else goto " << node->iffalse->idx;
return true;
}
bool ASTPrintVisitor::visit_jump(AST_Jump* node) {
stream << "goto " << node->target->idx;
return true;
}
bool ASTPrintVisitor::visit_clsattribute(AST_ClsAttribute* node) {
// printf("getclsattr(");
// node->value->accept(this);
......@@ -1848,16 +1798,7 @@ bool ASTPrintVisitor::visit_clsattribute(AST_ClsAttribute* node) {
return true;
}
bool ASTPrintVisitor::visit_makefunction(AST_MakeFunction* node) {
stream << "make_";
return false;
}
bool ASTPrintVisitor::visit_makeclass(AST_MakeClass* node) {
stream << "make_";
return false;
}
namespace {
class FlattenVisitor : public ASTVisitor {
private:
std::vector<AST*>* output;
......@@ -2101,30 +2042,14 @@ public:
return false;
}
virtual bool visit_branch(AST_Branch* node) {
output->push_back(node);
return false;
}
virtual bool visit_jump(AST_Jump* node) {
output->push_back(node);
return false;
}
virtual bool visit_clsattribute(AST_ClsAttribute* node) {
output->push_back(node);
return false;
}
virtual bool visit_makeclass(AST_MakeClass* node) {
output->push_back(node);
return false;
}
virtual bool visit_makefunction(AST_MakeFunction* node) {
output->push_back(node);
return false;
}
};
}
void flatten(const llvm::SmallVector<AST_stmt*, 4>& roots, std::vector<AST*>& output, bool expand_scopes) {
void flatten(llvm::ArrayRef<AST_stmt*> roots, std::vector<AST*>& output, bool expand_scopes) {
FlattenVisitor visitor(&output, expand_scopes);
for (int i = 0; i < roots.size(); i++) {
......
......@@ -206,8 +206,6 @@ class AST_stmt : public AST {
public:
virtual void accept_stmt(ASTStmtVisitor* v) = 0;
int cxx_exception_count = 0;
AST_stmt(AST_TYPE::AST_TYPE type) : AST(type) {}
};
......@@ -220,7 +218,6 @@ public:
class AST_alias : public AST {
public:
InternedString name, asname;
int name_vreg = -1, asname_vreg = -1;
virtual void accept(ASTVisitor* v);
......@@ -352,9 +349,6 @@ public:
std::vector<AST_expr*> args;
std::vector<AST_keyword*> keywords;
// used during execution stores all keyword names
std::unique_ptr<std::vector<BoxedString*>> keywords_names;
virtual void accept(ASTVisitor* v);
AST_Call() : AST_expr(AST_TYPE::Call) {}
......@@ -723,25 +717,13 @@ public:
// different bytecodes.
ScopeInfo::VarScopeType lookup_type;
// These are only valid for lookup_type == FAST or CLOSURE
// The interpreter and baseline JIT store variables with FAST and CLOSURE scopes in an array (vregs) this specifies
// the zero based index of this variable inside the vregs array. If uninitialized it's value is -1.
int vreg;
bool is_kill = false;
// Only valid for lookup_type == DEREF:
DerefInfo deref_info = DerefInfo({ INT_MAX, INT_MAX });
// Only valid for lookup_type == CLOSURE:
int closure_offset = -1;
virtual void accept(ASTVisitor* v);
AST_Name(InternedString id, AST_TYPE::AST_TYPE ctx_type, int lineno, int col_offset = 0)
: AST_expr(AST_TYPE::Name, lineno, col_offset),
ctx_type(ctx_type),
id(id),
lookup_type(ScopeInfo::VarScopeType::UNKNOWN),
vreg(-1) {}
lookup_type(ScopeInfo::VarScopeType::UNKNOWN) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Name;
};
......@@ -987,60 +969,12 @@ public:
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Yield;
};
class AST_MakeFunction : public AST_expr {
public:
AST_FunctionDef* function_def;
virtual void accept(ASTVisitor* v);
AST_MakeFunction(AST_FunctionDef* fd)
: AST_expr(AST_TYPE::MakeFunction, fd->lineno, fd->col_offset), function_def(fd) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::MakeFunction;
};
class AST_MakeClass : public AST_expr {
public:
AST_ClassDef* class_def;
virtual void accept(ASTVisitor* v);
AST_MakeClass(AST_ClassDef* cd) : AST_expr(AST_TYPE::MakeClass, cd->lineno, cd->col_offset), class_def(cd) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::MakeClass;
};
// AST pseudo-nodes that will get added during CFG-construction. These don't exist in the input AST, but adding them in
// lets us avoid creating a completely new IR for this phase
class CFGBlock;
class AST_Branch : public AST_stmt {
public:
AST_expr* test;
CFGBlock* iftrue, *iffalse;
virtual void accept(ASTVisitor* v);
virtual void accept_stmt(ASTStmtVisitor* v);
AST_Branch() : AST_stmt(AST_TYPE::Branch) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Branch;
};
class AST_Jump : public AST_stmt {
public:
CFGBlock* target;
virtual void accept(ASTVisitor* v);
virtual void accept_stmt(ASTStmtVisitor* v);
AST_Jump() : AST_stmt(AST_TYPE::Jump) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Jump;
};
class AST_ClsAttribute : public AST_expr {
public:
AST_expr* value;
......@@ -1102,8 +1036,6 @@ template <typename T> T* ast_cast(AST* node) {
return static_cast<T*>(node);
}
class ASTVisitor {
protected:
public:
......@@ -1170,11 +1102,6 @@ public:
virtual bool visit_while(AST_While* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_with(AST_With* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_yield(AST_Yield* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_makeclass(AST_MakeClass* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_makefunction(AST_MakeFunction* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_branch(AST_Branch* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_jump(AST_Jump* node) { RELEASE_ASSERT(0, ""); }
};
class NoopASTVisitor : public ASTVisitor {
......@@ -1243,11 +1170,6 @@ public:
virtual bool visit_while(AST_While* node) { return false; }
virtual bool visit_with(AST_With* node) { return false; }
virtual bool visit_yield(AST_Yield* node) { return false; }
virtual bool visit_branch(AST_Branch* node) { return false; }
virtual bool visit_jump(AST_Jump* node) { return false; }
virtual bool visit_makeclass(AST_MakeClass* node) { return false; }
virtual bool visit_makefunction(AST_MakeFunction* node) { return false; }
};
class ASTStmtVisitor {
......@@ -1279,9 +1201,6 @@ public:
virtual void visit_tryfinally(AST_TryFinally* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_while(AST_While* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_with(AST_With* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_branch(AST_Branch* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_jump(AST_Jump* node) { RELEASE_ASSERT(0, ""); }
};
void print_ast(AST* ast);
......@@ -1358,17 +1277,12 @@ public:
virtual bool visit_while(AST_While* node);
virtual bool visit_with(AST_With* node);
virtual bool visit_yield(AST_Yield* node);
virtual bool visit_branch(AST_Branch* node);
virtual bool visit_jump(AST_Jump* node);
virtual bool visit_makefunction(AST_MakeFunction* node);
virtual bool visit_makeclass(AST_MakeClass* node);
};
// Given an AST node, return a vector of the node plus all its descendents.
// This is useful for analyses that care more about the constituent nodes than the
// exact tree structure; ex, finding all "global" directives.
void flatten(const llvm::SmallVector<AST_stmt*, 4>& roots, std::vector<AST*>& output, bool expand_scopes);
void flatten(llvm::ArrayRef<AST_stmt*> roots, std::vector<AST*>& output, bool expand_scopes);
void flatten(AST_expr* root, std::vector<AST*>& output, bool expand_scopes);
// Similar to the flatten() function, but filters for a specific type of ast nodes:
template <class T, class R> void findNodes(const R& roots, std::vector<T*>& output, bool expand_scopes) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -786,9 +786,9 @@ private:
BST_Compare* makeCompare(AST_TYPE::AST_TYPE oper, BST_expr* left, BST_expr* right) {
auto compare = new BST_Compare();
compare->ops.push_back(oper);
compare->op = oper;
compare->left = left;
compare->comparators.push_back(right);
compare->comparator = right;
return compare;
}
......@@ -818,7 +818,7 @@ private:
assign->value = val;
assign->col_offset = val->col_offset;
assign->lineno = val->lineno;
assign->targets.push_back(target);
assign->target = target;
push_back(assign);
}
......@@ -829,7 +829,7 @@ private:
assign->lineno = val->lineno;
if (target->type == AST_TYPE::Name) {
assign->targets.push_back(makeName(ast_cast<AST_Name>(target)->id, AST_TYPE::Store, val->lineno, 0));
assign->target = makeName(ast_cast<AST_Name>(target)->id, AST_TYPE::Store, val->lineno, 0);
push_back(assign);
} else if (target->type == AST_TYPE::Subscript) {
AST_Subscript* s = ast_cast<AST_Subscript>(target);
......@@ -842,7 +842,7 @@ private:
s_target->col_offset = s->col_offset;
s_target->lineno = s->lineno;
assign->targets.push_back(s_target);
assign->target = s_target;
push_back(assign);
} else if (target->type == AST_TYPE::Attribute) {
AST_Attribute* a = ast_cast<AST_Attribute>(target);
......@@ -855,7 +855,7 @@ private:
a_target->col_offset = a->col_offset;
a_target->lineno = a->lineno;
assign->targets.push_back(a_target);
assign->target = a_target;
push_back(assign);
} else if (target->type == AST_TYPE::Tuple || target->type == AST_TYPE::List) {
std::vector<AST_expr*>* elts;
......@@ -876,7 +876,7 @@ private:
// A little hackery: push the assign, even though we're not done constructing it yet,
// so that we can iteratively push more stuff after it
assign->targets.push_back(new_target);
assign->target = new_target;
push_back(assign);
for (int i = 0; i < elts->size(); i++) {
......@@ -895,7 +895,7 @@ private:
assign->value = val;
assign->col_offset = val->col_offset;
assign->lineno = val->lineno;
assign->targets.push_back(makeName(id, AST_TYPE::Store, val->lineno, 0));
assign->target = makeName(id, AST_TYPE::Store, val->lineno, 0);
push_back(assign);
}
......@@ -1122,12 +1122,11 @@ private:
rtn->lineno = node->lineno;
rtn->col_offset = node->col_offset;
rtn->ops = node->ops;
rtn->op = node->ops[0];
rtn->left = remapExpr(node->left);
for (auto elt : node->comparators) {
rtn->comparators.push_back(remapExpr(elt));
}
assert(node->comparators.size() == 1);
rtn->comparator = remapExpr(node->comparators[0]);
return rtn;
} else {
InternedString name = nodeName();
......@@ -1146,10 +1145,10 @@ private:
val->lineno = node->lineno;
val->left = left;
if (i < node->ops.size() - 1)
val->comparators.push_back(_dup(right));
val->comparator = _dup(right);
else
val->comparators.push_back(right);
val->ops.push_back(node->ops[i]);
val->comparator = right;
val->op = node->ops[i];
pushAssign(name, val);
......@@ -1754,9 +1753,8 @@ public:
if (node->type == BST_TYPE::Assign) {
BST_Assign* asgn = bst_cast<BST_Assign>(node);
assert(asgn->targets.size() == 1);
if (asgn->targets[0]->type == BST_TYPE::Name) {
BST_Name* target = bst_cast<BST_Name>(asgn->targets[0]);
if (asgn->target->type == BST_TYPE::Name) {
BST_Name* target = bst_cast<BST_Name>(asgn->target);
if (target->id.s()[0] != '#') {
// assigning to a non-temporary
#ifndef NDEBUG
......@@ -1789,9 +1787,8 @@ public:
// Deleting temporary names is safe, since we only use it to represent kills.
if (node->type == BST_TYPE::Delete) {
BST_Delete* del = bst_cast<BST_Delete>(node);
assert(del->targets.size() == 1);
if (del->targets[0]->type == BST_TYPE::Name) {
BST_Name* target = bst_cast<BST_Name>(del->targets[0]);
if (del->target->type == BST_TYPE::Name) {
BST_Name* target = bst_cast<BST_Name>(del->target);
if (target->id.s()[0] == '#') {
curblock->push_back(node);
return;
......@@ -1836,7 +1833,7 @@ public:
target->elts.push_back(makeName(exc_info.exc_type_name, AST_TYPE::Store, node->lineno));
target->elts.push_back(makeName(exc_info.exc_value_name, AST_TYPE::Store, node->lineno));
target->elts.push_back(makeName(exc_info.exc_traceback_name, AST_TYPE::Store, node->lineno));
exc_asgn->targets.push_back(target);
exc_asgn->target = target;
exc_asgn->value = new BST_LangPrimitive(BST_LangPrimitive::LANDINGPAD);
curblock->push_back(exc_asgn);
......@@ -1897,10 +1894,8 @@ public:
return true;
}
bool visit_global(AST_Global* node) override {
BST_Global* newnode = new BST_Global();
newnode->names = std::move(node->names);
push_back(newnode);
bool visit_global(AST_Global*) override {
// nothing todo only the scoping analysis cares about this node
return true;
}
......@@ -2183,9 +2178,6 @@ public:
bool visit_delete(AST_Delete* node) override {
for (auto t : node->targets) {
BST_Delete* astdel = new BST_Delete();
astdel->lineno = node->lineno;
astdel->col_offset = node->col_offset;
BST_expr* target = NULL;
switch (t->type) {
case AST_TYPE::Subscript: {
......@@ -2235,11 +2227,13 @@ public:
RELEASE_ASSERT(0, "Unsupported del target: %d", t->type);
}
if (target != NULL)
astdel->targets.push_back(target);
if (astdel->targets.size() > 0)
if (target != NULL) {
BST_Delete* astdel = new BST_Delete();
astdel->lineno = node->lineno;
astdel->col_offset = node->col_offset;
astdel->target = target;
push_back(astdel);
}
}
return true;
......@@ -2271,7 +2265,7 @@ public:
remapped->nl = node->nl;
}
remapped->values.push_back(remapExpr(v));
remapped->value = remapExpr(v);
push_back(remapped);
i++;
......@@ -2447,7 +2441,7 @@ public:
BST_stmt* makeKill(InternedString name) {
// There might be a better way to represent this, maybe with a dedicated AST_Kill bytecode?
auto del = new BST_Delete();
del->targets.push_back(makeName(name, AST_TYPE::Del, 0, 0, false));
del->target = makeName(name, AST_TYPE::Del, 0, 0, false);
return del;
}
......@@ -2934,8 +2928,6 @@ public:
AssignVRegsVisitor() : current_block(0), next_vreg(0) {}
bool visit_alias(BST_alias* node) override { RELEASE_ASSERT(0, "these should be removed by the cfg"); }
bool visit_arguments(BST_arguments* node) override {
for (BST_expr* d : node->defaults)
d->accept(this);
......@@ -2957,12 +2949,6 @@ public:
return true;
}
bool visit_lambda(BST_Lambda* node) override {
node->args->accept(this);
return true;
}
bool isNameUsedInSingleBlock(InternedString id) {
assert(step != TrackBlockUsage);
assert(sym_blocks_map.count(id));
......@@ -3087,7 +3073,7 @@ static CFG* computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_ty
auto module_name_value = new BST_Name(stringpool.get("__name__"), AST_TYPE::Load, lineno);
fillScopingInfo(module_name_value, scoping);
module_assign->targets.push_back(module_name_target);
module_assign->target = module_name_target;
module_assign->value = module_name_value;
module_assign->lineno = lineno;
......@@ -3100,7 +3086,7 @@ static CFG* computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_ty
BST_Assign* doc_assign = new BST_Assign();
auto doc_target_name = new BST_Name(stringpool.get("__doc__"), AST_TYPE::Store, lineno);
fillScopingInfo(doc_target_name, scoping);
doc_assign->targets.push_back(doc_target_name);
doc_assign->target = doc_target_name;
auto doc_val = new BST_Str();
doc_val->str_data = ast_cast<AST_Str>(first_expr->value)->str_data;
doc_val->str_type = ast_cast<AST_Str>(first_expr->value)->str_type;
......
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