Re: DMD2 vs LDC2 inliner

2019-02-26 Thread kinke via Digitalmars-d-learn

On Tuesday, 26 February 2019 at 04:36:59 UTC, James Blachly wrote:

Sadly, the pragma does not accept enum:

Error: pragma `inline` pragma(inline, true or false) expected, 
not inline_overlaps


That's most likely a (trivial) bug and should be fixed.

As stated in the docs, the pragma can also be declared as 
statement inside the function body:


bool overlaps(...)
{
version (GDC) pragma(inline, true);
...
}


Re: DMD2 vs LDC2 inliner

2019-02-25 Thread James Blachly via Digitalmars-d-learn

On 2/25/19 2:09 AM, Nicholas Wilson wrote:

Leaving aside the issue of why DMD can't handle this, the entire reason
pragma(inline, bool) takes a bool is for it to be (potentially) 
predicated.

In this case you want:

version(DigitalMars)
  private enum inline_overlaps = false;
else // assuming GDC is good
  private enum inline_overlaps = true;

pragma(inline, inline_overlaps)
bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, 
IntervalType2 int2)

{
  return ...;
}


Sadly, the pragma does not accept enum:

Error: pragma `inline` pragma(inline, true or false) expected, not 
inline_overlaps


Re: DMD2 vs LDC2 inliner

2019-02-25 Thread James Blachly via Digitalmars-d-learn

On 2/25/19 2:09 AM, Nicholas Wilson wrote:

Leaving aside the issue of why DMD can't handle this, the entire reason
pragma(inline, bool) takes a bool is for it to be (potentially) predicated.
In this case you want:

version(DigitalMars)
  private enum inline_overlaps = false;
else // assuming GDC is good
  private enum inline_overlaps = true;

pragma(inline, inline_overlaps)
bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, 
IntervalType2 int2)

{
  return ...;
}


I still have yet to internalize the power of compile-time values. Thanks 
for the reminder and solution!


Re: DMD2 vs LDC2 inliner

2019-02-24 Thread Nicholas Wilson via Digitalmars-d-learn
On Monday, 25 February 2019 at 04:08:38 UTC, Jonathan M Davis 
wrote:
One issue that's commonly brought up about dmd's inliner is 
that it's in the front-end, which apparently is a poor way to 
do inlining. One side effect of that though would be that 
unless the ldc folks go to extra effort to disable the 
front-end's inliner


We do.

, ldc has that inliner - and then it's inlining using llvm. So, 
given that, it's practically guaranteed to do a better job.


It does anyway ;)





Re: DMD2 vs LDC2 inliner

2019-02-24 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 25 February 2019 at 02:49:36 UTC, James Blachly wrote:
Any ideas why DMD2 cannot inline this, but LDC2 has no problem 
doing so -- or suggestions for what I can do to make DMD2 
inline it?


Alternatively, I could version(DigitalMars) and version(LDC), 
but AFAICT this requires me to duplicate the entire template, 
because I cannot figure out how to make the version() directive 
apply only to the pragma.


Template instantiation is with a simple struct having integer 
members start and end.


Thanks in advance for tips.
---
pragma(inline, true)
bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, 
IntervalType2 int2)


Leaving aside the issue of why DMD can't handle this, the entire 
reason
pragma(inline, bool) takes a bool is for it to be (potentially) 
predicated.

In this case you want:

version(DigitalMars)
 private enum inline_overlaps = false;
else // assuming GDC is good
 private enum inline_overlaps = true;

pragma(inline, inline_overlaps)
bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, 
IntervalType2 int2)

{
 return ...;
}


Re: DMD2 vs LDC2 inliner

2019-02-24 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, February 24, 2019 7:49:36 PM MST James Blachly via Digitalmars-d-
learn wrote:
> Any ideas why DMD2 cannot inline this, but LDC2 has no problem doing so
> -- or suggestions for what I can do to make DMD2 inline it?

The unfortunate reality of the matter is that dmd's inliner is very poor,
and while dmd's optimizer is decent in general, llvm has had way more work
into improving its optimizer in recent years, so ldc is just plain going to
be better at optimizing code. dmd will do a decent job optimizing code, but
if you really care about your code being optimized, you need to use ldc or
gdc. And the gap there is likely to get larger over time, not smaller,
because relatively little work is put into dmd's backend. Given that dmd's
backend has now been ported to D, we may see more work being done on it, but
I expect that most of the effort will still go to the front-end, and llvm
and gcc simply have far more folks working on them, so aside from
optimizations that are D-specific, their backends are more likely to see
improvement than dmd's backend is.

One issue that's commonly brought up about dmd's inliner is that it's in the
front-end, which apparently is a poor way to do inlining. One side effect of
that though would be that unless the ldc folks go to extra effort to disable
the front-end's inliner, ldc has that inliner - and then it's inlining using
llvm. So, given that, it's practically guaranteed to do a better job.

- Jonathan M Davis





DMD2 vs LDC2 inliner

2019-02-24 Thread James Blachly via Digitalmars-d-learn
Any ideas why DMD2 cannot inline this, but LDC2 has no problem doing so 
-- or suggestions for what I can do to make DMD2 inline it?


Alternatively, I could version(DigitalMars) and version(LDC), but AFAICT 
this requires me to duplicate the entire template, because I cannot 
figure out how to make the version() directive apply only to the pragma.


Template instantiation is with a simple struct having integer members 
start and end.


Thanks in advance for tips.
---
pragma(inline, true)
bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, 
IntervalType2 int2)

if (__traits(hasMember, IntervalType1, "start") &&
__traits(hasMember, IntervalType1, "end") &&
__traits(hasMember, IntervalType2, "start") &&
__traits(hasMember, IntervalType2, "end"))
{
// int1   ====
// int2 ===  ===
if (int2.start <= int1.start &&  int1.start < int2.end) return true;

// int1  ===  ===
// int2   ===  ===
else if (int1.start <= int2.start && int2.start < int1.end) return 
true;


// int1  =|   =
// int2   =   |  =
else return false;
}