<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<div class="moz-cite-prefix">On 12/01/2014 02:42 PM, Andrew Trick
wrote:<br>
</div>
<blockquote
cite="mid:A1A1CB5D-299D-4D03-BA15-DD1FA70A6B74@apple.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html;
charset=windows-1252">
<br class="">
<div>
<blockquote type="cite" class="">
<div class="">On Dec 1, 2014, at 2:21 PM, Philip Reames <<a
moz-do-not-send="true"
href="mailto:listmail@philipreames.com" class="">listmail@philipreames.com</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type" class="">
<div bgcolor="#FFFFFF" text="#000000" class=""> <br
class="">
<div class="moz-cite-prefix">On 12/01/2014 11:14 AM,
Andrew Trick wrote:<br class="">
</div>
<blockquote
cite="mid:3C814DCF-2BCF-413A-906F-560B84918529@apple.com"
type="cite" class="">
<meta http-equiv="Content-Type" content="text/html;
charset=windows-1252" class="">
<br class="">
<div class="">
<blockquote type="cite" class="">
<div class="">On Oct 21, 2014, at 4:03 PM, Philip
Reames <<a moz-do-not-send="true"
href="mailto:listmail@philipreames.com" class="">listmail@philipreames.com</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class=""><span style="font-family: Helvetica;
font-size: 12px; font-style: normal;
font-variant: normal; font-weight: normal;
letter-spacing: normal; line-height: normal;
orphans: auto; text-align: start; text-indent:
0px; text-transform: none; white-space: normal;
widows: auto; word-spacing: 0px;
-webkit-text-stroke-width: 0px; float: none;
display: inline !important;" class="">Sanjoy
made a good point. We don't actually need a new
variant of "invariant.start". Simply using an
invariant.start with no uses gives us a notion
of an invariant region with no end. (Since the
result doesn't escape, there can be no end
hidden inside a function call.) This seems
like a simple notion to exploit and is strict
step forward from where we are, without a new
intrinsic.</span></div>
</blockquote>
</div>
<br class="">
<div class="">
<div class="">I'm coming back to this because it is a
sticking point for me in all of the proposals that
were floated informally on the commits list. I would
really like this to work, but can't prove that it's
safe.</div>
</div>
</blockquote>
As I said in the other thread, !invariant.load and
llvm.invariant.* are not the same. This thread is
discussing the later, not the former. The other thread is
discussing the former, but not the later. <br class="">
<blockquote
cite="mid:3C814DCF-2BCF-413A-906F-560B84918529@apple.com"
type="cite" class="">
<div class="">
<div class=""><br class="">
</div>
<div class="">Given:</div>
<div class=""><br class="">
</div>
<div class="">%a = newArray()</div>
<div class="">%pLen = gep(%a, <length offset>)</div>
<div class="">invariant.start(<size>, %pLen)</div>
<div class="">%len = load %pLen</div>
<div class=""><br class="">
</div>
<div class="">%o = foo() // may deallocate %a</div>
<div class="">store %something</div>
<div class="">load %o</div>
<div class=""><br class="">
</div>
<div class="">I want to claim that the LLVM optimizer
cannot do the following (but don't have a complete
line of reasoning yet):</div>
<div class=""><br class="">
</div>
<div class="">%a = newArray()</div>
<div class="">%pLen = gep(%a, <length offset>)</div>
<div class="">invariant.start(<size>, %pLen)</div>
<div class="">%len = load %pLen</div>
<div class=""><br class="">
</div>
<div class="">%o = foo() // may deallocate %a</div>
<div class="">if ptrtoint(%o) == ptrtoint(%pLen)</div>
<div class=""> load %pLen</div>
<div class=""> store %something // Oops... this might
alias</div>
<div class="">else</div>
<div class=""> store %something</div>
<div class=""> load %o</div>
</div>
</blockquote>
Just to make sure we're on the same page, it *would* be
legal for the optimizer to construct:<br class="">
<div class="">%a = newArray()</div>
<div class="">%pLen = gep(%a, <length offset>)</div>
<div class="">invariant.start(<size>, %pLen)</div>
<div class="">%len = load %pLen</div>
<div class=""><br class="">
</div>
<div class="">%o = foo() // may deallocate %a</div>
<div class="">if ptrtoint(%o) == ptrtoint(%pLen)</div>
<div class=""> store %something // Oops... this might
alias<br class="">
load %pLen <--- This is now after the store<br
class="">
</div>
<div class="">else</div>
<div class=""> store %something</div>
<div class=""> load %o<br class="">
<br class="">
Are we in agreement here? <br class="">
</div>
</div>
</div>
</blockquote>
<div><br class="">
</div>
It’s fine in the sense that memory access has not been
reordered… yet.</div>
</blockquote>
I think I've actually convinced myself my example is not okay, but
for a completely different reason. :) See my last comment below.<br>
<blockquote
cite="mid:A1A1CB5D-299D-4D03-BA15-DD1FA70A6B74@apple.com"
type="cite">
<div><br class="">
</div>
<div>But is there an implicit invariant.end(%pLen) at the call to
foo(), at which point the array can be freed and another object
allocated in its place? I don’t think so. </div>
</blockquote>
Given the current semantics, if the result of the invariant.start is
not passed to foo, we can assume foo does not contain an
invariant.end. However, for foo to allocate a new object in the
same memory, it must write to that memory. Doing so without ending
the previous invariant region is ill defined. As such, your example
isn't a valid test. <br>
<br>
We have two cases:<br>
a) The invariant region hasn't ended. As a result, the input IR is
ill defined and the problematic reordering can happen. <br>
b) The invariant region ended (and we either encountered a
llvm.invariant.end, or saw the result of invariant.start passed to
foo). In this case, the location is no longer invariant and the
reordering isn't legal and wouldn't happen.<br>
<br>
As I think came up before, this would imply that an invariant.end
can't be dropped without dropping it's corresponding
invariant.start. That's problematic. <br>
<br>
<blockquote
cite="mid:A1A1CB5D-299D-4D03-BA15-DD1FA70A6B74@apple.com"
type="cite">
<div>The way I interpreted the conclusion of this email thread is
that invariant.start can be used without invariant.end. </div>
</blockquote>
We had a proposal for this, but I don't believe it's actually been
implemented yet. I believe this proposal is still consistent with
everything I said above though. <br>
<blockquote
cite="mid:A1A1CB5D-299D-4D03-BA15-DD1FA70A6B74@apple.com"
type="cite">
<div>Since the token returned by the intrinsic never escapes, you
can just assume the memory is invariant at all uses. The problem
here is that the optimizer could (in theory) introduce new uses
of the pointer after the object lifetime. This is the same
problem that you yourself have raised. I hoped we could sidestep
the problem because it crops up with any representation that
attaches invariance to a pointer value. If we have an answer for
this, then we can easily debate other representations like
broadening !invariant.load metadata semantics and introducing
new intrinsics.</div>
</blockquote>
I agree there is a general issue here. However, I don't actually
think it's an issue of invariance. Instead, I see this as being a
problem of *derefenceability*. Regardless of the 'invariant-ness'
of the memory in question, it's problematic for the optimizer to
insert uses after a deallocation because the memory transitions from
dereferenceable to non-dereferenceable. (i.e. Consider a malloc
routine allocates one page per object, and a free which protects the
page freed.) Any transformation which inserts such a load is
dangerous. <br>
<br>
What your example really shows is that we can have two names for the
same *memory address*. One of those names can be dereferenceable
while the other is not. <br>
<br>
The dynamic check of the pointer values essentially allows the
optimizer to chose which of the two names for the same physical
address it wants to use. I think that is valid, but it's odd to say
the least. The particular example you've shown isn't legal since
the optimizer is choosing to insert a load to a non-dereferenceable
location and thus could introduce a fault. <br>
<blockquote
cite="mid:A1A1CB5D-299D-4D03-BA15-DD1FA70A6B74@apple.com"
type="cite">
<div><br class="">
</div>
<div>-Andy</div>
<div><br class="">
<blockquote type="cite" class="">
<div class="">
<div bgcolor="#FFFFFF" text="#000000" class="">
<div class=""> <br class="">
What is the argument that you see leading from the
second to your problematic example? I'm missing the
reasoning by which you got there. I agree that the
example is problematic, I'm just not sure how it would
arise. <br class="">
</div>
<br class="">
<br class="">
<blockquote
cite="mid:3C814DCF-2BCF-413A-906F-560B84918529@apple.com"
type="cite" class="">
<div class="">
<div class=""><br class="">
</div>
<div class="">Either we need to make a convincing
argument, or bail on most of the tentative proposals
for expressing invariance, and resort to generating
IR like this:</div>
<div class=""><br class="">
</div>
<div class="">%a = newArray()</div>
<div class="">%pLen = gep(%a, <length offset>)</div>
<div class="">%t = invariant.start(<size>,
%pLen)</div>
<div class="">%len = load %pLen</div>
<div class=""><br class="">
</div>
<div class="">%o = foo() // may deallocate %a</div>
<div class="">invariant.end(%t, <size>, %pLen)</div>
<div class="">store %something</div>
<div class="">load %o</div>
<div class=""><br class="">
</div>
<div class="">...which is pretty painful to implement
and may be very difficult to optimize.</div>
</div>
<div class=""><br class="">
</div>
<div class="">-Andy</div>
</blockquote>
<br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</blockquote>
<br>
</body>
</html>