Features Download

From: James Molloy <james.molloy <at> arm.com>
Subject: Re: Contributing the Apple ARM64 compiler backend
Newsgroups: gmane.comp.compilers.llvm.devel
Date: Wednesday 25th June 2014 15:12:23 UTC (over 4 years ago)
Hi Manjunath,

At the time of writing that status we had only done our initial analysis.
This was done without real hardware and attempted to identify poor code
sequences but we were unable to quantify how much effect this would

Since then we've done more analysis using Cortex-A57 and Cortex-A53 on an
internal development platform.

For SPEC, we are between 10% and 0% behind GCC on 9 benchmarks, and 25%
ahead on one benchmark. Most benchmarks are less than 5% behind GCC.

Because of the licencing of SPEC, I have to be quite restricted in what I
say and I can't give any numbers - sorry about that.

We are focussing on Cortex-A57, and the things we've identified so far are:
  * The CSEL instruction behaves worse than the equivalent branch structure
in at least one benchmark. In an out of order core, select-like
are going to be slower than their branched equivalent if the branch is
predictable due to CSEL having two dependencies.

  * Redundant calculations inside if conditions. We've seen:
    1. "if (a[x].b < c[y].d || a[x].e > c[y].f)" - the calculations of a[x]
and c[y] are repeated, when they are common. We've also seen similar
instances where multiple registers are used to compute very similar
addresses (such as x+0 and x+4!) and this increases register pressure.
    2. "if (a < 0 && b == c || a > 0 && b == d)" - the first comparison of
'a' against zero is done twice, when the flag results of the first
comparison could be used for the second comparison.

  * For a loop such as "for (i = 0; i < n; ++i)
{do_something_with(&x[i]);}", GCC is using &x[i] as the loop induction
variable where LLVM uses i and performs the calculation &x[i] on every
iteration. This only creates one more add instruction but the loop we see
in only has 5 or so instructions.

  * The inline heuristics are way behind GCC's. If we crank the inline
threshold up to 1000, we can remove a 6.5% performance regression from one
benchmark entirely.

  * We're generating (due to SLP vectorizer and a DAG combine) loads into Q
registers when merging consecutive loads. This is bad, because there are no
callee-saved Q registers! So if the live range crosses a function call, it
will have to be immediately spilled again.  This can be easily fixed by
using load-pair instructions instead. I have a patch to fix this.

The list above is non-exhaustive and only contains things that we think may
affect multiple benchmarks or real-world code.

I've also noticed:
  * Our inline memcpy expansion pass is emitting "LDR q0, [..]; STR q0,
[..]" pairs, which is less than ideal on A53. If we switched to emitting
"LDP x0, x1, [..]; STP x0, x1, [..]", we'd get around 30% better inline
memcpy performance on A53. A57 seems to deal well with the LDR q sequence.

I'm sorry I'm unable to provide code samples for most of the issues found
far - this is an artefact of them having come from SPEC. Trivial examples
not always show the same behaviour, and as we're still investigating we
haven't yet been able to reduce most of these to an anonymisable testcase.

Hope this helps, but doubt it does,


> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On
> Behalf Of Manjunath N
> Sent: 24 June 2014 10:45
> To: [email protected]
> Subject: Re: [LLVMdev] Contributing the Apple ARM64 compiler backend
> Eric Christopher  gmail.com> writes:
> >
> > > The big pain issues I see merging from ARM64 to AArch64 are:
> > > 1.      Apple have created a fairly complete scheduling model already
> for
> > > ARM64, and we'd have to merge the partial? model in AArch64 and
> theirs.
> We
> > > risk regressing performance on Apple's targets here, and we can't
> determine
> > > ourselves whether we have or not. This is not ideal.
> > > 2.      Porting over the DAG-to-DAG optimizations and any other
> > > optimizations that rely on the tablegen layout will be very tricky.
> > > 3.      The conditional compare pass is fairly comprehensive - we'd
> have
> to
> > > port that over or rewrite it and that would be a lot of work.
> > > 4.      A very quick analysis last night indicated that ARM64 has
> > > implemented just under half of the optimizations we discovered
> opportunities
> > > for in SPEC and EEMBC. That's a fairly comprehensive number of
> > > optimizations, and they won't all be easy to port.
> Eric,
> You mention that there a quite a few  optimization opportunities in SPEC
> 2000/ EEMBC.
> I am looking to optimize the Aarch64 backend. Could you please let me
> the big optimizations possible?
> _______________________________________________
> LLVM Developers mailing list
> [email protected]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
CD: 17ms