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) {
|
||||
int true_block = chunk_->LookupDestination(instr->true_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) {
|
||||
InstanceType from = instr->from();
|
||||
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) {
|
||||
Token::Value op = instr->op();
|
||||
|
||||
|
@ -299,6 +299,13 @@ class LCodeGen BASE_EMBEDDED {
|
||||
Label* is_not_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().
|
||||
// Caller should branch on equal condition.
|
||||
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) {
|
||||
stream->Add("if is_smi(");
|
||||
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) {
|
||||
stream->Add("if has_instance_type(");
|
||||
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) {
|
||||
ASSERT(instr->value()->representation().IsTagged());
|
||||
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(
|
||||
HHasInstanceTypeAndBranch* instr) {
|
||||
ASSERT(instr->value()->representation().IsTagged());
|
||||
|
@ -109,8 +109,10 @@ class LCodeGen;
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsNilAndBranch) \
|
||||
V(IsObjectAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
V(StringCompareAndBranch) \
|
||||
V(JSArrayLength) \
|
||||
V(Label) \
|
||||
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> {
|
||||
public:
|
||||
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> {
|
||||
public:
|
||||
explicit LHasInstanceTypeAndBranch(LOperand* value) {
|
||||
|
Loading…
Reference in New Issue
Block a user