<div dir="ltr">On Fri, Dec 6, 2013 at 6:41 AM, Robert Lytton <span dir="ltr"><<a href="mailto:robert@xmos.com" target="_blank">robert@xmos.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">





<div>
<div style="direction:ltr;font-size:10pt;font-family:Tahoma">Hi,<br>
<br>
I have a problem relating to the way clang handles static const structure declarations in c++ classes.<br>
<br>
If only the declaration is visible:<br>
<font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr">    class K {static const struct S k; ...}</span></font><font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr"><br>
</span></font>the constness is not emitted in the declaration:<br>
<font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr">    @_ZN1K1kE = external global %struct.S<br>
should this not be:</span></font><br>
<font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr">    @_ZN1K1kE = external
</span></font><font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr"><font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr">constant</span></font> %struct.S</span></font><br>
<br>
If the definition is visible too:<br>
<font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr">    class J {static const struct S j;...}<br>
    const struct S J::j = {1,2};</span></font><br>
we get a global 'const' definition, viz:<br>
<font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr">    @_ZN1J1jE = constant %struct.S { i32 1, i32 2 }, align 4<br>
</span></font><br>
It should be noted that the handling of arrays always uses const - see below.<br>
<br>
Am I correct in believing this is a bug?<br>
Can anyone direct me to where the problem may reside?<br>
<br>
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.<br></div></div></blockquote><div><br></div><div>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:</div>
<div><br>"LLVM explicitly allows <i>declarations</i> 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."<br>
<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div style="direction:ltr;font-size:10pt;font-family:Tahoma">

Robert<br>
<br>
<br>
<font color="black" face="Tahoma"><span style="font-size:10pt" dir="ltr">struct S{int s1; int s2;};<br>
<br>
class I {<br>
  static const int i[2];<br>
  static int ii();<br>
};<br>
int I::ii(){return i[0];}<br>
// I::i defined else where - OK<br>
<br>
class J {<br>
  static const struct S j;<br>
  static struct S jj();<br>
};<br>
struct S J::jj(){return j;}<br>
const struct S J::j = {1,2};<br>
<br>
<br>
class K {<br>
  static const struct S k;<br>
  static struct S kk();<br>
};<br>
struct S K::kk(){return k;}<br>
// K::k defined else where - const is lost<br>
<br>
<br>
%struct.S = type { i32, i32 }<br>
@_ZN1I1iE = external constant [2 x i32]<br>
@_ZN1J1jE = constant %struct.S { i32 1, i32 2 }, align 4<br>
@_ZN1K1kE = external global %struct.S<br>
<br>
define i32 @_ZN1I2iiEv() #0 align 2 {<br>
entry:<br>
  %0 = load i32* getelementptr inbounds ([2 x i32]* @_ZN1I1iE, i32 0, i32 0), align 4<br>
  ret i32 %0<br>
}<br>
<br>
define void @_ZN1J2jjEv(%struct.S* noalias sret %agg.result) #0 align 2 {<br>
entry:<br>
  %0 = bitcast %struct.S* %agg.result to i8*<br>
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* bitcast (%struct.S* @_ZN1J1jE to i8*), i32 8, i32 4, i1 false)<br>
  ret void<br>
}<br>
<br>
define void @_ZN1K2kkEv(%struct.S* noalias sret %agg.result) #0 align 2 {<br>
entry:<br>
  %0 = bitcast %struct.S* %agg.result to i8*<br>
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* bitcast (%struct.S* @_ZN1K1kE to i8*), i32 8, i32 4, i1 false)<br>
  ret void<br>
}</span></font><br>
<br>
</div>
</div>

<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div>