Contributing the Apple ARM64 compiler backend

All,

Attached below are the patches that make up the Apple ARM64 compiler backend (in addition to compiler_rt, libc++ and lldb support), and we'd like to start the process of integrating them into mainline LLVM. We and ARM have discussed a general approach to integrating them into mainline and look forward to working through this with the community at large.

First a bit of context to help jump-start the discussion. The ARM64 backend is a complete production quality implementation for ARM’s 64-bit architecture, AArch64. It supports both iOS and Linux as target platforms. In the source tree, the backend co-exists with the AArch64 backend without conflicts.

As a first step, we'd like to add this as a peer of the AArch64 backend. While having two AArch64 backends in the tree long term doesn’t make sense, this approach worked well when the Sparc backends were merged and for AMDIL. This will allow us to work quickly towards merging the ports to create a backend that is truly the best of both. The public AArch64 backend has attracted an excellent core group of contributors all of whom have done great work and we are very much looking forward to collaborating with them and the rest of the community to make this happen.

Getting to that idillic end-state of one AArch64 backend in the tree which encompasses the best of both is going to take a fair bit of work and a lot of discussion amongst the interested parties. To get there, I think a rough roadmap like the following makes sense:

1. Import the ARM64 backend into the public tree so it’s easily accessible for everyone to investigate.
2. Test it. Benchmark it. Explore it. Get data for the community to work with about the state of the back end. ARM has some excellent data that will help guide us here.
3. Identify the core backend to build on and to merge features and tuning from the other to. The data I have seen so far leads me to believe ARM64 is the correct choice here, but that’s a decision primarily for the contributors above.
4. Clean up the codebase (C++11-ify it, for example), fix any regressions and test failures identified in benchmarking.

This will give us a backend that is a superset of both ARM64 and AArch64 in terms both of performance and functionality. We can then consolidate to a single backend, named AArch64 for consistency with the current public tree.

Regards,
Jim Grosbach

arm64-libc++.patch.gz (1.22 KB)

arm64-compiler-rt.patch.gz (2.19 KB)

arm64-llvm.patch.gz (689 KB)

arm64-clang.patch.gz (107 KB)

First and foremost, I'd like to say that I think this is a really great
roadmap.

1. Import the ARM64 backend into the public tree so it’s easily accessible
for everyone to investigate.

I support this, and would ask that this be done essentially right away. I
don't think patches are going to be reasonable ways to evaluate this. I
have two specific reasons for thinking this is a good thing to do
essentially "right away":

1) It comes from existing long-time and very experienced community members,
so I have no concerns over either coding convention adherence or long term
maintenance problems.

2) This is complex enough and requires enough study that a patch series is
completely infeasible.

I'd like to hear from the existing AArch64 backend maintainers if they have
any concerns about getting #1 done right away?

Attached below are the patches that make up the Apple ARM64 compiler backend (in addition to compiler_rt, libc++ and lldb support), and we'd like to start the process of integrating them into mainline LLVM. We and ARM have discussed a general approach to integrating them into mainline and look forward to working through this with the community at large.

W00t!! With libraries and debugger support, nice!

2. Test it. Benchmark it. Explore it. Get data for the community to work with about the state of the back end. ARM has some excellent data that will help guide us here.

Count me in. Would that be a different triple? arm64-linux-gnu?

3. Identify the core backend to build on and to merge features and tuning from the other to. The data I have seen so far leads me to believe ARM64 is the correct choice here, but that's a decision primarily for the contributors above.

Either way, we'll have to move features form one side to the other. I
don't see bad choices ahead, just hard work.

This will give us a backend that is a superset of both ARM64 and AArch64 in terms both of performance and functionality. We can then consolidate to a single backend, named AArch64 for consistency with the current public tree.

Do you have an idea of how much work would be involved and a
finger-in-the-air estimate of time?

I don't think we'll be able to move everything and remove one of the
back-ends in a single release cycle, so it doesn't make sense to wait
for 3.5 to go out before the merge, since it won't be ready by the
time 3.6 leaves the door. So, now is as good as any time to start
this. If people are concerned with confusion, we may just ship one of
the back-ends on the final binaries, whichever is in better shape.

Thanks Jim, glad to see things are finally rolling out. Interesting times ahead!

cheers,
--renato

Hi Chandler,

I'd like to hear from the existing AArch64 backend maintainers if they have
any concerns about getting #1 done right away?

I agree (with my AArch64 maintainer hat on).

The goal of merging these two backends will hopefully do a lot to make
sure the eventual code is better than what exists now in either
individual directory; and doing the real work towards that will be
*much* easier when both are in-tree.

Tim.

Hi Renato,

2. Test it. Benchmark it. Explore it. Get data for the community to work with about the state of the back end. ARM has some excellent data that will help guide us here.

Count me in. Would that be a different triple? arm64-linux-gnu?

Yep. "--target arm64-linux-gnu" should behave basically the same as
aarch64-linux-gnu, except ending up in the ARM64 backend. Complete
with the usual issues of finding your toolchain's includes & libs;
we've not solved that.

Cheers.

Tim.

Patches welcome, indeed!

Joe

Completely agree, plus:

3) You guys probably have that back-end in parallel internally up and
running already. With tests.

I vote for incremental post-commit review and testing.

cheers,
--renato

Getting to that idillic end-state of one AArch64 backend in the tree which encompasses the best of both is going to take a fair bit of work and a lot of discussion amongst the interested parties. To get there, I think a rough roadmap like the following makes sense:

1. Import the ARM64 backend into the public tree so it's easily accessible for everyone to investigate.
2. Test it. Benchmark it. Explore it. Get data for the community to work with about the state of the back end. ARM has some excellent data that will help guide us here.
3. Identify the core backend to build on and to merge features and tuning from the other to. The data I have seen so far leads me to believe ARM64 is the correct choice here, but that's a decision primarily for the contributors above.
4. Clean up the codebase (C++11-ify it, for example), fix any regressions and test failures identified in benchmarking.

Sounds great. It'd be good to get the target independent bits applied
separately (hopefully after the arm64 backend is committed so that
tests are more obvious), but I'm in favor of committing this as soon
as you can type svn ci with the appropriate splits for patches.

-eric

From: "Tim Northover" <t.p.northover@gmail.com>
To: "Renato Golin" <renato.golin@linaro.org>
Cc: "LLVM Developers Mailing List" <LLVMdev@cs.uiuc.edu>
Sent: Friday, March 28, 2014 3:47:49 PM
Subject: Re: [LLVMdev] Contributing the Apple ARM64 compiler backend

Hi Renato,
>> 2. Test it. Benchmark it. Explore it. Get data for the community
>> to work with about the state of the back end. ARM has some
>> excellent data that will help guide us here.
>
> Count me in. Would that be a different triple? arm64-linux-gnu?

Yep. "--target arm64-linux-gnu" should behave basically the same as
aarch64-linux-gnu, except ending up in the ARM64 backend. Complete
with the usual issues of finding your toolchain's includes & libs;
we've not solved that.

Is a different target triple the right thing to do here? I think that would introduce a ton of user confusion. How about we keep the target triples as they are, and add some other way to choose the desired backend?

-Hal

I share your concern. However, I suspect that a) we will always have at
least an alias as both triples are probably in use at this point, and b) it
won't be the end of the world to have two triples for the same arch long
term. amd64 and x86_64 wasn't the end of the world either. ::shrug::

Hi Hal,

Is a different target triple the right thing to do here? I think that would introduce a ton of user confusion. How about we keep the target triples as they are, and add some other way to choose the desired backend?

In the short term, it's almost essential. Both of these targets are
going to be existing simultaneously for a while and all the LLVM tools
(for testing if nothing else) are setup to select the target based on
the triple.

