My favorites | Sign in
Project Home Downloads Wiki Issues Source
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 410: not the best optimization
3 people starred this issue and may be notified of changes. Back to list
Status:  Invalid
Owner:  ----
Closed:  Apr 2011


Sign in to add a comment
 
Apr 6, 2011
#1 schu...@gmail.com
I think an assignment to a variable, followed immediately by usage of that variable, can be inlined.  However, if there is any statement in between that cannot be proven to be free of side-effects, then the compiler won't inline it.

In your case, assignment to variable "start" is separated from the usage of "start" only by the assignment statement to "end".  However, this statement is free of side-effects since Math.max is an internal function and the compiler knows that it is side-effect-free.

However, in your case, assignment to variable "end" is separated from the usage of that variable by a statement, which is an assignment of "start" to a property.  Now, I believe that the compiler does not assume that merely assigning to a property is always side-effect-free; that is because some properties, when assigned, actually cause different behavior, or change global state (such as RegExp).  In some systems, property assignments actually trigger certain system-specific features (e.g. hardware interface) that may in-turn contain side-effects.

So, the variable "end" cannot be inlined because the statement `tb.selectionStart = start;` may have side effects (perhaps only in wierd cases).

Apr 6, 2011
#2 johnl...@google.com
For the record, here is the code in question:

function f(a, b) {
    var start = Math.min(a, b);
    var end = Math.max(a, b);

    tb.selectionStart = start;
    tb.selectionEnd = end;
};

In order to inline "end", the compiler needs to know two things:
1) that Math.max is side-effect free (which it knows)
2) that the result of "Math.max" does not depend on global state (which it does not)

This is a side-effect free function: "Math.max = function() { return tb.selectionStart }" 
but with this definition of "Math.max" if "end" were to be inlined the value of tb.SelectionEnd would not be what is expected.


Apr 6, 2011
Project Member #3 concavel...@gmail.com
(No comment was entered for this change.)
Status: Invalid
Apr 6, 2011
#4 schu...@gmail.com
John, nice to know this is due to "global state" instead of side-effects.  These things get tricky!  Now if it is certain that Math.max does not get redefined (i.e. it remains the internally-implemented function), can the compiler then mark it as not depending on global state?

Apr 7, 2011
Project Member #5 chadkill...@missouristate.edu
Maybe I'm just missing something, but I would also have expected this code in advanced mode to be inlined:

var tb = {selectionStart: 0, selectionEnd: 0};

function f(a, b) {
  var start = Math.min(a, b);
  var end = Math.max(a, b);
  tb.selectionStart = start;
  tb.selectionEnd = end;
}
f(1, 12);
window["tb"] = tb;

Instead I get:

var a = {selectionStart:0, selectionEnd:0}, b = Math.max(1, 12);
a.selectionStart = Math.min(1, 12);
a.selectionEnd = b;
window.tb = a;

In advanced, shouldn't the compiler be able to tell that Math.max doesn't depend on the global state?
Apr 8, 2011
Project Member #6 concavel...@gmail.com
For the simple cases, the infrastructure just isn't there yet.  We special case "Math" already so it wouldn't be a stretch to special case it further.  But in the general case we would need four things:
* "Math" to be annotated or discovered to be "const"
* "Math.min" to be annotated or discovered to be "const"
* the function to be annotated with a "I don't don't have any dependencies on non-const values or any const values that may not be initialized yet"
* that values read by function can not be aliases of a affected value:

The last one is a killer.

Here are some obvious examples:

function f(a, b) {
  var start = Math.min(a.selectionStart, b.selectionEnd);
  var end = Math.max(a.selectionStart, b.selectionEnd);
  tb.selectionStart = start;
  tb.selectionEnd = end;
}

or 

function f(a, b) {
  var start = Math.min(a, b);
  var end = Math.max(a, b);
  arguments[0] = start;
  arguments[1] = end;
}



Sign in to add a comment

Powered by Google Project Hosting