[LLVMdev] [cfe-dev] RFC: A proposal to move toward using C++11 features in LLVM & Clang / bounding support for old host compilers

David Chisnall David.Chisnall at cl.cam.ac.uk
Thu Nov 7 01:10:49 PST 2013


On 6 Nov 2013, at 19:23, Renato Golin <renato.golin at linaro.org> wrote:

> BUT, right now working off a release is painful because of the
> integration cost of upgrading to a new release.  APIs totally change,
> new bugs have to be tracked down, performance regressions fixed, etc.
> Integrating our changes is a lot of work but it's not the only hard
> part.  Dealing with all of the upstream changes at once is a massive
> undertaking.

I'm actually in two minds about this.  The attributes churn over the last year was horrendous, so I've now gone back to only tracking releases for some out-of-tree projects.  APIs were introduced with little thought, replaced, renamed, and finally stabilised, and no documentation appeared.  It's easier to suffer this pain once every six months than once every svn up.

And this is VERY bad for the LLVM community, because it means that people who aren't LLVM developers won't be testing trunk.  They'll wait for a new release, then start testing if their code is broken.  We saw this with 3.3 when there were a flurry of questions about API changes straight after the release.  None of these should have come as a surprise to people if they'd been following trunk.

> So, here we have an even more serious problem. I can only see these options:
> 
> 1. Ignore releases, everyone works on trunk
>   - Changes are gradual
>   1.a No API changes
>     - No code breakage, we can use compilers as old as Stallman
>     - Every platform is covered
>     - The toolchain doesn't evolve
>   1.b. API changes between each release
>     - API changes under our feet, massive work all the time
>     - Many API changes can happen at the same time
>     - Warning time can be as little as one day
>     - The toolchain evolves with time

There is a middle ground, which is used by most libraries that are not LLVM: you have a deprecation policy so that APIs are deprecated in one release and then removed in the next (or the one after that).  

This does impose a burden on LLVM developers, because it means that you have to reimplement the old APIs in terms of the new ones.  In other projects, I've found that this forces you to think very hard about the API changes, and after a period of initial pain the result is much cleaner APIs.  

For trivial changes, where someone decides to change the spelling of a method because the old one didn't meet some convention (I've lost count of the number of times this has happened), it means that now you get a compiler warning saying 'getfoo() is deprecated, use getFoo() instead', rather than a 'getfoo() doesn't exist, go and read the docs (if they exist) to find out what it is called this week'.

> 2. Use stable releases, only core developers work on trunk
>   - Changes are big, infrequent
>   2.a No API changes
>     - No code breakage, we can use compilers as old as Stallman
>     - Every platform is covered
>     - The toolchain doesn't evolve
>   2.b API changes between each release
>     - API changes only after *at least* six months notice
>     - Massive work to move code, but only twice a year
>     - The toolchain evolves with time
> 
> In a nutshell, if we want the toolchain to evolve with time, we'll need to have API changes, and we'll need to update surrounding software to cope with that. The only difference is if we want to be doing this as our day-to-day job, or twice a year (or even less than that if you stay on a release for a while longer). I personally think that it's more manageable to do that on releases than on trunk (been there, done that, and it sucks).
> 
> All projects that depend on GCC do that on a release basis (including kernels, distros, etc) and they have a massive undertaking on each release of the toolchain. That includes new errors, new libraries, new options. In your case it's a little worse, because it'll also change the compiler you'll have to use on *your* project, and that's not something GCC users are used to, but it has to happen one day or another.

I don't think GCC is the right comparison, because GCC is a compiler.  LLVM is (intended to be) a set of reusable libraries for building compilers.  

Maintaining approximately stable APIs and providing a deprecation strategy and well-documented upgrade mechanisms (i.e. If you are using this API, you need to stop and start using this one.  Here is where the new one is documented, and here are some examples of how it's used.) is the difference between LLVM being a set of reusable libraries and LLVM being a bunch of common code that's been factored out of a few programs.

David





More information about the llvm-dev mailing list