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
if (LOG_IC_ASSEMBLY)
assembler->comment("_cmp");
assembler::Register v1_reg = v1->getInReg();
assembler::Register v2_reg = v2->getInReg();
assembler::Register v1_reg = v1->getInReg(Location::any(), false, dest);
assembler::Register v2_reg = v2->getInReg(Location::any(), false, dest);
assert(v1_reg != v2_reg); // TODO how do we ensure this?
v1->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);
assembler->cmp(v1_reg, v2_reg);
switch (cmp_type) {
......@@ -2004,6 +2008,11 @@ void Rewriter::spillRegister(assembler::XMMRegister reg) {
}
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();
if (dest.type == Location::AnyReg) {
......@@ -2012,7 +2021,7 @@ assembler::Register Rewriter::allocReg(Location dest, Location otherThan) {
assembler::Register best_reg(0);
// TODO prioritize spilling a constant register?
for (assembler::Register reg : allocatable_regs) {
for (assembler::Register reg : valid_registers) {
if (Location(reg) != otherThan) {
if (vars_by_location.count(reg) == 0) {
return reg;
......@@ -2042,6 +2051,7 @@ assembler::Register Rewriter::allocReg(Location dest, Location otherThan) {
assert(failed || vars_by_location.count(best_reg) == 0);
return best_reg;
} 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);
if (vars_by_location.count(reg)) {
......
......@@ -483,6 +483,8 @@ protected:
// Allocates a register. dest must be of type Register or AnyReg
// 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,
llvm::ArrayRef<assembler::Register> valid_registers);
assembler::XMMRegister allocXMMReg(Location dest, Location otherThan = Location::any());
// Allocates an 8-byte region in the scratch space
Location allocScratch();
......
......@@ -223,7 +223,7 @@ RewriterVar* JitFragmentWriter::emitCallattr(AST_expr* node, RewriterVar* obj, B
RewriterVar* args_array = nullptr;
if (args.size())
args_array = allocArgs(args);
args_array = allocArgs(args, RewriterVar::SetattrType::REF_USED);
else
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
}
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);
}
......
......@@ -5732,8 +5732,8 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
bool neg = (op_type == AST_TYPE::IsNot);
if (rewrite_args) {
RewriterVar* cmpres = rewrite_args->lhs->cmp(neg ? AST_TYPE::NotEq : AST_TYPE::Eq, rewrite_args->rhs,
rewrite_args->destination);
RewriterVar* cmpres
= rewrite_args->lhs->cmp(neg ? AST_TYPE::NotEq : AST_TYPE::Eq, rewrite_args->rhs, assembler::RDI);
rewrite_args->out_rtn
= rewrite_args->rewriter->call(false, (void*)boxBool, cmpres)->setType(RefType::OWNED);
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