<div dir="ltr">I don't see how this is any different from volatile markers on loads/stores or memory barriers or several other optimizer blocking devices.  They generally end up crippling the optimizers without much added benefit.<div><br></div><div>Would it be possible to stop the code motion you want to block by explicitly exposing data dependencies?  Or simply disabling some optimizations with pragmas?</div><div><br></div><div><br></div><div>Diego.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 2, 2015 at 6:57 PM, Richard Diamond via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hey all,<br></div><div><br></div><div>I'd like to propose a new intrinsic for use in preventing optimizations from deleting IR due to constant propagation, dead code elimination, etc.</div><div><br></div><div><br></div><div><font size="4"># Background/</font><span style="font-size:large">Motivation</span></div><div><br></div><div>In Rust we have a crate called `test` which provides a function, `black_box`, which is designed to be a no-op function that prevents constprop, die, etc from interfering with tests/benchmarks but otherwise doesn't negatively affect resulting machine code quality. `test` currently implements this function by using inline asm, which marks a pointer to the argument as used by the assembly. </div><div><br></div><div>At the IR level, this creates an alloca, stores it's argument to it, calls the no-op inline asm with the alloca pointer, and then returns a load of the alloca. Obviously, `mem2reg` would normally optimize this sort of pattern away, however the deliberate use of the no-op asm prevents other desirable optimizations (such as the aforementioned `mem2reg` pass) a little too well.</div><div><br></div><div>Existing and upcoming virtual ISA targets also don't have this luxury (PNaCl/JS and WebAssembly, respectively). For these kind of targets, Rust's `test` currently forbids inlining of `black_box`, which crudely achieves the same effect. This is undesirable for any target because of the associated call overhead.</div><div><br></div><div>The IR for `test::black_box::<i32>` is currently (it gets inlined, as desired, so I've omitted the function signature):</div><div><br></div><div>````llvm</div><div>  %dummy.i = alloca i32, align 4<br></div><div>  %2 = bitcast i32* %dummy.i to i8*<br></div><div><div>  call void @llvm.lifetime.start(i64 4, i8* %2) #1</div><div>; Here, the value operand was the original argument to `test::black_box::<i32>`</div><div>  store i32 2, i32* %dummy.i, align 4</div><div>  call void asm "", "r,~{dirflag},~{fpsr},~{flags}"(i32* %dummy.i) #1, !srcloc !0</div><div>  %3 = load i32, i32* %dummy.i, align 4</div><div>  call void @llvm.lifetime.end(i64 4, i8* %2) #1</div></div><div>````</div><div><br></div><div>This could be better.</div><div><br></div><div><font size="4"># Solution</font></div><div><br></div><div>Add a new intrinsic, called `llvm.blackbox`, which accepts a value of any type and returns a value of the same type. As with many other intrinsics, this intrinsic shall remain unknown to all optimizations, before and during codegen. Specifically, this intrinsic should prevent all optimizations which operate by assuming properties of the value passed to the intrinsic. Once the last optimization pass (of any kind) is finished, all calls can be RAUW its argument.</div><div><br></div><div>Table-gen def:</div><div><br></div><div>```tablegen</div><div>def int_blackbox : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>]>;<br></div><div>```</div><div><br></div><div>Thus, using the previous example, `%3` would become:</div><div>```llvm</div><div>  %3 = call i32 @llvm.blackbox.i32(i32 2)</div><div><br></div><div>```</div><div><br></div><div># </div><div><br></div><div>Thoughts and suggestions welcome.</div><div><br></div><div>Thanks,</div><div>Richard Diamond</div></div>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div>