Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upIssue 1827 - Inline does not faithfully copy variables at identical times - haxe #1827
Comments
|
[comment from si...@haxe.org, published at 18/05/2013, 09:06:54] var t = new Main(); {
t.a = t.b;
t.b = t.a;
}
; |
|
[comment from si...@haxe.org, published at 23/05/2013, 10:25:02] |
|
[comment from ncanna...@gmail.com, published at 23/05/2013, 10:36:03] ATM, inline differs from traditional functions in that the time at which arguments are evaluated is delayed until it's actually used in the method. Unused arguments are even discarded, which is great if you want for instance to have assert(expr) that entirely disappear in release. I would vote for a good explanations in the Haxe 3.0 Manual about this particular way inline can break code. |
|
[comment from si...@haxe.org, published at 23/05/2013, 10:41:40] |
|
[comment from thomas.p...@gmail.com, published at 23/05/2013, 10:46:17] I really think that inline should be working in a secure way. If you really want to offer a higher level of inlining, which can be cool, I'd suggest to not make it by default, but in a specific compiler argument like "--inline-depth 2" or whatever. Thomas |
|
[comment from david.el...@gmail.com, published at 23/05/2013, 10:51:58] |
|
[comment from si...@haxe.org, published at 23/05/2013, 10:54:48] |
|
[comment from ncanna...@gmail.com, published at 23/05/2013, 11:16:15] For instance : inline function doIf( flag : Bool, a : Int, b : Int ) {
return if( flag ) a else b;
}
doIf(true,obj.foo,obj.bar); currently compiles to "obj.foo" would compile to : {
var _tmp1 = obj.foo;
var _tmp2 = obj.bar;
_tmp1;
}
|
|
[comment from ncanna...@gmail.com, published at 23/05/2013, 11:16:53] |
|
[comment from si...@haxe.org, published at 23/05/2013, 11:19:36] |
|
[comment from si...@haxe.org, published at 23/05/2013, 11:48:06]
|
|
[comment from ncanna...@gmail.com, published at 24/05/2013, 08:06:49] |
|
[comment from ncanna...@gmail.com, published at 24/05/2013, 09:32:20] |
|
@Simn I mentioned that idea because current inline implementation is a bit too strong, since if not used with real care, it can lead to some very frustrating debugging session. I really think most of people experimenting such a problem do not fill issues, thinking it was their mistake (which currently is) That's why I'd go for a default inlining algorithm safer, but that we can change using a compiler flag to the current algorithm. |
|
Do we agree on 'correct' then 'fast'? On Fri, May 31, 2013 at 10:32 AM, kiroukou notifications@github.com wrote:
Stéphane Le Dorze http://lambdabrella.blogspot.com/ Tel: +33 (0) 6 08 76 70 15 |
|
Does this bug cause https://code.google.com/p/hxformat/issues/detail?id=55 ? |
|
In order to keep inline power and still deal with the issue we will have to perform some global optimization as suggested in #2135 , we will push that to the same release then |
|
Here's another one:
The inliner doesn't create a temp var for the first argument because the argument itself doesn't have any side-effects. The generated code then increments before use:
That's pretty rubbish... |
|
If you specified that the order of evaluation of the arguments to inline function is not specified, or that evaluation might actually not occur if optimized out, then it works. We still have the issue with "delayed evaluation" of the original issue example. |
|
But I don't like this specification. :( |
|
@Simn that's how it is currently, and I think it allows some nice things. inline is for performance optimisation anyway, so users using it should know the pro/cons and adapt to it, or stick with a standard call. |
|
Still I believe any optimisation should not change the behaviour of a program. The current spec let inlining changes argument evaluation order (from specified to unspecified), which make it more than an optimisation. And I think argument evaluation order is pretty important and should be specified - let's imagine if it is not specified for normal function calls. |
|
I second that. |
|
@nadako : it won't in some cases, such as |
|
While I agree that's a breaking change and we should be careful, I wonder how many people actually RELY on that behaviour besides you :-P I think it takes quite deep knowledge of haxe inlining (which is something only you have as an author) to be 100% sure that As a "common" haxe programmer, I'd find that quite unreliable and would just use a simple and straightforward macro for case like yours ( Also, I wonder if there are more uses for the "optimization" besides that |
|
I'm confused:
Generates (neko):
|
|
@Simn that's a regression, not sure since when |
|
Can we get rid of this feature if it has been broken for more than a year? I'd even go ahead and bisect it. :) |
|
This "feature"?
|
|
Well surprise: fa24c15 You made that change yourself and even put it in the changelog. |
|
lol |
|
Ah, that's indeed quite funny :-) But then I think it still works well for things such as |
|
You can't be serious. :P |
|
That's what the code tells me, and I even remember documenting it ! @Simn does the analyser deopt |
|
@Simn and what about |
|
It removes these. Why wouldn't it? Operations on null values are undefined anyway, right? |
|
Is this related to this issue? I couldn't find an issue exactly relevant. Edit: After reinitializing the array, it works fine. The original array had a fixed length of 0 I guess? |
|
OK, let's move on with this and have inline respect order of evaluation. I still recommend we directly inline constants (and lambda functions) in-place instead of putting them in temp vars so we keep code optimization the way it is right now without having to enable the analyzer |
|
It's funny because by now I'm leaning towards your original position. The effects of enforcing this are substantial and without a really good optimization pass it is going to cause performance regressions. So I suppose the question is if I'm capable of implementing that really good optimization pass, and given the mutable and dynamic nature of Haxe I'm not so sure about that. |
|
Ah-ah ! I agree that until we are sure to be able to perform good optimizations on par with we have we have right now we shouldn't change the behavior. At least we agree now on both what would be nice and how hard it is to get there :) |
|
This is the code example I use to remind myself that it's impossible to statically detect inlining order problems in general: class Main {
var a:Int;
var b:Int;
function new() {
a = 1;
b = 2;
}
@:extern inline function set(inA:Int, inB:Int) {
setA(inA);
setB(inB);
}
function setA(i:Int) a = i;
function setB(i:Int) b = i;
static function alias(t:Main) return t;
public static function main() {
var t = new Main();
var t2 = alias(t);
t.set(t.b, t2.a);
trace(t.a + "," + t.b);
}
}I'm posting this because every other month I come back to this issue and think that I can somehow fix it in the inliner, while that is, in fact, impossible. |
[Google Issue #1827 : https://code.google.com/p/haxe/issues/detail?id=1827]
by gameh...@gmail.com, at 18/05/2013, 08:52:25
The following gived different results depending where 'set' is inlined. The actucal bug came from matrix multiplication.
http://code.google.com/p/hxcpp/issues/detail?id=241
class Test
{ var a:Int; var b:Int; function new() { a=1; b=2; } inline function set(inA:Int, inB:Int) { a = inA; b = inB; } public static function main() { var t = new Test(); t.set(t.b,t.a); trace(t.a +"," +t.b); } }Maybe this should just be 'implementer beware'.