Commit 4253de66 authored by Marius Wachtler's avatar Marius Wachtler

bjit: directly emit 'is' and 'is not' comparisons

also fix a build error when ICs are disabled
parent 031526a5
...@@ -632,14 +632,18 @@ void Rewriter::_cmp(RewriterVar* result, RewriterVar* v1, AST_TYPE::AST_TYPE cmp ...@@ -632,14 +632,18 @@ void Rewriter::_cmp(RewriterVar* result, RewriterVar* v1, AST_TYPE::AST_TYPE cmp
if (LOG_IC_ASSEMBLY) if (LOG_IC_ASSEMBLY)
assembler->comment("_cmp"); assembler->comment("_cmp");
assembler::Register v1_reg = v1->getInReg(); assembler::Register v1_reg = v1->getInReg(Location::any(), false, dest);
assembler::Register v2_reg = v2->getInReg(); assembler::Register v2_reg = v2->getInReg(Location::any(), false, dest);
assert(v1_reg != v2_reg); // TODO how do we ensure this? assert(v1_reg != v2_reg); // TODO how do we ensure this?
v1->bumpUseEarlyIfPossible(); v1->bumpUseEarlyIfPossible();
v2->bumpUseEarlyIfPossible(); v2->bumpUseEarlyIfPossible();
assembler::Register newvar_reg = allocReg(dest); // sete and setne has special register requirements (can't use r8-r15)
const assembler::Register valid_registers[] = {
assembler::RAX, assembler::RCX, assembler::RDX, assembler::RSI, assembler::RDI,
};
assembler::Register newvar_reg = allocReg(dest, Location::any(), valid_registers);
result->initializeInReg(newvar_reg); result->initializeInReg(newvar_reg);
assembler->cmp(v1_reg, v2_reg); assembler->cmp(v1_reg, v2_reg);
switch (cmp_type) { switch (cmp_type) {
...@@ -2004,6 +2008,11 @@ void Rewriter::spillRegister(assembler::XMMRegister reg) { ...@@ -2004,6 +2008,11 @@ void Rewriter::spillRegister(assembler::XMMRegister reg) {
} }
assembler::Register Rewriter::allocReg(Location dest, Location otherThan) { assembler::Register Rewriter::allocReg(Location dest, Location otherThan) {
return allocReg(dest, otherThan, allocatable_regs);
}
assembler::Register Rewriter::allocReg(Location dest, Location otherThan,
llvm::ArrayRef<assembler::Register> valid_registers) {
assertPhaseEmitting(); assertPhaseEmitting();
if (dest.type == Location::AnyReg) { if (dest.type == Location::AnyReg) {
...@@ -2012,7 +2021,7 @@ assembler::Register Rewriter::allocReg(Location dest, Location otherThan) { ...@@ -2012,7 +2021,7 @@ assembler::Register Rewriter::allocReg(Location dest, Location otherThan) {
assembler::Register best_reg(0); assembler::Register best_reg(0);
// TODO prioritize spilling a constant register? // TODO prioritize spilling a constant register?
for (assembler::Register reg : allocatable_regs) { for (assembler::Register reg : valid_registers) {
if (Location(reg) != otherThan) { if (Location(reg) != otherThan) {
if (vars_by_location.count(reg) == 0) { if (vars_by_location.count(reg) == 0) {
return reg; return reg;
...@@ -2042,6 +2051,7 @@ assembler::Register Rewriter::allocReg(Location dest, Location otherThan) { ...@@ -2042,6 +2051,7 @@ assembler::Register Rewriter::allocReg(Location dest, Location otherThan) {
assert(failed || vars_by_location.count(best_reg) == 0); assert(failed || vars_by_location.count(best_reg) == 0);
return best_reg; return best_reg;
} else if (dest.type == Location::Register) { } else if (dest.type == Location::Register) {
assert(std::find(valid_registers.begin(), valid_registers.end(), dest.asRegister()) != valid_registers.end());
assembler::Register reg(dest.regnum); assembler::Register reg(dest.regnum);
if (vars_by_location.count(reg)) { if (vars_by_location.count(reg)) {
......
...@@ -483,6 +483,8 @@ protected: ...@@ -483,6 +483,8 @@ protected:
// Allocates a register. dest must be of type Register or AnyReg // Allocates a register. dest must be of type Register or AnyReg
// If otherThan is a register, guaranteed to not use that register. // If otherThan is a register, guaranteed to not use that register.
assembler::Register allocReg(Location dest, Location otherThan = Location::any()); assembler::Register allocReg(Location dest, Location otherThan = Location::any());
assembler::Register allocReg(Location dest, Location otherThan,
llvm::ArrayRef<assembler::Register> valid_registers);
assembler::XMMRegister allocXMMReg(Location dest, Location otherThan = Location::any()); assembler::XMMRegister allocXMMReg(Location dest, Location otherThan = Location::any());
// Allocates an 8-byte region in the scratch space // Allocates an 8-byte region in the scratch space
Location allocScratch(); Location allocScratch();
......
...@@ -223,7 +223,7 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B ...@@ -223,7 +223,7 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B
RewriterVar* args_array = nullptr; RewriterVar* args_array = nullptr;
if (args.size()) if (args.size())
args_array = allocArgs(args); args_array = allocArgs(args, RewriterVar::SetattrType::REF_USED);
else else
RELEASE_ASSERT(!keyword_names_var, "0 args but keyword names are set"); RELEASE_ASSERT(!keyword_names_var, "0 args but keyword names are set");
...@@ -244,7 +244,10 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B ...@@ -244,7 +244,10 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B
} }
RewriterVar* JitFragmentWriter::emitCompare(AST_expr* node, 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 if (op_type == AST_TYPE::Is || op_type == AST_TYPE::IsNot) {
RewriterVar* cmp_result = lhs->cmp(op_type == AST_TYPE::IsNot ? AST_TYPE::NotEq : AST_TYPE::Eq, rhs);
return call(false, (void*)boxBool, cmp_result)->setType(RefType::OWNED);
}
return emitPPCall((void*)compare, { lhs, rhs, imm(op_type) }, 2, 240, node).first->setType(RefType::OWNED); return emitPPCall((void*)compare, { lhs, rhs, imm(op_type) }, 2, 240, node).first->setType(RefType::OWNED);
} }
......
...@@ -5732,8 +5732,8 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit ...@@ -5732,8 +5732,8 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
bool neg = (op_type == AST_TYPE::IsNot); bool neg = (op_type == AST_TYPE::IsNot);
if (rewrite_args) { if (rewrite_args) {
RewriterVar* cmpres = rewrite_args->lhs->cmp(neg ? AST_TYPE::NotEq : AST_TYPE::Eq, rewrite_args->rhs, RewriterVar* cmpres
rewrite_args->destination); = rewrite_args->lhs->cmp(neg ? AST_TYPE::NotEq : AST_TYPE::Eq, rewrite_args->rhs, assembler::RDI);
rewrite_args->out_rtn rewrite_args->out_rtn
= rewrite_args->rewriter->call(false, (void*)boxBool, cmpres)->setType(RefType::OWNED); = rewrite_args->rewriter->call(false, (void*)boxBool, cmpres)->setType(RefType::OWNED);
rewrite_args->out_success = true; rewrite_args->out_success = true;
......
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