LLVM 4.0 AVR backend

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

LLVM 4.0 AVR backend

David Brown-4
It might be a little heretical to ask here, but has anyone tried out the
experimental AVR backend in the latest llvm/clang release?  I have not
made much use of clang, but it's been good for gcc to have a bit of
friendly competition.  I think it will be interesting to see how
clang/llvm differs from gcc for the AVR.


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

Erik Christiansen-2
Reply-To: [hidden email]

On 16.03.17 08:54, David Brown wrote:
> It might be a little heretical to ask here, but has anyone tried out the
> experimental AVR backend in the latest llvm/clang release?  I have not
> made much use of clang, but it's been good for gcc to have a bit of
> friendly competition.  I think it will be interesting to see how
> clang/llvm differs from gcc for the AVR.

No, I haven't tried it. As even gcc backend support moves at a sedate
pace, I'm moved to wonder who works on the llvm avr backend?

Your move to discover what user base it has is a good one, but after a
couple of decades of using gcc on multiple targets, I'm probably rusted
on to the toolchain which has served me so well for so long in so many
battles.

Erik


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

David Brown-4
On 16/03/17 09:30, Erik Christiansen wrote:

> Reply-To: [hidden email]
>
> On 16.03.17 08:54, David Brown wrote:
>> It might be a little heretical to ask here, but has anyone tried out the
>> experimental AVR backend in the latest llvm/clang release?  I have not
>> made much use of clang, but it's been good for gcc to have a bit of
>> friendly competition.  I think it will be interesting to see how
>> clang/llvm differs from gcc for the AVR.
>
> No, I haven't tried it. As even gcc backend support moves at a sedate
> pace, I'm moved to wonder who works on the llvm avr backend?
>
> Your move to discover what user base it has is a good one, but after a
> couple of decades of using gcc on multiple targets, I'm probably rusted
> on to the toolchain which has served me so well for so long in so many
> battles.
>

I don't really know anything about the llvm AVR backend, or who is
working on it - I just saw it described in the release notes for llvm 4.0.

I too have been using gcc on a range of targets for something like 20
years (building a gcc cross-compiler for the 68k running on Windows was
not an easy job in those days!), and I haven't had any new projects for
the AVR for a good while.  But I am always interested to see if
alternatives suit my needs better - if llvm/clang can do a better job
for me than gcc, I'm as loyal as a cat.




_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

Senthil Kumar Selvaraj-2
In reply to this post by David Brown-4

David Brown writes:

> It might be a little heretical to ask here, but has anyone tried out the
> experimental AVR backend in the latest llvm/clang release?  I have not
> made much use of clang, but it's been good for gcc to have a bit of
> friendly competition.  I think it will be interesting to see how
> clang/llvm differs from gcc for the AVR.

I built it a while back when I added basic support for avr to clang.
Dylan McKay, who IIRC has corresponded in this list before, owns the
backend, and has added a bunch of support to clang as well. His
primary motivation is to get the Rust programming language running on
the avr, again IIRC.

Last I checked, I still had to use the binutils linker, as lld didn't
yet know about the avr. The generated code did look suboptimal compared
to gcc, but I didn't play around much to be honest.

Regards
Senthil

>
>
> _______________________________________________
> AVR-GCC-list mailing list
> [hidden email]
> https://lists.nongnu.org/mailman/listinfo/avr-gcc-list


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

David Brown-4
On 16/03/17 11:22, Senthil Kumar Selvaraj wrote:

>
> David Brown writes:
>
>> It might be a little heretical to ask here, but has anyone tried out the
>> experimental AVR backend in the latest llvm/clang release?  I have not
>> made much use of clang, but it's been good for gcc to have a bit of
>> friendly competition.  I think it will be interesting to see how
>> clang/llvm differs from gcc for the AVR.
>
> I built it a while back when I added basic support for avr to clang.
> Dylan McKay, who IIRC has corresponded in this list before, owns the
> backend, and has added a bunch of support to clang as well. His
> primary motivation is to get the Rust programming language running on
> the avr, again IIRC.
>
> Last I checked, I still had to use the binutils linker, as lld didn't
> yet know about the avr. The generated code did look suboptimal compared
> to gcc, but I didn't play around much to be honest.
>

