[LLVMdev] [RFC] Developer Policy for LLVM C API

46 views
Skip to first unread message

Juergen Ributzka

unread,
Jul 17, 2015, 3:39:54 PM7/17/15
to LLVM Dev, Lang Hames
Hi @ll,

a few of us had recently a discussion about how to manage the C API and possible policies regarding addition, maintenance, deprecation, and removal of API.

Even thought there is a strong agreement in the community that we shouldn't break released C API and should be backwards compatible, there doesn’t seem to be a developer policy that backs that up. This is something we should fix.

I was wondering what the interested parties think of the current approach and what could/should we improve to make the use and maintenance of the C API easier for users and the developers alike.

I was hoping we could also introduce a process that allows the removal of an API after it has been deprecated for a whole release and the release notes stated that it will be removed.

Thoughts? Comments?

Cheers,
Juergen
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Sean Silva

unread,
Jul 17, 2015, 3:57:28 PM7/17/15
to Juergen Ributzka, Lang Hames, LLVM Dev
I think it makes sense to officially document this. It has apparently never graduated from being "tribal knowledge".

As far as the concrete details, I haven't thought too much, but the deprecation process you suggested makes sense to me.

-- Sean Silva

Eric Christopher

unread,
Jul 17, 2015, 4:32:38 PM7/17/15
to Sean Silva, Juergen Ributzka, Lang Hames, LLVM Dev
Hi Juergen, Sean,

I definitely agree with needing to write down the policy and definitely any policy should include a deprecation time :)

Did you want to write up something and let us poke at it?

A couple of thoughts outside of a deprecation policy:

a) guarantee that the api itself won't go away, but could possibly be turned into a noop? (i.e. source compatibility)
b) versioning? (Should we add support for versioning in anyhow? Maybe a C API version 2 to start this off with?)
c) One of the big things appears to be the push and pull for "A C API for all C++ entry points" along with "We don't want to get locked into immobility because we have a C API for all C++ entry points". Perhaps part of this might be defining an actual stable set of things along with an unstable set of things?

What was the rest of your discussion on this? Any particular points you think the community would be interested in?

Just some random thoughts.

-eric

Eric Christopher

unread,
Jul 17, 2015, 4:41:41 PM7/17/15
to Sean Silva, Juergen Ributzka, Lang Hames, LLVM Dev
Oh, one other addition here:

I'm totally ok with a small first patch that puts in a developer policy of "we try to keep the C API stable across releases and the deprecation policy is blah blah blah"

-eric

Eric Christopher

unread,
Jul 17, 2015, 5:10:19 PM7/17/15
to Rafael Espíndola, LLVM Dev, Lang Hames
On Fri, Jul 17, 2015 at 2:05 PM Rafael Espíndola <rafael.e...@gmail.com> wrote:
> c) One of the big things appears to be the push and pull for "A C API for
> all C++ entry points" along with "We don't want to get locked into
> immobility because we have a C API for all C++ entry points". Perhaps part
> of this might be defining an actual stable set of things along with an
> unstable set of things?

This is a good idea. We should clearly document a subset that is stable.

Being stable should also have a very high bar. Things like "we have a
shipping product that has to work with two versions of llvm and has to
dynamic link with it".

So something that the webkit jit needs is in. Some API that is in C
just so someone can statically link a C/Go/Ocaml program with llvm is
not.


This is pretty open to abuse, let's just define what seems to make sense rather than tying it like this.

-eric
 
Cheers,
Rafael

Rafael Espíndola

unread,
Jul 17, 2015, 5:12:31 PM7/17/15
to Eric Christopher, LLVM Dev, Lang Hames
> c) One of the big things appears to be the push and pull for "A C API for
> all C++ entry points" along with "We don't want to get locked into
> immobility because we have a C API for all C++ entry points". Perhaps part
> of this might be defining an actual stable set of things along with an
> unstable set of things?

This is a good idea. We should clearly document a subset that is stable.

Being stable should also have a very high bar. Things like "we have a
shipping product that has to work with two versions of llvm and has to
dynamic link with it".

So something that the webkit jit needs is in. Some API that is in C
just so someone can statically link a C/Go/Ocaml program with llvm is
not.

Cheers,
Rafael

Philip Reames

unread,
Jul 17, 2015, 5:38:05 PM7/17/15
to Rafael Espíndola, Eric Christopher, Lang Hames, LLVM Dev


On 07/17/2015 02:05 PM, Rafael Espíndola wrote:
>> c) One of the big things appears to be the push and pull for "A C API for
>> all C++ entry points" along with "We don't want to get locked into
>> immobility because we have a C API for all C++ entry points". Perhaps part
>> of this might be defining an actual stable set of things along with an
>> unstable set of things?
> This is a good idea. We should clearly document a subset that is stable.
>
> Being stable should also have a very high bar. Things like "we have a
> shipping product that has to work with two versions of llvm and has to
> dynamic link with it".
+1 to the general notion of stable vs unstable

>
> So something that the webkit jit needs is in. Some API that is in C
> just so someone can statically link a C/Go/Ocaml program with llvm is
> not.
-1 to this particular definition thereof

Rafael Espíndola

unread,
Jul 17, 2015, 5:45:41 PM7/17/15
to Philip Reames, Lang Hames, LLVM Dev
>> So something that the webkit jit needs is in. Some API that is in C
>> just so someone can statically link a C/Go/Ocaml program with llvm is
>> not.
>
> -1 to this particular definition thereof

Not a definition, just an example of something that has a reason to
use dynamic linking and work with multiple versions of llvm.

Hayden Livingston

unread,
Jul 17, 2015, 6:08:50 PM7/17/15
to Rafael Espíndola, LLVM Dev, Lang Hames
Can we also codify when something should be added to the C API? For a
lot of folks the C API is the only usable interface. I am one of them.

