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

Side by Side Diff: src/hydrogen.cc

Issue 9365013: Inline builtin Math functions functions in more cases. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 8 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5040 matching lines...) Expand 10 before | Expand all | Expand 10 after
5051 function_return()->SetJoinId(expr->id()); 5051 function_return()->SetJoinId(expr->id());
5052 set_current_block(function_return()); 5052 set_current_block(function_return());
5053 } else { 5053 } else {
5054 set_current_block(NULL); 5054 set_current_block(NULL);
5055 } 5055 }
5056 delete target_state; 5056 delete target_state;
5057 return true; 5057 return true;
5058 } 5058 }
5059 5059
5060 5060
5061 bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr, 5061 bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) {
Vyacheslav Egorov (Chromium) 2012/02/08 10:50:59 maybe it's time to have enum for drop_extra so it
5062 HValue* receiver, 5062 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
5063 Handle<Map> receiver_map, 5063 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
5064 CheckType check_type) { 5064 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
5065 switch (id) {
5066 case kMathRound:
5067 case kMathFloor:
5068 case kMathAbs:
5069 case kMathSqrt:
5070 case kMathLog:
5071 case kMathSin:
5072 case kMathCos:
5073 if (argument_count == 2) {
Vyacheslav Egorov (Chromium) 2012/02/08 10:50:59 I think you can just use expr->arguments()->length
fschneider 2012/02/08 11:45:18 Done.
5074 HValue* argument = Pop();
5075 HValue* context = environment()->LookupContext();
5076 Drop(1); // Receiver.
5077 HUnaryMathOperation* op =
5078 new(zone()) HUnaryMathOperation(context, argument, id);
5079 op->set_position(expr->position());
5080 if (drop_extra) Drop(1); // Optionally drop the function.
Vyacheslav Egorov (Chromium) 2012/02/08 10:50:59 It would be good to add test case that ensures tha
fschneider 2012/02/08 11:45:18 Done.
5081 ast_context()->ReturnInstruction(op, expr->id());
5082 return true;
5083 }
5084 break;
5085 default:
5086 // Not supported for inlining yet.
5087 break;
5088 }
5089 return false;
5090 }
5091
5092
5093 bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
5094 HValue* receiver,
5095 Handle<Map> receiver_map,
5096 CheckType check_type) {
5065 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); 5097 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null());
5066 // Try to inline calls like Math.* as operations in the calling function. 5098 // Try to inline calls like Math.* as operations in the calling function.
5067 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 5099 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
5068 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 5100 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
5069 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 5101 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
5070 switch (id) { 5102 switch (id) {
5071 case kStringCharCodeAt: 5103 case kStringCharCodeAt:
5072 case kStringCharAt: 5104 case kStringCharAt:
5073 if (argument_count == 2 && check_type == STRING_CHECK) { 5105 if (argument_count == 2 && check_type == STRING_CHECK) {
5074 HValue* index = Pop(); 5106 HValue* index = Pop();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
5148 if (result == NULL) { 5180 if (result == NULL) {
5149 result = new(zone()) HPower(left, right); 5181 result = new(zone()) HPower(left, right);
5150 } 5182 }
5151 ast_context()->ReturnInstruction(result, expr->id()); 5183 ast_context()->ReturnInstruction(result, expr->id());
5152 return true; 5184 return true;
5153 } 5185 }
5154 break; 5186 break;
5155 case kMathRandom: 5187 case kMathRandom:
5156 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { 5188 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
5157 AddCheckConstantFunction(expr, receiver, receiver_map, true); 5189 AddCheckConstantFunction(expr, receiver, receiver_map, true);
5158 Drop(1); 5190 Drop(1); // Receiver.
5159 HValue* context = environment()->LookupContext(); 5191 HValue* context = environment()->LookupContext();
5160 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 5192 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
5161 AddInstruction(global_object); 5193 AddInstruction(global_object);
5162 HRandom* result = new(zone()) HRandom(global_object); 5194 HRandom* result = new(zone()) HRandom(global_object);
5163 ast_context()->ReturnInstruction(result, expr->id()); 5195 ast_context()->ReturnInstruction(result, expr->id());
5164 return true; 5196 return true;
5165 } 5197 }
5166 break; 5198 break;
5167 case kMathMax: 5199 case kMathMax:
5168 case kMathMin: 5200 case kMathMin:
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5316 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 5348 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
5317 5349
5318 SmallMapList* types = expr->GetReceiverTypes(); 5350 SmallMapList* types = expr->GetReceiverTypes();
5319 5351
5320 HValue* receiver = 5352 HValue* receiver =
5321 environment()->ExpressionStackAt(expr->arguments()->length()); 5353 environment()->ExpressionStackAt(expr->arguments()->length());
5322 if (expr->IsMonomorphic()) { 5354 if (expr->IsMonomorphic()) {
5323 Handle<Map> receiver_map = (types == NULL || types->is_empty()) 5355 Handle<Map> receiver_map = (types == NULL || types->is_empty())
5324 ? Handle<Map>::null() 5356 ? Handle<Map>::null()
5325 : types->first(); 5357 : types->first();
5326 if (TryInlineBuiltinFunction(expr, 5358 if (TryInlineBuiltinMethodCall(expr,
5327 receiver, 5359 receiver,
5328 receiver_map, 5360 receiver_map,
5329 expr->check_type())) { 5361 expr->check_type())) {
5362 if (FLAG_trace_inlining) {
5363 PrintF("Inlining builtin ");
5364 expr->target()->ShortPrint();
5365 PrintF("\n");
5366 }
5330 return; 5367 return;
5331 } 5368 }
5332 5369
5333 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || 5370 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
5334 expr->check_type() != RECEIVER_MAP_CHECK) { 5371 expr->check_type() != RECEIVER_MAP_CHECK) {
5335 // When the target has a custom call IC generator, use the IC, 5372 // When the target has a custom call IC generator, use the IC,
5336 // because it is likely to generate better code. Also use the IC 5373 // because it is likely to generate better code. Also use the IC
5337 // when a primitive receiver check is required. 5374 // when a primitive receiver check is required.
5338 HValue* context = environment()->LookupContext(); 5375 HValue* context = environment()->LookupContext();
5339 call = PreProcessCall( 5376 call = PreProcessCall(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5390 // Replace the global object with the global receiver. 5427 // Replace the global object with the global receiver.
5391 HGlobalReceiver* global_receiver = 5428 HGlobalReceiver* global_receiver =
5392 new(zone()) HGlobalReceiver(global_object); 5429 new(zone()) HGlobalReceiver(global_object);
5393 // Index of the receiver from the top of the expression stack. 5430 // Index of the receiver from the top of the expression stack.
5394 const int receiver_index = argument_count - 1; 5431 const int receiver_index = argument_count - 1;
5395 AddInstruction(global_receiver); 5432 AddInstruction(global_receiver);
5396 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 5433 ASSERT(environment()->ExpressionStackAt(receiver_index)->
5397 IsGlobalObject()); 5434 IsGlobalObject());
5398 environment()->SetExpressionStackAt(receiver_index, global_receiver); 5435 environment()->SetExpressionStackAt(receiver_index, global_receiver);
5399 5436
5437 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop.
5438 if (FLAG_trace_inlining) {
5439 PrintF("Inlining builtin ");
5440 expr->target()->ShortPrint();
5441 PrintF("\n");
5442 }
5443 return;
5444 }
5400 if (TryInline(expr)) return; 5445 if (TryInline(expr)) return;
5401 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 5446 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
5402 argument_count)); 5447 argument_count));
5403 } else { 5448 } else {
5404 HValue* context = environment()->LookupContext(); 5449 HValue* context = environment()->LookupContext();
5405 HGlobalObject* receiver = new(zone()) HGlobalObject(context); 5450 HGlobalObject* receiver = new(zone()) HGlobalObject(context);
5406 AddInstruction(receiver); 5451 AddInstruction(receiver);
5407 PushAndAdd(new(zone()) HPushArgument(receiver)); 5452 PushAndAdd(new(zone()) HPushArgument(receiver));
5408 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 5453 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
5409 5454
5410 call = new(zone()) HCallGlobal(context, var->name(), argument_count); 5455 call = new(zone()) HCallGlobal(context, var->name(), argument_count);
5411 Drop(argument_count); 5456 Drop(argument_count);
5412 } 5457 }
5413 5458
5414 } else if (expr->IsMonomorphic()) { 5459 } else if (expr->IsMonomorphic()) {
5415 // The function is on the stack in the unoptimized code during 5460 // The function is on the stack in the unoptimized code during
5416 // evaluation of the arguments. 5461 // evaluation of the arguments.
5417 CHECK_ALIVE(VisitForValue(expr->expression())); 5462 CHECK_ALIVE(VisitForValue(expr->expression()));
5418 HValue* function = Top(); 5463 HValue* function = Top();
5419 HValue* context = environment()->LookupContext(); 5464 HValue* context = environment()->LookupContext();
5420 HGlobalObject* global = new(zone()) HGlobalObject(context); 5465 HGlobalObject* global = new(zone()) HGlobalObject(context);
5421 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); 5466 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global);
5422 AddInstruction(global); 5467 AddInstruction(global);
5423 PushAndAdd(receiver); 5468 PushAndAdd(receiver);
5424 CHECK_ALIVE(VisitExpressions(expr->arguments())); 5469 CHECK_ALIVE(VisitExpressions(expr->arguments()));
5425 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); 5470 AddInstruction(new(zone()) HCheckFunction(function, expr->target()));
5471
5472 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
5473 if (FLAG_trace_inlining) {
5474 PrintF("Inlining builtin ");
5475 expr->target()->ShortPrint();
5476 PrintF("\n");
5477 }
5478 return;
5479 }
5480
5426 if (TryInline(expr, true)) { // Drop function from environment. 5481 if (TryInline(expr, true)) { // Drop function from environment.
5427 return; 5482 return;
5428 } else { 5483 } else {
5429 call = PreProcessCall(new(zone()) HInvokeFunction(context, 5484 call = PreProcessCall(new(zone()) HInvokeFunction(context,
5430 function, 5485 function,
5431 argument_count)); 5486 argument_count));
5432 Drop(1); // The function. 5487 Drop(1); // The function.
5433 } 5488 }
5434 5489
5435 } else { 5490 } else {
(...skipping 2025 matching lines...) Expand 10 before | Expand all | Expand 10 after
7461 } 7516 }
7462 } 7517 }
7463 7518
7464 #ifdef DEBUG 7519 #ifdef DEBUG
7465 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7520 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7466 if (allocator_ != NULL) allocator_->Verify(); 7521 if (allocator_ != NULL) allocator_->Verify();
7467 #endif 7522 #endif
7468 } 7523 }
7469 7524
7470 } } // namespace v8::internal 7525 } } // namespace v8::internal
OLDNEW
« 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