MIPS: Landing: [hydrogen] optimize switch with string clauses.
Port r10019 (9bbb78bf) Original commit message: Patch by Fedor Indutny <fedor.indutny@gmail.com>. BUG= TEST= Review URL: http://codereview.chromium.org/8574073 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10043 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
de389f1d23
commit
be1a94b626
@ -1677,6 +1677,32 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Condition LCodeGen::EmitIsString(Register input,
|
||||||
|
Register temp1,
|
||||||
|
Label* is_not_string) {
|
||||||
|
__ JumpIfSmi(input, is_not_string);
|
||||||
|
__ GetObjectType(input, temp1, temp1);
|
||||||
|
|
||||||
|
return lt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
|
||||||
|
Register reg = ToRegister(instr->InputAt(0));
|
||||||
|
Register temp1 = ToRegister(instr->TempAt(0));
|
||||||
|
|
||||||
|
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
||||||
|
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
||||||
|
Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
||||||
|
|
||||||
|
Condition true_cond =
|
||||||
|
EmitIsString(reg, temp1, false_label);
|
||||||
|
|
||||||
|
EmitBranch(true_block, false_block, true_cond, temp1,
|
||||||
|
Operand(FIRST_NONSTRING_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
|
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
|
||||||
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
||||||
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
||||||
@ -1702,6 +1728,40 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Condition ComputeCompareCondition(Token::Value op) {
|
||||||
|
switch (op) {
|
||||||
|
case Token::EQ_STRICT:
|
||||||
|
case Token::EQ:
|
||||||
|
return eq;
|
||||||
|
case Token::LT:
|
||||||
|
return lt;
|
||||||
|
case Token::GT:
|
||||||
|
return gt;
|
||||||
|
case Token::LTE:
|
||||||
|
return le;
|
||||||
|
case Token::GTE:
|
||||||
|
return ge;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return kNoCondition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
||||||
|
Token::Value op = instr->op();
|
||||||
|
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
||||||
|
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
||||||
|
|
||||||
|
Handle<Code> ic = CompareIC::GetUninitialized(op);
|
||||||
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
|
Condition condition = ComputeCompareCondition(op);
|
||||||
|
|
||||||
|
EmitBranch(true_block, false_block, condition, v0, Operand(zero_reg));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
|
static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
|
||||||
InstanceType from = instr->from();
|
InstanceType from = instr->from();
|
||||||
InstanceType to = instr->to();
|
InstanceType to = instr->to();
|
||||||
@ -2002,26 +2062,6 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Condition ComputeCompareCondition(Token::Value op) {
|
|
||||||
switch (op) {
|
|
||||||
case Token::EQ_STRICT:
|
|
||||||
case Token::EQ:
|
|
||||||
return eq;
|
|
||||||
case Token::LT:
|
|
||||||
return lt;
|
|
||||||
case Token::GT:
|
|
||||||
return gt;
|
|
||||||
case Token::LTE:
|
|
||||||
return le;
|
|
||||||
case Token::GTE:
|
|
||||||
return ge;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return kNoCondition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoCmpT(LCmpT* instr) {
|
void LCodeGen::DoCmpT(LCmpT* instr) {
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
|
@ -299,6 +299,13 @@ class LCodeGen BASE_EMBEDDED {
|
|||||||
Label* is_not_object,
|
Label* is_not_object,
|
||||||
Label* is_object);
|
Label* is_object);
|
||||||
|
|
||||||
|
// Emits optimized code for %_IsString(x). Preserves input register.
|
||||||
|
// Returns the condition on which a final split to
|
||||||
|
// true and false label should be made, to optimize fallthrough.
|
||||||
|
Condition EmitIsString(Register input,
|
||||||
|
Register temp1,
|
||||||
|
Label* is_not_string);
|
||||||
|
|
||||||
// Emits optimized code for %_IsConstructCall().
|
// Emits optimized code for %_IsConstructCall().
|
||||||
// Caller should branch on equal condition.
|
// Caller should branch on equal condition.
|
||||||
void EmitIsConstructCall(Register temp1, Register temp2);
|
void EmitIsConstructCall(Register temp1, Register temp2);
|
||||||
|
@ -228,6 +228,13 @@ void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIsStringAndBranch::PrintDataTo(StringStream* stream) {
|
||||||
|
stream->Add("if is_string(");
|
||||||
|
InputAt(0)->PrintTo(stream);
|
||||||
|
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
|
void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
|
||||||
stream->Add("if is_smi(");
|
stream->Add("if is_smi(");
|
||||||
InputAt(0)->PrintTo(stream);
|
InputAt(0)->PrintTo(stream);
|
||||||
@ -242,6 +249,14 @@ void LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LStringCompareAndBranch::PrintDataTo(StringStream* stream) {
|
||||||
|
stream->Add("if string_compare(");
|
||||||
|
InputAt(0)->PrintTo(stream);
|
||||||
|
InputAt(1)->PrintTo(stream);
|
||||||
|
stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
|
void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
|
||||||
stream->Add("if has_instance_type(");
|
stream->Add("if has_instance_type(");
|
||||||
InputAt(0)->PrintTo(stream);
|
InputAt(0)->PrintTo(stream);
|
||||||
@ -1452,6 +1467,13 @@ LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
|
||||||
|
ASSERT(instr->value()->representation().IsTagged());
|
||||||
|
LOperand* temp = TempRegister();
|
||||||
|
return new LIsStringAndBranch(UseRegisterAtStart(instr->value()), temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
|
LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
|
||||||
ASSERT(instr->value()->representation().IsTagged());
|
ASSERT(instr->value()->representation().IsTagged());
|
||||||
return new LIsSmiAndBranch(Use(instr->value()));
|
return new LIsSmiAndBranch(Use(instr->value()));
|
||||||
@ -1466,6 +1488,17 @@ LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LInstruction* LChunkBuilder::DoStringCompareAndBranch(
|
||||||
|
HStringCompareAndBranch* instr) {
|
||||||
|
ASSERT(instr->left()->representation().IsTagged());
|
||||||
|
ASSERT(instr->right()->representation().IsTagged());
|
||||||
|
LOperand* left = UseFixed(instr->left(), a1);
|
||||||
|
LOperand* right = UseFixed(instr->right(), a0);
|
||||||
|
LStringCompareAndBranch* result = new LStringCompareAndBranch(left, right);
|
||||||
|
return MarkAsCall(result, instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
|
LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
|
||||||
HHasInstanceTypeAndBranch* instr) {
|
HHasInstanceTypeAndBranch* instr) {
|
||||||
ASSERT(instr->value()->representation().IsTagged());
|
ASSERT(instr->value()->representation().IsTagged());
|
||||||
|
@ -109,8 +109,10 @@ class LCodeGen;
|
|||||||
V(IsConstructCallAndBranch) \
|
V(IsConstructCallAndBranch) \
|
||||||
V(IsNilAndBranch) \
|
V(IsNilAndBranch) \
|
||||||
V(IsObjectAndBranch) \
|
V(IsObjectAndBranch) \
|
||||||
|
V(IsStringAndBranch) \
|
||||||
V(IsSmiAndBranch) \
|
V(IsSmiAndBranch) \
|
||||||
V(IsUndetectableAndBranch) \
|
V(IsUndetectableAndBranch) \
|
||||||
|
V(StringCompareAndBranch) \
|
||||||
V(JSArrayLength) \
|
V(JSArrayLength) \
|
||||||
V(Label) \
|
V(Label) \
|
||||||
V(LazyBailout) \
|
V(LazyBailout) \
|
||||||
@ -658,6 +660,20 @@ class LIsObjectAndBranch: public LControlInstruction<1, 1> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LIsStringAndBranch: public LControlInstruction<1, 1> {
|
||||||
|
public:
|
||||||
|
LIsStringAndBranch(LOperand* value, LOperand* temp) {
|
||||||
|
inputs_[0] = value;
|
||||||
|
temps_[0] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
|
||||||
|
DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
|
||||||
|
|
||||||
|
virtual void PrintDataTo(StringStream* stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class LIsSmiAndBranch: public LControlInstruction<1, 0> {
|
class LIsSmiAndBranch: public LControlInstruction<1, 0> {
|
||||||
public:
|
public:
|
||||||
explicit LIsSmiAndBranch(LOperand* value) {
|
explicit LIsSmiAndBranch(LOperand* value) {
|
||||||
@ -686,6 +702,23 @@ class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LStringCompareAndBranch: public LControlInstruction<2, 0> {
|
||||||
|
public:
|
||||||
|
LStringCompareAndBranch(LOperand* left, LOperand* right) {
|
||||||
|
inputs_[0] = left;
|
||||||
|
inputs_[1] = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
|
||||||
|
"string-compare-and-branch")
|
||||||
|
DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
|
||||||
|
|
||||||
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
|
|
||||||
|
virtual void PrintDataTo(StringStream* stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
|
class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
|
||||||
public:
|
public:
|
||||||
explicit LHasInstanceTypeAndBranch(LOperand* value) {
|
explicit LHasInstanceTypeAndBranch(LOperand* value) {
|
||||||
|
Loading…
Reference in New Issue
Block a user