We are not as vocally represented because don't generally give back to
the community, usually because we are just consumers of this library.
(Or maybe I'm totally wrong and lots of us give back).

For example, ORC APIs in C the bindings.

Rafael Espíndola

unread,
Jul 17, 2015, 6:27:21 PM7/17/15
to Hayden Livingston, LLVM Dev, Lang Hames
On 17 July 2015 at 15:04, Hayden Livingston <halivi...@gmail.com> wrote:
> Can we also codify when something should be added to the C API? For a
> lot of folks the C API is the only usable interface. I am one of them.
>
> We are not as vocally represented because don't generally give back to
> the community, usually because we are just consumers of this library.
> (Or maybe I'm totally wrong and lots of us give back).
>
> For example, ORC APIs in C the bindings.

If they are not guaranteed to be stable, I don't think we need any
special restrictions on adding new C apis.

Philip Reames

unread,
Jul 17, 2015, 6:33:52 PM7/17/15
to Juergen Ributzka, LLVM Dev, Lang Hames

On 07/17/2015 12:36 PM, Juergen Ributzka wrote:
> Hi @ll,
>
> a few of us had recently a discussion about how to manage the C API and possible policies regarding addition, maintenance, deprecation, and removal of API.
>
> Even thought there is a strong agreement in the community that we shouldn't break released C API and should be backwards compatible, there doesn’t seem to be a developer policy that backs that up. This is something we should fix.

+1


>
> I was wondering what the interested parties think of the current approach and what could/should we improve to make the use and maintenance of the C API easier for users and the developers alike.
>
> I was hoping we could also introduce a process that allows the removal of an API after it has been deprecated for a whole release and the release notes stated that it will be removed.

+1

I'd suggest we also have an officially unofficial policy about not
versioning just for style or cleanliness reasons. i.e. We should try to
minimize churn of the API unless it's actually needed, or supporting an
old API becomes unjustifiably complicated.

Eric Christopher

unread,
Jul 17, 2015, 6:36:01 PM7/17/15
to Philip Reames, Juergen Ributzka, LLVM Dev, Lang Hames
On Fri, Jul 17, 2015 at 3:33 PM Philip Reames <list...@philipreames.com> wrote:


On 07/17/2015 12:36 PM, Juergen Ributzka wrote:
> Hi @ll,
>
> a few of us had recently a discussion about how to manage the C API and possible policies regarding addition, maintenance, deprecation, and removal of API.
>
> Even thought there is a strong agreement in the community that we shouldn't break released C API and should be backwards compatible, there doesn’t seem to be a developer policy that backs that up. This is something we should fix.
+1
>
> I was wondering what the interested parties think of the current approach and what could/should we improve to make the use and maintenance of the C API easier for users and the developers alike.
>
> I was hoping we could also introduce a process that allows the removal of an API after it has been deprecated for a whole release and the release notes stated that it will be removed.
+1

I'd suggest we also have an officially unofficial policy about not
versioning just for style or cleanliness reasons.  i.e. We should try to
minimize churn of the API unless it's actually needed, or supporting an
old API becomes unjustifiably complicated.


Could you explain what you mean here? As far as I can tell this is "I don't want versioning unless I want versioning and then I'll want it because it's convenient for me"

-eric 

Eric Christopher

unread,
Jul 17, 2015, 6:43:56 PM7/17/15
to Juergen Ributzka, LLVM Dev, Lang Hames
Hi Juergen,

I've actually got another, perhaps more radical, plan. Let's just get rid of the C API or move it to another project. This simplifies a lot of the plans here where people have too many different ideas of how the C API should work.

At this point the people who want a stable C API per incremental version can do that and handle the overhead of porting themselves and the people that want a C API that just happens to be a C interface can have a wrapper (or SWIG or whatever they want).

I realize it's radical, but it seems that there are so many different wants for C API here that solving everyone's problems or wants is going to be impossible.

-eric

Philip Reames

unread,
Jul 17, 2015, 7:21:18 PM7/17/15
to Eric Christopher, Juergen Ributzka, LLVM Dev, Lang Hames
What I was trying to get at is that we should aim to not change the API unless it's actually *needed*.  Just because we have a versioning mechanism doesn't mean we should freely make use of it.  Some examples:
- Renaming a method in the API - bad
- Dropping a method involving functionality no longer supported - good

We tend to be much more free with the C++ APIs (with good cause).  I don't want to see this applied to the C API.  We should still seek to keep a stable API even if we do have a formal mechanism for revising it.

p.s. If that sounds obvious, you've read it right.  :)  This wasn't intended to be controversial, just to cement in writing the attitude we've already taken. 

p.p.s. The preceding would only apply to the "stable" parts of the API. 

Philip

Philip Reames

unread,
Jul 17, 2015, 7:27:48 PM7/17/15
to Eric Christopher, Juergen Ributzka, LLVM Dev, Lang Hames


On 07/17/2015 03:41 PM, Eric Christopher wrote:
Hi Juergen,

I've actually got another, perhaps more radical, plan. Let's just get rid of the C API or move it to another project. This simplifies a lot of the plans here where people have too many different ideas of how the C API should work.

At this point the people who want a stable C API per incremental version can do that and handle the overhead of porting themselves and the people that want a C API that just happens to be a C interface can have a wrapper (or SWIG or whatever they want).

I realize it's radical, but it seems that there are so many different wants for C API here that solving everyone's problems or wants is going to be impossible.
I really haven't seen that much of a split here honestly.  Everyone agrees we need a stable C API for core functionality.  The only disagreement seems to be about when something gets promoted to "core" status and even that's been minimal. 

(I have no opinion w.r.t. your actual proposal.)

David Majnemer

unread,
Jul 17, 2015, 8:23:01 PM7/17/15
to Eric Christopher, Lang Hames, LLVM Dev
On Fri, Jul 17, 2015 at 3:41 PM, Eric Christopher <echr...@gmail.com> wrote:
Hi Juergen,

I've actually got another, perhaps more radical, plan. Let's just get rid of the C API or move it to another project. This simplifies a lot of the plans here where people have too many different ideas of how the C API should work.

At this point the people who want a stable C API per incremental version can do that and handle the overhead of porting themselves and the people that want a C API that just happens to be a C interface can have a wrapper (or SWIG or whatever they want).

I realize it's radical, but it seems that there are so many different wants for C API here that solving everyone's problems or wants is going to be impossible.

I am strongly in favor of moving the bindings, C or otherwise, to another project.

Jim Grosbach

unread,
Jul 17, 2015, 9:01:44 PM7/17/15
to Eric Christopher, Owen Anderson, Lang Hames, LLVM Dev
This is interesting. If we did this, the same would apply to the other language bindings, too, yes? We’d end up with a few different mini-projects (or possibly just one w/ a configurable build system).

It would also set the stage for, potentially, multiple sets of bindings. As Eric points out, one size doesn’t always fit all, and our current path of trying to find some sort of happy medium may not be the best. This would allow us to have one, or more, binding set which map to different use cases appropriately.

So long as we set things up in a way that makes it easy to configure both a unified and discrete (in tree vs. using a “make install” artifact) build, had good bot coverage, etc, etc, I think this could work really well.


That said, it’s also a bit of a derail from and most orthogonal to Juergen’s main topic. Perhaps we should split this off to a different thread?

-Jim

Sean Silva

unread,
Jul 17, 2015, 9:07:08 PM7/17/15
to Eric Christopher, Lang Hames, LLVM Dev
On Fri, Jul 17, 2015 at 3:41 PM, Eric Christopher <echr...@gmail.com> wrote:
Hi Juergen,

I've actually got another, perhaps more radical, plan. Let's just get rid of the C API or move it to another project. This simplifies a lot of the plans here where people have too many different ideas of how the C API should work.

At this point the people who want a stable C API per incremental version can do that and handle the overhead of porting themselves and the people that want a C API that just happens to be a C interface can have a wrapper (or SWIG or whatever they want).

I realize it's radical, but it seems that there are so many different wants for C API here that solving everyone's problems or wants is going to be impossible.

This might backfire if this results in a much better tested interface between the C++ and C API implementation, such that we will actually get red bots when we "break the C API" and be forced to fix it.

-- Sean Silva

Lang Hames

unread,
Jul 17, 2015, 9:27:22 PM7/17/15
to Jim Grosbach, Owen Anderson, LLVM Dev, Lang Hames
+1 for Eric's idea, as it would solve my problem with providing a C API for Orc: Being a templated and component-based library, there's no definitive Orc JIT configuration to provide a C API for. Separate projects would allow different clients to pick an API that makes sense for them.

Cheers,
Lang.

Andrew Wilkins

unread,
Jul 17, 2015, 9:32:55 PM7/17/15
to Eric Christopher, Sean Silva, Juergen Ributzka, LLVM Dev, Lang Hames
On Sat, 18 Jul 2015 at 04:34 Eric Christopher <echr...@gmail.com> wrote:
Hi Juergen, Sean,

I definitely agree with needing to write down the policy and definitely any policy should include a deprecation time :)

Did you want to write up something and let us poke at it?

A couple of thoughts outside of a deprecation policy:

a) guarantee that the api itself won't go away, but could possibly be turned into a noop? (i.e. source compatibility)

This was done recently with the Go bindings to make the LLVM tree green, which led to not-immediately-obvious breakage in llgo. If source compatibility were broken, it would have been clear what needed to be changed. As a user, I'd prefer that over preserving source compatibility.

b) versioning? (Should we add support for versioning in anyhow? Maybe a C API version 2 to start this off with?)
c) One of the big things appears to be the push and pull for "A C API for all C++ entry points" along with "We don't want to get locked into immobility because we have a C API for all C++ entry points". Perhaps part of this might be defining an actual stable set of things along with an unstable set of things?