Thanks for that information.

It would be interesting to know if clang/llvm could generate better code
for the AVR.  gcc has a few fundamental problems with the port.  In
particular, gcc expects its targets to have registers capable of holding
an int - in this case, 16 bits.  So the AVR port of gcc has to work with
register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole
passes try to remove redundant operations.  But there are always some
redundant operations that get left, and the register allocator cannot
take full advantage of the AVR's registers when you are using 8-bit
types.  I have no idea if the same thing affects llvm, or if there is
potential for getting better results there.

Of course, this would require someone spending a good deal of time and
effort on the task - it would be a challenge to justify it as a business
decision for Microchip.



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

Victor Aprea-2
ICBW but I think the CodeBender team were using Clang at least, though I don't think they were using LLVM. GCC is pretty entrenched, but there was a good deal of excitement about the rise of LLVM last year IIRC...

Cheers,
Vic

Victor Aprea // Wicked Device

On Thu, Mar 16, 2017 at 7:12 AM, David Brown <[hidden email]> wrote:
On 16/03/17 11:22, Senthil Kumar Selvaraj wrote:
>
> David Brown writes:
>
>> It might be a little heretical to ask here, but has anyone tried out the
>> experimental AVR backend in the latest llvm/clang release?  I have not
>> made much use of clang, but it's been good for gcc to have a bit of
>> friendly competition.  I think it will be interesting to see how
>> clang/llvm differs from gcc for the AVR.
>
> I built it a while back when I added basic support for avr to clang.
> Dylan McKay, who IIRC has corresponded in this list before, owns the
> backend, and has added a bunch of support to clang as well. His
> primary motivation is to get the Rust programming language running on
> the avr, again IIRC.
>
> Last I checked, I still had to use the binutils linker, as lld didn't
> yet know about the avr. The generated code did look suboptimal compared
> to gcc, but I didn't play around much to be honest.
>

Thanks for that information.

It would be interesting to know if clang/llvm could generate better code
for the AVR.  gcc has a few fundamental problems with the port.  In
particular, gcc expects its targets to have registers capable of holding
an int - in this case, 16 bits.  So the AVR port of gcc has to work with
register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole
passes try to remove redundant operations.  But there are always some
redundant operations that get left, and the register allocator cannot
take full advantage of the AVR's registers when you are using 8-bit
types.  I have no idea if the same thing affects llvm, or if there is
potential for getting better results there.

Of course, this would require someone spending a good deal of time and
effort on the task - it would be a challenge to justify it as a business
decision for Microchip.



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

Dylan McKay-2
Maintainer of the LLVM backend here.

gcc expects its targets to have registers capable of holding
> an int - in this case, 16 bits.  So the AVR port of gcc has to work with
> register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole
> passes try to remove redundant operations.

That's interesting - LLVM doesn't have this specific problem.

One problem the backend _does_ have is that LLVM assumes that the size of your largest register makes up the standard register size. This means that LLVM sees the X,Y,Z pointer registers, assumes 16-bit operations are generally supported, and then doesn't decide to split many 16-bit operations into 8-bit ones. To work around this, we define sets of 16-bit pseudo instructions and then have a custom pass to lower the IR into assembly, often producing suboptimal code.

This problem could be fixed, but it requires some changes to LLVM which are quite large.

Regarding the state of the backend, GCC should definitely be preferred. Now that LLVM 4.0 has been tagged, we're working on enabling that AVR backend in Rust. There will likely be a few assertion errors and latent bugs being hit.

On Fri, Mar 17, 2017 at 2:14 AM, Victor Aprea <[hidden email]> wrote:
ICBW but I think the CodeBender team were using Clang at least, though I don't think they were using LLVM. GCC is pretty entrenched, but there was a good deal of excitement about the rise of LLVM last year IIRC...

