Commit 72fb068f authored by Marius Wachtler's avatar Marius Wachtler

rewriter: add helper which makes it easier to select the best 'call' encoding

e.g. relative or absolute using a temp register
parent 805b30c7
...@@ -587,8 +587,7 @@ void Rewriter::_decref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bu ...@@ -587,8 +587,7 @@ void Rewriter::_decref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bu
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
assembler->mov(assembler::Immediate((void*)assertAlive), assembler::R11); _callOptimalEncoding(assembler::R11, (void*)assertAlive);
assembler->callq(assembler::R11);
assembler->mov(assembler::RAX, assembler::RDI); assembler->mov(assembler::RAX, assembler::RDI);
#endif #endif
// _setupCall doesn't remember that it added the arg regs to the location set // _setupCall doesn't remember that it added the arg regs to the location set
...@@ -599,8 +598,7 @@ void Rewriter::_decref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bu ...@@ -599,8 +598,7 @@ void Rewriter::_decref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bu
{ {
assembler::ForwardJump jnz(*assembler, assembler::COND_NOT_ZERO); assembler::ForwardJump jnz(*assembler, assembler::COND_NOT_ZERO);
#ifdef Py_TRACE_REFS #ifdef Py_TRACE_REFS
assembler->mov(assembler::Immediate((void*)_Py_Dealloc), assembler::R11); _callOptimalEncoding(assembler::R11, (void*)_Py_Dealloc);
assembler->callq(assembler::R11);
#else #else
assembler->movq(assembler::Indirect(reg, offsetof(Box, cls)), assembler::RAX); assembler->movq(assembler::Indirect(reg, offsetof(Box, cls)), assembler::RAX);
assembler->callq(assembler::Indirect(assembler::RAX, offsetof(BoxedClass, tp_dealloc))); assembler->callq(assembler::Indirect(assembler::RAX, offsetof(BoxedClass, tp_dealloc)));
...@@ -1148,6 +1146,20 @@ void Rewriter::_setupCall(bool has_side_effects, llvm::ArrayRef<RewriterVar*> ar ...@@ -1148,6 +1146,20 @@ void Rewriter::_setupCall(bool has_side_effects, llvm::ArrayRef<RewriterVar*> ar
#endif #endif
} }
void Rewriter::_callOptimalEncoding(assembler::Register tmp_reg, void* func_addr) {
assert(vars_by_location.count(tmp_reg) == 0);
uint64_t asm_address = (uint64_t)assembler->curInstPointer() + 5;
uint64_t real_asm_address = asm_address + (uint64_t)rewrite->getSlotStart() - (uint64_t)assembler->startAddr();
int64_t offset = (int64_t)((uint64_t)func_addr - real_asm_address);
if (isLargeConstant(offset)) {
const_loader.loadConstIntoReg((uint64_t)func_addr, tmp_reg);
assembler->callq(tmp_reg);
} else {
assembler->call(assembler::Immediate(offset));
assert(assembler->hasFailed() || asm_address == (uint64_t)assembler->curInstPointer());
}
}
void Rewriter::_call(RewriterVar* result, bool has_side_effects, bool can_throw, void* func_addr, void Rewriter::_call(RewriterVar* result, bool has_side_effects, bool can_throw, void* func_addr,
llvm::ArrayRef<RewriterVar*> args, llvm::ArrayRef<RewriterVar*> args_xmm, llvm::ArrayRef<RewriterVar*> args, llvm::ArrayRef<RewriterVar*> args_xmm,
llvm::ArrayRef<RewriterVar*> vars_to_bump) { llvm::ArrayRef<RewriterVar*> vars_to_bump) {
...@@ -1163,19 +1175,7 @@ void Rewriter::_call(RewriterVar* result, bool has_side_effects, bool can_throw, ...@@ -1163,19 +1175,7 @@ void Rewriter::_call(RewriterVar* result, bool has_side_effects, bool can_throw,
assertConsistent(); assertConsistent();
// make sure setupCall doesn't use R11 _callOptimalEncoding(r, func_addr);
assert(vars_by_location.count(assembler::R11) == 0);
uint64_t asm_address = (uint64_t)assembler->curInstPointer() + 5;
uint64_t real_asm_address = asm_address + (uint64_t)rewrite->getSlotStart() - (uint64_t)assembler->startAddr();
int64_t offset = (int64_t)((uint64_t)func_addr - real_asm_address);
if (isLargeConstant(offset)) {
const_loader.loadConstIntoReg((uint64_t)func_addr, r);
assembler->callq(r);
} else {
assembler->call(assembler::Immediate(offset));
assert(assembler->hasFailed() || asm_address == (uint64_t)assembler->curInstPointer());
}
if (can_throw) if (can_throw)
registerDecrefInfoHere(); registerDecrefInfoHere();
...@@ -1920,8 +1920,7 @@ void Rewriter::_checkAndThrowCAPIException(RewriterVar* r, int64_t exc_val, asse ...@@ -1920,8 +1920,7 @@ void Rewriter::_checkAndThrowCAPIException(RewriterVar* r, int64_t exc_val, asse
_setupCall(false, {}); _setupCall(false, {});
{ {
assembler::ForwardJump jnz(*assembler, assembler::COND_NOT_ZERO); assembler::ForwardJump jnz(*assembler, assembler::COND_NOT_ZERO);
assembler->mov(assembler::Immediate((void*)throwCAPIException), assembler::R11); _callOptimalEncoding(assembler::R11, (void*)throwCAPIException);
assembler->callq(assembler::R11);
registerDecrefInfoHere(); registerDecrefInfoHere();
} }
......
...@@ -570,6 +570,11 @@ protected: ...@@ -570,6 +570,11 @@ protected:
void _decref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bump = {}); void _decref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bump = {});
void _xdecref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bump = {}); void _xdecref(RewriterVar* var, llvm::ArrayRef<RewriterVar*> vars_to_bump = {});
// emits a call instruction using the smallest encoding.
// either doing a relative call if or otherwise loading the address into the supplied register and calling it.
// the caller of this function must make sure that the supplied register can be safely overwriten.
void _callOptimalEncoding(assembler::Register tmp_reg, void* func_addr);
void assertConsistent() { void assertConsistent() {
#ifndef NDEBUG #ifndef NDEBUG
for (RewriterVar& var : vars) { for (RewriterVar& var : vars) {
......
...@@ -1012,8 +1012,8 @@ void JitFragmentWriter::_emitGetLocal(RewriterVar* val_var, const char* name) { ...@@ -1012,8 +1012,8 @@ void JitFragmentWriter::_emitGetLocal(RewriterVar* val_var, const char* name) {
{ {
assembler::ForwardJump jnz(*assembler, assembler::COND_NOT_ZERO); assembler::ForwardJump jnz(*assembler, assembler::COND_NOT_ZERO);
assembler->mov(assembler::Immediate((uint64_t)name), assembler::RDI); assembler->mov(assembler::Immediate((uint64_t)name), assembler::RDI);
assembler->mov(assembler::Immediate((void*)assertNameDefinedHelper), assembler::R11);
assembler->callq(assembler::R11); _callOptimalEncoding(assembler::R11, (void*)assertNameDefinedHelper);
registerDecrefInfoHere(); registerDecrefInfoHere();
} }
......
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