IMO, just having a single stable C API for the core would keep things clear; no having to check whether this function or that function is stable. Separate non-stable APIs can be maintained outside the core easily enough. They don't even need to be in-tree if they're not stable.

Reid Kleckner

unread,
Jul 30, 2015, 2:54:37 PM7/30/15
to Juergen Ributzka, Lang Hames, LLVM Dev
+1, I agree with keeping the existing C API stable, and requiring one release of deprecation with an alternative in place to remove something from it.

Nobody is going to take the time to design a well-thought out C API that is powerful enough for frontend IRGen and is forward compatible with future versions of LLVM. That's an unsolved problem. We should stick with what we have.

The only thing we can do to keep LLVM flexible is to limit the set of new things we expose over the C API boundary, which I'm totally in favor of.

On Fri, Jul 17, 2015 at 12:36 PM, Juergen Ributzka <jue...@apple.com> wrote:

Eric Christopher

unread,
Jul 30, 2015, 4:09:19 PM7/30/15
to Reid Kleckner, Juergen Ributzka, LLVM Dev, Lang Hames
I think the idea of having a (hopefully not too) fluid C API that can encompass everything people want to be able to do in the language of their choice and calls into LLVM to do work sounds like a great idea. I think it would be useful to expand the number of people who are able to do research and development with LLVM without having to reinvent LLVM. That said, this is directly at odds with our desire to have a stable C API that can be supported long term (as you said at the end of the email). I.e. where do we draw the line on what can or should be added to the C API? What if the people that want the functionality are willing to deal with it being (occasionally) unstable?

I don't agree with you that no one will take the time to design a well thought out C API. We've managed to get a lot of real world experience lately at both how these things will be used, and how we'll maintain such a thing. I think Juergen and others are a good group to come up with an answer to our engineering challenge.

-eric

Reid Kleckner

unread,
Jul 30, 2015, 4:55:57 PM7/30/15
to Eric Christopher, LLVM Dev, Lang Hames
On Thu, Jul 30, 2015 at 1:04 PM, Eric Christopher <echr...@gmail.com> wrote:
I think the idea of having a (hopefully not too) fluid C API that can encompass everything people want to be able to do in the language of their choice and calls into LLVM to do work sounds like a great idea. I think it would be useful to expand the number of people who are able to do research and development with LLVM without having to reinvent LLVM. That said, this is directly at odds with our desire to have a stable C API that can be supported long term (as you said at the end of the email). I.e. where do we draw the line on what can or should be added to the C API? What if the people that want the functionality are willing to deal with it being (occasionally) unstable?

Yeah, splitting the concerns of API completeness and API stability seems like a good idea. Right now we have clients like llgo that want to generate new debug info, and are perfectly happy to keep up to date with changes. They need a complete API, not a stable API, and our insistence on a stable C API has actually gotten in the way here.
 
I don't agree with you that no one will take the time to design a well thought out C API. We've managed to get a lot of real world experience lately at both how these things will be used, and how we'll maintain such a thing. I think Juergen and others are a good group to come up with an answer to our engineering challenge.

Sure, if people are planning to design a stable API that leave LLVM with more flexibility, then I'm all in favor of switching over to it. So far I haven't heard any new suggestions. I think any such design would probably be write-only, and revolve around sharing the bitcode auto-upgrade logic.

Philip Reames

unread,
Jul 30, 2015, 6:40:27 PM7/30/15
to Reid Kleckner, Eric Christopher, Lang Hames, LLVM Dev
It's sounds like we've reached two rough conclusions:
1) We need both a stable and a non-stable fully featured C API.  It's a somewhat open question whether both or either should be part of the main tree. 
2) Everyone seemed okay with the proposed deprecation policy for the stable API.

Given this, I would propose we designate the existing C API as the "hopefully stable, but subject to future clean up per policy..."  Update the documentation to note that LLVM does not currently have a fully featured C API.  Update the docs to reflect the deprecation policy for the existing C API. 

We can then start discussing how we should create the fully featured API.  I'd lean towards a tool like Swig, but we could also do it purely on demand.  For example, I could add some shims for the experimental GC support without committing to supporting the current APIs long term. 

Philip

Eric Christopher

unread,
Jul 30, 2015, 6:49:39 PM7/30/15
to Philip Reames, Reid Kleckner, LLVM Dev
On Thu, Jul 30, 2015 at 3:36 PM Philip Reames <list...@philipreames.com> wrote:
It's sounds like we've reached two rough conclusions:
1) We need both a stable and a non-stable fully featured C API.  It's a somewhat open question whether both or either should be part of the main tree. 

I'm fine with the stable API being in the main tree. I proposed moving it out originally so that it could get some work before moving it in. I'm reasonably confident that we can get something working in tree for a stable API by the next release though.
 
2) Everyone seemed okay with the proposed deprecation policy for the stable API.


Yes.
 
Given this, I would propose we designate the existing C API as the "hopefully stable, but subject to future clean up per policy..."  Update

This is where we disagree. I've tried to lay out a design that I think would be good for a stable API and the current one does not meet any guidelines there. It's too much a thin wrapper on top of the existing C++ API. There's no clear delineation for when/how/whether we extend it. It's already easy to subtly break the existing one.

My proposal here is simply thus:

We deprecate the existing API as "moving to unstable". For the next release cycle, as a new C API comes into existence, we continue our best effort toward keeping the existing API as stable as possible ("best effort") just like we always have. At the next release we flip the switch that says "this is now not stable, please use X". In the mean time we can either a) move a bindings level C API into a separate directory starting with the existing wrapped C++ API that we have as part of the C API, or b) expand in the current directory and copy a set of APIs off to another directory. How to do this with minimal churn in external projects is important - this is why I'm inclined to say that the bindings API reside in the current C API directory, but others are more hesitant, I'm just not sure in their mind how the final transition from "best effort stable" to "stable".

-eric

Mehdi Amini

unread,
Jul 30, 2015, 7:01:13 PM7/30/15
to Eric Christopher, LLVM Dev
On Jul 30, 2015, at 3:46 PM, Eric Christopher <echr...@gmail.com> wrote:



On Thu, Jul 30, 2015 at 3:36 PM Philip Reames <list...@philipreames.com> wrote:
It's sounds like we've reached two rough conclusions:
1) We need both a stable and a non-stable fully featured C API.  It's a somewhat open question whether both or either should be part of the main tree. 

I'm fine with the stable API being in the main tree. I proposed moving it out originally so that it could get some work before moving it in. I'm reasonably confident that we can get something working in tree for a stable API by the next release though.
 
2) Everyone seemed okay with the proposed deprecation policy for the stable API.


Yes.
 
Given this, I would propose we designate the existing C API as the "hopefully stable, but subject to future clean up per policy..."  Update

This is where we disagree. I've tried to lay out a design that I think would be good for a stable API and the current one does not meet any guidelines there. It's too much a thin wrapper on top of the existing C++ API. There's no clear delineation for when/how/whether we extend it. It's already easy to subtly break the existing one.

My proposal here is simply thus:

We deprecate the existing API as "moving to unstable". For the next release cycle, as a new C API comes into existence, we continue our best effort toward keeping the existing API as stable as possible ("best effort") just like we always have. At the next release we flip the switch that says "this is now not stable, please use X”.

+1 for me.

Applying a strict policy on the current API while it currently mixes “binding-like” functionality with element of a stable API seems like a heavy constraint. I’d rather have an opt-in policy rather than opt-out.
Deprecating all the current C API in 3.8 and considering “unstable” after 3.9 seems reasonable and leave some time to opt-in what has to be stable after 3.9 (3.10 or 4.0? I don’t know the numbering policy).