Cheers,
Vic

Victor Aprea // Wicked Device

On Thu, Mar 16, 2017 at 7:12 AM, David Brown <[hidden email]> wrote:
On 16/03/17 11:22, Senthil Kumar Selvaraj wrote:
>
> David Brown writes:
>
>> It might be a little heretical to ask here, but has anyone tried out the
>> experimental AVR backend in the latest llvm/clang release?  I have not
>> made much use of clang, but it's been good for gcc to have a bit of
>> friendly competition.  I think it will be interesting to see how
>> clang/llvm differs from gcc for the AVR.
>
> I built it a while back when I added basic support for avr to clang.
> Dylan McKay, who IIRC has corresponded in this list before, owns the
> backend, and has added a bunch of support to clang as well. His
> primary motivation is to get the Rust programming language running on
> the avr, again IIRC.
>
> Last I checked, I still had to use the binutils linker, as lld didn't
> yet know about the avr. The generated code did look suboptimal compared
> to gcc, but I didn't play around much to be honest.
>

Thanks for that information.

It would be interesting to know if clang/llvm could generate better code
for the AVR.  gcc has a few fundamental problems with the port.  In
particular, gcc expects its targets to have registers capable of holding
an int - in this case, 16 bits.  So the AVR port of gcc has to work with
register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole
passes try to remove redundant operations.  But there are always some
redundant operations that get left, and the register allocator cannot
take full advantage of the AVR's registers when you are using 8-bit
types.  I have no idea if the same thing affects llvm, or if there is
potential for getting better results there.

Of course, this would require someone spending a good deal of time and
effort on the task - it would be a challenge to justify it as a business
decision for Microchip.



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

David Brown-4
On 16/03/17 22:33, Dylan McKay wrote:

> Maintainer of the LLVM backend here.
>
>> gcc expects its targets to have registers capable of holding
>> an int - in this case, 16 bits.  So the AVR port of gcc has to work with
>> register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole
>> passes try to remove redundant operations.
>
> That's interesting - LLVM doesn't have this specific problem.
>
> One problem the backend _does_ have is that LLVM assumes that the size
> of your largest register makes up the standard register size. This means
> that LLVM sees the X,Y,Z pointer registers, assumes 16-bit operations
> are generally supported, and then doesn't decide to split many 16-bit
> operations into 8-bit ones. To work around this, we define sets of
> 16-bit pseudo instructions and then have a custom pass to lower the IR
> into assembly, often producing suboptimal code.

That sounds like a similar problem - or at least, a problem with similar
effects.  I haven't actually studied the AVR port of gcc (I haven't dug
into the details of gcc in general), but know a bit about it from using
it for many years, following the lists, discussions on "missed
optimisation" bug reports, and so on.  It is entirely possible that my
description of avr gcc's challenge is not quite right, and that it is
more similar to llvm's.

avr gcc has collected a fair number of peephole optimisations to improve
the quality of the output, and does quite a good job of it these days -
but you still see occasional code where calculations are done with
16-bit register pairs even though the top half will be thrown away.

But remember, although it is good to aim for the best possible code, in
most cases "good enough is good enough".  The beauty of tools like gcc
and llvm for the avr is not in getting "perfect" code - it is in the
fantastic range of features of these two tools, compared to any
alternatives in the market.  And while it is challenging to get the
low-level optimisations as good as possible, these compilers have lots
of high-level optimisations that you get "for free".

>
> This problem could be fixed, but it requires some changes to LLVM which
> are quite large.

I can appreciate that.  Like gcc, llvm supports a range of targets but
has to make certain assumptions about them in order to avoid being
overly complex.  For example, I believe gcc requires CHAR_BIT to be 8,
which makes many things a lot easier but excludes its use for some DSP
devices and "dinosaur" processors.  I assume llvm has similar
restrictions.

>
> Regarding the state of the backend, GCC should definitely be preferred.
> Now that LLVM 4.0 has been tagged, we're working on enabling that AVR
> backend in Rust. There will likely be a few assertion errors and latent
> bugs being hit.

