From shap at eros-os.com Wed May 14 07:55:32 2008 From: shap at eros-os.com (Jonathan S. Shapiro) Date: Wed, 14 May 2008 08:55:32 -0400 Subject: [bitc-dev] Conditional compilation Message-ID: <1210769732.6988.22.camel@shaptop.om-md.eros-os.com> I am coming to the reluctant conclusion that BitC needs a limited form of conditional compilation system. Let me give two illustrations of the problem: 1. Arch-dependent alignment I just spent two days hunting down a subtle C alignment problem. On the Coldfire CPU, int32 quantities are only aligned at 16 bit boundaries. Which is fine, except that the kernel re-entry stack pointer has to be aligned at a 32-bit boundary (this is a hardware restriction). By sheer dumb luck I had a structure that worked, and then I added a change that made it magically stop working. Other platforms have no such alignment constraint. This one is actually a nice problem to have, because (aside from the effect on sizeof()) alignment is non-semantic from a program analysis perspective. But the point is that real programs will require mechanisms that let them be parameterized to both the architecture and the target platform. 2. Debugging Elision In debugging some low-level (driver) Coyotos application code, I needed to introduce a bunch of printfs. In consequence, I had to give these applications a capability to a writable stream. In consequence, they are no longer confined, and in the production implementations they really need to be. It is easy enough to reconfigure the build to replace the logging cap with a null cap in production configurations, but in some cases it may be desirable to remove the debugging printf code entirely when no debugging I/O will be possible (note: probably not in this particular case, but in general). Now both of these use cases boil down to setting some constant value and then writing code that is conditional on that value. This can be handled through the module include system. The case that scares me more is the case where platform dependencies force us to change the type signatures of procedures. For example, the seek() system call on a 64-bit filesystem platform has a different signature than the one on a 32-bit filesystem platform. The problem with these cases is that they touch the type system, and that raises issues about type propagation, inference, and compatibility. Thoughts on how to handle this? shap From swaroop at cs.jhu.edu Wed May 14 11:21:16 2008 From: swaroop at cs.jhu.edu (Swaroop Sridhar) Date: Wed, 14 May 2008 12:21:16 -0400 Subject: [bitc-dev] Conditional compilation In-Reply-To: <1210769732.6988.22.camel@shaptop.om-md.eros-os.com> References: <1210769732.6988.22.camel@shaptop.om-md.eros-os.com> Message-ID: <482B117C.9000600@cs.jhu.edu> Jonathan S. Shapiro wrote: > I am coming to the reluctant conclusion that BitC needs a limited form > of conditional compilation system. Let me give two illustrations of the > problem: > > 1. Arch-dependent alignment > 2. Debugging Elision > > Now both of these use cases boil down to setting some constant value and > then writing code that is conditional on that value. This can be handled > through the module include system. I agree. > The case that scares me more is the case where platform dependencies > force us to change the type signatures of procedures. For example, the > seek() system call on a 64-bit filesystem platform has a different > signature than the one on a 32-bit filesystem platform. I think what you are saying here is that we can parametrize functions over layout, alignment, etc., but this will complicate their signatures? For example: we could have seek: (forall (fs 'b) (fn ('b) ())) Different implementations will supply different instances for seek: (definstance (fs int32) ...) (definstance (fs int64) ...) However, this might result in complicated function/interface signatures in general, because of multiple parameters like architecture, endian-ness, file-system, etc. > The problem with > these cases is that they touch the type system, and that raises issues > about type propagation, inference, and compatibility. This is definitely true. Since layout/alignment constraints are not syntax directed, I think that they will increase the amount of annotations that the user must provide in general. The inference system will propagate types and constraints, but (more detailed) annotations will be necessary at declarations and interfaces. I think that the compatibility issues are similar to mutability -- it is just that there are more atomic labels in this case. The following paper uses a type/effect system for parameterizing C-like programs over low-level layout/alignment constraints: ``A Theory of Platform-Dependent Low-Level Software'': Marius Nita, Dan Grossman, and Craig Chambers http://www.cs.washington.edu/homes/djg/papers/tpdlls.pdf I have not read the paper completely. It describes the logical type system that produces layout constraints for a simple subset of C (basically a sequence of statements and loops). Trying to infer these constraints will either have to be done on the whole program, or require detailed type+effect annotations. In a way, this problem can be partially alleviated by using conditional compilation. For example, we already have support for the most trivial form of architecture dependent conditional compilation in the form of `word' type, which varies by architecture. A similar approach is proposed in ``Automatic Transformation of Bit-Level C Code to Support Multiple Equivalent Data Layouts'': Marius Nita and Dan Grossman http://www.cs.washington.edu/homes/djg/papers/nita-cc08.pdf In their system, programmers write code assuming a particular data layout, but specify how different layouts of the same data relate to each other. A translation tool generates code for the others layouts. Swaroop. From shap at eros-os.com Wed May 14 13:19:45 2008 From: shap at eros-os.com (Jonathan S. Shapiro) Date: Wed, 14 May 2008 14:19:45 -0400 Subject: [bitc-dev] Conditional compilation In-Reply-To: <482B117C.9000600@cs.jhu.edu> References: <1210769732.6988.22.camel@shaptop.om-md.eros-os.com> <482B117C.9000600@cs.jhu.edu> Message-ID: <1210789185.18954.104.camel@shaptop.om-md.eros-os.com> On Wed, 2008-05-14 at 12:21 -0400, Swaroop Sridhar wrote: > > The case that scares me more is the case where platform dependencies > > force us to change the type signatures of procedures. For example, the > > seek() system call on a 64-bit filesystem platform has a different > > signature than the one on a 32-bit filesystem platform. > > I think what you are saying here is that we can parametrize functions > over layout, alignment, etc., but this will complicate their signatures? > > For example: we could have > > seek: (forall (fs 'b) (fn ('b) ())) Umm. No, this isn't what I meant at all. I think what I was saying is that we need to look again at having some mechanism for typealias. There is a two-sided problem here. On the one hand, we must enable users to properly define something like off_t for their target platform. On the other, off_t is an integral type, and valid programs are likely to run into typing problems when the type of off_t changes. Off the top of my head, I don't see a good solution for this at the moment. > This is definitely true. Since layout/alignment constraints are not > syntax directed, I think that they will increase the amount of > annotations that the user must provide in general. I'm not concerned here about annotation at all. If you want a non-conventional layout constraint, we clearly cannot discover it "by magic". > The following paper uses a type/effect system for parameterizing C-like > programs over low-level layout/alignment constraints: > ``A Theory of Platform-Dependent Low-Level Software'': Marius Nita, > Dan Grossman, and Craig Chambers > http://www.cs.washington.edu/homes/djg/papers/tpdlls.pdf Thanks for that pointer. > In a way, this problem can be partially alleviated by using conditional > compilation. For example, we already have support for the most trivial > form of architecture dependent conditional compilation in the form of > `word' type, which varies by architecture. That isn't enough for the problem I am thinking about. The example use-case was that int32 is 16 bit aligned on Coldfire, but I had a structure containing a lot of these where one part of the structure really needed to be aligned at a 32-bit boundary. > A similar approach is proposed in > ``Automatic Transformation of Bit-Level C Code to Support Multiple > Equivalent Data Layouts'': Marius Nita and Dan Grossman > http://www.cs.washington.edu/homes/djg/papers/nita-cc08.pdf I'll look at that too. shap