— 
Mehdi

Philip Reames

unread,
Jul 31, 2015, 5:25:20 PM7/31/15
to Eric Christopher, Reid Kleckner, LLVM Dev


On 07/30/2015 03:46 PM, Eric Christopher wrote:


On Thu, Jul 30, 2015 at 3:36 PM Philip Reames <list...@philipreames.com> wrote:
It's sounds like we've reached two rough conclusions:
1) We need both a stable and a non-stable fully featured C API.  It's a somewhat open question whether both or either should be part of the main tree. 

I'm fine with the stable API being in the main tree. I proposed moving it out originally so that it could get some work before moving it in. I'm reasonably confident that we can get something working in tree for a stable API by the next release though.
 
2) Everyone seemed okay with the proposed deprecation policy for the stable API.


Yes.
 
Given this, I would propose we designate the existing C API as the "hopefully stable, but subject to future clean up per policy..."  Update

This is where we disagree. I've tried to lay out a design that I think would be good for a stable API and the current one does not meet any guidelines there. It's too much a thin wrapper on top of the existing C++ API. There's no clear delineation for when/how/whether we extend it. It's already easy to subtly break the existing one.

My proposal here is simply thus:

We deprecate the existing API as "moving to unstable". For the next release cycle, as a new C API comes into existence, we continue our best effort toward keeping the existing API as stable as possible ("best effort") just like we always have. At the next release we flip the switch that says "this is now not stable, please use X".
I have no real objection to this, but I am also not a consumer of the existing C API.  I think this is a big enough change that we'd need to make sure this got widely disseminated via a top-level RFC email, LLVM Weekly, and the release notes. 
In the mean time we can either a) move a bindings level C API into a separate directory starting with the existing wrapped C++ API that we have as part of the C API, or b) expand in the current directory and copy a set of APIs off to another directory. How to do this with minimal churn in external projects is important - this is why I'm inclined to say that the bindings API reside in the current C API directory, but others are more hesitant, I'm just not sure in their mind how the final transition from "best effort stable" to "stable".
I'm having a hard time parsing this paragraph.  Specifically "expand" what?  and which API is transitioning?  If I'm reading the rest of your proposal right, we effectively won't have *any* stable API in tree after the current one is downgraded to "unstable C binding".  What did I miss? 

deadal nix via llvm-dev

unread,
Aug 16, 2015, 9:45:54 PM8/16/15
to llvm...@lists.llvm.org
Being able to read and generate IR is at least some very basic thing we can agree on is needed. Can we get some testing for it ? Personally I don't really mind if this is going to be stable or not, but at least, having some test coverage would allow to take whatever path that is going to be taken willingly.

I'd like also to remind all to not fall into the hypothetical nirvana fallacy, ie comparing proposed solution with an idealized and unrealized one. That's a good recipe for endless bikescheding when pretty much anythign would be better than the status quo.

2015-07-17 12:36 GMT-07:00 Juergen Ributzka <jue...@apple.com>:
Hi @ll,

a few of us had recently a discussion about how to manage the C API and possible policies regarding addition, maintenance, deprecation, and removal of API.

Even thought there is a strong agreement in the community that we shouldn't break released C API and should be backwards compatible, there doesn’t seem to be a developer policy that backs that up. This is something we should fix.

I was wondering what the interested parties think of the current approach and what could/should we improve to make the use and maintenance of the C API easier for users and the developers alike.

I was hoping we could also introduce a process that allows the removal of an API after it has been deprecated for a whole release and the release notes stated that it will be removed.

Thoughts? Comments?

Cheers,
Juergen

Eric Christopher via llvm-dev

unread,
Aug 17, 2015, 12:48:19 AM8/17/15
to deadal nix, llvm...@lists.llvm.org
On Sun, Aug 16, 2015 at 6:45 PM deadal nix via llvm-dev <llvm...@lists.llvm.org> wrote:
Being able to read and generate IR is at least some very basic thing we can agree on is needed. Can we get some testing for it ? Personally I don't really mind if this is going to be stable or not, but at least, having some test coverage would allow to take whatever path that is going to be taken willingly.


Right, and that's the problem. Expanding the C API to cover reading and generating IR in a stable way will lock the C++ API down in a way that I'm not comfortable with - I think it has already gone too far.

-eric
 
I'd like also to remind all to not fall into the hypothetical nirvana fallacy, ie comparing proposed solution with an idealized and unrealized one. That's a good recipe for endless bikescheding when pretty much anythign would be better than the status quo.

2015-07-17 12:36 GMT-07:00 Juergen Ributzka <jue...@apple.com>:
Hi @ll,

a few of us had recently a discussion about how to manage the C API and possible policies regarding addition, maintenance, deprecation, and removal of API.

Even thought there is a strong agreement in the community that we shouldn't break released C API and should be backwards compatible, there doesn’t seem to be a developer policy that backs that up. This is something we should fix.

I was wondering what the interested parties think of the current approach and what could/should we improve to make the use and maintenance of the C API easier for users and the developers alike.

I was hoping we could also introduce a process that allows the removal of an API after it has been deprecated for a whole release and the release notes stated that it will be removed.

Thoughts? Comments?

Cheers,
Juergen
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

_______________________________________________
LLVM Developers mailing list

deadal nix via llvm-dev

unread,
Aug 17, 2015, 12:50:08 AM8/17/15
to Eric Christopher, llvm...@lists.llvm.org
2015-08-16 21:47 GMT-07:00 Eric Christopher <echr...@gmail.com>:


On Sun, Aug 16, 2015 at 6:45 PM deadal nix via llvm-dev <llvm...@lists.llvm.org> wrote:
Being able to read and generate IR is at least some very basic thing we can agree on is needed. Can we get some testing for it ? Personally I don't really mind if this is going to be stable or not, but at least, having some test coverage would allow to take whatever path that is going to be taken willingly.


Right, and that's the problem. Expanding the C API to cover reading and generating IR in a stable way will lock the C++ API down in a way that I'm not comfortable with - I think it has already gone too far.

-eric

That seems like a bare minimum.

The C++ evolve from one version to another, what is preventing the C API to do the same ?

Eric Christopher via llvm-dev

unread,
Aug 17, 2015, 12:51:53 AM8/17/15
to deadal nix, llvm...@lists.llvm.org
The promise of stability. We don't promise that the C++ API will stay stable.

-eric 

deadal nix via llvm-dev

unread,
Aug 17, 2015, 1:35:29 AM8/17/15
to Eric Christopher, llvm-dev
Why was that promise be made in the first place ? Has it been made in the first place ?

Also, whether, the C API is stable or change between version, being able to read and write IR from it seems like a bare minimum and having test for this as well.

Having a test does not prevent the API to be changed. It just ensure that it is changed willingly as one would have to update the test in addition of the API.

Eric Christopher via llvm-dev

unread,
Aug 17, 2015, 2:30:18 AM8/17/15
to deadal nix, llvm-dev
On Sun, Aug 16, 2015 at 10:35 PM deadal nix <dead...@gmail.com> wrote:


2015-08-16 21:51 GMT-07:00 Eric Christopher <echr...@gmail.com>:


On Sun, Aug 16, 2015 at 9:49 PM deadal nix <dead...@gmail.com> wrote:
2015-08-16 21:47 GMT-07:00 Eric Christopher <echr...@gmail.com>:


On Sun, Aug 16, 2015 at 6:45 PM deadal nix via llvm-dev <llvm...@lists.llvm.org> wrote:
Being able to read and generate IR is at least some very basic thing we can agree on is needed. Can we get some testing for it ? Personally I don't really mind if this is going to be stable or not, but at least, having some test coverage would allow to take whatever path that is going to be taken willingly.