I have not tried Rust as yet, but I think it is marvellous to see a
choice here.

C is basically a static language - it is something we know, it is well
enough defined and small enough that it offers few surprises (once you
understand the details), and it has /stability/.  That stability is a
strength and a curse - C does not change (much) with time.  When we want
a language for embedded programming that gains new features and
possibilities, that is currently C++.  Rust offers some features and
benefits over C++ - while C++ can do things that Rust cannot.  I look
forward to Rust maturing and these two languages being inspired by each
other - they will always be different, but both gain from competition in
a similar market.

Kind of like gcc and llvm :-)



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

MortenEngelhardt.Olsen
Personally, I can only applaud the goal of running Rust on AVR. (talking as a current spare-time rustacean).

 :: Morten

-----Original Message-----
From: AVR-GCC-list [mailto:avr-gcc-list-bounces+meolsen=[hidden email]] On Behalf Of David Brown
Sent: 17. mars 2017 09:40
To: Dylan McKay <[hidden email]>; Victor Aprea <[hidden email]>
Cc: [hidden email]; Senthil Kumar Selvaraj - I41766 <[hidden email]>
Subject: Re: [avr-gcc-list] LLVM 4.0 AVR backend

On 16/03/17 22:33, Dylan McKay wrote:

> Maintainer of the LLVM backend here.
>
>> gcc expects its targets to have registers capable of holding an int -
>> in this case, 16 bits.  So the AVR port of gcc has to work with
>> register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend
>> peephole passes try to remove redundant operations.
>
> That's interesting - LLVM doesn't have this specific problem.
>
> One problem the backend _does_ have is that LLVM assumes that the size
> of your largest register makes up the standard register size. This
> means that LLVM sees the X,Y,Z pointer registers, assumes 16-bit
> operations are generally supported, and then doesn't decide to split
> many 16-bit operations into 8-bit ones. To work around this, we define
> sets of 16-bit pseudo instructions and then have a custom pass to
> lower the IR into assembly, often producing suboptimal code.

That sounds like a similar problem - or at least, a problem with similar effects.  I haven't actually studied the AVR port of gcc (I haven't dug into the details of gcc in general), but know a bit about it from using it for many years, following the lists, discussions on "missed optimisation" bug reports, and so on.  It is entirely possible that my description of avr gcc's challenge is not quite right, and that it is more similar to llvm's.

avr gcc has collected a fair number of peephole optimisations to improve the quality of the output, and does quite a good job of it these days - but you still see occasional code where calculations are done with 16-bit register pairs even though the top half will be thrown away.

But remember, although it is good to aim for the best possible code, in most cases "good enough is good enough".  The beauty of tools like gcc and llvm for the avr is not in getting "perfect" code - it is in the fantastic range of features of these two tools, compared to any alternatives in the market.  And while it is challenging to get the low-level optimisations as good as possible, these compilers have lots of high-level optimisations that you get "for free".

>
> This problem could be fixed, but it requires some changes to LLVM
> which are quite large.

I can appreciate that.  Like gcc, llvm supports a range of targets but has to make certain assumptions about them in order to avoid being overly complex.  For example, I believe gcc requires CHAR_BIT to be 8, which makes many things a lot easier but excludes its use for some DSP devices and "dinosaur" processors.  I assume llvm has similar restrictions.

>
> Regarding the state of the backend, GCC should definitely be preferred.
> Now that LLVM 4.0 has been tagged, we're working on enabling that AVR
> backend in Rust. There will likely be a few assertion errors and
> latent bugs being hit.

I have not tried Rust as yet, but I think it is marvellous to see a choice here.

C is basically a static language - it is something we know, it is well enough defined and small enough that it offers few surprises (once you understand the details), and it has /stability/.  That stability is a strength and a curse - C does not change (much) with time.  When we want a language for embedded programming that gains new features and possibilities, that is currently C++.  Rust offers some features and benefits over C++ - while C++ can do things that Rust cannot.  I look forward to Rust maturing and these two languages being inspired by each other - they will always be different, but both gain from competition in a similar market.

