Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLVM tier: adjust num of IC slots depending on the num of times the IC got rewritten in the bjit tier #977

Merged
merged 1 commit into from
Oct 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/asm_writing/icinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,16 @@ void ICInfo::visitGCReferences(gc::GCVisitor* v) {
}
#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;
}
}
4 changes: 4 additions & 0 deletions src/asm_writing/icinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,13 @@ class ICInfo {
// For use of the rewriter for computing aggressiveness:
int percentMegamorphic() const { return times_rewritten * 100 / IC_MEGAMORPHIC_THRESHOLD; }
int percentBackedoff() const { return retry_backoff; }
int timesRewritten() const { return times_rewritten; }

friend class ICSlotRewrite;
static void visitGCReferences(gc::GCVisitor* visitor);

static ICInfo* getICInfoForNode(AST* node);
void associateNodeWithICInfo(AST* node);
};

void registerGCTrackedICInfo(ICInfo* ic);
Expand Down
2 changes: 1 addition & 1 deletion src/asm_writing/rewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ template <int N = 24> class SmallFunction {

class RewriterAction {
public:
SmallFunction<48> action;
SmallFunction<56> action;

template <typename F> RewriterAction(F&& action) : action(std::forward<F>(action)) {}

Expand Down
20 changes: 10 additions & 10 deletions src/codegen/ast_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ASTInterpreter {

private:
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_Name* name, Value value);
Box* doOSR(AST_Jump* node);
Expand Down Expand Up @@ -421,14 +421,14 @@ Box* ASTInterpreter::execute(ASTInterpreter& interpreter, CFGBlock* start_block,
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) {
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:
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:
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:
RELEASE_ASSERT(0, "not implemented");
}
Expand Down Expand Up @@ -483,7 +483,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) {
AST_Attribute* attr = (AST_Attribute*)node;
Value o = visit_expr(attr->value);
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);
} else if (node->type == AST_TYPE::Tuple) {
AST_Tuple* tuple = (AST_Tuple*)node;
Expand Down Expand Up @@ -540,7 +540,7 @@ Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) {
Value ASTInterpreter::visit_binop(AST_BinOp* node) {
Value left = visit_expr(node->left);
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) {
Expand Down Expand Up @@ -816,7 +816,7 @@ Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* node) {

Value left = visit_expr(node->left);
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) {
Expand Down Expand Up @@ -1276,7 +1276,7 @@ Value ASTInterpreter::visit_compare(AST_Compare* node) {
RELEASE_ASSERT(node->comparators.size() == 1, "not implemented");
Value left = visit_expr(node->left);
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) {
Expand Down Expand Up @@ -1553,7 +1553,7 @@ Value ASTInterpreter::visit_subscript(AST_Subscript* node) {
Value value = visit_expr(node->value);
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) {
Expand Down
36 changes: 19 additions & 17 deletions src/codegen/baseline_jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,12 @@ RewriterVar* JitFragmentWriter::imm(void* val) {
return loadConst((uint64_t)val);
}

RewriterVar* JitFragmentWriter::emitAugbinop(RewriterVar* lhs, RewriterVar* rhs, int op_type) {
return emitPPCall((void*)augbinop, { lhs, rhs, imm(op_type) }, 2, 320);
RewriterVar* JitFragmentWriter::emitAugbinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) {
return emitPPCall((void*)augbinop, { lhs, rhs, imm(op_type) }, 2, 320, node);
}

RewriterVar* JitFragmentWriter::emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type) {
return emitPPCall((void*)binop, { lhs, rhs, imm(op_type) }, 2, 240);
RewriterVar* JitFragmentWriter::emitBinop(AST_expr* node, RewriterVar* lhs, RewriterVar* rhs, int op_type) {
return emitPPCall((void*)binop, { lhs, rhs, imm(op_type) }, 2, 240, node);
}

RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
Expand Down Expand Up @@ -198,7 +198,7 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B
if (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
// We could make this faster but for now: keep it simple, stupid...
RewriterVar* attr_var = imm(attr);
Expand Down Expand Up @@ -227,9 +227,9 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B
#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
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,
Expand Down Expand Up @@ -289,7 +289,7 @@ RewriterVar* JitFragmentWriter::emitExceptionMatches(RewriterVar* v, RewriterVar
}

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) {
Expand Down Expand Up @@ -319,8 +319,8 @@ RewriterVar* JitFragmentWriter::emitGetGlobal(Box* global, BoxedString* s) {
return emitPPCall((void*)getGlobal, { imm(global), imm(s) }, 2, 512);
}

RewriterVar* JitFragmentWriter::emitGetItem(RewriterVar* value, RewriterVar* slice) {
return emitPPCall((void*)getitem, { value, slice }, 2, 512);
RewriterVar* JitFragmentWriter::emitGetItem(AST_expr* node, RewriterVar* value, RewriterVar* slice) {
return emitPPCall((void*)getitem, { value, slice }, 2, 512, node);
}

RewriterVar* JitFragmentWriter::emitGetLocal(InternedString s, int vreg) {
Expand Down Expand Up @@ -392,7 +392,7 @@ RewriterVar* JitFragmentWriter::emitRuntimeCall(AST_expr* node, RewriterVar* obj
if (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
RewriterVar* argspec_var = imm(argspec.asInt());
RewriterVar* keyword_names_var = keyword_names ? imm(keyword_names) : nullptr;
Expand Down Expand Up @@ -491,8 +491,8 @@ void JitFragmentWriter::emitReturn(RewriterVar* v) {
addAction([=]() { _emitReturn(v); }, { v }, ActionType::NORMAL);
}

void JitFragmentWriter::emitSetAttr(RewriterVar* obj, BoxedString* s, RewriterVar* attr) {
emitPPCall((void*)setattr, { obj, imm(s), attr }, 2, 512);
void JitFragmentWriter::emitSetAttr(AST_expr* node, RewriterVar* obj, BoxedString* s, RewriterVar* attr) {
emitPPCall((void*)setattr, { obj, imm(s), attr }, 2, 512, node);
}

void JitFragmentWriter::emitSetBlockLocal(InternedString s, RewriterVar* v) {
Expand Down Expand Up @@ -619,6 +619,7 @@ int JitFragmentWriter::finishCompilation() {
std::unique_ptr<ICInfo> pp
= registerCompiledPatchpoint(start_addr, slowpath_start, initialization_info.continue_addr,
slowpath_rtn_addr, pp_info.ic.get(), pp_info.stack_info, LiveOutSet());
pp->associateNodeWithICInfo(pp_info.node);
pp.release();
}

Expand Down Expand Up @@ -673,7 +674,7 @@ uint64_t JitFragmentWriter::asUInt(InternedString s) {
#endif

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());
#if ENABLE_BASELINEJIT_ICS
RewriterVar* result = createNewVar();
Expand All @@ -683,7 +684,8 @@ RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<Rewri
memcpy(_args, args.begin(), sizeof(RewriterVar*) * args_size);

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);

if (type_recorder) {
Expand Down Expand Up @@ -830,7 +832,7 @@ void JitFragmentWriter::_emitOSRPoint(RewriterVar* result, RewriterVar* node_var
}

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);

if (args.size() > 6) { // only 6 args can get passed in registers.
Expand Down Expand Up @@ -882,7 +884,7 @@ void JitFragmentWriter::_emitPPCall(RewriterVar* result, void* func_addr, llvm::
assertConsistent();

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);
result->initializeInReg(assembler::RAX);
Expand Down
15 changes: 8 additions & 7 deletions src/codegen/baseline_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ class JitFragmentWriter : public Rewriter {
uint8_t* end_addr;
std::unique_ptr<ICSetupInfo> ic;
StackInfo stack_info;
AST* node;
};

llvm::SmallVector<PPInfo, 8> pp_infos;
Expand All @@ -203,11 +204,11 @@ class JitFragmentWriter : public Rewriter {
RewriterVar* imm(uint64_t val);
RewriterVar* imm(void* val);

RewriterVar* emitAugbinop(RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitAugbinop(AST_expr* node, 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,
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* emitCreateList(const llvm::ArrayRef<RewriterVar*> values);
RewriterVar* emitCreateSet(const llvm::ArrayRef<RewriterVar*> values);
Expand All @@ -221,7 +222,7 @@ class JitFragmentWriter : public Rewriter {
RewriterVar* emitGetBoxedLocals();
RewriterVar* emitGetClsAttr(RewriterVar* obj, 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* emitGetPystonIter(RewriterVar* v);
RewriterVar* emitHasnext(RewriterVar* v);
Expand Down Expand Up @@ -249,7 +250,7 @@ class JitFragmentWriter : public Rewriter {
void emitRaise0();
void emitRaise3(RewriterVar* arg0, RewriterVar* arg1, RewriterVar* arg2);
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 emitSetCurrentInst(AST_stmt* node);
void emitSetExcInfo(RewriterVar* type, RewriterVar* value, RewriterVar* traceback);
Expand All @@ -274,7 +275,7 @@ class JitFragmentWriter : public Rewriter {
#endif

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 Box* callattrHelper(Box* obj, BoxedString* attr, CallattrFlags flags, TypeRecorder* type_recorder,
Expand All @@ -294,7 +295,7 @@ class JitFragmentWriter : public Rewriter {
void _emitJump(CFGBlock* b, RewriterVar* block_next, int& size_of_exit_to_interp);
void _emitOSRPoint(RewriterVar* result, RewriterVar* node_var);
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 _emitReturn(RewriterVar* v);
void _emitSideExit(RewriterVar* var, RewriterVar* val_constant, CFGBlock* next_block, RewriterVar* false_path);
Expand Down
10 changes: 5 additions & 5 deletions src/codegen/compvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class UnknownType : public ConcreteCompilerType {
// converted->getValue()->dump(); llvm::errs() << '\n';
bool do_patchpoint = ENABLE_ICSETATTRS;
if (do_patchpoint) {
ICSetupInfo* pp = createSetattrIC(info.getTypeRecorder());
ICSetupInfo* pp = createSetattrIC(info.getTypeRecorder(), info.getBJitICInfo());

std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue());
Expand Down Expand Up @@ -374,7 +374,7 @@ class UnknownType : public ConcreteCompilerType {
bool do_patchpoint = ENABLE_ICGETITEMS;
llvm::Value* rtn;
if (do_patchpoint) {
ICSetupInfo* pp = createGetitemIC(info.getTypeRecorder());
ICSetupInfo* pp = createGetitemIC(info.getTypeRecorder(), info.getBJitICInfo());

std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue());
Expand Down Expand Up @@ -471,7 +471,7 @@ class UnknownType : public ConcreteCompilerType {
}

if (do_patchpoint) {
ICSetupInfo* pp = createBinexpIC(info.getTypeRecorder());
ICSetupInfo* pp = createBinexpIC(info.getTypeRecorder(), info.getBJitICInfo());

std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue());
Expand Down Expand Up @@ -554,7 +554,7 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C

bool do_patchpoint = ENABLE_ICGETATTRS;
if (do_patchpoint) {
ICSetupInfo* pp = createGetattrIC(info.getTypeRecorder());
ICSetupInfo* pp = createGetattrIC(info.getTypeRecorder(), info.getBJitICInfo());

std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue());
Expand Down Expand Up @@ -650,7 +650,7 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
if (do_patchpoint) {
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);

Expand Down
6 changes: 4 additions & 2 deletions src/codegen/irgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,16 @@ class OpInfo {
private:
const EffortLevel effort;
TypeRecorder* const type_recorder;
ICInfo* bjit_ic_info;

public:
const UnwindInfo unw_info;

OpInfo(EffortLevel effort, TypeRecorder* type_recorder, const UnwindInfo& unw_info)
: effort(effort), type_recorder(type_recorder), unw_info(unw_info) {}
OpInfo(EffortLevel effort, TypeRecorder* type_recorder, const UnwindInfo& unw_info, ICInfo* bjit_ic_info)
: effort(effort), type_recorder(type_recorder), bjit_ic_info(bjit_ic_info), unw_info(unw_info) {}

TypeRecorder* getTypeRecorder() const { return type_recorder; }
ICInfo* getBJitICInfo() const { return bjit_ic_info; }

ExceptionStyle preferredExceptionStyle() const { return unw_info.preferredExceptionStyle(); }
};
Expand Down
7 changes: 5 additions & 2 deletions src/codegen/irgen/irgenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "analysis/function_analysis.h"
#include "analysis/scoping_analysis.h"
#include "analysis/type_analysis.h"
#include "asm_writing/icinfo.h"
#include "codegen/codegen.h"
#include "codegen/compvars.h"
#include "codegen/irgen.h"
Expand Down Expand Up @@ -596,10 +597,12 @@ class IRGeneratorImpl : public IRGenerator {
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) {
assert(check_val->getType() == g.i1);
Expand Down
Loading