Commit 106533f9 authored by Marius Wachtler's avatar Marius Wachtler Committed by GitHub

Merge pull request #1383 from undingen/cleanup_bst

move constants into CodeConstants, call BoxedCode destructor, cleanup BST nodes
parents 1961ce67 a2560414
...@@ -89,17 +89,17 @@ private: ...@@ -89,17 +89,17 @@ private:
ExprTypeMap& expr_types; ExprTypeMap& expr_types;
TypeSpeculations& type_speculations; TypeSpeculations& type_speculations;
TypeAnalysis::SpeculationLevel speculation; TypeAnalysis::SpeculationLevel speculation;
const ConstantVRegInfo& constant_vregs; const CodeConstants& code_constants;
BasicBlockTypePropagator(CFGBlock* block, TypeMap& initial, ExprTypeMap& expr_types, BasicBlockTypePropagator(CFGBlock* block, TypeMap& initial, ExprTypeMap& expr_types,
TypeSpeculations& type_speculations, TypeAnalysis::SpeculationLevel speculation, TypeSpeculations& type_speculations, TypeAnalysis::SpeculationLevel speculation,
const ConstantVRegInfo& constant_vregs) const CodeConstants& code_constants)
: block(block), : block(block),
sym_table(initial), sym_table(initial),
expr_types(expr_types), expr_types(expr_types),
type_speculations(type_speculations), type_speculations(type_speculations),
speculation(speculation), speculation(speculation),
constant_vregs(constant_vregs) {} code_constants(code_constants) {}
void run() { void run() {
for (int i = 0; i < block->body.size(); i++) { for (int i = 0; i < block->body.size(); i++) {
...@@ -118,7 +118,7 @@ private: ...@@ -118,7 +118,7 @@ private:
printf("in propagator, speculating that %s would actually be %s, at ", printf("in propagator, speculating that %s would actually be %s, at ",
old_type->debugName().c_str(), speculated_type->debugName().c_str()); old_type->debugName().c_str(), speculated_type->debugName().c_str());
fflush(stdout); fflush(stdout);
print_bst(node, constant_vregs); print_bst(node, code_constants);
llvm::outs().flush(); llvm::outs().flush();
printf("\n"); printf("\n");
} }
...@@ -131,7 +131,7 @@ private: ...@@ -131,7 +131,7 @@ private:
} }
CompilerType* getConstantType(int vreg) { CompilerType* getConstantType(int vreg) {
Box* o = constant_vregs.getConstant(vreg); Box* o = code_constants.getConstant(vreg);
if (o->cls == int_cls) if (o->cls == int_cls)
return INT; return INT;
else if (o->cls == float_cls) else if (o->cls == float_cls)
...@@ -284,7 +284,7 @@ private: ...@@ -284,7 +284,7 @@ private:
if (VERBOSITY() >= 2 && func == UNDEF) { if (VERBOSITY() >= 2 && func == UNDEF) {
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno); printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno);
print_bst(node, constant_vregs); print_bst(node, code_constants);
printf("\n"); printf("\n");
} }
...@@ -297,7 +297,7 @@ private: ...@@ -297,7 +297,7 @@ private:
if (VERBOSITY() >= 2 && func == UNDEF) { if (VERBOSITY() >= 2 && func == UNDEF) {
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno); printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno);
print_bst(node, constant_vregs); print_bst(node, code_constants);
printf("\n"); printf("\n");
} }
...@@ -399,7 +399,7 @@ private: ...@@ -399,7 +399,7 @@ private:
if (VERBOSITY() >= 2 && rtn == UNDEF) { if (VERBOSITY() >= 2 && rtn == UNDEF) {
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno); printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno);
print_bst(node, constant_vregs); print_bst(node, code_constants);
printf("\n"); printf("\n");
} }
_doSet(node->vreg_dst, rtn); _doSet(node->vreg_dst, rtn);
...@@ -551,9 +551,9 @@ private: ...@@ -551,9 +551,9 @@ private:
public: public:
static TypeMap propagate(CFGBlock* block, const TypeMap& starting, ExprTypeMap& expr_types, static TypeMap propagate(CFGBlock* block, const TypeMap& starting, ExprTypeMap& expr_types,
TypeSpeculations& type_speculations, TypeAnalysis::SpeculationLevel speculation, TypeSpeculations& type_speculations, TypeAnalysis::SpeculationLevel speculation,
const ConstantVRegInfo& constant_vregs) { const CodeConstants& code_constants) {
TypeMap ending = starting; TypeMap ending = starting;
BasicBlockTypePropagator(block, ending, expr_types, type_speculations, speculation, constant_vregs).run(); BasicBlockTypePropagator(block, ending, expr_types, type_speculations, speculation, code_constants).run();
return ending; return ending;
} }
}; };
...@@ -632,7 +632,7 @@ public: ...@@ -632,7 +632,7 @@ public:
} }
static PropagatingTypeAnalysis* doAnalysis(SpeculationLevel speculation, TypeMap&& initial_types, static PropagatingTypeAnalysis* doAnalysis(SpeculationLevel speculation, TypeMap&& initial_types,
CFGBlock* initial_block, const ConstantVRegInfo& constant_vregs) { CFGBlock* initial_block, const CodeConstants& code_constants) {
Timer _t("PropagatingTypeAnalysis::doAnalysis()"); Timer _t("PropagatingTypeAnalysis::doAnalysis()");
CFG* cfg = initial_block->cfg; CFG* cfg = initial_block->cfg;
...@@ -673,7 +673,7 @@ public: ...@@ -673,7 +673,7 @@ public:
} }
TypeMap ending = BasicBlockTypePropagator::propagate(block, starting_types.find(block)->second, expr_types, TypeMap ending = BasicBlockTypePropagator::propagate(block, starting_types.find(block)->second, expr_types,
type_speculations, speculation, constant_vregs); type_speculations, speculation, code_constants);
if (VERBOSITY("types") >= 3) { if (VERBOSITY("types") >= 3) {
printf("before (after):\n"); printf("before (after):\n");
...@@ -730,7 +730,7 @@ public: ...@@ -730,7 +730,7 @@ public:
// public entry point: // public entry point:
TypeAnalysis* doTypeAnalysis(CFG* cfg, const ParamNames& arg_names, const std::vector<ConcreteCompilerType*>& arg_types, TypeAnalysis* doTypeAnalysis(CFG* cfg, const ParamNames& arg_names, const std::vector<ConcreteCompilerType*>& arg_types,
EffortLevel effort, TypeAnalysis::SpeculationLevel speculation, EffortLevel effort, TypeAnalysis::SpeculationLevel speculation,
const ConstantVRegInfo& constant_vregs) { const CodeConstants& code_constants) {
// if (effort == EffortLevel::INTERPRETED) { // if (effort == EffortLevel::INTERPRETED) {
// return new NullTypeAnalysis(); // return new NullTypeAnalysis();
//} //}
...@@ -750,11 +750,11 @@ TypeAnalysis* doTypeAnalysis(CFG* cfg, const ParamNames& arg_names, const std::v ...@@ -750,11 +750,11 @@ TypeAnalysis* doTypeAnalysis(CFG* cfg, const ParamNames& arg_names, const std::v
assert(i == arg_types.size()); assert(i == arg_types.size());
return PropagatingTypeAnalysis::doAnalysis(speculation, std::move(initial_types), cfg->getStartingBlock(), return PropagatingTypeAnalysis::doAnalysis(speculation, std::move(initial_types), cfg->getStartingBlock(),
constant_vregs); code_constants);
} }
TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortLevel effort, TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
TypeAnalysis::SpeculationLevel speculation, const ConstantVRegInfo& constant_vregs) { TypeAnalysis::SpeculationLevel speculation, const CodeConstants& code_constants) {
auto cfg = entry_descriptor->code->source->cfg; auto cfg = entry_descriptor->code->source->cfg;
auto&& vreg_info = cfg->getVRegInfo(); auto&& vreg_info = cfg->getVRegInfo();
TypeMap initial_types(vreg_info.getTotalNumOfVRegs()); TypeMap initial_types(vreg_info.getTotalNumOfVRegs());
...@@ -764,6 +764,6 @@ TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortL ...@@ -764,6 +764,6 @@ TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortL
} }
return PropagatingTypeAnalysis::doAnalysis(speculation, std::move(initial_types), return PropagatingTypeAnalysis::doAnalysis(speculation, std::move(initial_types),
entry_descriptor->backedge->target, constant_vregs); entry_descriptor->backedge->target, code_constants);
} }
} }
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
namespace pyston { namespace pyston {
class CFGBlock; class CFGBlock;
class ConstantVRegInfo; class CodeConstants;
class BoxedClass; class BoxedClass;
class BST_stmt_with_dest; class BST_stmt_with_dest;
class OSREntryDescriptor; class OSREntryDescriptor;
...@@ -45,9 +45,9 @@ public: ...@@ -45,9 +45,9 @@ public:
TypeAnalysis* doTypeAnalysis(CFG* cfg, const ParamNames& param_names, TypeAnalysis* doTypeAnalysis(CFG* cfg, const ParamNames& param_names,
const std::vector<ConcreteCompilerType*>& arg_types, EffortLevel effort, const std::vector<ConcreteCompilerType*>& arg_types, EffortLevel effort,
TypeAnalysis::SpeculationLevel speculation, const ConstantVRegInfo& constant_vregs); TypeAnalysis::SpeculationLevel speculation, const CodeConstants& code_constants);
TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortLevel effort, TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
TypeAnalysis::SpeculationLevel speculation, const ConstantVRegInfo& constant_vregs); TypeAnalysis::SpeculationLevel speculation, const CodeConstants& code_constants);
} }
#endif #endif
...@@ -181,7 +181,7 @@ public: ...@@ -181,7 +181,7 @@ public:
BoxedClosure* getPassedClosure() { return frame_info.passed_closure; } BoxedClosure* getPassedClosure() { return frame_info.passed_closure; }
Box** getVRegs() { return vregs; } Box** getVRegs() { return vregs; }
const ScopingResults& getScopeInfo() { return scope_info; } const ScopingResults& getScopeInfo() { return scope_info; }
const ConstantVRegInfo& getConstantVRegInfo() { return getCode()->constant_vregs; } const CodeConstants& getCodeConstants() { return getCode()->code_constants; }
void addSymbol(int vreg, Box* value, bool allow_duplicates); void addSymbol(int vreg, Box* value, bool allow_duplicates);
void setGenerator(Box* gen); void setGenerator(Box* gen);
...@@ -900,7 +900,7 @@ Value ASTInterpreter::visit_stmt(BST_stmt* node) { ...@@ -900,7 +900,7 @@ Value ASTInterpreter::visit_stmt(BST_stmt* node) {
if (0) { if (0) {
printf("%20s % 2d ", getCode()->name->c_str(), current_block->idx); printf("%20s % 2d ", getCode()->name->c_str(), current_block->idx);
print_bst(node, getConstantVRegInfo()); print_bst(node, getCodeConstants());
printf("\n"); printf("\n");
} }
...@@ -1528,7 +1528,7 @@ Value ASTInterpreter::visit_set(BST_Set* node) { ...@@ -1528,7 +1528,7 @@ Value ASTInterpreter::visit_set(BST_Set* node) {
Value ASTInterpreter::getVReg(int vreg, bool is_kill) { Value ASTInterpreter::getVReg(int vreg, bool is_kill) {
assert(vreg != VREG_UNDEFINED); assert(vreg != VREG_UNDEFINED);
if (vreg < 0) { if (vreg < 0) {
Box* o = getConstantVRegInfo().getConstant(vreg); Box* o = getCodeConstants().getConstant(vreg);
return Value(incref(o), jit ? jit->imm(o)->setType(RefType::BORROWED) : NULL); return Value(incref(o), jit ? jit->imm(o)->setType(RefType::BORROWED) : NULL);
} }
...@@ -1564,10 +1564,10 @@ Value ASTInterpreter::getVReg(int vreg, bool is_kill) { ...@@ -1564,10 +1564,10 @@ Value ASTInterpreter::getVReg(int vreg, bool is_kill) {
} }
current_block->print(getConstantVRegInfo()); current_block->print(getCodeConstants());
printf("vreg: %d num cross: %d\n", vreg, getVRegInfo().getNumOfCrossBlockVRegs()); printf("vreg: %d num cross: %d\n", vreg, getVRegInfo().getNumOfCrossBlockVRegs());
printf("\n\n"); printf("\n\n");
current_block->cfg->print(getConstantVRegInfo()); current_block->cfg->print(getCodeConstants());
assert(0); assert(0);
return Value(); return Value();
......
...@@ -1027,7 +1027,7 @@ std::pair<CompiledFunction*, llvm::Function*> doCompile(BoxedCode* code, SourceI ...@@ -1027,7 +1027,7 @@ std::pair<CompiledFunction*, llvm::Function*> doCompile(BoxedCode* code, SourceI
assert((entry_descriptor != NULL) + (spec != NULL) == 1); assert((entry_descriptor != NULL) + (spec != NULL) == 1);
if (VERBOSITY("irgen") >= 2) if (VERBOSITY("irgen") >= 2)
source->cfg->print(code->constant_vregs); source->cfg->print(code->code_constants);
assert(g.cur_module == NULL); assert(g.cur_module == NULL);
...@@ -1101,10 +1101,10 @@ std::pair<CompiledFunction*, llvm::Function*> doCompile(BoxedCode* code, SourceI ...@@ -1101,10 +1101,10 @@ std::pair<CompiledFunction*, llvm::Function*> doCompile(BoxedCode* code, SourceI
speculation_level = TypeAnalysis::SOME; speculation_level = TypeAnalysis::SOME;
TypeAnalysis* types; TypeAnalysis* types;
if (entry_descriptor) if (entry_descriptor)
types = doTypeAnalysis(entry_descriptor, effort, speculation_level, code->constant_vregs); types = doTypeAnalysis(entry_descriptor, effort, speculation_level, code->code_constants);
else else
types = doTypeAnalysis(source->cfg, *param_names, spec->arg_types, effort, speculation_level, types = doTypeAnalysis(source->cfg, *param_names, spec->arg_types, effort, speculation_level,
code->constant_vregs); code->code_constants);
_t2.split(); _t2.split();
......
...@@ -694,6 +694,9 @@ void BoxedCode::addVersion(void* f, ConcreteCompilerType* rtn_type, const std::v ...@@ -694,6 +694,9 @@ void BoxedCode::addVersion(void* f, ConcreteCompilerType* rtn_type, const std::v
} }
bool BoxedCode::tryDeallocatingTheBJitCode() { bool BoxedCode::tryDeallocatingTheBJitCode() {
if (code_blocks.empty())
return true;
// we can only delete the code object if we are not executing it currently // we can only delete the code object if we are not executing it currently
assert(bjit_num_inside >= 0); assert(bjit_num_inside >= 0);
if (bjit_num_inside != 0) { if (bjit_num_inside != 0) {
......
...@@ -69,6 +69,10 @@ IRGenState::IRGenState(BoxedCode* code, CompiledFunction* cf, llvm::Function* fu ...@@ -69,6 +69,10 @@ IRGenState::IRGenState(BoxedCode* code, CompiledFunction* cf, llvm::Function* fu
IRGenState::~IRGenState() { IRGenState::~IRGenState() {
} }
const CodeConstants& IRGenState::getCodeConstants() {
return code->code_constants;
}
llvm::Value* IRGenState::getPassedClosure() { llvm::Value* IRGenState::getPassedClosure() {
assert(getScopeInfo().takesClosure()); assert(getScopeInfo().takesClosure());
assert(passed_closure); assert(passed_closure);
...@@ -721,9 +725,9 @@ public: ...@@ -721,9 +725,9 @@ public:
return rtn; return rtn;
} }
Box* getIntConstant(int64_t n) override { return irstate->getSourceInfo()->parent_module->getIntConstant(n); } Box* getIntConstant(int64_t n) override { return irstate->getCodeConstants().getIntConstant(n); }
Box* getFloatConstant(double d) override { return irstate->getSourceInfo()->parent_module->getFloatConstant(d); } Box* getFloatConstant(double d) override { return irstate->getCodeConstants().getFloatConstant(d); }
void refConsumed(llvm::Value* v, llvm::Instruction* inst) override { void refConsumed(llvm::Value* v, llvm::Instruction* inst) override {
irstate->getRefcounts()->refConsumed(v, inst); irstate->getRefcounts()->refConsumed(v, inst);
...@@ -1225,7 +1229,7 @@ private: ...@@ -1225,7 +1229,7 @@ private:
CompilerVariable* evalVReg(int vreg, bool is_kill = true) { CompilerVariable* evalVReg(int vreg, bool is_kill = true) {
assert(vreg != VREG_UNDEFINED); assert(vreg != VREG_UNDEFINED);
if (vreg < 0) { if (vreg < 0) {
Box* o = irstate->getCode()->constant_vregs.getConstant(vreg); Box* o = irstate->getCode()->code_constants.getConstant(vreg);
if (o->cls == int_cls) { if (o->cls == int_cls) {
return makeInt(((BoxedInt*)o)->n); return makeInt(((BoxedInt*)o)->n);
} else if (o->cls == float_cls) { } else if (o->cls == float_cls) {
...@@ -1612,7 +1616,7 @@ private: ...@@ -1612,7 +1616,7 @@ private:
printf("Speculating that %s is actually %s, at ", rtn->getType()->debugName().c_str(), printf("Speculating that %s is actually %s, at ", rtn->getType()->debugName().c_str(),
speculated_type->debugName().c_str()); speculated_type->debugName().c_str());
fflush(stdout); fflush(stdout);
print_bst(node, irstate->getCode()->constant_vregs); print_bst(node, irstate->getCode()->code_constants);
llvm::outs().flush(); llvm::outs().flush();
printf("\n"); printf("\n");
} }
...@@ -1624,7 +1628,7 @@ private: ...@@ -1624,7 +1628,7 @@ private:
auto source = irstate->getSourceInfo(); auto source = irstate->getSourceInfo();
printf("On %s:%d, function %s:\n", irstate->getCode()->filename->c_str(), printf("On %s:%d, function %s:\n", irstate->getCode()->filename->c_str(),
irstate->getCode()->firstlineno, irstate->getCode()->name->c_str()); irstate->getCode()->firstlineno, irstate->getCode()->name->c_str());
irstate->getSourceInfo()->cfg->print(irstate->getCode()->constant_vregs); irstate->getSourceInfo()->cfg->print(irstate->getCode()->code_constants);
} }
RELEASE_ASSERT(!rtn->canConvertTo(speculated_type), "%s %s", rtn->getType()->debugName().c_str(), RELEASE_ASSERT(!rtn->canConvertTo(speculated_type), "%s %s", rtn->getType()->debugName().c_str(),
speculated_type->debugName().c_str()); speculated_type->debugName().c_str());
......
...@@ -92,6 +92,7 @@ public: ...@@ -92,6 +92,7 @@ public:
CompiledFunction* getCurFunction() { return cf; } CompiledFunction* getCurFunction() { return cf; }
BoxedCode* getCode() { return code; } BoxedCode* getCode() { return code; }
const CodeConstants& getCodeConstants();
ExceptionStyle getExceptionStyle() { return cf->exception_style; } ExceptionStyle getExceptionStyle() { return cf->exception_style; }
......
...@@ -754,8 +754,8 @@ void BST_MakeSlice::accept_stmt(StmtVisitor* v) { ...@@ -754,8 +754,8 @@ void BST_MakeSlice::accept_stmt(StmtVisitor* v) {
return v->visit_makeslice(this); return v->visit_makeslice(this);
} }
void print_bst(BST_stmt* bst, const ConstantVRegInfo& constant_vregs) { void print_bst(BST_stmt* bst, const CodeConstants& code_constants) {
PrintVisitor v(constant_vregs, 0, llvm::outs()); PrintVisitor v(code_constants, 0, llvm::outs());
bst->accept(&v); bst->accept(&v);
v.flush(); v.flush();
} }
...@@ -771,7 +771,7 @@ bool PrintVisitor::visit_vreg(int* vreg, bool is_dst) { ...@@ -771,7 +771,7 @@ bool PrintVisitor::visit_vreg(int* vreg, bool is_dst) {
if (*vreg != VREG_UNDEFINED) { if (*vreg != VREG_UNDEFINED) {
stream << "%" << *vreg; stream << "%" << *vreg;
if (*vreg < 0) if (*vreg < 0)
stream << "|" << autoDecref(repr(constant_vregs.getConstant(*vreg)))->s() << "|"; stream << "|" << autoDecref(repr(code_constants.getConstant(*vreg)))->s() << "|";
} else } else
stream << "%undef"; stream << "%undef";
......
...@@ -165,8 +165,18 @@ public: ...@@ -165,8 +165,18 @@ public:
bool has_dest_vreg() const override { return true; } bool has_dest_vreg() const override { return true; }
}; };
#define BSTNODE(opcode) \
virtual void accept(BSTVisitor* v); \
virtual void accept_stmt(StmtVisitor* v); \
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::opcode;
#define BSTFIXEDVREGS(opcode, base_class) \
BSTNODE(opcode) \
BST_##opcode() : base_class(BST_TYPE::opcode) {}
#define BSTVARVREGS(opcode, base_class, num_elts, vreg_dst) \ #define BSTVARVREGS(opcode, base_class, num_elts, vreg_dst) \
public: \ public: \
BSTNODE(opcode) \
static BST_##opcode* create(int num_elts) { return new (num_elts) BST_##opcode(num_elts); } \ static BST_##opcode* create(int num_elts) { return new (num_elts) BST_##opcode(num_elts); } \
static void operator delete(void* ptr) { ::operator delete[](ptr); } \ static void operator delete(void* ptr) { ::operator delete[](ptr); } \
\ \
...@@ -182,6 +192,7 @@ private: ...@@ -182,6 +192,7 @@ private:
#define BSTVARVREGS2(opcode, base_class, num_elts, num_elts2, vreg_dst) \ #define BSTVARVREGS2(opcode, base_class, num_elts, num_elts2, vreg_dst) \
public: \ public: \
BSTNODE(opcode) \
static BST_##opcode* create(int num_elts, int num_elts2) { \ static BST_##opcode* create(int num_elts, int num_elts2) { \
return new (num_elts + num_elts2) BST_##opcode(num_elts, num_elts2); \ return new (num_elts + num_elts2) BST_##opcode(num_elts, num_elts2); \
} \ } \
...@@ -200,6 +211,7 @@ private: ...@@ -200,6 +211,7 @@ private:
#define BSTVARVREGS2CALL(opcode, num_elts, num_elts2, vreg_dst) \ #define BSTVARVREGS2CALL(opcode, num_elts, num_elts2, vreg_dst) \
public: \ public: \
BSTNODE(opcode) \
static BST_##opcode* create(int num_elts, int num_elts2) { \ static BST_##opcode* create(int num_elts, int num_elts2) { \
return new (num_elts + num_elts2) BST_##opcode(num_elts, num_elts2); \ return new (num_elts + num_elts2) BST_##opcode(num_elts, num_elts2); \
} \ } \
...@@ -219,12 +231,7 @@ class BST_Assert : public BST_stmt { ...@@ -219,12 +231,7 @@ class BST_Assert : public BST_stmt {
public: public:
int vreg_msg = VREG_UNDEFINED; int vreg_msg = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Assert, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_Assert() : BST_stmt(BST_TYPE::Assert) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Assert;
}; };
class BST_UnpackIntoArray : public BST_stmt { class BST_UnpackIntoArray : public BST_stmt {
...@@ -233,11 +240,6 @@ public: ...@@ -233,11 +240,6 @@ public:
const int num_elts; const int num_elts;
int vreg_dst[1]; int vreg_dst[1];
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::UnpackIntoArray;
BSTVARVREGS(UnpackIntoArray, BST_stmt, num_elts, vreg_dst) BSTVARVREGS(UnpackIntoArray, BST_stmt, num_elts, vreg_dst)
}; };
...@@ -248,12 +250,7 @@ class BST_CopyVReg : public BST_stmt_with_dest { ...@@ -248,12 +250,7 @@ class BST_CopyVReg : public BST_stmt_with_dest {
public: public:
int vreg_src = VREG_UNDEFINED; // this vreg will not get killed! int vreg_src = VREG_UNDEFINED; // this vreg will not get killed!
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(CopyVReg, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_CopyVReg() : BST_stmt_with_dest(BST_TYPE::CopyVReg) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::CopyVReg;
}; };
...@@ -270,13 +267,7 @@ public: ...@@ -270,13 +267,7 @@ public:
// Only valid for lookup_type == CLOSURE: // Only valid for lookup_type == CLOSURE:
int closure_offset = -1; int closure_offset = -1;
BSTFIXEDVREGS(StoreName, BST_stmt)
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_StoreName() : BST_stmt(BST_TYPE::StoreName) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::StoreName;
}; };
class BST_StoreAttr : public BST_stmt { class BST_StoreAttr : public BST_stmt {
...@@ -285,12 +276,7 @@ public: ...@@ -285,12 +276,7 @@ public:
int vreg_target = VREG_UNDEFINED; int vreg_target = VREG_UNDEFINED;
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(StoreAttr, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_StoreAttr() : BST_stmt(BST_TYPE::StoreAttr) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::StoreAttr;
}; };
class BST_StoreSub : public BST_stmt { class BST_StoreSub : public BST_stmt {
...@@ -299,12 +285,7 @@ public: ...@@ -299,12 +285,7 @@ public:
int vreg_slice = VREG_UNDEFINED; int vreg_slice = VREG_UNDEFINED;
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(StoreSub, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_StoreSub() : BST_stmt(BST_TYPE::StoreSub) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::StoreSub;
}; };
class BST_StoreSubSlice : public BST_stmt { class BST_StoreSubSlice : public BST_stmt {
...@@ -313,12 +294,7 @@ public: ...@@ -313,12 +294,7 @@ public:
int vreg_lower = VREG_UNDEFINED, vreg_upper = VREG_UNDEFINED; int vreg_lower = VREG_UNDEFINED, vreg_upper = VREG_UNDEFINED;
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(StoreSubSlice, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_StoreSubSlice() : BST_stmt(BST_TYPE::StoreSubSlice) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::StoreSubSlice;
}; };
class BST_LoadName : public BST_stmt_with_dest { class BST_LoadName : public BST_stmt_with_dest {
...@@ -333,12 +309,7 @@ public: ...@@ -333,12 +309,7 @@ public:
// Only valid for lookup_type == CLOSURE: // Only valid for lookup_type == CLOSURE:
int closure_offset = -1; int closure_offset = -1;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(LoadName, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_LoadName() : BST_stmt_with_dest(BST_TYPE::LoadName) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::LoadName;
}; };
class BST_LoadAttr : public BST_stmt_with_dest { class BST_LoadAttr : public BST_stmt_with_dest {
...@@ -347,12 +318,7 @@ public: ...@@ -347,12 +318,7 @@ public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
bool clsonly = false; bool clsonly = false;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(LoadAttr, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_LoadAttr() : BST_stmt_with_dest(BST_TYPE::LoadAttr) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::LoadAttr;
}; };
class BST_LoadSub : public BST_stmt_with_dest { class BST_LoadSub : public BST_stmt_with_dest {
...@@ -360,12 +326,7 @@ public: ...@@ -360,12 +326,7 @@ public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
int vreg_slice = VREG_UNDEFINED; int vreg_slice = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(LoadSub, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_LoadSub() : BST_stmt_with_dest(BST_TYPE::LoadSub) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::LoadSub;
}; };
class BST_LoadSubSlice : public BST_stmt_with_dest { class BST_LoadSubSlice : public BST_stmt_with_dest {
...@@ -373,12 +334,7 @@ public: ...@@ -373,12 +334,7 @@ public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
int vreg_lower = VREG_UNDEFINED, vreg_upper = VREG_UNDEFINED; int vreg_lower = VREG_UNDEFINED, vreg_upper = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(LoadSubSlice, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_LoadSubSlice() : BST_stmt_with_dest(BST_TYPE::LoadSubSlice) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::LoadSubSlice;
}; };
class BST_AugBinOp : public BST_stmt_with_dest { class BST_AugBinOp : public BST_stmt_with_dest {
...@@ -386,12 +342,7 @@ public: ...@@ -386,12 +342,7 @@ public:
AST_TYPE::AST_TYPE op_type; AST_TYPE::AST_TYPE op_type;
int vreg_left = VREG_UNDEFINED, vreg_right = VREG_UNDEFINED; int vreg_left = VREG_UNDEFINED, vreg_right = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(AugBinOp, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_AugBinOp() : BST_stmt_with_dest(BST_TYPE::AugBinOp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::AugBinOp;
}; };
class BST_BinOp : public BST_stmt_with_dest { class BST_BinOp : public BST_stmt_with_dest {
...@@ -399,12 +350,7 @@ public: ...@@ -399,12 +350,7 @@ public:
AST_TYPE::AST_TYPE op_type; AST_TYPE::AST_TYPE op_type;
int vreg_left = VREG_UNDEFINED, vreg_right = VREG_UNDEFINED; int vreg_left = VREG_UNDEFINED, vreg_right = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(BinOp, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_BinOp() : BST_stmt_with_dest(BST_TYPE::BinOp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::BinOp;
}; };
class BST_Call : public BST_stmt_with_dest { class BST_Call : public BST_stmt_with_dest {
...@@ -425,11 +371,6 @@ public: ...@@ -425,11 +371,6 @@ public:
int vreg_func = VREG_UNDEFINED; int vreg_func = VREG_UNDEFINED;
int elts[1]; int elts[1];
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::CallFunc;
BSTVARVREGS2CALL(CallFunc, num_args, num_keywords, elts) BSTVARVREGS2CALL(CallFunc, num_args, num_keywords, elts)
}; };
...@@ -439,11 +380,6 @@ public: ...@@ -439,11 +380,6 @@ public:
InternedString attr; InternedString attr;
int elts[1]; int elts[1];
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::CallAttr;
BSTVARVREGS2CALL(CallAttr, num_args, num_keywords, elts) BSTVARVREGS2CALL(CallAttr, num_args, num_keywords, elts)
}; };
...@@ -453,11 +389,6 @@ public: ...@@ -453,11 +389,6 @@ public:
InternedString attr; InternedString attr;
int elts[1]; int elts[1];
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::CallClsAttr;
BSTVARVREGS2CALL(CallClsAttr, num_args, num_keywords, elts) BSTVARVREGS2CALL(CallClsAttr, num_args, num_keywords, elts)
}; };
...@@ -468,19 +399,11 @@ public: ...@@ -468,19 +399,11 @@ public:
int vreg_comparator = VREG_UNDEFINED; int vreg_comparator = VREG_UNDEFINED;
int vreg_left = VREG_UNDEFINED; int vreg_left = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Compare, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_Compare() : BST_stmt_with_dest(BST_TYPE::Compare) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Compare;
}; };
class BST_ClassDef : public BST_stmt { class BST_ClassDef : public BST_stmt {
public: public:
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BoxedCode* code; BoxedCode* code;
InternedString name; InternedString name;
...@@ -488,19 +411,12 @@ public: ...@@ -488,19 +411,12 @@ public:
const int num_decorator; const int num_decorator;
int decorator[1]; int decorator[1];
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ClassDef;
BSTVARVREGS(ClassDef, BST_stmt, num_decorator, decorator) BSTVARVREGS(ClassDef, BST_stmt, num_decorator, decorator)
}; };
class BST_Dict : public BST_stmt_with_dest { class BST_Dict : public BST_stmt_with_dest {
public: public:
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Dict, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_Dict() : BST_stmt_with_dest(BST_TYPE::Dict) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Dict;
}; };
class BST_DeleteAttr : public BST_stmt { class BST_DeleteAttr : public BST_stmt {
...@@ -508,12 +424,7 @@ public: ...@@ -508,12 +424,7 @@ public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
InternedString attr; InternedString attr;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(DeleteAttr, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_DeleteAttr() : BST_stmt(BST_TYPE::DeleteAttr) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::DeleteAttr;
}; };
class BST_DeleteName : public BST_stmt { class BST_DeleteName : public BST_stmt {
...@@ -527,13 +438,7 @@ public: ...@@ -527,13 +438,7 @@ public:
// Only valid for lookup_type == CLOSURE: // Only valid for lookup_type == CLOSURE:
int closure_offset = -1; int closure_offset = -1;
BSTFIXEDVREGS(DeleteName, BST_stmt)
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_DeleteName() : BST_stmt(BST_TYPE::DeleteName) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::DeleteName;
}; };
class BST_DeleteSub : public BST_stmt { class BST_DeleteSub : public BST_stmt {
...@@ -541,12 +446,7 @@ public: ...@@ -541,12 +446,7 @@ public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
int vreg_slice = VREG_UNDEFINED; int vreg_slice = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(DeleteSub, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_DeleteSub() : BST_stmt(BST_TYPE::DeleteSub) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::DeleteSub;
}; };
class BST_DeleteSubSlice : public BST_stmt { class BST_DeleteSubSlice : public BST_stmt {
...@@ -555,12 +455,7 @@ public: ...@@ -555,12 +455,7 @@ public:
int vreg_lower = VREG_UNDEFINED; int vreg_lower = VREG_UNDEFINED;
int vreg_upper = VREG_UNDEFINED; int vreg_upper = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(DeleteSubSlice, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_DeleteSubSlice() : BST_stmt(BST_TYPE::DeleteSubSlice) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::DeleteSubSlice;
}; };
class BST_Exec : public BST_stmt { class BST_Exec : public BST_stmt {
...@@ -569,12 +464,7 @@ public: ...@@ -569,12 +464,7 @@ public:
int vreg_globals = VREG_UNDEFINED; int vreg_globals = VREG_UNDEFINED;
int vreg_locals = VREG_UNDEFINED; int vreg_locals = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Exec, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_Exec() : BST_stmt(BST_TYPE::Exec) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Exec;
}; };
class BST_FunctionDef : public BST_stmt { class BST_FunctionDef : public BST_stmt {
...@@ -588,12 +478,6 @@ public: ...@@ -588,12 +478,6 @@ public:
int elts[1]; // decorators followed by defaults int elts[1]; // decorators followed by defaults
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::FunctionDef;
BSTVARVREGS2(FunctionDef, BST_stmt, num_decorator, num_defaults, elts) BSTVARVREGS2(FunctionDef, BST_stmt, num_decorator, num_defaults, elts)
}; };
...@@ -602,11 +486,6 @@ public: ...@@ -602,11 +486,6 @@ public:
const int num_elts; const int num_elts;
int elts[1]; int elts[1];
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::List;
BSTVARVREGS(List, BST_stmt_with_dest, num_elts, elts) BSTVARVREGS(List, BST_stmt_with_dest, num_elts, elts)
}; };
...@@ -614,12 +493,7 @@ class BST_Repr : public BST_stmt_with_dest { ...@@ -614,12 +493,7 @@ class BST_Repr : public BST_stmt_with_dest {
public: public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Repr, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_Repr() : BST_stmt_with_dest(BST_TYPE::Repr) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Repr;
}; };
class BST_Print : public BST_stmt { class BST_Print : public BST_stmt {
...@@ -628,12 +502,7 @@ public: ...@@ -628,12 +502,7 @@ public:
bool nl; bool nl;
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Print, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_Print() : BST_stmt(BST_TYPE::Print) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Print;
}; };
class BST_Raise : public BST_stmt { class BST_Raise : public BST_stmt {
...@@ -644,24 +513,14 @@ public: ...@@ -644,24 +513,14 @@ public:
// Ie "raise Exception()" will have type==Exception(), inst==None, tback==None // Ie "raise Exception()" will have type==Exception(), inst==None, tback==None
int vreg_arg0 = VREG_UNDEFINED, vreg_arg1 = VREG_UNDEFINED, vreg_arg2 = VREG_UNDEFINED; int vreg_arg0 = VREG_UNDEFINED, vreg_arg1 = VREG_UNDEFINED, vreg_arg2 = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Raise, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_Raise() : BST_stmt(BST_TYPE::Raise) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Raise;
}; };
class BST_Return : public BST_stmt { class BST_Return : public BST_stmt {
public: public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Return, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_Return() : BST_stmt(BST_TYPE::Return) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Return;
}; };
class BST_Set : public BST_stmt_with_dest { class BST_Set : public BST_stmt_with_dest {
...@@ -669,11 +528,6 @@ public: ...@@ -669,11 +528,6 @@ public:
const int num_elts; const int num_elts;
int elts[1]; int elts[1];
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Set;
BSTVARVREGS(Set, BST_stmt_with_dest, num_elts, elts) BSTVARVREGS(Set, BST_stmt_with_dest, num_elts, elts)
}; };
...@@ -681,12 +535,7 @@ class BST_MakeSlice : public BST_stmt_with_dest { ...@@ -681,12 +535,7 @@ class BST_MakeSlice : public BST_stmt_with_dest {
public: public:
int vreg_lower = VREG_UNDEFINED, vreg_upper = VREG_UNDEFINED, vreg_step = VREG_UNDEFINED; int vreg_lower = VREG_UNDEFINED, vreg_upper = VREG_UNDEFINED, vreg_step = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(MakeSlice, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_MakeSlice() : BST_stmt_with_dest(BST_TYPE::MakeSlice) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::MakeSlice;
}; };
class BST_Tuple : public BST_stmt_with_dest { class BST_Tuple : public BST_stmt_with_dest {
...@@ -694,11 +543,6 @@ public: ...@@ -694,11 +543,6 @@ public:
const int num_elts; const int num_elts;
int elts[1]; int elts[1];
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Tuple;
BSTVARVREGS(Tuple, BST_stmt_with_dest, num_elts, elts) BSTVARVREGS(Tuple, BST_stmt_with_dest, num_elts, elts)
}; };
...@@ -707,54 +551,34 @@ public: ...@@ -707,54 +551,34 @@ public:
int vreg_operand = VREG_UNDEFINED; int vreg_operand = VREG_UNDEFINED;
AST_TYPE::AST_TYPE op_type; AST_TYPE::AST_TYPE op_type;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(UnaryOp, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_UnaryOp() : BST_stmt_with_dest(BST_TYPE::UnaryOp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::UnaryOp;
}; };
class BST_Yield : public BST_stmt_with_dest { class BST_Yield : public BST_stmt_with_dest {
public: public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Yield, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_Yield() : BST_stmt_with_dest(BST_TYPE::Yield) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Yield;
}; };
class BST_MakeFunction : public BST_stmt_with_dest { class BST_MakeFunction : public BST_stmt_with_dest {
public: public:
BST_FunctionDef* function_def; BST_FunctionDef* function_def;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_MakeFunction(BST_FunctionDef* fd) : BST_stmt_with_dest(BST_TYPE::MakeFunction, fd->lineno), function_def(fd) {} BST_MakeFunction(BST_FunctionDef* fd) : BST_stmt_with_dest(BST_TYPE::MakeFunction, fd->lineno), function_def(fd) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::MakeFunction; BSTNODE(MakeFunction)
}; };
class BST_MakeClass : public BST_stmt_with_dest { class BST_MakeClass : public BST_stmt_with_dest {
public: public:
BST_ClassDef* class_def; BST_ClassDef* class_def;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_MakeClass(BST_ClassDef* cd) : BST_stmt_with_dest(BST_TYPE::MakeClass, cd->lineno), class_def(cd) {} BST_MakeClass(BST_ClassDef* cd) : BST_stmt_with_dest(BST_TYPE::MakeClass, cd->lineno), class_def(cd) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::MakeClass; BSTNODE(MakeClass)
}; };
// BST pseudo-nodes that will get added during CFG-construction. These don't exist in the input BST, but adding them in
// lets us avoid creating a completely new IR for this phase
class CFGBlock; class CFGBlock;
class BST_Branch : public BST_stmt { class BST_Branch : public BST_stmt {
...@@ -762,24 +586,14 @@ public: ...@@ -762,24 +586,14 @@ public:
int vreg_test = VREG_UNDEFINED; int vreg_test = VREG_UNDEFINED;
CFGBlock* iftrue, *iffalse; CFGBlock* iftrue, *iffalse;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Branch, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_Branch() : BST_stmt(BST_TYPE::Branch) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Branch;
}; };
class BST_Jump : public BST_stmt { class BST_Jump : public BST_stmt {
public: public:
CFGBlock* target; CFGBlock* target;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Jump, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_Jump() : BST_stmt(BST_TYPE::Jump) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Jump;
}; };
class BST_Invoke : public BST_stmt { class BST_Invoke : public BST_stmt {
...@@ -788,46 +602,28 @@ public: ...@@ -788,46 +602,28 @@ public:
CFGBlock* normal_dest, *exc_dest; CFGBlock* normal_dest, *exc_dest;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Invoke(BST_stmt* stmt) : BST_stmt(BST_TYPE::Invoke), stmt(stmt) {} BST_Invoke(BST_stmt* stmt) : BST_stmt(BST_TYPE::Invoke), stmt(stmt) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Invoke; BSTNODE(Invoke)
}; };
// grabs the info about the last raised exception // grabs the info about the last raised exception
class BST_Landingpad : public BST_stmt_with_dest { class BST_Landingpad : public BST_stmt_with_dest {
public: public:
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Landingpad, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_Landingpad() : BST_stmt_with_dest(BST_TYPE::Landingpad) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Landingpad;
}; };
class BST_Locals : public BST_stmt_with_dest { class BST_Locals : public BST_stmt_with_dest {
public: public:
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Locals, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_Locals() : BST_stmt_with_dest(BST_TYPE::Locals) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Locals;
}; };
class BST_GetIter : public BST_stmt_with_dest { class BST_GetIter : public BST_stmt_with_dest {
public: public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(GetIter, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_GetIter() : BST_stmt_with_dest(BST_TYPE::GetIter) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::GetIter;
}; };
class BST_ImportFrom : public BST_stmt_with_dest { class BST_ImportFrom : public BST_stmt_with_dest {
...@@ -835,12 +631,7 @@ public: ...@@ -835,12 +631,7 @@ public:
int vreg_module = VREG_UNDEFINED; int vreg_module = VREG_UNDEFINED;
int vreg_name = VREG_UNDEFINED; int vreg_name = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(ImportFrom, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_ImportFrom() : BST_stmt_with_dest(BST_TYPE::ImportFrom) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ImportFrom;
}; };
class BST_ImportName : public BST_stmt_with_dest { class BST_ImportName : public BST_stmt_with_dest {
...@@ -849,25 +640,14 @@ public: ...@@ -849,25 +640,14 @@ public:
int level = VREG_UNDEFINED; int level = VREG_UNDEFINED;
int vreg_name = VREG_UNDEFINED; int vreg_name = VREG_UNDEFINED;
BSTFIXEDVREGS(ImportName, BST_stmt_with_dest)
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_ImportName() : BST_stmt_with_dest(BST_TYPE::ImportName) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ImportName;
}; };
class BST_ImportStar : public BST_stmt_with_dest { class BST_ImportStar : public BST_stmt_with_dest {
public: public:
int vreg_name = VREG_UNDEFINED; int vreg_name = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(ImportStar, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_ImportStar() : BST_stmt_with_dest(BST_TYPE::ImportStar) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ImportStar;
}; };
// determines whether something is "true" for purposes of `if' and so forth // determines whether something is "true" for purposes of `if' and so forth
...@@ -875,12 +655,7 @@ class BST_Nonzero : public BST_stmt_with_dest { ...@@ -875,12 +655,7 @@ class BST_Nonzero : public BST_stmt_with_dest {
public: public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(Nonzero, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_Nonzero() : BST_stmt_with_dest(BST_TYPE::Nonzero) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Nonzero;
}; };
class BST_CheckExcMatch : public BST_stmt_with_dest { class BST_CheckExcMatch : public BST_stmt_with_dest {
...@@ -888,12 +663,7 @@ public: ...@@ -888,12 +663,7 @@ public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
int vreg_cls = VREG_UNDEFINED; int vreg_cls = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(CheckExcMatch, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_CheckExcMatch() : BST_stmt_with_dest(BST_TYPE::CheckExcMatch) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::CheckExcMatch;
}; };
class BST_SetExcInfo : public BST_stmt { class BST_SetExcInfo : public BST_stmt {
...@@ -902,46 +672,26 @@ public: ...@@ -902,46 +672,26 @@ public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
int vreg_traceback = VREG_UNDEFINED; int vreg_traceback = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(SetExcInfo, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_SetExcInfo() : BST_stmt(BST_TYPE::SetExcInfo) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::SetExcInfo;
}; };
class BST_UncacheExcInfo : public BST_stmt { class BST_UncacheExcInfo : public BST_stmt {
public: public:
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(UncacheExcInfo, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_UncacheExcInfo() : BST_stmt(BST_TYPE::UncacheExcInfo) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::UncacheExcInfo;
}; };
class BST_HasNext : public BST_stmt_with_dest { class BST_HasNext : public BST_stmt_with_dest {
public: public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(HasNext, BST_stmt_with_dest)
virtual void accept_stmt(StmtVisitor* v);
BST_HasNext() : BST_stmt_with_dest(BST_TYPE::HasNext) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::HasNext;
}; };
class BST_PrintExpr : public BST_stmt { class BST_PrintExpr : public BST_stmt {
public: public:
int vreg_value = VREG_UNDEFINED; int vreg_value = VREG_UNDEFINED;
virtual void accept(BSTVisitor* v); BSTFIXEDVREGS(PrintExpr, BST_stmt)
virtual void accept_stmt(StmtVisitor* v);
BST_PrintExpr() : BST_stmt(BST_TYPE::PrintExpr) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::PrintExpr;
}; };
...@@ -1156,20 +906,20 @@ public: ...@@ -1156,20 +906,20 @@ public:
virtual void visit_yield(BST_Yield* node) { RELEASE_ASSERT(0, ""); } virtual void visit_yield(BST_Yield* node) { RELEASE_ASSERT(0, ""); }
}; };
class ConstantVRegInfo; class CodeConstants;
void print_bst(BST_stmt* bst, const ConstantVRegInfo& constant_vregs); void print_bst(BST_stmt* bst, const CodeConstants& code_constants);
class PrintVisitor : public BSTVisitor { class PrintVisitor : public BSTVisitor {
private: private:
llvm::raw_ostream& stream; llvm::raw_ostream& stream;
const ConstantVRegInfo& constant_vregs; const CodeConstants& code_constants;
int indent; int indent;
void printIndent(); void printIndent();
void printOp(AST_TYPE::AST_TYPE op_type); void printOp(AST_TYPE::AST_TYPE op_type);
public: public:
PrintVisitor(const ConstantVRegInfo& constant_vregs, int indent, llvm::raw_ostream& stream) PrintVisitor(const CodeConstants& code_constants, int indent, llvm::raw_ostream& stream)
: BSTVisitor(false /* visit child CFG */), stream(stream), constant_vregs(constant_vregs), indent(indent) {} : BSTVisitor(false /* visit child CFG */), stream(stream), code_constants(code_constants), indent(indent) {}
virtual ~PrintVisitor() {} virtual ~PrintVisitor() {}
void flush() { stream.flush(); } void flush() { stream.flush(); }
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "core/bst.h" #include "core/bst.h"
#include "core/options.h" #include "core/options.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/complex.h"
#include "runtime/long.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
#include "runtime/types.h" #include "runtime/types.h"
...@@ -185,7 +187,7 @@ void CFGBlock::unconnectFrom(CFGBlock* successor) { ...@@ -185,7 +187,7 @@ void CFGBlock::unconnectFrom(CFGBlock* successor) {
successor->predecessors.end()); successor->predecessors.end());
} }
void CFGBlock::print(const ConstantVRegInfo& constant_vregs, llvm::raw_ostream& stream) { void CFGBlock::print(const CodeConstants& code_constants, llvm::raw_ostream& stream) {
stream << "Block " << idx; stream << "Block " << idx;
if (info) if (info)
stream << " '" << info << "'"; stream << " '" << info << "'";
...@@ -200,7 +202,7 @@ void CFGBlock::print(const ConstantVRegInfo& constant_vregs, llvm::raw_ostream& ...@@ -200,7 +202,7 @@ void CFGBlock::print(const ConstantVRegInfo& constant_vregs, llvm::raw_ostream&
} }
stream << "\n"; stream << "\n";
PrintVisitor pv(constant_vregs, 4, stream); PrintVisitor pv(code_constants, 4, stream);
for (int j = 0; j < body.size(); j++) { for (int j = 0; j < body.size(); j++) {
stream << " "; stream << " ";
body[j]->accept(&pv); body[j]->accept(&pv);
...@@ -246,10 +248,10 @@ public: ...@@ -246,10 +248,10 @@ public:
AST* orig_node); AST* orig_node);
}; };
static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_type, static std::pair<CFG*, CodeConstants> computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_type,
int lineno, AST_arguments* args, BoxedString* filename, int lineno, AST_arguments* args, BoxedString* filename,
SourceInfo* source, const ParamNames& param_names, SourceInfo* source, const ParamNames& param_names, ScopeInfo* scoping,
ScopeInfo* scoping, ModuleCFGProcessor* cfgizer); ModuleCFGProcessor* cfgizer);
// This keeps track of the result of an instruction it's either a name, const or undefined. // This keeps track of the result of an instruction it's either a name, const or undefined.
struct TmpValue { struct TmpValue {
...@@ -362,15 +364,25 @@ private: ...@@ -362,15 +364,25 @@ private:
CFGBlock* curblock; CFGBlock* curblock;
std::vector<ContInfo> continuations; std::vector<ContInfo> continuations;
std::vector<ExcBlockInfo> exc_handlers; std::vector<ExcBlockInfo> exc_handlers;
// maps constants to their vreg number
llvm::DenseMap<Box*, int> consts; llvm::DenseMap<Box*, int> consts;
ConstantVRegInfo constant_vregs; CodeConstants code_constants;
llvm::StringMap<BoxedString*> str_constants;
llvm::StringMap<Box*> unicode_constants;
// I'm not sure how well it works to use doubles as hashtable keys; thankfully
// it's not a big deal if we get misses.
std::unordered_map<int64_t, Box*> imaginary_constants;
llvm::StringMap<Box*> long_constants;
llvm::DenseMap<InternedString, int> interned_string_constants;
unsigned int next_var_index = 0; unsigned int next_var_index = 0;
friend std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_type, friend std::pair<CFG*, CodeConstants> computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_type,
int lineno, AST_arguments* args, BoxedString* filename, int lineno, AST_arguments* args, BoxedString* filename,
SourceInfo* source, const ParamNames& param_names, SourceInfo* source, const ParamNames& param_names,
ScopeInfo* scoping, ModuleCFGProcessor* cfgizer); ScopeInfo* scoping, ModuleCFGProcessor* cfgizer);
public: public:
CFGVisitor(BoxedString* filename, SourceInfo* source, InternedStringPool& stringpool, ScopeInfo* scoping, CFGVisitor(BoxedString* filename, SourceInfo* source, InternedStringPool& stringpool, ScopeInfo* scoping,
...@@ -513,21 +525,44 @@ private: ...@@ -513,21 +525,44 @@ private:
auto it = consts.find(o); auto it = consts.find(o);
if (it != consts.end()) if (it != consts.end())
return it->second; return it->second;
int vreg = constant_vregs.addConstant(o); int vreg = code_constants.createVRegEntryForConstant(o);
consts[o] = vreg; consts[o] = vreg;
return vreg; return vreg;
} }
static int64_t getDoubleBits(double d) {
int64_t rtn;
static_assert(sizeof(rtn) == sizeof(d), "");
memcpy(&rtn, &d, sizeof(d));
return rtn;
}
TmpValue makeNum(int64_t n, int lineno) {
Box* o = code_constants.getIntConstant(n);
int vreg_const = addConst(o);
return TmpValue(vreg_const, lineno);
}
TmpValue remapNum(AST_Num* num) { TmpValue remapNum(AST_Num* num) {
Box* o = NULL; Box* o = NULL;
if (num->num_type == AST_Num::INT) { if (num->num_type == AST_Num::INT) {
o = source->parent_module->getIntConstant(num->n_int); o = code_constants.getIntConstant(num->n_int);
} else if (num->num_type == AST_Num::FLOAT) { } else if (num->num_type == AST_Num::FLOAT) {
o = source->parent_module->getFloatConstant(num->n_float); o = code_constants.getFloatConstant(num->n_float);
} else if (num->num_type == AST_Num::LONG) { } else if (num->num_type == AST_Num::LONG) {
o = source->parent_module->getLongConstant(num->n_long); Box*& r = long_constants[num->n_long];
if (!r) {
r = createLong(num->n_long);
code_constants.addOwnedRef(r);
}
o = r;
} else if (num->num_type == AST_Num::COMPLEX) { } else if (num->num_type == AST_Num::COMPLEX) {
o = source->parent_module->getPureImaginaryConstant(num->n_float); Box*& r = imaginary_constants[getDoubleBits(num->n_float)];
if (!r) {
r = createPureImaginary(num->n_float);
code_constants.addOwnedRef(r);
}
o = r;
} else } else
RELEASE_ASSERT(0, "not implemented"); RELEASE_ASSERT(0, "not implemented");
...@@ -535,23 +570,34 @@ private: ...@@ -535,23 +570,34 @@ private:
return TmpValue(vreg_const, num->lineno); return TmpValue(vreg_const, num->lineno);
} }
TmpValue makeStr(llvm::StringRef str, int lineno = 0) {
BoxedString*& o = str_constants[str];
// we always intern the string
if (!o) {
o = internStringMortal(str);
code_constants.addOwnedRef(o);
}
int vreg_const = addConst(o);
return TmpValue(vreg_const, lineno);
}
TmpValue remapStr(AST_Str* str) { TmpValue remapStr(AST_Str* str) {
// TODO make this serializable // TODO make this serializable
Box* o = NULL;
if (str->str_type == AST_Str::STR) { if (str->str_type == AST_Str::STR) {
o = source->parent_module->getStringConstant(str->str_data, true); return makeStr(str->str_data, str->lineno);
} else if (str->str_type == AST_Str::UNICODE) { } else if (str->str_type == AST_Str::UNICODE) {
o = source->parent_module->getUnicodeConstant(str->str_data); Box*& r = unicode_constants[str->str_data];
} else { if (!r) {
RELEASE_ASSERT(0, "%d", str->str_type); r = decodeUTF8StringPtr(str->str_data);
code_constants.addOwnedRef(r);
}
return TmpValue(addConst(r), str->lineno);
} }
RELEASE_ASSERT(0, "%d", str->str_type);
int vreg_const = addConst(o);
return TmpValue(vreg_const, str->lineno);
} }
TmpValue makeNum(int n, int lineno) { TmpValue makeNum(int n, int lineno) {
Box* o = source->parent_module->getIntConstant(n); Box* o = code_constants.getIntConstant(n);
int vreg_const = addConst(o); int vreg_const = addConst(o);
return TmpValue(vreg_const, lineno); return TmpValue(vreg_const, lineno);
} }
...@@ -561,12 +607,6 @@ private: ...@@ -561,12 +607,6 @@ private:
return TmpValue(vreg_const, lineno); return TmpValue(vreg_const, lineno);
} }
TmpValue makeStr(llvm::StringRef str, int lineno = 0) {
Box* o = source->parent_module->getStringConstant(str, true);
int vreg_const = addConst(o);
return TmpValue(vreg_const, lineno);
}
TmpValue applyComprehensionCall(AST_ListComp* node, TmpValue name) { TmpValue applyComprehensionCall(AST_ListComp* node, TmpValue name) {
TmpValue elt = remapExpr(node->elt); TmpValue elt = remapExpr(node->elt);
return makeCallAttr(name, internString("append"), true, { elt }); return makeCallAttr(name, internString("append"), true, { elt });
...@@ -2855,11 +2895,11 @@ public: ...@@ -2855,11 +2895,11 @@ public:
} }
}; };
void CFG::print(const ConstantVRegInfo& constant_vregs, llvm::raw_ostream& stream) { void CFG::print(const CodeConstants& code_constants, llvm::raw_ostream& stream) {
stream << "CFG:\n"; stream << "CFG:\n";
stream << blocks.size() << " blocks\n"; stream << blocks.size() << " blocks\n";
for (int i = 0; i < blocks.size(); i++) for (int i = 0; i < blocks.size(); i++)
blocks[i]->print(constant_vregs, stream); blocks[i]->print(code_constants, stream);
stream.flush(); stream.flush();
} }
...@@ -3047,10 +3087,10 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names, llvm::DenseM ...@@ -3047,10 +3087,10 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names, llvm::DenseM
} }
static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_type, static std::pair<CFG*, CodeConstants> computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_type,
int lineno, AST_arguments* args, BoxedString* filename, int lineno, AST_arguments* args, BoxedString* filename,
SourceInfo* source, const ParamNames& param_names, SourceInfo* source, const ParamNames& param_names, ScopeInfo* scoping,
ScopeInfo* scoping, ModuleCFGProcessor* cfgizer) { ModuleCFGProcessor* cfgizer) {
STAT_TIMER(t0, "us_timer_computecfg", 0); STAT_TIMER(t0, "us_timer_computecfg", 0);
CFG* rtn = new CFG(); CFG* rtn = new CFG();
...@@ -3139,7 +3179,7 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo ...@@ -3139,7 +3179,7 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo
if (VERBOSITY("cfg") >= 3) { if (VERBOSITY("cfg") >= 3) {
printf("Before cfg checking and transformations:\n"); printf("Before cfg checking and transformations:\n");
rtn->print(visitor.constant_vregs); rtn->print(visitor.code_constants);
} }
#ifndef NDEBUG #ifndef NDEBUG
...@@ -3167,7 +3207,7 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo ...@@ -3167,7 +3207,7 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo
if (b->predecessors.size() == 0) { if (b->predecessors.size() == 0) {
if (b != rtn->getStartingBlock()) { if (b != rtn->getStartingBlock()) {
rtn->print(visitor.constant_vregs); rtn->print(visitor.code_constants);
} }
ASSERT(b == rtn->getStartingBlock(), "%d", b->idx); ASSERT(b == rtn->getStartingBlock(), "%d", b->idx);
} }
...@@ -3222,13 +3262,13 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo ...@@ -3222,13 +3262,13 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo
deduped[e]++; deduped[e]++;
if (deduped[e] == 2) { if (deduped[e] == 2) {
printf("Duplicated: "); printf("Duplicated: ");
print_bst(e, visitor.constant_vregs); print_bst(e, visitor.code_constants);
printf("\n"); printf("\n");
no_dups = false; no_dups = false;
} }
} }
if (!no_dups) if (!no_dups)
rtn->print(visitor.constant_vregs); rtn->print(visitor.code_constants);
assert(no_dups); assert(no_dups);
// Uncomment this for some heavy checking to make sure that we don't forget // Uncomment this for some heavy checking to make sure that we don't forget
...@@ -3331,10 +3371,10 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo ...@@ -3331,10 +3371,10 @@ static std::pair<CFG*, ConstantVRegInfo> computeCFG(llvm::ArrayRef<AST_stmt*> bo
if (VERBOSITY("cfg") >= 2) { if (VERBOSITY("cfg") >= 2) {
printf("Final cfg:\n"); printf("Final cfg:\n");
rtn->print(visitor.constant_vregs, llvm::outs()); rtn->print(visitor.code_constants, llvm::outs());
} }
return std::make_pair(rtn, visitor.constant_vregs); return std::make_pair(rtn, std::move(visitor.code_constants));
} }
...@@ -3381,17 +3421,17 @@ BoxedCode* ModuleCFGProcessor::runRecursively(llvm::ArrayRef<AST_stmt*> body, Bo ...@@ -3381,17 +3421,17 @@ BoxedCode* ModuleCFGProcessor::runRecursively(llvm::ArrayRef<AST_stmt*> body, Bo
for (auto e : param_names.allArgsAsName()) for (auto e : param_names.allArgsAsName())
fillScopingInfo(e, scope_info); fillScopingInfo(e, scope_info);
ConstantVRegInfo constant_vregs; CodeConstants code_constants;
std::tie(si->cfg, constant_vregs) std::tie(si->cfg, code_constants)
= computeCFG(body, ast_type, lineno, args, fn, si.get(), param_names, scope_info, this); = computeCFG(body, ast_type, lineno, args, fn, si.get(), param_names, scope_info, this);
BoxedCode* code; BoxedCode* code;
if (args) if (args)
code = new BoxedCode(args->args.size(), args->vararg, args->kwarg, lineno, std::move(si), code = new BoxedCode(args->args.size(), args->vararg, args->kwarg, lineno, std::move(si),
std::move(constant_vregs), std::move(param_names), fn, name, std::move(code_constants), std::move(param_names), fn, name,
autoDecref(getDocString(body))); autoDecref(getDocString(body)));
else else
code = new BoxedCode(0, false, false, lineno, std::move(si), std::move(constant_vregs), std::move(param_names), code = new BoxedCode(0, false, false, lineno, std::move(si), std::move(code_constants), std::move(param_names),
fn, name, autoDecref(getDocString(body))); fn, name, autoDecref(getDocString(body)));
return code; return code;
...@@ -3403,7 +3443,7 @@ BoxedCode* computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future ...@@ -3403,7 +3443,7 @@ BoxedCode* computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future
.runRecursively(ast->getBody(), ast->getName(), ast->lineno, nullptr, ast); .runRecursively(ast->getBody(), ast->getName(), ast->lineno, nullptr, ast);
} }
void printCFG(CFG* cfg, const ConstantVRegInfo& constant_vregs) { void printCFG(CFG* cfg, const CodeConstants& code_constants) {
cfg->print(constant_vregs); cfg->print(code_constants);
} }
} }
...@@ -88,7 +88,7 @@ public: ...@@ -88,7 +88,7 @@ public:
void unconnectFrom(CFGBlock* successor); void unconnectFrom(CFGBlock* successor);
void push_back(BST_stmt* node) { body.push_back(node); } void push_back(BST_stmt* node) { body.push_back(node); }
void print(const ConstantVRegInfo& constant_vregs, llvm::raw_ostream& stream = llvm::outs()); void print(const CodeConstants& code_constants, llvm::raw_ostream& stream = llvm::outs());
}; };
// the vregs are split into three parts. // the vregs are split into three parts.
...@@ -210,7 +210,7 @@ public: ...@@ -210,7 +210,7 @@ public:
blocks.push_back(block); blocks.push_back(block);
} }
void print(const ConstantVRegInfo& constant_vregs, llvm::raw_ostream& stream = llvm::outs()); void print(const CodeConstants& code_constants, llvm::raw_ostream& stream = llvm::outs());
}; };
class VRegSet { class VRegSet {
...@@ -331,7 +331,7 @@ public: ...@@ -331,7 +331,7 @@ public:
BoxedCode* computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn, BoxedCode* computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn,
BoxedModule* bm); BoxedModule* bm);
void printCFG(CFG* cfg, const ConstantVRegInfo& constant_vregs); void printCFG(CFG* cfg, const CodeConstants& code_constants);
} }
#endif #endif
...@@ -107,16 +107,18 @@ void BoxedCode::dealloc(Box* b) noexcept { ...@@ -107,16 +107,18 @@ void BoxedCode::dealloc(Box* b) noexcept {
Py_XDECREF(o->name); Py_XDECREF(o->name);
Py_XDECREF(o->_doc); Py_XDECREF(o->_doc);
o->tryDeallocatingTheBJitCode();
o->source.reset(nullptr); o->source.reset(nullptr);
o->~BoxedCode();
o->cls->tp_free(o); o->cls->tp_free(o);
} }
BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, int firstlineno, BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, int firstlineno,
std::unique_ptr<SourceInfo> source, ConstantVRegInfo constant_vregs, ParamNames param_names, std::unique_ptr<SourceInfo> source, CodeConstants code_constants, ParamNames param_names,
BoxedString* filename, BoxedString* name, Box* doc) BoxedString* filename, BoxedString* name, Box* doc)
: source(std::move(source)), : source(std::move(source)),
constant_vregs(std::move(constant_vregs)), code_constants(std::move(code_constants)),
filename(incref(filename)), filename(incref(filename)),
name(incref(name)), name(incref(name)),
firstlineno(firstlineno), firstlineno(firstlineno),
......
...@@ -480,68 +480,6 @@ std::string BoxedModule::name() { ...@@ -480,68 +480,6 @@ std::string BoxedModule::name() {
} }
} }
BORROWED(BoxedString*) BoxedModule::getStringConstant(llvm::StringRef ast_str, bool intern) {
BoxedString*& r = str_constants[ast_str];
if (intern) {
// If we had previously created a box for this string, we have to create a new
// string (or at least, be prepared to return a different value that we had already
// interned). This is fine, except we have to be careful because we promised
// that we would keep the previously-created string alive.
// So, make sure to put it onto the keep_alive list.
if (r && !PyString_CHECK_INTERNED(r)) {
RELEASE_ASSERT(0, "this codepath has been dead for a little while, make sure it still works");
keep_alive.push_back(r);
r = NULL;
}
if (!r)
r = internStringMortal(ast_str);
} else if (!r)
r = boxString(ast_str);
return r;
}
BORROWED(Box*) BoxedModule::getUnicodeConstant(llvm::StringRef ast_str) {
Box*& r = unicode_constants[ast_str];
if (!r)
r = decodeUTF8StringPtr(ast_str);
return r;
}
BORROWED(BoxedInt*) BoxedModule::getIntConstant(int64_t n) {
BoxedInt*& r = int_constants[n];
if (!r)
r = (BoxedInt*)boxInt(n);
return r;
}
static int64_t getDoubleBits(double d) {
int64_t rtn;
static_assert(sizeof(rtn) == sizeof(d), "");
memcpy(&rtn, &d, sizeof(d));
return rtn;
}
BORROWED(BoxedFloat*) BoxedModule::getFloatConstant(double d) {
BoxedFloat*& r = float_constants[getDoubleBits(d)];
if (!r)
r = static_cast<BoxedFloat*>(boxFloat(d));
return r;
}
BORROWED(Box*) BoxedModule::getPureImaginaryConstant(double d) {
Box*& r = imaginary_constants[getDoubleBits(d)];
if (!r)
r = createPureImaginary(d);
return r;
}
BORROWED(Box*) BoxedModule::getLongConstant(llvm::StringRef ast_str) {
Box*& r = long_constants[ast_str];
if (!r)
r = createLong(ast_str);
return r;
}
// This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers / // This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers /
// finally-blocks in scope. // finally-blocks in scope.
extern "C" Box* createFunctionFromMetadata(BoxedCode* code, BoxedClosure* closure, Box* globals, extern "C" Box* createFunctionFromMetadata(BoxedCode* code, BoxedClosure* closure, Box* globals,
...@@ -3817,21 +3755,12 @@ void BoxedModule::dealloc(Box* b) noexcept { ...@@ -3817,21 +3755,12 @@ void BoxedModule::dealloc(Box* b) noexcept {
BoxedModule::clear(self); BoxedModule::clear(self);
self->str_constants.~ContiguousMap();
self->unicode_constants.~ContiguousMap();
self->int_constants.~ContiguousMap();
self->float_constants.~ContiguousMap();
self->imaginary_constants.~ContiguousMap();
self->long_constants.~ContiguousMap();
assert(!self->keep_alive.size());
b->cls->tp_free(self); b->cls->tp_free(self);
} }
int BoxedModule::traverse(Box* _m, visitproc visit, void* arg) noexcept { int BoxedModule::traverse(Box* _m, visitproc visit, void* arg) noexcept {
BoxedModule* m = static_cast<BoxedModule*>(_m); BoxedModule* m = static_cast<BoxedModule*>(_m);
Py_TRAVERSE(m->attrs); Py_TRAVERSE(m->attrs);
assert(!m->keep_alive.size());
return 0; return 0;
} }
...@@ -3849,15 +3778,6 @@ extern "C" void _PyModule_Clear(PyObject* b) noexcept { ...@@ -3849,15 +3778,6 @@ extern "C" void _PyModule_Clear(PyObject* b) noexcept {
HCAttrs* attrs = self->getHCAttrsPtr(); HCAttrs* attrs = self->getHCAttrsPtr();
attrs->moduleClear(); attrs->moduleClear();
clearContiguousMap(self->str_constants);
clearContiguousMap(self->unicode_constants);
clearContiguousMap(self->int_constants);
clearContiguousMap(self->float_constants);
clearContiguousMap(self->imaginary_constants);
clearContiguousMap(self->long_constants);
assert(!self->keep_alive.size());
} }
int BoxedModule::clear(Box* b) noexcept { int BoxedModule::clear(Box* b) noexcept {
...@@ -4102,6 +4022,33 @@ int BoxedClosure::clear(Box* _o) noexcept { ...@@ -4102,6 +4022,33 @@ int BoxedClosure::clear(Box* _o) noexcept {
return 0; return 0;
} }
BORROWED(BoxedInt*) CodeConstants::getIntConstant(int64_t n) const {
BoxedInt*& r = int_constants[n];
if (!r) {
r = (BoxedInt*)boxInt(n);
addOwnedRef(r);
}
return r;
}
BORROWED(BoxedFloat*) CodeConstants::getFloatConstant(double d) const {
int64_t double_as_int64;
static_assert(sizeof(double_as_int64) == sizeof(d), "");
memcpy(&double_as_int64, &d, sizeof(d));
BoxedFloat*& r = float_constants[double_as_int64];
if (!r) {
r = (BoxedFloat*)boxFloat(d);
addOwnedRef(r);
}
return r;
}
void CodeConstants::dealloc() const {
decrefArray(owned_refs.data(), owned_refs.size());
owned_refs.clear();
}
#ifndef Py_REF_DEBUG #ifndef Py_REF_DEBUG
#define PRINT_TOTAL_REFS() #define PRINT_TOTAL_REFS()
#else /* Py_REF_DEBUG */ #else /* Py_REF_DEBUG */
......
...@@ -1070,20 +1070,42 @@ public: ...@@ -1070,20 +1070,42 @@ public:
}; };
static_assert(sizeof(BoxedDict) == sizeof(PyDictObject), ""); static_assert(sizeof(BoxedDict) == sizeof(PyDictObject), "");
class ConstantVRegInfo { class CodeConstants {
private: private:
// stores all constants accessible by vregs in the corrext order
// constants[-(vreg + 1)] will allow one to retrieve the constant for a vreg
std::vector<Box*> constants; std::vector<Box*> constants;
// all objects we need to decref when the code object dies
mutable std::vector<Box*> owned_refs;
// Note: DenseMap doesn't work here since we don't prevent the tombstone/empty
// keys from reaching it.
mutable std::unordered_map<int64_t, BoxedInt*> int_constants;
// I'm not sure how well it works to use doubles as hashtable keys; thankfully
// it's not a big deal if we get misses.
mutable std::unordered_map<int64_t, BoxedFloat*> float_constants;
public: public:
ConstantVRegInfo(){}; CodeConstants() {}
CodeConstants(CodeConstants&&) = default;
CodeConstants& operator=(CodeConstants&&) = default;
~CodeConstants() { dealloc(); }
Box* getConstant(int vreg) const { return constants[-(vreg + 1)]; } BORROWED(Box*) getConstant(int vreg) const { return constants[-(vreg + 1)]; }
// returns the vreg num for the constant (which is a negative number) // returns the vreg num for the constant (which is a negative number)
int addConstant(Box* o) { int createVRegEntryForConstant(Box* o) {
constants.push_back(o); constants.push_back(o);
return -constants.size(); return -constants.size();
} }
void addOwnedRef(Box* o) const { owned_refs.emplace_back(o); }
BORROWED(BoxedInt*) getIntConstant(int64_t n) const;
BORROWED(BoxedFloat*) getFloatConstant(double d) const;
void dealloc() const;
}; };
...@@ -1095,8 +1117,8 @@ public: ...@@ -1095,8 +1117,8 @@ public:
// BoxedCode objects also keep track of any machine code that we have available for this function. // BoxedCode objects also keep track of any machine code that we have available for this function.
class BoxedCode : public Box { class BoxedCode : public Box {
public: public:
std::unique_ptr<SourceInfo> source; // source can be NULL for functions defined in the C/C++ runtime std::unique_ptr<SourceInfo> source; // source can be NULL for functions defined in the C/C++ runtime
const ConstantVRegInfo BORROWED(constant_vregs); // keeps track of all constants inside the bytecode const CodeConstants BORROWED(code_constants); // keeps track of all constants inside the bytecode
BoxedString* filename = nullptr; BoxedString* filename = nullptr;
BoxedString* name = nullptr; BoxedString* name = nullptr;
...@@ -1135,8 +1157,7 @@ public: ...@@ -1135,8 +1157,7 @@ public:
// Constructor for Python code objects: // Constructor for Python code objects:
BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, int firstlineno, std::unique_ptr<SourceInfo> source, BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, int firstlineno, std::unique_ptr<SourceInfo> source,
ConstantVRegInfo constant_vregs, ParamNames param_names, BoxedString* filename, BoxedString* name, CodeConstants code_constants, ParamNames param_names, BoxedString* filename, BoxedString* name, Box* doc);
Box* doc);
// Constructor for code objects created by the runtime: // Constructor for code objects created by the runtime:
BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const char* name, const char* doc = "", BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const char* name, const char* doc = "",
......
...@@ -254,7 +254,7 @@ extern "C" void dumpEx(void* p, int levels) { ...@@ -254,7 +254,7 @@ extern "C" void dumpEx(void* p, int levels) {
printf("Defined at %s:%d\n", code->filename->c_str(), code->firstlineno); printf("Defined at %s:%d\n", code->filename->c_str(), code->firstlineno);
if (code->source->cfg && levels > 0) { if (code->source->cfg && levels > 0) {
code->source->cfg->print(code->constant_vregs); code->source->cfg->print(code->code_constants);
} }
} else { } else {
printf("A builtin function\n"); printf("A builtin function\n");
......
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