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

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') | test/mjsunit/compiler/math-floor-global.js » ('j') | 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) {
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 switch (id) {
5065 case kMathRound:
5066 case kMathFloor:
5067 case kMathAbs:
5068 case kMathSqrt:
5069 case kMathLog:
5070 case kMathSin:
5071 case kMathCos:
5072 if (expr->arguments()->length() == 1) {
5073 HValue* argument = Pop();
5074 HValue* context = environment()->LookupContext();
5075 Drop(1); // Receiver.
5076 HUnaryMathOperation* op =
5077 new(zone()) HUnaryMathOperation(context, argument, id);
5078 op->set_position(expr->position());
5079 if (drop_extra) Drop(1); // Optionally drop the function.
5080 ast_context()->ReturnInstruction(op, expr->id());
5081 return true;
5082 }
5083 break;
5084 default:
5085 // Not supported for inlining yet.
5086 break;
5087 }
5088 return false;
5089 }
5090
5091
5092 bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
5093 HValue* receiver,
5094 Handle<Map> receiver_map,
5095 CheckType check_type) {
5065 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); 5096 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null());
5066 // Try to inline calls like Math.* as operations in the calling function. 5097 // Try to inline calls like Math.* as operations in the calling function.
5067 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 5098 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
5068 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 5099 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
5069 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 5100 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
5070 switch (id) { 5101 switch (id) {
5071 case kStringCharCodeAt: 5102 case kStringCharCodeAt:
5072 case kStringCharAt: 5103 case kStringCharAt:
5073 if (argument_count == 2 && check_type == STRING_CHECK) { 5104 if (argument_count == 2 && check_type == STRING_CHECK) {
5074 HValue* index = Pop(); 5105 HValue* index = Pop();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
5148 if (result == NULL) { 5179 if (result == NULL) {
5149 result = new(zone()) HPower(left, right); 5180 result = new(zone()) HPower(left, right);
5150 } 5181 }
5151 ast_context()->ReturnInstruction(result, expr->id()); 5182 ast_context()->ReturnInstruction(result, expr->id());
5152 return true; 5183 return true;
5153 } 5184 }
5154 break; 5185 break;
5155 case kMathRandom: 5186 case kMathRandom:
5156 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { 5187 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
5157 AddCheckConstantFunction(expr, receiver, receiver_map, true); 5188 AddCheckConstantFunction(expr, receiver, receiver_map, true);
5158 Drop(1); 5189 Drop(1); // Receiver.
5159 HValue* context = environment()->LookupContext(); 5190 HValue* context = environment()->LookupContext();
5160 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 5191 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
5161 AddInstruction(global_object); 5192 AddInstruction(global_object);
5162 HRandom* result = new(zone()) HRandom(global_object); 5193 HRandom* result = new(zone()) HRandom(global_object);
5163 ast_context()->ReturnInstruction(result, expr->id()); 5194 ast_context()->ReturnInstruction(result, expr->id());
5164 return true; 5195 return true;
5165 } 5196 }
5166 break; 5197 break;
5167 case kMathMax: 5198 case kMathMax:
5168 case kMathMin: 5199 case kMathMin:
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
5316 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 5347 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
5317 5348
5318 SmallMapList* types = expr->GetReceiverTypes(); 5349 SmallMapList* types = expr->GetReceiverTypes();
5319 5350
5320 HValue* receiver = 5351 HValue* receiver =
5321 environment()->ExpressionStackAt(expr->arguments()->length()); 5352 environment()->ExpressionStackAt(expr->arguments()->length());
5322 if (expr->IsMonomorphic()) { 5353 if (expr->IsMonomorphic()) {
5323 Handle<Map> receiver_map = (types == NULL || types->is_empty()) 5354 Handle<Map> receiver_map = (types == NULL || types->is_empty())
5324 ? Handle<Map>::null() 5355 ? Handle<Map>::null()
5325 : types->first(); 5356 : types->first();
5326 if (TryInlineBuiltinFunction(expr, 5357 if (TryInlineBuiltinMethodCall(expr,
5327 receiver, 5358 receiver,
5328 receiver_map, 5359 receiver_map,
5329 expr->check_type())) { 5360 expr->check_type())) {
5361 if (FLAG_trace_inlining) {
5362 PrintF("Inlining builtin ");
5363 expr->target()->ShortPrint();
5364 PrintF("\n");
5365 }
5330 return; 5366 return;
5331 } 5367 }
5332 5368
5333 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || 5369 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
5334 expr->check_type() != RECEIVER_MAP_CHECK) { 5370 expr->check_type() != RECEIVER_MAP_CHECK) {
5335 // When the target has a custom call IC generator, use the IC, 5371 // 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 5372 // because it is likely to generate better code. Also use the IC
5337 // when a primitive receiver check is required. 5373 // when a primitive receiver check is required.
5338 HValue* context = environment()->LookupContext(); 5374 HValue* context = environment()->LookupContext();
5339 call = PreProcessCall( 5375 call = PreProcessCall(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5390 // Replace the global object with the global receiver. 5426 // Replace the global object with the global receiver.
5391 HGlobalReceiver* global_receiver = 5427 HGlobalReceiver* global_receiver =
5392 new(zone()) HGlobalReceiver(global_object); 5428 new(zone()) HGlobalReceiver(global_object);
5393 // Index of the receiver from the top of the expression stack. 5429 // Index of the receiver from the top of the expression stack.
5394 const int receiver_index = argument_count - 1; 5430 const int receiver_index = argument_count - 1;
5395 AddInstruction(global_receiver); 5431 AddInstruction(global_receiver);
5396 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 5432 ASSERT(environment()->ExpressionStackAt(receiver_index)->
5397 IsGlobalObject()); 5433 IsGlobalObject());
5398 environment()->SetExpressionStackAt(receiver_index, global_receiver); 5434 environment()->SetExpressionStackAt(receiver_index, global_receiver);
5399 5435
5436 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop.
5437 if (FLAG_trace_inlining) {
5438 PrintF("Inlining builtin ");
5439 expr->target()->ShortPrint();
5440 PrintF("\n");
5441 }
5442 return;
5443 }
5400 if (TryInline(expr)) return; 5444 if (TryInline(expr)) return;
5401 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 5445 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
5402 argument_count)); 5446 argument_count));
5403 } else { 5447 } else {
5404 HValue* context = environment()->LookupContext(); 5448 HValue* context = environment()->LookupContext();
5405 HGlobalObject* receiver = new(zone()) HGlobalObject(context); 5449 HGlobalObject* receiver = new(zone()) HGlobalObject(context);
5406 AddInstruction(receiver); 5450 AddInstruction(receiver);
5407 PushAndAdd(new(zone()) HPushArgument(receiver)); 5451 PushAndAdd(new(zone()) HPushArgument(receiver));
5408 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 5452 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
5409 5453
5410 call = new(zone()) HCallGlobal(context, var->name(), argument_count); 5454 call = new(zone()) HCallGlobal(context, var->name(), argument_count);
5411 Drop(argument_count); 5455 Drop(argument_count);
5412 } 5456 }
5413 5457
5414 } else if (expr->IsMonomorphic()) { 5458 } else if (expr->IsMonomorphic()) {
5415 // The function is on the stack in the unoptimized code during 5459 // The function is on the stack in the unoptimized code during
5416 // evaluation of the arguments. 5460 // evaluation of the arguments.
5417 CHECK_ALIVE(VisitForValue(expr->expression())); 5461 CHECK_ALIVE(VisitForValue(expr->expression()));
5418 HValue* function = Top(); 5462 HValue* function = Top();
5419 HValue* context = environment()->LookupContext(); 5463 HValue* context = environment()->LookupContext();
5420 HGlobalObject* global = new(zone()) HGlobalObject(context); 5464 HGlobalObject* global = new(zone()) HGlobalObject(context);
5421 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); 5465 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global);
5422 AddInstruction(global); 5466 AddInstruction(global);
5423 PushAndAdd(receiver); 5467 PushAndAdd(receiver);
5424 CHECK_ALIVE(VisitExpressions(expr->arguments())); 5468 CHECK_ALIVE(VisitExpressions(expr->arguments()));
5425 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); 5469 AddInstruction(new(zone()) HCheckFunction(function, expr->target()));
5470
5471 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
5472 if (FLAG_trace_inlining) {
5473 PrintF("Inlining builtin ");
5474 expr->target()->ShortPrint();
5475 PrintF("\n");
5476 }
5477 return;
5478 }
5479
5426 if (TryInline(expr, true)) { // Drop function from environment. 5480 if (TryInline(expr, true)) { // Drop function from environment.
5427 return; 5481 return;
5428 } else { 5482 } else {
5429 call = PreProcessCall(new(zone()) HInvokeFunction(context, 5483 call = PreProcessCall(new(zone()) HInvokeFunction(context,
5430 function, 5484 function,
5431 argument_count)); 5485 argument_count));
5432 Drop(1); // The function. 5486 Drop(1); // The function.
5433 } 5487 }
5434 5488
5435 } else { 5489 } else {
(...skipping 2025 matching lines...) Expand 10 before | Expand all | Expand 10 after
7461 } 7515 }
7462 } 7516 }
7463 7517
7464 #ifdef DEBUG 7518 #ifdef DEBUG
7465 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7519 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7466 if (allocator_ != NULL) allocator_->Verify(); 7520 if (allocator_ != NULL) allocator_->Verify();
7467 #endif 7521 #endif
7468 } 7522 }
7469 7523
7470 } } // namespace v8::internal 7524 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | test/mjsunit/compiler/math-floor-global.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698