Right, and that's the problem. Expanding the C API to cover reading and generating IR in a stable way will lock the C++ API down in a way that I'm not comfortable with - I think it has already gone too far.

-eric

That seems like a bare minimum.

The C++ evolve from one version to another, what is preventing the C API to do the same ?


The promise of stability. We don't promise that the C++ API will stay stable.

-eric 


Why was that promise be made in the first place ? Has it been made in the first place ?


Please read the rest of the thread :)
 
Also, whether, the C API is stable or change between version, being able to read and write IR from it seems like a bare minimum and having test for this as well.

Having a test does not prevent the API to be changed. It just ensure that it is changed willingly as one would have to update the test in addition of the API.


Your reading of this is not the same as anyone else's reading for what would be considered stable.

-eric

deadal nix via llvm-dev

unread,
Aug 17, 2015, 3:00:49 AM8/17/15
to Eric Christopher, llvm-dev
2015-08-16 23:29 GMT-07:00 Eric Christopher <echr...@gmail.com>:



Please read the rest of the thread :)
 

I did. Nobody seems to agree on what is supposed to be what, if the current API is supposed to be the stable one or not and so on. Quite frankly, I do not care. I want to be able to use the C API, and I would like for it to be tested so we avoid episodes like the landing pad one in the future.


 
Also, whether, the C API is stable or change between version, being able to read and write IR from it seems like a bare minimum and having test for this as well.

Having a test does not prevent the API to be changed. It just ensure that it is changed willingly as one would have to update the test in addition of the API.


Your reading of this is not the same as anyone else's reading for what would be considered stable.

-eric

Once again, doesn't matter. i'm trying to get some test in.

This thread has gone full ouroboros . Basically, few contributor use the C API, and it is not well tested. Yet, when some people use the C API (some in this thread showed up, including myself) or want to contribute to it, it always devolve into some endless bikescheding and nothing gets done.

Things is, core devs do not care for the most part about the C API. C API user have hard time to get involved because core dev do not care and it take an absurd amount of energy for a non core dev to get anything in.


Reid Kleckner via llvm-dev

unread,
Aug 17, 2015, 11:34:58 AM8/17/15
to deadal nix, llvm-dev
On Sun, Aug 16, 2015 at 10:34 PM, deadal nix via llvm-dev <llvm...@lists.llvm.org> wrote:

2015-08-16 21:51 GMT-07:00 Eric Christopher <echr...@gmail.com>:
The promise of stability. We don't promise that the C++ API will stay stable.


Why was that promise be made in the first place ? Has it been made in the first place ?

It sounds like you're in favor of dropping C API stability then, if it's holding us back? That feedback is actually really helpful. :)

There are really three goals here: flexibility to change LLVM IR, completeness of the C API, and stability of the C API. Pick two.

The goals are mutually incompatible and we have to trade off one for the other. Most of the LLVM core developers value goal #1, the ability to change the IR. Look at the pointee type changes that David Blaikie is working on, and the new EH representation. If we promise both stability and completeness, these things are impossible.

One way forward is to guarantee stability, but limit completeness. This would mean limiting the C API to constructs that will always and forever be easily represented in LLVM.

The other choice is to forget stability and wrap the C++ API completely, potentially with something auto-generated. We could make a more limited stability promise along the lines of "these APIs will be updated to reflect changes to the IR, and are otherwise stable." I think everyone would be fine with that.

Philip Reames via llvm-dev

unread,
Aug 17, 2015, 12:55:28 PM8/17/15
to Reid Kleckner, deadal nix, llvm-dev
In particular, such an API would be a good start to the "unstable" API which has been discussed.  If you wanted to use the opportunity to introduce such a thing, I'd be in support.  Put it in a different directory for now, but if we decide to merge the current C API into the unstable grouping, we'll combine them at some point. 

deadal nix via llvm-dev

unread,
Aug 17, 2015, 1:28:56 PM8/17/15
to Reid Kleckner, llvm-dev
2015-08-17 8:34 GMT-07:00 Reid Kleckner <r...@google.com>:
On Sun, Aug 16, 2015 at 10:34 PM, deadal nix via llvm-dev <llvm...@lists.llvm.org> wrote:

2015-08-16 21:51 GMT-07:00 Eric Christopher <echr...@gmail.com>:
The promise of stability. We don't promise that the C++ API will stay stable.


Why was that promise be made in the first place ? Has it been made in the first place ?

It sounds like you're in favor of dropping C API stability then, if it's holding us back? That feedback is actually really helpful. :)

There are really three goals here: flexibility to change LLVM IR, completeness of the C API, and stability of the C API. Pick two.


Yes but these aren't black and white IMO. These are need in tension, sure, but all API have these kind of problem not specifically the C API.

 
The goals are mutually incompatible and we have to trade off one for the other. Most of the LLVM core developers value goal #1, the ability to change the IR. Look at the pointee type changes that David Blaikie is working on, and the new EH representation. If we promise both stability and completeness, these things are impossible.


Yes I was actually thinking about that. This is the kind of change that justify a change in the C API IMO. We should try our best to keep the C API stable, but if somethign fundamental changes in LLVM, and that there is no nice way to map it to the old API, then

 
One way forward is to guarantee stability, but limit completeness. This would mean limiting the C API to constructs that will always and forever be easily represented in LLVM.


That would be a problem for me. It seems like other in this thread mentioned the incompleteness of the C API as a problem for them and mentioned the use of various hacks to work around it. On my side I tried to propose diff to increase completeness of the C API in the past, but the review process was frankly too painful and I mostly give up. I'd be up for being a maintainer of the C API if that is needed.

 
The other choice is to forget stability and wrap the C++ API completely, potentially with something auto-generated. We could make a more limited stability promise along the lines of "these APIs will be updated to reflect changes to the IR, and are otherwise stable." I think everyone would be fine with that.

I do not think this is a good idea. The C API is used a lot to use LLVM from other languages than C++ . When used directly from C, you get function signature, but when used from other languages, changing method randomly cause undefined behavior. For instance, the landing pad instruction was changed recently and the C API to create a landing pad was updated. As a result, 2 thing happened :
 - It was not possible to set the personality function from C, which is a problem for many frontends.
 - In other languages, as mangling remained the same, the thing compiles and fail randomly at runtime.

This need to be avoided as much as possible. I'd propose the following policy :
1/ Do change the IR as per need of LLVM development. The C API must not prevent LLVM to move forward.
2/ If the change can be mapped nicely without changing the C API, then do that.
3/ If there is no way to map it nicely, then update the C API.

For instance, the pointer update work would probably be a valid reason to go with 3/ .

Right now, as far as I'm concerned, the main limitation of the C API are the capability to set attributes and the capability to use atomic loads/stores.

In any ways, I do think the patch adding tests for existing API should be merged. The need for test for the C API was mentioned various times in this thread and I do think that whatever the road taken, having test is a good thing.

James Y Knight via llvm-dev

