Reviewers: Vyacheslav Egorov,
Description:
Inline builtin Math functions functions in more cases.
Until now we only could inline as specialized HIR instructions when called
as a method (e.g. Math.abs)
It is very common practice to abbreviate calls to those functions by
defining
a global or local variable like:
var a = Math.abs;
var x = a(123);
This change allows inlining them when called as a function (global or
local).
Please review this at https://chromiumcodereview.appspot.com/9365013/
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/
Affected files:
M src/hydrogen.h
M src/hydrogen.cc
Index: src/hydrogen.cc
===================================================================
--- src/hydrogen.cc (revision 10631)
+++ src/hydrogen.cc (working copy)
@@ -5058,10 +5058,42 @@
}
-bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr,
- HValue* receiver,
- Handle<Map> receiver_map,
- CheckType check_type) {
+bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool
drop_extra) {
+ if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
+ BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
+ int argument_count = expr->arguments()->length() + 1; // Plus receiver.
+ switch (id) {
+ case kMathRound:
+ case kMathFloor:
+ case kMathAbs:
+ case kMathSqrt:
+ case kMathLog:
+ case kMathSin:
+ case kMathCos:
+ if (argument_count == 2) {
+ HValue* argument = Pop();
+ HValue* context = environment()->LookupContext();
+ Drop(1); // Receiver.
+ HUnaryMathOperation* op =
+ new(zone()) HUnaryMathOperation(context, argument, id);
+ op->set_position(expr->position());
+ if (drop_extra) Drop(1); // Optionally drop the function.
+ ast_context()->ReturnInstruction(op, expr->id());
+ return true;
+ }
+ break;
+ default:
+ // Not supported for inlining yet.
+ break;
+ }
+ return false;
+}
+
+
+bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
+ HValue* receiver,
+ Handle<Map> receiver_map,
+ CheckType check_type) {
ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null());
// Try to inline calls like Math.* as operations in the calling function.
if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
@@ -5155,7 +5187,7 @@
case kMathRandom:
if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
AddCheckConstantFunction(expr, receiver, receiver_map, true);
- Drop(1);
+ Drop(1); // Receiver.
HValue* context = environment()->LookupContext();
HGlobalObject* global_object = new(zone()) HGlobalObject(context);
AddInstruction(global_object);
@@ -5323,10 +5355,15 @@
Handle<Map> receiver_map = (types == NULL || types->is_empty())
? Handle<Map>::null()
: types->first();
- if (TryInlineBuiltinFunction(expr,
- receiver,
- receiver_map,
- expr->check_type())) {
+ if (TryInlineBuiltinMethodCall(expr,
+ receiver,
+ receiver_map,
+ expr->check_type())) {
+ if (FLAG_trace_inlining) {
+ PrintF("Inlining builtin ");
+ expr->target()->ShortPrint();
+ PrintF("\n");
+ }
return;
}
@@ -5397,6 +5434,14 @@
IsGlobalObject());
environment()->SetExpressionStackAt(receiver_index,
global_receiver);
+ if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to
drop.
+ if (FLAG_trace_inlining) {
+ PrintF("Inlining builtin ");
+ expr->target()->ShortPrint();
+ PrintF("\n");
+ }
+ return;
+ }
if (TryInline(expr)) return;
call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
argument_count));
@@ -5423,6 +5468,16 @@
PushAndAdd(receiver);
CHECK_ALIVE(VisitExpressions(expr->arguments()));
AddInstruction(new(zone()) HCheckFunction(function, expr->target()));
+
+ if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
+ if (FLAG_trace_inlining) {
+ PrintF("Inlining builtin ");
+ expr->target()->ShortPrint();
+ PrintF("\n");
+ }
+ return;
+ }
+
if (TryInline(expr, true)) { // Drop function from environment.
return;
} else {
Index: src/hydrogen.h
===================================================================
--- src/hydrogen.h (revision 10631)
+++ src/hydrogen.h (working copy)
@@ -918,10 +918,11 @@
bool TryCallApply(Call* expr);
bool TryInline(Call* expr, bool drop_extra = false);
- bool TryInlineBuiltinFunction(Call* expr,
+ bool TryInlineBuiltinMethodCall(Call* expr,
HValue* receiver,
Handle<Map> receiver_map,
CheckType check_type);
+ bool TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra);
// If --trace-inlining, print a line of the inlining trace. Inlining
// succeeded if the reason string is NULL and failed if there is a
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev