Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Unified Diff: src/hydrogen.cc

Issue 8242002: Recognize special comparisons via pattern matching on the hydrogen graph. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
===================================================================
--- src/hydrogen.cc (revision 9587)
+++ src/hydrogen.cc (working copy)
@@ -5791,38 +5791,69 @@
void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
Kevin Millikin (Chromium) 2011/10/13 13:11:59 I'd prefer to use more specific types here. The c
Sven Panne 2011/10/13 14:21:38 Done.
- Expression* sub_expr,
- Handle<String> check) {
- CHECK_ALIVE(VisitForTypeOf(sub_expr));
- HValue* value = Pop();
- HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check);
+ HValue* typeof_expr,
+ HValue* check) {
+ HValue* value = HTypeof::cast(typeof_expr)->value();
+ Handle<String> blah = Handle<String>::cast(HConstant::cast(check)->handle());
Kevin Millikin (Chromium) 2011/10/13 13:11:59 There must be a better name.
Sven Panne 2011/10/13 14:21:38 hurz? (http://www.youtube.com/watch?v=RAx0P-8n5K4)
+ HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, blah);
instr->set_position(expr->position());
- return ast_context()->ReturnControl(instr, expr->id());
+ ast_context()->ReturnControl(instr, expr->id());
+ typeof_expr->DeleteAndReplaceWith(instr);
Kevin Millikin (Chromium) 2011/10/13 13:11:59 I don't think this is right. instr is a control i
Sven Panne 2011/10/13 14:21:38 I'd like to go for the first alternative (replacin
}
-bool HGraphBuilder::TryLiteralCompare(CompareOperation* expr) {
- Expression *sub_expr;
- Handle<String> check;
- if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
- HandleLiteralCompareTypeof(expr, sub_expr, check);
+static bool MatchLiteralCompareNil(HValue* left,
+ Token::Value op,
+ HValue* right,
+ Handle<Object> nil,
+ HValue** expr) {
+ if (left->IsConstant() &&
+ HConstant::cast(left)->handle().is_identical_to(nil) &&
+ Token::IsEqualityOp(op)) {
+ *expr = right;
return true;
}
+ return false;
+}
- if (expr->IsLiteralCompareUndefined(&sub_expr)) {
- HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
- return true;
- }
- if (expr->IsLiteralCompareNull(&sub_expr)) {
- HandleLiteralCompareNil(expr, sub_expr, kNullValue);
+static bool MatchLiteralCompareTypeof(HValue* left,
+ Token::Value op,
+ HValue* right,
+ HValue** typeof_expr,
+ HValue** check) {
+ if (left->IsTypeof() &&
+ Token::IsEqualityOp(op) &&
+ right->IsConstant() &&
+ HConstant::cast(right)->HasStringValue()) {
+ *typeof_expr = left;
Kevin Millikin (Chromium) 2011/10/13 13:11:59 If you take my suggestion above, this is where you
Sven Panne 2011/10/13 14:21:38 Done.
+ *check = right;
return true;
}
-
return false;
}
+static bool IsLiteralCompareTypeof(HValue* left,
+ Token::Value op,
+ HValue* right,
+ HValue** typeof_expr,
+ HValue** check) {
+ return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) ||
+ MatchLiteralCompareTypeof(right, op, left, typeof_expr, check);
+}
+
+
+static bool IsLiteralCompareNil(HValue* left,
+ Token::Value op,
+ HValue* right,
+ Handle<Object> nil,
+ HValue** expr) {
+ return MatchLiteralCompareNil(left, op, right, nil, expr) ||
+ MatchLiteralCompareNil(right, op, left, nil, expr);
+}
+
+
void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
@@ -5840,11 +5871,9 @@
return ast_context()->ReturnControl(instr, expr->id());
}
- // Check for special cases that compare against literals.
- if (TryLiteralCompare(expr)) return;
-
TypeInfo type_info = oracle()->CompareType(expr);
// Check if this expression was ever executed according to type feedback.
+ // Note that for the special typeof/null/undefined cases we get unknown here.
if (type_info.IsUninitialized()) {
AddInstruction(new(zone()) HSoftDeoptimize);
current_block()->MarkAsDeoptimizing();
@@ -5859,6 +5888,20 @@
HValue* left = Pop();
Token::Value op = expr->op();
+ HValue* typeof_expr = NULL;
Kevin Millikin (Chromium) 2011/10/13 13:11:59 And HTypeof* typeof_expr = NULL; Handle<String> c
Sven Panne 2011/10/13 14:21:38 Done.
+ HValue* check = NULL;
+ if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) {
+ return HandleLiteralCompareTypeof(expr, typeof_expr, check);
+ }
+ HValue* sub_expr = NULL;
+ Factory* f = graph()->isolate()->factory();
+ if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) {
+ return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
+ }
+ if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) {
+ return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
+ }
+
if (op == Token::INSTANCEOF) {
// Check to see if the rhs of the instanceof is a global function not
// residing in new space. If it is we assume that the function will stay the
@@ -5947,13 +5990,11 @@
void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
- Expression* sub_expr,
+ HValue* value,
NilValue nil) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- CHECK_ALIVE(VisitForValue(sub_expr));
- HValue* value = Pop();
EqualityKind kind =
expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality;
HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil);
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698