[cfe-dev] static const structures declared as "external global %struct.S" instead of "external constant %struct.S"

Richard Smith richard at metafoo.co.uk
Fri Dec 6 10:20:22 PST 2013


On Fri, Dec 6, 2013 at 6:41 AM, Robert Lytton <robert at xmos.com> wrote:

>  Hi,
>
> I have a problem relating to the way clang handles static const structure
> declarations in c++ classes.
>
> If only the declaration is visible:
>     class K {static const struct S k; ...}
> the constness is not emitted in the declaration:
>     @_ZN1K1kE = external global %struct.S
> should this not be:
>     @_ZN1K1kE = external constant %struct.S
>
> If the definition is visible too:
>     class J {static const struct S j;...}
>     const struct S J::j = {1,2};
> we get a global 'const' definition, viz:
>     @_ZN1J1jE = constant %struct.S { i32 1, i32 2 }, align 4
>
> It should be noted that the handling of arrays always uses const - see
> below.
>
> Am I correct in believing this is a bug?
> Can anyone direct me to where the problem may reside?
>
> This is a problem on the XCore target as we handle constant and
> non-constant data in separate areas and hence will emit different assembler
> instructions.
>

The 'k' object may or may not be able to be marked 'constant' (depending on
its initializer). Some LLVM passes will promote it from 'global' to
'constant', too. If the instructions you emit for 'global' reads don't work
on 'constant' objects and vice versa, that's a bug in your target. Here's a
quote from the LangRef:

"LLVM explicitly allows *declarations* of global variables to be marked
constant, even if the final definition of the global is not. This
capability can be used to enable slightly better optimization of the
program, but requires the language definition to guarantee that
optimizations based on the ‘constantness’ are valid for the translation
units that do not include the definition."

Robert
>
>
> struct S{int s1; int s2;};
>
> class I {
>   static const int i[2];
>   static int ii();
> };
> int I::ii(){return i[0];}
> // I::i defined else where - OK
>
> class J {
>   static const struct S j;
>   static struct S jj();
> };
> struct S J::jj(){return j;}
> const struct S J::j = {1,2};
>
>
> class K {
>   static const struct S k;
>   static struct S kk();
> };
> struct S K::kk(){return k;}
> // K::k defined else where - const is lost
>
>
> %struct.S = type { i32, i32 }
> @_ZN1I1iE = external constant [2 x i32]
> @_ZN1J1jE = constant %struct.S { i32 1, i32 2 }, align 4
> @_ZN1K1kE = external global %struct.S
>
> define i32 @_ZN1I2iiEv() #0 align 2 {
> entry:
>   %0 = load i32* getelementptr inbounds ([2 x i32]* @_ZN1I1iE, i32 0, i32
> 0), align 4
>   ret i32 %0
> }
>
> define void @_ZN1J2jjEv(%struct.S* noalias sret %agg.result) #0 align 2 {
> entry:
>   %0 = bitcast %struct.S* %agg.result to i8*
>   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* bitcast (%struct.S*
> @_ZN1J1jE to i8*), i32 8, i32 4, i1 false)
>   ret void
> }
>
> define void @_ZN1K2kkEv(%struct.S* noalias sret %agg.result) #0 align 2 {
> entry:
>   %0 = bitcast %struct.S* %agg.result to i8*
>   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* bitcast (%struct.S*
> @_ZN1K1kE to i8*), i32 8, i32 4, i1 false)
>   ret void
> }
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131206/b26112be/attachment.html>


More information about the cfe-dev mailing list