unread,
Aug 17, 2015, 3:31:17 PM8/17/15
to deadal nix, llvm-dev
As someone who used the LLVM C API for an experiment back in 2009ish (porting the SBCL lisp compiler to target LLVM as a backend -- never finished), I thought it was great that LLVM provided the C API. I was sad that it wasn't properly updated to include support for all the newly introduced IR features, though. (E.g. atomics). I tried to send patches for some of that stuff a while later, but didn't manage to get it in. (I wasn't active in llvm at that point, I was just trying to contribute a patch. I gave up.).

It doesn't make sense to me to have the C API be less than a full wrapping of the IR building functions. Having less than that, you almost might as well not have it at all. (Which would be sad.)

I'd like suggest that the most important thing for the C API is NOT a 100% promise of eternal compatibility, but to _strive_ for compatibility, as much as is realistically possible. If it's not possible, oh well. We're not talking about libc here, so the costs of changing it incompatibly -- with careful deliberation -- are not impossibly huge. I mean, even libstdc++ changes its ABI occassionally! LLVM's C API certainly shouldn't be considered more important to keep stable than libstdc++!

That said, incompatible changes ought not be made just for trivial reasons: they should be made when there's a true need, e.g. when an existing LLVM-C function cannot sensibly maintain its existing behavior anymore because the underlying functionality of LLVM was removed, or drastically changed.

I'd propose that the only 100% strict rule should be that if the ABI/API changes, it is done in a way that *loudly* breaks old programs -- e.g. they fail to compile, link, or run (depending on how the other-lang wrappers are accessing the API functions) -- not that you get some random weird misbehavior because a function's argument types or return type has been changed.

Ideally, if you're going to remove an API, you'd deprecate it first, if you can see the problem coming. Otherwise, oh well -- it's not reasonable to hold up LLVM development to adhere to deprecation policy on the C API.

That is:
1) Adding new functions for new LLVM functionality: great.
2) Removing old functions: if it's required -- after careful deliberation.
3) Modifying the signature of existing functions: no way.

A couple of concrete examples:

- Let's say you run out of space in an existing enum type (ahem, LLVMAttribute...).

You should introduce new function names, taking a better type (perhaps some sort of set type, instead of a fixed-width integer...), mark the old ones deprecated so that users will update to the new functions. But, keep the old ones around so that old code can keep working. There's no real need to remove the old deprecated functions -- they'll keep working as well as they ever did with the smaller-valued attributes.

- Let's say you remove types from pointers.

This is a change that can be seen coming up. So, one should fairly early on add an LLVMBuildGEP2 function that takes the extra type argument. Leave the old function name around for now (deprecated), because with the current state of LLVM, it can continue to work just fine.

When LLVM is changed to *actually* remove all pointer types in its core, then the LLVMBuildGEP function cannot reasonably continue to exist. It simply cannot work, if pointers don't have types, and the type isn't provided. So, remove it.

Preferably, there would be a release of LLVM in between with both functions available to let people have some time to adjust, but if not, oh well.


Daniel Berlin via llvm-dev

unread,
Aug 17, 2015, 3:46:43 PM8/17/15
to James Y Knight, llvm-dev
On Mon, Aug 17, 2015 at 12:31 PM, James Y Knight via llvm-dev
<llvm...@lists.llvm.org> wrote:
>
> I'd propose that the only 100% strict rule should be that if the ABI/API
> changes, it is done in a way that *loudly* breaks old programs -- e.g. they
> fail to compile, link, or run (depending on how the other-lang wrappers are
> accessing the API functions) -- not that you get some random weird
> misbehavior because a function's argument types or return type has been
> changed.


This would require a level of testing that we don't have, just to make
sure that happens, no?

>
> Ideally, if you're going to remove an API, you'd deprecate it first, if you
> can see the problem coming. Otherwise, oh well -- it's not reasonable to
> hold up LLVM development to adhere to deprecation policy on the C API.
>
> That is:
> 1) Adding new functions for new LLVM functionality: great.
> 2) Removing old functions: if it's required -- after careful deliberation.
> 3) Modifying the signature of existing functions: no way.
>
> A couple of concrete examples:
>
> - Let's say you run out of space in an existing enum type (ahem,
> LLVMAttribute...).
>
> You should introduce new function names, taking a better type (perhaps some
> sort of set type, instead of a fixed-width integer...), mark the old ones
> deprecated so that users will update to the new functions. But, keep the old
> ones around so that old code can keep working. There's no real need to
> remove the old deprecated functions -- they'll keep working as well as they
> ever did with the smaller-valued attributes.

Maybe?
Maybe not?
Maybe they were broken when built.

deadal nix via llvm-dev

unread,
Aug 17, 2015, 3:50:56 PM8/17/15
to Daniel Berlin, llvm-dev

2015-08-17 12:46 GMT-07:00 Daniel Berlin <dbe...@dberlin.org>:
On Mon, Aug 17, 2015 at 12:31 PM, James Y Knight via llvm-dev
<llvm...@lists.llvm.org> wrote:
>
> I'd propose that the only 100% strict rule should be that if the ABI/API
> changes, it is done in a way that *loudly* breaks old programs -- e.g. they
> fail to compile, link, or run (depending on how the other-lang wrappers are
> accessing the API functions) -- not that you get some random weird
> misbehavior because a function's argument types or return type has been
> changed.


This would require a level of testing that we don't have, just to make
sure that happens, no?


Daniel Berlin via llvm-dev

unread,
Aug 17, 2015, 3:54:57 PM8/17/15
to deadal nix, llvm-dev
So, while a good start, do we believe we can realistically achieve
95+% C APi test coverage or whatever and keep it there?

