<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Jan 31, 2015 at 2:07 PM, Peter Collingbourne <span dir="ltr"><<a href="mailto:peter@pcc.me.uk" target="_blank">peter@pcc.me.uk</a>></span> wrote:<br><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"><span class="">On Sat, Jan 31, 2015 at 11:35:01AM -0800, JF Bastien wrote:<br>
> Trying to summarize all opinions expressed here: Peter is proposing an<br>
> initial implementation that would only work with LTO. Folks seem put off by<br>
> this implementation affecting IR without having proven itself, and having<br>
> shortcomings (as Jim pointed out). Kostya proposed going through metadata<br>
> (and Chris kind of did too by mentioning tbaa), but Peter points out that<br>
> this will make the implementation trickier.<br>
><br>
> It sounds like going through metadata for the LTO-only proof-of-concept<br>
> would be preferable, even if more complex. Peter, how more complex would<br>
> that be?<br>
<br>
</span>I was just thinking about how the metadata-based design for this might work.<br>
<br>
We could have a named metadata global containing the list of bitset entries.<br>
Each entry would be a pair consisting of an identifier for the bitset (in<br>
this case, the mangled name of the class) and a pointer into a global<br>
(in this case, a valid vtable pointer).<br>
<br>
For example, this class hierarchy:<br>
<span class=""><br>
class A { virtual void f(); };<br>
</span>class B : A { virtual void f(); };<br>
class C : A { virtual void f(); };<br>
<br>
would have these bitsets:<br>
<br>
!llvm.bitsets = !{!0, !1, !2, !3, !4}<br>
<br>
!0 = !{!"1A", i8* getelementptr inbounds ([3 x i8*]* @_ZTV1A, i32 0, i32 2)}<br>
!1 = !{!"1A", i8* getelementptr inbounds ([3 x i8*]* @_ZTV1B, i32 0, i32 2)}<br>
!2 = !{!"1A", i8* getelementptr inbounds ([3 x i8*]* @_ZTV1C, i32 0, i32 2)}<br>
!3 = !{!"1B", i8* getelementptr inbounds ([3 x i8*]* @_ZTV1B, i32 0, i32 2)}<br>
!4 = !{!"1C", i8* getelementptr inbounds ([3 x i8*]* @_ZTV1C, i32 0, i32 2)}<br>
<br>
The LLVM linker can already merge the contents of named metadata globals.<br>
<br>
The intrinsic for reading from bitsets would have this definition:<br>
<br>
declare i1 @llvm.bitset.test(i8*, metadata)<br>
<br>
and would be called like this:<br>
<br>
  %x = call i1 @llvm.bitset.test(i8* %p, metadata !{!"1A"})<br>
<br>
The disadvantage of this design is that metadata strings always have global<br>
scope, so identically named classes in anonymous namespaces in different<br>
translation units would receive the same bitset. (We can't just use the<br>
vtable globals as bitset identifiers, because they may be erased by globaldce.<br>
There are probably various things we could do to force the globals to stick<br>
around, if we wanted to go that way.)<br></blockquote><div><br class=""><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important;background-color:rgb(255,255,255)">That's pretty unfortunate. Can you mangle anonymous namespace class names further for your purpose? With the module name?</span></div><div><br></div><div><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">
Does that seem more reasonable to people?<br></blockquote><div><br></div><div>Seems reasonable as a first step. It doesn't seem like anyone is opposed to trying it out, and adding to IR if the metadata approach shows this to be a desirable feature.</div><div><br></div><div>The one think we need to ensure is that your metadata can be dropped by the optimizer and the code remains correct. I'm guessing no vtable would mean anything goes (not check)? That's bad security-wise, but it'll at least work. We may want to make sure nothing gets dropped through a debug flag, so that we can compile Chrome and be confident that all the checks we want are there.</div></div></div></div>