Longer term we want a single backend (probably in the AArch64
directory since that's the official name). Theoretically, we could
drop "arm64" as a triple then (provided Clang still supported "-arch
arm64" for compatibility), but in reality it would be a little odd if
"-arch arm64" worked but "--target arm64" didn't. I suspect arm64 and
aarch64 will just become synonyms at that point.

Cheers.

Tim.

Indeed, getting #1 done (importing the ARM64 backend into the public tree)
right away seems the right thing to do.

Thanks,

Kristof

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of Tim Northover
Sent: 28 March 2014 20:44
To: Chandler Carruth
Cc: Kevin Qin; LLVM Developers Mailing List
Subject: Re: [LLVMdev] Contributing the Apple ARM64 compiler backend

Hi Chandler,

> I'd like to hear from the existing AArch64 backend maintainers if they
> have any concerns about getting #1 done right away?

I agree (with my AArch64 maintainer hat on).

The goal of merging these two backends will hopefully do a lot to make

sure

I agree here, I'd prefer not to have to switch on and off various backends.

-eric

From: "Tim Northover" <t.p.northover@gmail.com>
To: "Hal Finkel" <hfinkel@anl.gov>
Cc: "LLVM Developers Mailing List" <LLVMdev@cs.uiuc.edu>, "Renato Golin" <renato.golin@linaro.org>
Sent: Friday, March 28, 2014 4:41:48 PM
Subject: Re: [LLVMdev] Contributing the Apple ARM64 compiler backend

Hi Hal,

> Is a different target triple the right thing to do here? I think
> that would introduce a ton of user confusion. How about we keep
> the target triples as they are, and add some other way to choose
> the desired backend?

In the short term, it's almost essential. Both of these targets are
going to be existing simultaneously for a while and all the LLVM
tools
(for testing if nothing else) are setup to select the target based on
the triple.

Longer term we want a single backend (probably in the AArch64
directory since that's the official name). Theoretically, we could
drop "arm64" as a triple then (provided Clang still supported "-arch
arm64" for compatibility), but in reality it would be a little odd if
"-arch arm64" worked but "--target arm64" didn't. I suspect arm64 and
aarch64 will just become synonyms at that point.

Okay; this sounds reasonable, at least from an infrastructure perspective. However, I think we'll want to have clear guidance regarding what we want users, and more importantly, packagers, to do.

Are these two backends ABI compatible? If I have a toolchain setup for the existing aarch64-linux-gnu triple, could I try the new backend and still have clang find the linker and other object files in the lib/gcc directories? I assume that, if that makes sense, we'll want to make that work.

-Hal

Maybe we can put some deadlines on merges? E.g. expect two backends to
be merged by 3.5 release?

Are these two backends ABI compatible?

They should be, where there's overlap. AArch64 doesn't have any MachO
support at the moment. ARM64 does have ELF support (obviously with
less testing than AArch64's). Any ABI discrepancy would be considered
a bug.

If I have a toolchain setup for the existing aarch64-linux-gnu triple, could
I try the new backend and still have clang find the linker and other object
files in the lib/gcc directories?

I believe so. You *should* be able to take any command-line you now
have with "--target aarch64-X-Y-Z", replace it with "--target
arm64-X-Y-Z" and it will just work.

Once the merge really gets started, that's a property everyone wants
to make sure is preserved: no regressions with existing commands for
trunk, and the final backend should be a drop-in replacement for both
iOS and ELF targets. Hopefully strictly better in both cases.

A big choice approaching is exactly how we go about the merge. In my
opinion trying an actual merge on .td files isn't going to work
(massive inconsistency even if we could make it happen technically) so
we're going to have to pick one of the two as a core for the final
backend, and strip all the useful bits out of the other one
cherry-pick style.

Cheers.

Tim.

From: "Tim Northover" <t.p.northover@gmail.com>
To: "Hal Finkel" <hfinkel@anl.gov>
Cc: "LLVM Developers Mailing List" <LLVMdev@cs.uiuc.edu>, "Renato Golin" <renato.golin@linaro.org>
Sent: Friday, March 28, 2014 5:06:11 PM
Subject: Re: [LLVMdev] Contributing the Apple ARM64 compiler backend

> Are these two backends ABI compatible?

They should be, where there's overlap. AArch64 doesn't have any MachO
support at the moment. ARM64 does have ELF support (obviously with
less testing than AArch64's). Any ABI discrepancy would be considered
a bug.

> If I have a toolchain setup for the existing aarch64-linux-gnu
> triple, could
> I try the new backend and still have clang find the linker and
> other object
> files in the lib/gcc directories?

I believe so. You *should* be able to take any command-line you now
have with "--target aarch64-X-Y-Z", replace it with "--target
arm64-X-Y-Z" and it will just work.

Okay, thanks!

Once the merge really gets started, that's a property everyone wants
to make sure is preserved: no regressions with existing commands for
trunk, and the final backend should be a drop-in replacement for both
iOS and ELF targets. Hopefully strictly better in both cases.

A big choice approaching is exactly how we go about the merge. In my
opinion trying an actual merge on .td files isn't going to work
(massive inconsistency even if we could make it happen technically)
so
we're going to have to pick one of the two as a core for the final
backend, and strip all the useful bits out of the other one
cherry-pick style.

Yep, I'd suspect as much.

In any case, I agree with everyone else :wink: -- go ahead and commit it.

-Hal

I just tried to apply the patches to the community clang and llvm tips and
there are conflicts.

Do you guys plan to rebase the patches?

I vote for importing the ARM64 backend into the public tree as soon as
possible.

Thanks,
Ana.

My suggestions:

1. Do #1 below as you suggested as quickly as feasible.
2. String up and flog any and all executives and lawyers who forced the world to wait since September for this. Perhaps beat them with a big stick labeled "Technical Debt."
3. A few minor review things that popped out at me:

libc++: _LIBCPP_NONUNIQUE_RTTI_BIT needs a block comment to explain why.
llvm:
  include/LLVM/MC/MCAsmInfo.h: ^meast^means
  Linker Optimization Hints seem to be documented in Radar. Perhaps a bit more commenting in here?
  I also saw a few 80-column violations scroll by, and several first line comment length issues as well.

I look forward to arm64 and the new relocations landing in lld soon as well. :slight_smile:

Alex

Are these two backends ABI compatible?

They should be, where there's overlap. AArch64 doesn't have any MachO
support at the moment. ARM64 does have ELF support (obviously with
less testing than AArch64's). Any ABI discrepancy would be considered
a bug.

It depends on what you mean. The ARM64 backend supports the standard AAPCS64 ABI, and as Tim says, any discrepancies are bugs. It also supports a slightly different ABI that Apple uses. We settled on a calling convention before the standard was fully specified, and we ended up not adopting all of the changes that came later. The places where we diverge are documented here:

https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html