(That seems necessary if we made James's 100% strict rule a 100% strict rule)

James Y Knight via llvm-dev

unread,
Aug 17, 2015, 4:01:25 PM8/17/15
to Daniel Berlin, llvm-dev
On Mon, Aug 17, 2015 at 3:46 PM, Daniel Berlin <dbe...@dberlin.org> wrote:
On Mon, Aug 17, 2015 at 12:31 PM, James Y Knight via llvm-dev
<llvm...@lists.llvm.org> wrote:
>
> I'd propose that the only 100% strict rule should be that if the ABI/API
> changes, it is done in a way that *loudly* breaks old programs -- e.g. they
> fail to compile, link, or run (depending on how the other-lang wrappers are
> accessing the API functions) -- not that you get some random weird
> misbehavior because a function's argument types or return type has been
> changed.


This would require a level of testing that we don't have, just to make
sure that happens, no?

Okay, kinda? I mean, more testing is always good. If you're missing a test, and then break something by accident, well, that sucks. But, the important first step is to agree that the *policy* is to not change the C API in that way. If something like that does happen, treat it as a bug to be (hopefully) fixed, rather than something that's allowed by the development policy so "oh well".

With the way the C API is currently defined, maintaining that property actually seems like it's pretty straightforward, because all the types it uses are defined in the C API headers. So, basically: be careful about how you change the C API headers. Which people already are being.

Maybe I shouldn't have said "100% strict" -- I didn't actually mean "the world will explode if we get this wrong and introduce a bug" -- it certainly won't. It would just be inconvenient, so have a policy of not doing it.

Antoine Pitrou via llvm-dev

unread,
Aug 17, 2015, 4:20:38 PM8/17/15
to llvm...@lists.llvm.org

James Knight wrote:
> It doesn't make sense to me to have the C API be less than a full wrapping
> of the IR building functions. Having less than that, you almost might as
> well not have it at all. (Which would be sad.

As a data point, our approach in llvmlite (a lightweight LLVM binding
for Python -- http://llvmlite.pydata.org/) is to build the textual IR in
pure Python, to minimize the API contact surface with LLVM. But even
with that approach, the LLVM C API is too limited for us - we have to
call the C++ API at times.

> I'd propose that the only 100% strict rule should be that if the ABI/API
> changes, it is done in a way that *loudly* breaks old programs -- e.g. they
> fail to compile, link, or run (depending on how the other-lang wrappers are
> accessing the API functions) -- not that you get some random weird
> misbehavior because a function's argument types or return type has been
> changed.

I agree with this. Mandating that the C API is "100% stable" does not
seem to make a lot of sense when LLVM is changing so much otherwise, and
when you need to call C++ APIs anyway for non-toy applications...

Regards

Antoine.

David Blaikie via llvm-dev

unread,
Aug 17, 2015, 4:47:32 PM8/17/15
to James Y Knight, llvm-dev
On Mon, Aug 17, 2015 at 12:31 PM, James Y Knight via llvm-dev <llvm...@lists.llvm.org> wrote:
As someone who used the LLVM C API for an experiment back in 2009ish (porting the SBCL lisp compiler to target LLVM as a backend -- never finished), I thought it was great that LLVM provided the C API. I was sad that it wasn't properly updated to include support for all the newly introduced IR features, though. (E.g. atomics). I tried to send patches for some of that stuff a while later, but didn't manage to get it in. (I wasn't active in llvm at that point, I was just trying to contribute a patch. I gave up.).

It doesn't make sense to me to have the C API be less than a full wrapping of the IR building functions. Having less than that, you almost might as well not have it at all. (Which would be sad.)

I'd like suggest that the most important thing for the C API is NOT a 100% promise of eternal compatibility, but to _strive_ for compatibility, as much as is realistically possible. If it's not possible, oh well. We're not talking about libc here, so the costs of changing it incompatibly -- with careful deliberation -- are not impossibly huge. I mean, even libstdc++ changes its ABI occassionally! LLVM's C API certainly shouldn't be considered more important to keep stable than libstdc++!

That said, incompatible changes ought not be made just for trivial reasons: they should be made when there's a true need, e.g. when an existing LLVM-C function cannot sensibly maintain its existing behavior anymore because the underlying functionality of LLVM was removed, or drastically changed.

FWIW we do this (drastically change LLVM) pretty often. See Debug Info metadata, DataLayout, my typeless pointer work, Chandler's pass manager work, etc.
 

I'd propose that the only 100% strict rule should be that if the ABI/API changes, it is done in a way that *loudly* breaks old programs -- e.g. they fail to compile, link, or run (depending on how the other-lang wrappers are accessing the API functions) -- not that you get some random weird misbehavior because a function's argument types or return type has been changed.

Ideally, if you're going to remove an API, you'd deprecate it first, if you can see the problem coming. Otherwise, oh well -- it's not reasonable to hold up LLVM development to adhere to deprecation policy on the C API.

That is:
1) Adding new functions for new LLVM functionality: great.
2) Removing old functions: if it's required -- after careful deliberation.
3) Modifying the signature of existing functions: no way.

A couple of concrete examples:

- Let's say you run out of space in an existing enum type (ahem, LLVMAttribute...).

You should introduce new function names, taking a better type (perhaps some sort of set type, instead of a fixed-width integer...), mark the old ones deprecated so that users will update to the new functions. But, keep the old ones around so that old code can keep working. There's no real need to remove the old deprecated functions -- they'll keep working as well as they ever did with the smaller-valued attributes.

But does it? What if the code is checking if two functions have the same attributes (perhaps this is an invalid notion in the absence of information about specific attributes) - if you compare the smaller-ranged attributes, you might incorrectly conclude that these two functions have the same attributes. Similarly for "no attributes specified" - you look at the enum, see that none are set & conclude that it's a plain, uninteresting function - so you create another plain, no-attributes function you think you can make equivalent.
 

- Let's say you remove types from pointers.

This is a change that can be seen coming up. So, one should fairly early on add an LLVMBuildGEP2 function that takes the extra type argument. Leave the old function name around for now (deprecated), because with the current state of LLVM, it can continue to work just fine.

When LLVM is changed to *actually* remove all pointer types in its core, then the LLVMBuildGEP function cannot reasonably continue to exist. It simply cannot work, if pointers don't have types, and the type isn't provided. So, remove it.

Yep, this is one we /might/ be able to manage - because we'll probably have to keep typed pointer information around for old bitcode deserialization. (but it does make the API awkward - when we finally do remove LLVMBuildGEP, do we rename LLVMBuildGEP2? Do we leave it there? & then we need LLVMBuildGEP3, etc, as things evolve?))

Also this works for writing, but not for reading - if code was expecting to read IR and assumed that pointers had types and bitcasts were present, etc - it's going to have a Bad Time reading new IR... the APIs wouldn't make any sense (there would be no getPointeeType on PointerType anymore - there would be no Type that could be returned in response to that query)

That's part of Eric's point, I think, once the API is low level enough, it will churn with every change in LLVM or possible require some heroics to avoid that churn which will slow down LLVM's API velocity (which is somewhere around "ludicrous speed"), which is something we rather like. The only way to make the C API more stable is to make it higher level (see libLTO for an example) so that we can own the migration & shelter users from it through that abstraction. If it's low level, it's going to churn or slow us down (and probably both).
 

Eric Christopher via llvm-dev

unread,
Aug 17, 2015, 5:19:45 PM8/17/15
to David Blaikie, James Y Knight, llvm-dev
On Mon, Aug 17, 2015 at 1:47 PM David Blaikie via llvm-dev <llvm...@lists.llvm.org> wrote:
On Mon, Aug 17, 2015 at 12:31 PM, James Y Knight via llvm-dev <llvm...@lists.llvm.org> wrote:
As someone who used the LLVM C API for an experiment back in 2009ish (porting the SBCL lisp compiler to target LLVM as a backend -- never finished), I thought it was great that LLVM provided the C API. I was sad that it wasn't properly updated to include support for all the newly introduced IR features, though. (E.g. atomics). I tried to send patches for some of that stuff a while later, but didn't manage to get it in. (I wasn't active in llvm at that point, I was just trying to contribute a patch. I gave up.).

It doesn't make sense to me to have the C API be less than a full wrapping of the IR building functions. Having less than that, you almost might as well not have it at all. (Which would be sad.)

I'd like suggest that the most important thing for the C API is NOT a 100% promise of eternal compatibility, but to _strive_ for compatibility, as much as is realistically possible. If it's not possible, oh well. We're not talking about libc here, so the costs of changing it incompatibly -- with careful deliberation -- are not impossibly huge. I mean, even libstdc++ changes its ABI occassionally! LLVM's C API certainly shouldn't be considered more important to keep stable than libstdc++!

That said, incompatible changes ought not be made just for trivial reasons: they should be made when there's a true need, e.g. when an existing LLVM-C function cannot sensibly maintain its existing behavior anymore because the underlying functionality of LLVM was removed, or drastically changed.

FWIW we do this (drastically change LLVM) pretty often. See Debug Info metadata, DataLayout, my typeless pointer work, Chandler's pass manager work, etc.
 

I'd propose that the only 100% strict rule should be that if the ABI/API changes, it is done in a way that *loudly* breaks old programs -- e.g. they fail to compile, link, or run (depending on how the other-lang wrappers are accessing the API functions) -- not that you get some random weird misbehavior because a function's argument types or return type has been changed.

Ideally, if you're going to remove an API, you'd deprecate it first, if you can see the problem coming. Otherwise, oh well -- it's not reasonable to hold up LLVM development to adhere to deprecation policy on the C API.

That is:
1) Adding new functions for new LLVM functionality: great.
2) Removing old functions: if it's required -- after careful deliberation.
3) Modifying the signature of existing functions: no way.

A couple of concrete examples:

- Let's say you run out of space in an existing enum type (ahem, LLVMAttribute...).

You should introduce new function names, taking a better type (perhaps some sort of set type, instead of a fixed-width integer...), mark the old ones deprecated so that users will update to the new functions. But, keep the old ones around so that old code can keep working. There's no real need to remove the old deprecated functions -- they'll keep working as well as they ever did with the smaller-valued attributes.

But does it? What if the code is checking if two functions have the same attributes (perhaps this is an invalid notion in the absence of information about specific attributes) - if you compare the smaller-ranged attributes, you might incorrectly conclude that these two functions have the same attributes. Similarly for "no attributes specified" - you look at the enum, see that none are set & conclude that it's a plain, uninteresting function - so you create another plain, no-attributes function you think you can make equivalent.
 

- Let's say you remove types from pointers.

This is a change that can be seen coming up. So, one should fairly early on add an LLVMBuildGEP2 function that takes the extra type argument. Leave the old function name around for now (deprecated), because with the current state of LLVM, it can continue to work just fine.

