[LLVMdev] Troubling promotion of return value to Integer ...
Jonathan S. Shapiro
shap at eros-os.com
Fri May 16 13:39:08 PDT 2008
On Fri, 2008-05-16 at 13:00 -0700, Chris Lattner wrote:
> Ok, so these are basically "copies with assertions". There are a
> couple of similar proposals for things like this (for example, with
> pointers you might want to make some assertion w.r.t. aliasing).
>
> The downside of this sort of approach (vs attributes) is that it
> increases the size of the every caller of the function. The advantage
> is that it is more explicit, potentially more general, and doesn't
> require new attributes for each size. OTOH, some of these advantages
> go away if this gets extended for other properties: we end up having a
> copy with attributes on it :)
Agreed, with one caveat:
I don't understand how attributes work at this point, but if the
use-case is specific to each caller, the attribute will need to be
attached separately to each call point, and the difference in space for
such cases vs "copies with assertions" may not turn out to be very big.
A general observation I would make -- this is coming from other systems
that I have worked on and does not reflect any understanding of LLVM
internals -- is that annotation schemes are often a source of error in
programs. Perhaps I have gotten them wrong when I have attempted them,
but what I have found in the past is that I end up with a lot of code
where I have a primary switch-like construct on the main object type (in
this case I imagine a switch on IR instruction), followed by a bunch of
special cases that look for applicable annotations within each case.
What I have observed to happen when code is structured this way is that
two types of coding failures become common:
1. Failures of case analysis, where some annotation is applicable in
several places or states, but is missing in some subset of these.
These can be hard to locate.
2. Failures of update, of the form "I caught 4 of the 5 places that
needed this update."
3. What one really ends up with, in effect, is a situation where the
*real* instruction (from a semantic perspective) was the alleged
instruction plus the semantically important annotation, but the
representational encoding of the real instruction has been made
awkward to deal with by splitting it into multiple substructures.
That is: they are "robust to error", in the sense that with high
likelihood errors will be introduced by maintenance over time.
Because of this, I have come to feel in my own code that
operation-specific annotations are often better dealt with by new
operations that can be inserted directly into the primary switch. I can
always run multiple cases into the same switch block, and the compiler
will help me notice which ones I forgot. I try to reserve use of
annotations and attributes for situations where:
1. The annotation/attribute is advisory or non-semantic, or
2. The annotation/attribute is almost universally applicable, and is
therefore not likely to need independent consideration at
multiple points in a long switch-like construct. Instead
it gets dealt with at one place, either at top or bottom of
the switch.
It's a trade-off, and I see no hard and fast rule that can be extracted
here, but my personal bias is to err in favor of robustness under
maintenance rather than in favor of reduced memory consumption.
shap
More information about the llvm-dev
mailing list