Kind of like gcc and llvm :-)



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

Georg-Johann Lay-2
In reply to this post by David Brown-4
On 16.03.2017 12:12, David Brown wrote:
> It would be interesting to know if clang/llvm could generate better code
> for the AVR.  gcc has a few fundamental problems with the port.  In
> particular, gcc expects its targets to have registers capable of holding
> an int - in this case, 16 bits.  So the AVR port of gcc has to work with

No.

> register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole

That's not a "problem" of GCC, the avr backend chose to implement it
that way, presumably to improve probability for MOVW which only works
on register /pairs/, same for ADIW, SBIW.  I didn't try to remove
that restriction from the backend for non-MOVW targets, but it would
be also an ABI change because inline asm constraint "r" guarantees
a register pair.

And I wouldn't expect a dramatic increase of code performance from
allowing odd registers.

> passes try to remove redundant operations.  But there are always some
> redundant operations that get left, and the register allocator cannot
> take full advantage of the AVR's registers when you are using 8-bit
> types.  I have no idea if the same thing affects llvm, or if there is
> potential for getting better results there.

Some of the artefacts are due to GCC being a multi-pass compiler, and
it's not always clear whether it is wise to split an instruction before
register allocation.  Most complaints address twiddling bytes like
when combining several bytes into one scalar.  One approach is more
combining and post-reload splitting which I added some time ago.
But as always, I won't backport pure optimizations and will follow
GCC policy to only backport "real" bug fixes.

Johann

> Of course, this would require someone spending a good deal of time and
> effort on the task - it would be a challenge to justify it as a business
> decision for Microchip.


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: LLVM 4.0 AVR backend

David Brown-4
On 17/03/17 17:02, Georg-Johann Lay wrote:

> On 16.03.2017 12:12, David Brown wrote:
>> It would be interesting to know if clang/llvm could generate better code
>> for the AVR.  gcc has a few fundamental problems with the port.  In
>> particular, gcc expects its targets to have registers capable of holding
>> an int - in this case, 16 bits.  So the AVR port of gcc has to work with
>
> No.
>
>> register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole
>
> That's not a "problem" of GCC, the avr backend chose to implement it
> that way, presumably to improve probability for MOVW which only works
> on register /pairs/, same for ADIW, SBIW.  I didn't try to remove
> that restriction from the backend for non-MOVW targets, but it would
> be also an ABI change because inline asm constraint "r" guarantees
> a register pair.

OK - thank you for the correction.

>
> And I wouldn't expect a dramatic increase of code performance from
> allowing odd registers.

Really?  I would have thought it could be significant, at least when the
programmer is careful to use 8-bit types when possible.  I have
certainly seen generated code where data is put in stack frames even
though there are odd registers that have not been used.  However, it is
a long time since I have updated my avr gcc (the latest I have used is
4.5.1), if things have changed here.

>
>> passes try to remove redundant operations.  But there are always some
>> redundant operations that get left, and the register allocator cannot
>> take full advantage of the AVR's registers when you are using 8-bit
>> types.  I have no idea if the same thing affects llvm, or if there is
>> potential for getting better results there.
>
> Some of the artefacts are due to GCC being a multi-pass compiler, and
> it's not always clear whether it is wise to split an instruction before
> register allocation.  Most complaints address twiddling bytes like
> when combining several bytes into one scalar.  One approach is more
> combining and post-reload splitting which I added some time ago.
> But as always, I won't backport pure optimizations and will follow
> GCC policy to only backport "real" bug fixes.

Of course.  Backporting quickly leads to duplicate effort, so it only
makes sense for serious problems such as incorrect code generation.

Maybe I just need to update my avr gcc compiler!

>
> Johann
>
>> Of course, this would require someone spending a good deal of time and
>> effort on the task - it would be a challenge to justify it as a business
>> decision for Microchip.
>


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list