When LLVM is changed to *actually* remove all pointer types in its core, then the LLVMBuildGEP function cannot reasonably continue to exist. It simply cannot work, if pointers don't have types, and the type isn't provided. So, remove it.

Yep, this is one we /might/ be able to manage - because we'll probably have to keep typed pointer information around for old bitcode deserialization. (but it does make the API awkward - when we finally do remove LLVMBuildGEP, do we rename LLVMBuildGEP2? Do we leave it there? & then we need LLVMBuildGEP3, etc, as things evolve?))

Also this works for writing, but not for reading - if code was expecting to read IR and assumed that pointers had types and bitcasts were present, etc - it's going to have a Bad Time reading new IR... the APIs wouldn't make any sense (there would be no getPointeeType on PointerType anymore - there would be no Type that could be returned in response to that query)

That's part of Eric's point, I think, once the API is low level enough, it will churn with every change in LLVM or possible require some heroics to avoid that churn which will slow down LLVM's API velocity (which is somewhere around "ludicrous speed"), which is something we rather like. The only way to make the C API more stable is to make it higher level (see libLTO for an example) so that we can own the migration & shelter users from it through that abstraction. If it's low level, it's going to churn or slow us down (and probably both).
 

Precisely :)

-eric

deadal nix via llvm-dev

unread,
Aug 17, 2015, 7:51:29 PM8/17/15
to David Blaikie, llvm-dev
2015-08-17 13:47 GMT-07:00 David Blaikie <dbla...@gmail.com>:

 

I'd propose that the only 100% strict rule should be that if the ABI/API changes, it is done in a way that *loudly* breaks old programs -- e.g. they fail to compile, link, or run (depending on how the other-lang wrappers are accessing the API functions) -- not that you get some random weird misbehavior because a function's argument types or return type has been changed.

Ideally, if you're going to remove an API, you'd deprecate it first, if you can see the problem coming. Otherwise, oh well -- it's not reasonable to hold up LLVM development to adhere to deprecation policy on the C API.

That is:
1) Adding new functions for new LLVM functionality: great.
2) Removing old functions: if it's required -- after careful deliberation.
3) Modifying the signature of existing functions: no way.

A couple of concrete examples:

- Let's say you run out of space in an existing enum type (ahem, LLVMAttribute...).

You should introduce new function names, taking a better type (perhaps some sort of set type, instead of a fixed-width integer...), mark the old ones deprecated so that users will update to the new functions. But, keep the old ones around so that old code can keep working. There's no real need to remove the old deprecated functions -- they'll keep working as well as they ever did with the smaller-valued attributes.

But does it? What if the code is checking if two functions have the same attributes (perhaps this is an invalid notion in the absence of information about specific attributes) - if you compare the smaller-ranged attributes, you might incorrectly conclude that these two functions have the same attributes. Similarly for "no attributes specified" - you look at the enum, see that none are set & conclude that it's a plain, uninteresting function - so you create another plain, no-attributes function you think you can make equivalent.
 

The attribute situation is fairly symptomatic of the state of the C API. You have 2 person in this thread that tried to improve that part of the API but eventually gave up. You have more person in that thread saying they'd need it and have to do various workaround to get things done without it.

 

- Let's say you remove types from pointers.

This is a change that can be seen coming up. So, one should fairly early on add an LLVMBuildGEP2 function that takes the extra type argument. Leave the old function name around for now (deprecated), because with the current state of LLVM, it can continue to work just fine.

When LLVM is changed to *actually* remove all pointer types in its core, then the LLVMBuildGEP function cannot reasonably continue to exist. It simply cannot work, if pointers don't have types, and the type isn't provided. So, remove it.

Yep, this is one we /might/ be able to manage - because we'll probably have to keep typed pointer information around for old bitcode deserialization. (but it does make the API awkward - when we finally do remove LLVMBuildGEP, do we rename LLVMBuildGEP2? Do we leave it there? & then we need LLVMBuildGEP3, etc, as things evolve?))


LLVMBuildTypedGEP or something and we can be done with it. When The old way is not supported anymore, LLVMBuildGEP can be removed, and eventually recycled if the need arise.
 
Also this works for writing, but not for reading - if code was expecting to read IR and assumed that pointers had types and bitcasts were present, etc - it's going to have a Bad Time reading new IR... the APIs wouldn't make any sense (there would be no getPointeeType on PointerType anymore - there would be no Type that could be returned in response to that query)

That's part of Eric's point, I think, once the API is low level enough, it will churn with every change in LLVM or possible require some heroics to avoid that churn which will slow down LLVM's API velocity (which is somewhere around "ludicrous speed"), which is something we rather like. The only way to make the C API more stable is to make it higher level (see libLTO for an example) so that we can own the migration & shelter users from it through that abstraction. If it's low level, it's going to churn or slow us down (and probably both).


Most of it won't move from one version to another. If something fundamental changes in LLVM from one version to the other, it is not a big deal to update the C API to reflect it. I do not think it is going to need anything heroic to keep it in place.

deadal nix via llvm-dev

unread,
Aug 19, 2015, 1:41:49 AM8/19/15
to David Blaikie, llvm-dev
Let's not get this die. The C API is too valuable to let this die.

I propose the following plan:
 - Add tests for the current API. This will allow to make sure that everything works and would ensure that changes are made intentionally, nto accidentally.
 - For area that do not exist in the C API right now, and for which support seems needed, we establish a plan to support it according to current functionality and planned evolution.
 - It is understood that the C API require more stability than the C++ one as it is often used accross language boundary where type checking cannot be done. On the other hand, no promise of stability is made so LLVM can still evolve at "ludicrous speed". If a change to LLVM cannot be mapped to the current API, the API is updated.

Deal ?

James Y Knight via llvm-dev

unread,
Aug 27, 2015, 7:34:40 PM8/27/15
to deadal nix, llvm-dev
On Aug 18, 2015, at 10:41 PM, deadal nix <dead...@gmail.com> wrote:
> Let's not get this die. The C API is too valuable to let this die.
>
> I propose the following plan:
> - Add tests for the current API. This will allow to make sure that everything works and would ensure that changes are made intentionally, nto accidentally.
> - For area that do not exist in the C API right now, and for which support seems needed, we establish a plan to support it according to current functionality and planned evolution.
> - It is understood that the C API require more stability than the C++ one as it is often used accross language boundary where type checking cannot be done. On the other hand, no promise of stability is made so LLVM can still evolve at "ludicrous speed". If a change to LLVM cannot be mapped to the current API, the API is updated.

+1 from me, with the additional "no changing existing functions' signatures, replace with new function if necessary" rule.

Perhaps you can make a patch to the DeveloperPolicy document actually writing down your view on the Developer Policy for the C API? Then we never have to debate it again, because it'll be written down for future reference. And, reviewing that patch will give people one last opportunity to object and/or bikeshed. :)

James

_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org

http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

James Y Knight via llvm-dev

unread,
Sep 15, 2015, 12:20:04 PM9/15/15
to deadal nix, llvm-dev
BTW for those following along, I wrote up a concrete proposal saying basically that, at http://reviews.llvm.org/D12685, if anyone else was interested in providing their input.

So far it's garnered a -1 from Eric.

Eric Christopher via llvm-dev

unread,
Sep 15, 2015, 2:22:45 PM9/15/15
to James Y Knight, deadal nix, llvm-dev
Just in case it wasn't said, I do want to thank you for sending out a concrete proposal here, I really appreciate it. It's good to have more proposals as direction.

I'm not sure what else I can say that I haven't as far as in this thread as a proposal, I can resend it out with a migration plan if that helps?

-eric

Reply all
Reply to author
Forward
0 new messages