Commit f09ceff0 authored by Marius Wachtler's avatar Marius Wachtler

LLVM tier: adjust num of IC slots depending on the num of times the IC got...

LLVM tier: adjust num of IC slots depending on the num of times the IC got rewritten in the bjit tier
parent c380bbc0
...@@ -367,4 +367,16 @@ void ICInfo::visitGCReferences(gc::GCVisitor* v) { ...@@ -367,4 +367,16 @@ void ICInfo::visitGCReferences(gc::GCVisitor* v) {
} }
#endif #endif
} }
static llvm::DenseMap<AST*, ICInfo*> ics_by_ast_node;
ICInfo* ICInfo::getICInfoForNode(AST* node) {
auto&& it = ics_by_ast_node.find(node);
if (it != ics_by_ast_node.end())
return it->second;
return NULL;
}
void ICInfo::associateNodeWithICInfo(AST* node) {
ics_by_ast_node[node] = this;
}
} }
...@@ -147,9 +147,13 @@ public: ...@@ -147,9 +147,13 @@ public:
// For use of the rewriter for computing aggressiveness: // For use of the rewriter for computing aggressiveness:
int percentMegamorphic() const { return times_rewritten * 100 / IC_MEGAMORPHIC_THRESHOLD; } int percentMegamorphic() const { return times_rewritten * 100 / IC_MEGAMORPHIC_THRESHOLD; }
int percentBackedoff() const { return retry_backoff; } int percentBackedoff() const { return retry_backoff; }
int timesRewritten() const { return times_rewritten; }
friend class ICSlotRewrite; friend class ICSlotRewrite;
static void visitGCReferences(gc::GCVisitor* visitor); static void visitGCReferences(gc::GCVisitor* visitor);
static ICInfo* getICInfoForNode(AST* node);
void associateNodeWithICInfo(AST* node);
}; };
void registerGCTrackedICInfo(ICInfo* ic); void registerGCTrackedICInfo(ICInfo* ic);
......
...@@ -318,7 +318,7 @@ public: ...@@ -318,7 +318,7 @@ public:
class RewriterAction { class RewriterAction {
public: public:
SmallFunction<48> action; SmallFunction<56> action;
template <typename F> RewriterAction(F&& action) : action(std::forward<F>(action)) {} template <typename F> RewriterAction(F&& action) : action(std::forward<F>(action)) {}
......
...@@ -75,7 +75,7 @@ public: ...@@ -75,7 +75,7 @@ public:
private: private:
Value createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body); Value createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body);
Value doBinOp(Value left, Value right, int op, BinExpType exp_type); Value doBinOp(AST_expr* node, Value left, Value right, int op, BinExpType exp_type);
void doStore(AST_expr* node, Value value); void doStore(AST_expr* node, Value value);
void doStore(AST_Name* name, Value value); void doStore(AST_Name* name, Value value);
Box* doOSR(AST_Jump* node); Box* doOSR(AST_Jump* node);
...@@ -421,14 +421,14 @@ Box* ASTInterpreter::execute(ASTInterpreter& interpreter, CFGBlock* start_block, ...@@ -421,14 +421,14 @@ Box* ASTInterpreter::execute(ASTInterpreter& interpreter, CFGBlock* start_block,
return executeInnerAndSetupFrame(interpreter, start_block, start_at); return executeInnerAndSetupFrame(interpreter, start_block, start_at);
} }
Value ASTInterpreter::doBinOp(Value left, Value right, int op, BinExpType exp_type) { Value ASTInterpreter::doBinOp(AST_expr* node, Value left, Value right, int op, BinExpType exp_type) {
switch (exp_type) { switch (exp_type) {
case BinExpType::AugBinOp: case BinExpType::AugBinOp:
return Value(augbinop(left.o, right.o, op), jit ? jit->emitAugbinop(left, right, op) : NULL); return Value(augbinop(left.o, right.o, op), jit ? jit->emitAugbinop(node, left, right, op) : NULL);
case BinExpType::BinOp: case BinExpType::BinOp:
return Value(binop(left.o, right.o, op), jit ? jit->emitBinop(left, right, op) : NULL); return Value(binop(left.o, right.o, op), jit ? jit->emitBinop(node, left, right, op) : NULL);
case BinExpType::Compare: case BinExpType::Compare:
return Value(compare(left.o, right.o, op), jit ? jit->emitCompare(left, right, op) : NULL); return Value(compare(left.o, right.o, op), jit ? jit->emitCompare(node, left, right, op) : NULL);
default: default:
RELEASE_ASSERT(0, "not implemented"); RELEASE_ASSERT(0, "not implemented");
} }
...@@ -483,7 +483,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) { ...@@ -483,7 +483,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) {
AST_Attribute* attr = (AST_Attribute*)node; AST_Attribute* attr = (AST_Attribute*)node;
Value o = visit_expr(attr->value); Value o = visit_expr(attr->value);
if (jit) if (jit)
jit->emitSetAttr(o, attr->attr.getBox(), value); jit->emitSetAttr(node, o, attr->attr.getBox(), value);
pyston::setattr(o.o, attr->attr.getBox(), value.o); pyston::setattr(o.o, attr->attr.getBox(), value.o);
} else if (node->type == AST_TYPE::Tuple) { } else if (node->type == AST_TYPE::Tuple) {
AST_Tuple* tuple = (AST_Tuple*)node; AST_Tuple* tuple = (AST_Tuple*)node;
...@@ -540,7 +540,7 @@ Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) { ...@@ -540,7 +540,7 @@ Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) {
Value ASTInterpreter::visit_binop(AST_BinOp* node) { Value ASTInterpreter::visit_binop(AST_BinOp* node) {
Value left = visit_expr(node->left); Value left = visit_expr(node->left);
Value right = visit_expr(node->right); Value right = visit_expr(node->right);
return doBinOp(left, right, node->op_type, BinExpType::BinOp); return doBinOp(node, left, right, node->op_type, BinExpType::BinOp);
} }
Value ASTInterpreter::visit_slice(AST_slice* node) { Value ASTInterpreter::visit_slice(AST_slice* node) {
...@@ -816,7 +816,7 @@ Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* node) { ...@@ -816,7 +816,7 @@ Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* node) {
Value left = visit_expr(node->left); Value left = visit_expr(node->left);
Value right = visit_expr(node->right); Value right = visit_expr(node->right);
return doBinOp(left, right, node->op_type, BinExpType::AugBinOp); return doBinOp(node, left, right, node->op_type, BinExpType::AugBinOp);
} }
Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
...@@ -1276,7 +1276,7 @@ Value ASTInterpreter::visit_compare(AST_Compare* node) { ...@@ -1276,7 +1276,7 @@ Value ASTInterpreter::visit_compare(AST_Compare* node) {
RELEASE_ASSERT(node->comparators.size() == 1, "not implemented"); RELEASE_ASSERT(node->comparators.size() == 1, "not implemented");
Value left = visit_expr(node->left); Value left = visit_expr(node->left);
Value right = visit_expr(node->comparators[0]); Value right = visit_expr(node->comparators[0]);
return doBinOp(left, right, node->ops[0], BinExpType::Compare); return doBinOp(node, left, right, node->ops[0], BinExpType::Compare);
} }
Value ASTInterpreter::visit_expr(AST_expr* node) { Value ASTInterpreter::visit_expr(AST_expr* node) {
...@@ -1553,7 +1553,7 @@ Value ASTInterpreter::visit_subscript(AST_Subscript* node) { ...@@ -1553,7 +1553,7 @@ Value ASTInterpreter::visit_subscript(AST_Subscript* node) {
Value value = visit_expr(node->value); Value value = visit_expr(node->value);
Value slice = visit_slice(node->slice); Value slice = visit_slice(node->slice);
return Value(getitem(value.o, slice.o), jit ? jit->emitGetItem(value, slice) : NULL); return Value(getitem(value.o, slice.o), jit ? jit->emitGetItem(node, value, slice) : NULL);
} }
Value ASTInterpreter::visit_list(AST_List* node) { Value ASTInterpreter::visit_list(AST_List* node) {
......
...@@ -162,12 +162,12 @@ RewriterVar* JitFragmentWriter::imm(void* val) { ...@@ -162,12 +162,12 @@ RewriterVar* JitFragmentWriter::imm(void* val) {
return loadConst((uint64_t)val); return loadConst((uint64_t)val);
} }
RewriterVar* JitFragmentWriter::emitAugbinop(RewriterVar* lhs, RewriterVar* rhs, int op_type) { RewriterVar* JitFragmentWriter::emitAugbinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) {
return emitPPCall((void*)augbinop, { lhs, rhs, imm(op_type) }, 2, 320); return emitPPCall((void*)augbinop, { lhs, rhs, imm(op_type) }, 2, 320, node);
} }
RewriterVar* JitFragmentWriter::emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type) { RewriterVar* JitFragmentWriter::emitBinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) {
return emitPPCall((void*)binop, { lhs, rhs, imm(op_type) }, 2, 240); return emitPPCall((void*)binop, { lhs, rhs, imm(op_type) }, 2, 240, node);
} }
RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags, RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
...@@ -198,7 +198,7 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B ...@@ -198,7 +198,7 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B
if (keyword_names) if (keyword_names)
call_args.push_back(imm(keyword_names)); call_args.push_back(imm(keyword_names));
return emitPPCall((void*)callattr, call_args, 2, 640, type_recorder); return emitPPCall((void*)callattr, call_args, 2, 640, node, type_recorder);
#else #else
// We could make this faster but for now: keep it simple, stupid... // We could make this faster but for now: keep it simple, stupid...
RewriterVar* attr_var = imm(attr); RewriterVar* attr_var = imm(attr);
...@@ -227,9 +227,9 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B ...@@ -227,9 +227,9 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B
#endif #endif
} }
RewriterVar* JitFragmentWriter::emitCompare(RewriterVar* lhs, RewriterVar* rhs, int op_type) { RewriterVar* JitFragmentWriter::emitCompare(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) {
// TODO: can directly emit the assembly for Is/IsNot // TODO: can directly emit the assembly for Is/IsNot
return emitPPCall((void*)compare, { lhs, rhs, imm(op_type) }, 2, 240); return emitPPCall((void*)compare, { lhs, rhs, imm(op_type) }, 2, 240, node);
} }
RewriterVar* JitFragmentWriter::emitCreateDict(const llvm::ArrayRef<RewriterVar*> keys, RewriterVar* JitFragmentWriter::emitCreateDict(const llvm::ArrayRef<RewriterVar*> keys,
...@@ -289,7 +289,7 @@ RewriterVar* JitFragmentWriter::emitExceptionMatches(RewriterVar* v, RewriterVar ...@@ -289,7 +289,7 @@ RewriterVar* JitFragmentWriter::emitExceptionMatches(RewriterVar* v, RewriterVar
} }
RewriterVar* JitFragmentWriter::emitGetAttr(RewriterVar* obj, BoxedString* s, AST_expr* node) { RewriterVar* JitFragmentWriter::emitGetAttr(RewriterVar* obj, BoxedString* s, AST_expr* node) {
return emitPPCall((void*)getattr, { obj, imm(s) }, 2, 512, getTypeRecorderForNode(node)); return emitPPCall((void*)getattr, { obj, imm(s) }, 2, 512, node, getTypeRecorderForNode(node));
} }
RewriterVar* JitFragmentWriter::emitGetBlockLocal(InternedString s, int vreg) { RewriterVar* JitFragmentWriter::emitGetBlockLocal(InternedString s, int vreg) {
...@@ -319,8 +319,8 @@ RewriterVar* JitFragmentWriter::emitGetGlobal(Box* global, BoxedString* s) { ...@@ -319,8 +319,8 @@ RewriterVar* JitFragmentWriter::emitGetGlobal(Box* global, BoxedString* s) {
return emitPPCall((void*)getGlobal, { imm(global), imm(s) }, 2, 512); return emitPPCall((void*)getGlobal, { imm(global), imm(s) }, 2, 512);
} }
RewriterVar* JitFragmentWriter::emitGetItem(RewriterVar* value, RewriterVar* slice) { RewriterVar* JitFragmentWriter::emitGetItem(AST_expr* node, RewriterVar* value, RewriterVar* slice) {
return emitPPCall((void*)getitem, { value, slice }, 2, 512); return emitPPCall((void*)getitem, { value, slice }, 2, 512, node);
} }
RewriterVar* JitFragmentWriter::emitGetLocal(InternedString s, int vreg) { RewriterVar* JitFragmentWriter::emitGetLocal(InternedString s, int vreg) {
...@@ -392,7 +392,7 @@ RewriterVar* JitFragmentWriter::emitRuntimeCall(AST_expr* node, RewriterVar* obj ...@@ -392,7 +392,7 @@ RewriterVar* JitFragmentWriter::emitRuntimeCall(AST_expr* node, RewriterVar* obj
if (keyword_names) if (keyword_names)
call_args.push_back(imm(keyword_names)); call_args.push_back(imm(keyword_names));
return emitPPCall((void*)runtimeCall, call_args, 2, 640, type_recorder); return emitPPCall((void*)runtimeCall, call_args, 2, 640, node, type_recorder);
#else #else
RewriterVar* argspec_var = imm(argspec.asInt()); RewriterVar* argspec_var = imm(argspec.asInt());
RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr; RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr;
...@@ -491,8 +491,8 @@ void JitFragmentWriter::emitReturn(RewriterVar* v) { ...@@ -491,8 +491,8 @@ void JitFragmentWriter::emitReturn(RewriterVar* v) {
addAction([=]() { _emitReturn(v); }, { v }, ActionType::NORMAL); addAction([=]() { _emitReturn(v); }, { v }, ActionType::NORMAL);
} }
void JitFragmentWriter::emitSetAttr(RewriterVar* obj, BoxedString* s, RewriterVar* attr) { void JitFragmentWriter::emitSetAttr(AST_expr* node, RewriterVar* obj, BoxedString* s, RewriterVar* attr) {
emitPPCall((void*)setattr, { obj, imm(s), attr }, 2, 512); emitPPCall((void*)setattr, { obj, imm(s), attr }, 2, 512, node);
} }
void JitFragmentWriter::emitSetBlockLocal(InternedString s, RewriterVar* v) { void JitFragmentWriter::emitSetBlockLocal(InternedString s, RewriterVar* v) {
...@@ -619,6 +619,7 @@ int JitFragmentWriter::finishCompilation() { ...@@ -619,6 +619,7 @@ int JitFragmentWriter::finishCompilation() {
std::unique_ptr<ICInfo> pp std::unique_ptr<ICInfo> pp
= registerCompiledPatchpoint(start_addr, slowpath_start, initialization_info.continue_addr, = registerCompiledPatchpoint(start_addr, slowpath_start, initialization_info.continue_addr,
slowpath_rtn_addr, pp_info.ic.get(), pp_info.stack_info, LiveOutSet()); slowpath_rtn_addr, pp_info.ic.get(), pp_info.stack_info, LiveOutSet());
pp->associateNodeWithICInfo(pp_info.node);
pp.release(); pp.release();
} }
...@@ -673,7 +674,7 @@ uint64_t JitFragmentWriter::asUInt(InternedString s) { ...@@ -673,7 +674,7 @@ uint64_t JitFragmentWriter::asUInt(InternedString s) {
#endif #endif
RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots,
int slot_size, TypeRecorder* type_recorder) { int slot_size, AST* ast_node, TypeRecorder* type_recorder) {
RewriterVar::SmallVector args_vec(args.begin(), args.end()); RewriterVar::SmallVector args_vec(args.begin(), args.end());
#if ENABLE_BASELINEJIT_ICS #if ENABLE_BASELINEJIT_ICS
RewriterVar* result = createNewVar(); RewriterVar* result = createNewVar();
...@@ -683,7 +684,8 @@ RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<Rewri ...@@ -683,7 +684,8 @@ RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<Rewri
memcpy(_args, args.begin(), sizeof(RewriterVar*) * args_size); memcpy(_args, args.begin(), sizeof(RewriterVar*) * args_size);
addAction([=]() { addAction([=]() {
this->_emitPPCall(result, func_addr, llvm::ArrayRef<RewriterVar*>(_args, args_size), num_slots, slot_size); this->_emitPPCall(result, func_addr, llvm::ArrayRef<RewriterVar*>(_args, args_size), num_slots, slot_size,
ast_node);
}, args, ActionType::NORMAL); }, args, ActionType::NORMAL);
if (type_recorder) { if (type_recorder) {
...@@ -830,7 +832,7 @@ void JitFragmentWriter::_emitOSRPoint(RewriterVar* result, RewriterVar* node_var ...@@ -830,7 +832,7 @@ void JitFragmentWriter::_emitOSRPoint(RewriterVar* result, RewriterVar* node_var
} }
void JitFragmentWriter::_emitPPCall(RewriterVar* result, void* func_addr, llvm::ArrayRef<RewriterVar*> args, void JitFragmentWriter::_emitPPCall(RewriterVar* result, void* func_addr, llvm::ArrayRef<RewriterVar*> args,
int num_slots, int slot_size) { int num_slots, int slot_size, AST* ast_node) {
assembler::Register r = allocReg(assembler::R11); assembler::Register r = allocReg(assembler::R11);
if (args.size() > 6) { // only 6 args can get passed in registers. if (args.size() > 6) { // only 6 args can get passed in registers.
...@@ -882,7 +884,7 @@ void JitFragmentWriter::_emitPPCall(RewriterVar* result, void* func_addr, llvm:: ...@@ -882,7 +884,7 @@ void JitFragmentWriter::_emitPPCall(RewriterVar* result, void* func_addr, llvm::
assertConsistent(); assertConsistent();
StackInfo stack_info(pp_scratch_size, pp_scratch_location); StackInfo stack_info(pp_scratch_size, pp_scratch_location);
pp_infos.emplace_back(PPInfo{ func_addr, pp_start, pp_end, std::move(setup_info), stack_info }); pp_infos.emplace_back(PPInfo{ func_addr, pp_start, pp_end, std::move(setup_info), stack_info, ast_node });
assert(vars_by_location.count(assembler::RAX) == 0); assert(vars_by_location.count(assembler::RAX) == 0);
result->initializeInReg(assembler::RAX); result->initializeInReg(assembler::RAX);
......
...@@ -191,6 +191,7 @@ private: ...@@ -191,6 +191,7 @@ private:
uint8_t* end_addr; uint8_t* end_addr;
std::unique_ptr<ICSetupInfo> ic; std::unique_ptr<ICSetupInfo> ic;
StackInfo stack_info; StackInfo stack_info;
AST* node;
}; };
llvm::SmallVector<PPInfo, 8> pp_infos; llvm::SmallVector<PPInfo, 8> pp_infos;
...@@ -203,11 +204,11 @@ public: ...@@ -203,11 +204,11 @@ public:
RewriterVar* imm(uint64_t val); RewriterVar* imm(uint64_t val);
RewriterVar* imm(void* val); RewriterVar* imm(void* val);
RewriterVar* emitAugbinop(RewriterVar* lhs, RewriterVar* rhs, int op_type); RewriterVar* emitAugbinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type); RewriterVar* emitBinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags, RewriterVar* emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names); const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names);
RewriterVar* emitCompare(RewriterVar* lhs, RewriterVar* rhs, int op_type); RewriterVar* emitCompare(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitCreateDict(const llvm::ArrayRef<RewriterVar*> keys, const llvm::ArrayRef<RewriterVar*> values); RewriterVar* emitCreateDict(const llvm::ArrayRef<RewriterVar*> keys, const llvm::ArrayRef<RewriterVar*> values);
RewriterVar* emitCreateList(const llvm::ArrayRef<RewriterVar*> values); RewriterVar* emitCreateList(const llvm::ArrayRef<RewriterVar*> values);
RewriterVar* emitCreateSet(const llvm::ArrayRef<RewriterVar*> values); RewriterVar* emitCreateSet(const llvm::ArrayRef<RewriterVar*> values);
...@@ -221,7 +222,7 @@ public: ...@@ -221,7 +222,7 @@ public:
RewriterVar* emitGetBoxedLocals(); RewriterVar* emitGetBoxedLocals();
RewriterVar* emitGetClsAttr(RewriterVar* obj, BoxedString* s); RewriterVar* emitGetClsAttr(RewriterVar* obj, BoxedString* s);
RewriterVar* emitGetGlobal(Box* global, BoxedString* s); RewriterVar* emitGetGlobal(Box* global, BoxedString* s);
RewriterVar* emitGetItem(RewriterVar* value, RewriterVar* slice); RewriterVar* emitGetItem(AST_expr* node, RewriterVar* value, RewriterVar* slice);
RewriterVar* emitGetLocal(InternedString s, int vreg); RewriterVar* emitGetLocal(InternedString s, int vreg);
RewriterVar* emitGetPystonIter(RewriterVar* v); RewriterVar* emitGetPystonIter(RewriterVar* v);
RewriterVar* emitHasnext(RewriterVar* v); RewriterVar* emitHasnext(RewriterVar* v);
...@@ -249,7 +250,7 @@ public: ...@@ -249,7 +250,7 @@ public:
void emitRaise0(); void emitRaise0();
void emitRaise3(RewriterVar* arg0, RewriterVar* arg1, RewriterVar* arg2); void emitRaise3(RewriterVar* arg0, RewriterVar* arg1, RewriterVar* arg2);
void emitReturn(RewriterVar* v); void emitReturn(RewriterVar* v);
void emitSetAttr(RewriterVar* obj, BoxedString* s, RewriterVar* attr); void emitSetAttr(AST_expr* node, RewriterVar* obj, BoxedString* s, RewriterVar* attr);
void emitSetBlockLocal(InternedString s, RewriterVar* v); void emitSetBlockLocal(InternedString s, RewriterVar* v);
void emitSetCurrentInst(AST_stmt* node); void emitSetCurrentInst(AST_stmt* node);
void emitSetExcInfo(RewriterVar* type, RewriterVar* value, RewriterVar* traceback); void emitSetExcInfo(RewriterVar* type, RewriterVar* value, RewriterVar* traceback);
...@@ -274,7 +275,7 @@ private: ...@@ -274,7 +275,7 @@ private:
#endif #endif
RewriterVar* emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, int slot_size, RewriterVar* emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, int slot_size,
TypeRecorder* type_recorder = NULL); AST* ast_node = NULL, TypeRecorder* type_recorder = NULL);
static void assertNameDefinedHelper(const char* id); static void assertNameDefinedHelper(const char* id);
static Box* callattrHelper(Box* obj, BoxedString* attr, CallattrFlags flags, TypeRecorder* type_recorder, static Box* callattrHelper(Box* obj, BoxedString* attr, CallattrFlags flags, TypeRecorder* type_recorder,
...@@ -294,7 +295,7 @@ private: ...@@ -294,7 +295,7 @@ private:
void _emitJump(CFGBlock* b, RewriterVar* block_next, int& size_of_exit_to_interp); void _emitJump(CFGBlock* b, RewriterVar* block_next, int& size_of_exit_to_interp);
void _emitOSRPoint(RewriterVar* result, RewriterVar* node_var); void _emitOSRPoint(RewriterVar* result, RewriterVar* node_var);
void _emitPPCall(RewriterVar* result, void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, void _emitPPCall(RewriterVar* result, void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots,
int slot_size); int slot_size, AST* ast_node);
void _emitRecordType(RewriterVar* type_recorder_var, RewriterVar* obj_cls_var); void _emitRecordType(RewriterVar* type_recorder_var, RewriterVar* obj_cls_var);
void _emitReturn(RewriterVar* v); void _emitReturn(RewriterVar* v);
void _emitSideExit(RewriterVar* var, RewriterVar* val_constant, CFGBlock* next_block, RewriterVar* false_path); void _emitSideExit(RewriterVar* var, RewriterVar* val_constant, CFGBlock* next_block, RewriterVar* false_path);
......
...@@ -259,7 +259,7 @@ public: ...@@ -259,7 +259,7 @@ public:
// converted->getValue()->dump(); llvm::errs() << '\n'; // converted->getValue()->dump(); llvm::errs() << '\n';
bool do_patchpoint = ENABLE_ICSETATTRS; bool do_patchpoint = ENABLE_ICSETATTRS;
if (do_patchpoint) { if (do_patchpoint) {
ICSetupInfo* pp = createSetattrIC(info.getTypeRecorder()); ICSetupInfo* pp = createSetattrIC(info.getTypeRecorder(), info.getBJitICInfo());
std::vector<llvm::Value*> llvm_args; std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue()); llvm_args.push_back(var->getValue());
...@@ -374,7 +374,7 @@ public: ...@@ -374,7 +374,7 @@ public:
bool do_patchpoint = ENABLE_ICGETITEMS; bool do_patchpoint = ENABLE_ICGETITEMS;
llvm::Value* rtn; llvm::Value* rtn;
if (do_patchpoint) { if (do_patchpoint) {
ICSetupInfo* pp = createGetitemIC(info.getTypeRecorder()); ICSetupInfo* pp = createGetitemIC(info.getTypeRecorder(), info.getBJitICInfo());
std::vector<llvm::Value*> llvm_args; std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue()); llvm_args.push_back(var->getValue());
...@@ -471,7 +471,7 @@ public: ...@@ -471,7 +471,7 @@ public:
} }
if (do_patchpoint) { if (do_patchpoint) {
ICSetupInfo* pp = createBinexpIC(info.getTypeRecorder()); ICSetupInfo* pp = createBinexpIC(info.getTypeRecorder(), info.getBJitICInfo());
std::vector<llvm::Value*> llvm_args; std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue()); llvm_args.push_back(var->getValue());
...@@ -554,7 +554,7 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C ...@@ -554,7 +554,7 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C
bool do_patchpoint = ENABLE_ICGETATTRS; bool do_patchpoint = ENABLE_ICGETATTRS;
if (do_patchpoint) { if (do_patchpoint) {
ICSetupInfo* pp = createGetattrIC(info.getTypeRecorder()); ICSetupInfo* pp = createGetattrIC(info.getTypeRecorder(), info.getBJitICInfo());
std::vector<llvm::Value*> llvm_args; std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue()); llvm_args.push_back(var->getValue());
...@@ -650,7 +650,7 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l ...@@ -650,7 +650,7 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
if (do_patchpoint) { if (do_patchpoint) {
assert(func_addr); assert(func_addr);
ICSetupInfo* pp = createCallsiteIC(info.getTypeRecorder(), args.size()); ICSetupInfo* pp = createCallsiteIC(info.getTypeRecorder(), args.size(), info.getBJitICInfo());
llvm::Value* uncasted = emitter.createIC(pp, func_addr, llvm_args, info.unw_info, target_exception_style); llvm::Value* uncasted = emitter.createIC(pp, func_addr, llvm_args, info.unw_info, target_exception_style);
......
...@@ -141,14 +141,16 @@ class OpInfo { ...@@ -141,14 +141,16 @@ class OpInfo {
private: private:
const EffortLevel effort; const EffortLevel effort;
TypeRecorder* const type_recorder; TypeRecorder* const type_recorder;
ICInfo* bjit_ic_info;
public: public:
const UnwindInfo unw_info; const UnwindInfo unw_info;
OpInfo(EffortLevel effort, TypeRecorder* type_recorder, const UnwindInfo& unw_info) OpInfo(EffortLevel effort, TypeRecorder* type_recorder, const UnwindInfo& unw_info, ICInfo* bjit_ic_info)
: effort(effort), type_recorder(type_recorder), unw_info(unw_info) {} : effort(effort), type_recorder(type_recorder), bjit_ic_info(bjit_ic_info), unw_info(unw_info) {}
TypeRecorder* getTypeRecorder() const { return type_recorder; } TypeRecorder* getTypeRecorder() const { return type_recorder; }
ICInfo* getBJitICInfo() const { return bjit_ic_info; }
ExceptionStyle preferredExceptionStyle() const { return unw_info.preferredExceptionStyle(); } ExceptionStyle preferredExceptionStyle() const { return unw_info.preferredExceptionStyle(); }
}; };
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "analysis/function_analysis.h" #include "analysis/function_analysis.h"
#include "analysis/scoping_analysis.h" #include "analysis/scoping_analysis.h"
#include "analysis/type_analysis.h" #include "analysis/type_analysis.h"
#include "asm_writing/icinfo.h"
#include "codegen/codegen.h" #include "codegen/codegen.h"
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "codegen/irgen.h" #include "codegen/irgen.h"
...@@ -596,10 +597,12 @@ private: ...@@ -596,10 +597,12 @@ private:
type_recorder = NULL; type_recorder = NULL;
} }
return OpInfo(irstate->getEffortLevel(), type_recorder, unw_info); return OpInfo(irstate->getEffortLevel(), type_recorder, unw_info, ICInfo::getICInfoForNode(ast));
} }
OpInfo getEmptyOpInfo(const UnwindInfo& unw_info) { return OpInfo(irstate->getEffortLevel(), NULL, unw_info); } OpInfo getEmptyOpInfo(const UnwindInfo& unw_info) {
return OpInfo(irstate->getEffortLevel(), NULL, unw_info, NULL);
}
void createExprTypeGuard(llvm::Value* check_val, AST* node, llvm::Value* node_value, AST_stmt* current_statement) { void createExprTypeGuard(llvm::Value* check_val, AST* node, llvm::Value* node_value, AST_stmt* current_statement) {
assert(check_val->getType() == g.i1); assert(check_val->getType() == g.i1);
......
...@@ -287,16 +287,31 @@ void* PatchpointInfo::getSlowpathAddr(unsigned int pp_id) { ...@@ -287,16 +287,31 @@ void* PatchpointInfo::getSlowpathAddr(unsigned int pp_id) {
return new_patchpoints[pp_id].second; return new_patchpoints[pp_id].second;
} }
int numSlots(ICInfo* bjit_ic_info, int default_num_slots) {
if (!bjit_ic_info)
return default_num_slots;
// this thresholds are chosen by running the benchmarks several times with different settings.
int num_slots = std::max(bjit_ic_info->getNumSlots(), default_num_slots);
if (bjit_ic_info->isMegamorphic())
num_slots *= 3;
else if (bjit_ic_info->timesRewritten() > IC_MEGAMORPHIC_THRESHOLD / 2)
num_slots += 2;
else
num_slots = std::min(std::max(bjit_ic_info->timesRewritten(), 1), default_num_slots);
return std::min(num_slots, 10);
}
ICSetupInfo* createGenericIC(TypeRecorder* type_recorder, bool has_return_value, int size) { ICSetupInfo* createGenericIC(TypeRecorder* type_recorder, bool has_return_value, int size) {
return ICSetupInfo::initialize(has_return_value, 1, size, ICSetupInfo::Generic, type_recorder); return ICSetupInfo::initialize(has_return_value, 1, size, ICSetupInfo::Generic, type_recorder);
} }
ICSetupInfo* createGetattrIC(TypeRecorder* type_recorder) { ICSetupInfo* createGetattrIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info) {
return ICSetupInfo::initialize(true, 2, 512, ICSetupInfo::Getattr, type_recorder); return ICSetupInfo::initialize(true, numSlots(bjit_ic_info, 2), 512, ICSetupInfo::Getattr, type_recorder);
} }
ICSetupInfo* createGetitemIC(TypeRecorder* type_recorder) { ICSetupInfo* createGetitemIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info) {
return ICSetupInfo::initialize(true, 1, 512, ICSetupInfo::Getitem, type_recorder); return ICSetupInfo::initialize(true, numSlots(bjit_ic_info, 1), 512, ICSetupInfo::Getitem, type_recorder);
} }
ICSetupInfo* createSetitemIC(TypeRecorder* type_recorder) { ICSetupInfo* createSetitemIC(TypeRecorder* type_recorder) {
...@@ -307,27 +322,25 @@ ICSetupInfo* createDelitemIC(TypeRecorder* type_recorder) { ...@@ -307,27 +322,25 @@ ICSetupInfo* createDelitemIC(TypeRecorder* type_recorder) {
return ICSetupInfo::initialize(false, 1, 512, ICSetupInfo::Delitem, type_recorder); return ICSetupInfo::initialize(false, 1, 512, ICSetupInfo::Delitem, type_recorder);
} }
ICSetupInfo* createSetattrIC(TypeRecorder* type_recorder) { ICSetupInfo* createSetattrIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info) {
return ICSetupInfo::initialize(false, 2, 512, ICSetupInfo::Setattr, type_recorder); return ICSetupInfo::initialize(false, numSlots(bjit_ic_info, 2), 512, ICSetupInfo::Setattr, type_recorder);
} }
ICSetupInfo* createDelattrIC(TypeRecorder* type_recorder) { ICSetupInfo* createDelattrIC(TypeRecorder* type_recorder) {
return ICSetupInfo::initialize(false, 1, 144, ICSetupInfo::Delattr, type_recorder); return ICSetupInfo::initialize(false, 1, 144, ICSetupInfo::Delattr, type_recorder);
} }
ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args) { ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args, ICInfo* bjit_ic_info) {
// TODO These are very large, but could probably be made much smaller with IC optimizations return ICSetupInfo::initialize(true, numSlots(bjit_ic_info, 4), 640 + 48 * num_args, ICSetupInfo::Callsite,
// - using rewriter2 for better code type_recorder);
// - not emitting duplicate guards
return ICSetupInfo::initialize(true, 4, 640 + 48 * num_args, ICSetupInfo::Callsite, type_recorder);
} }
ICSetupInfo* createGetGlobalIC(TypeRecorder* type_recorder) { ICSetupInfo* createGetGlobalIC(TypeRecorder* type_recorder) {
return ICSetupInfo::initialize(true, 1, 128, ICSetupInfo::GetGlobal, type_recorder); return ICSetupInfo::initialize(true, 1, 128, ICSetupInfo::GetGlobal, type_recorder);
} }
ICSetupInfo* createBinexpIC(TypeRecorder* type_recorder) { ICSetupInfo* createBinexpIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info) {
return ICSetupInfo::initialize(true, 4, 512, ICSetupInfo::Binexp, type_recorder); return ICSetupInfo::initialize(true, numSlots(bjit_ic_info, 4), 512, ICSetupInfo::Binexp, type_recorder);
} }
ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder) { ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder) {
......
...@@ -152,16 +152,17 @@ public: ...@@ -152,16 +152,17 @@ public:
TypeRecorder* type_recorder); TypeRecorder* type_recorder);
}; };
class ICInfo;
ICSetupInfo* createGenericIC(TypeRecorder* type_recorder, bool has_return_value, int size); ICSetupInfo* createGenericIC(TypeRecorder* type_recorder, bool has_return_value, int size);
ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args); ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args, ICInfo* bjit_ic_info);
ICSetupInfo* createGetGlobalIC(TypeRecorder* type_recorder); ICSetupInfo* createGetGlobalIC(TypeRecorder* type_recorder);
ICSetupInfo* createGetattrIC(TypeRecorder* type_recorder); ICSetupInfo* createGetattrIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info);
ICSetupInfo* createSetattrIC(TypeRecorder* type_recorder); ICSetupInfo* createSetattrIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info);
ICSetupInfo* createDelattrIC(TypeRecorder* type_recorder); ICSetupInfo* createDelattrIC(TypeRecorder* type_recorder);
ICSetupInfo* createGetitemIC(TypeRecorder* type_recorder); ICSetupInfo* createGetitemIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info);
ICSetupInfo* createSetitemIC(TypeRecorder* type_recorder); ICSetupInfo* createSetitemIC(TypeRecorder* type_recorder);
ICSetupInfo* createDelitemIC(TypeRecorder* type_recorder); ICSetupInfo* createDelitemIC(TypeRecorder* type_recorder);
ICSetupInfo* createBinexpIC(TypeRecorder* type_recorder); ICSetupInfo* createBinexpIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info);
ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder); ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder);
ICSetupInfo* createHasnextIC(TypeRecorder* type_recorder); ICSetupInfo* createHasnextIC(TypeRecorder* type_recorder);
......
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