<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 9, 2015, at 11:16 AM, Preston Briggs <<a href="mailto:briggs@reservoir.com" class="">briggs@reservoir.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">A GEP can represent a potentially large tree of instructions.<div class="">Seems like all the sub-trees are hidden from optimization;</div><div class="">that is, I never see licm or value numbering doing anything with them.</div><div class="">If I rewrite the GEPs as lots of little adds and multiplies,</div><div class="">then opt will do a better job (I speculate this happens during lowering).</div><div class=""><br class=""></div><div class="">One of the computations that's hidden in the GEP in my example</div><div class="">is the non-zero effort required to get the value of a label into a register.</div><div class="">I'd like to expose that effort to the optimizer; instead, it seems</div><div class="">hidden, papered over with the GEP.</div><div class=""><br class=""></div><div class="">Your point about putting labels in global variables seems to work</div><div class="">if I do it by hand. Kind of embarassing though, don't you think,</div><div class="">introducing an indirection to achieve better code?</div></div></div></blockquote><div><br class=""></div><div>Isn’t this indirection just how your target work? </div><div>It seems to me that this indirection just achieve exactly what you want: a more risc-like and less implicit representation!</div><div><br class=""></div><div>As far as I can tell, accessing a “label” does not require a load at the IR level, (and indeed it does not on most targets). It is baked in everywhere in the code that operates on the IR. You will fight the model all the time if you try to circumvent that. </div><div>For instance the bitcast of the global label I used in my first answer is a compile time constant expression for LLVM.</div><div>On the same topic, integer literals are assumed to be inlined in the code, we don’t expose any load in the IR to operate on a literal value.</div><div><br class=""></div><div>Also, you are relying on an implicit load (only on your target) for global labels, which I believe is not valid IR. For LLVM IR, a GEP is nothing more than pointer arithmetic.</div><div>Per LangRef:</div><div><br class=""></div><div>    The ‘getelementptr‘ instruction is used to get the address of a subelement of an aggregate data structure. It performs address calculation only and does not access memory. The instruction can also be used to calculate a vector of such addresses.<br class=""><br class="">Note the *does not access memory* part (now, you may argue that the “load” you are emitting is not accessing memory exposed in the optimizer memory model and this does not apply).</div><div><br class=""></div><div>— </div><div>Mehdi</div><div><br class=""></div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Preston</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Dec 9, 2015 at 9:17 AM, Mehdi Amini <span dir="ltr" class=""><<a href="mailto:mehdi.amini@apple.com" target="_blank" class="">mehdi.amini@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Dec 9, 2015, at 9:00 AM, Preston Briggs <<a href="mailto:briggs@reservoir.com" target="_blank" class="">briggs@reservoir.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class="">I suppose your view is reasonable, and perhaps common.<div class="">My own "taste" has always preferred machine-independent code</div><div class="">that is as simple as possible, so GEPs reduced to nothing more than an</div><div class="">add, etc, i.e., quite risc-like. Then optimize it to reduce the total number</div><div class="">of operations (as best we can), then raise the level during instruction</div><div class="">selection, taking advantage of available instructions.</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I’m not sure I see something related to risc-like here, it seems to me that  your problem is not GEP vs ADD but rather that you want to expose a mode where global addresses need to be loaded and can’t be referenced directly.</div><div class="">(Unless I misunderstood the problem which is very possible as well)</div><div class=""><br class=""></div><div class="">Maybe you could do this with a transformation that would put all the global variable addresses in a global array and reference them through the array. That’s the only workaround I could see.</div><div class=""><br class=""></div><div class="">— </div><span class="HOEnZb"><font color="#888888" class=""><div class="">Mehdi</div></font></span><div class=""><div class="h5"><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">I guess my whole scheme of using opt in this context is probably wrong headed.</div><div class=""><br class=""></div><div class="">Thanks</div><div class=""><br class=""></div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Dec 9, 2015 at 8:45 AM, Mehdi Amini <span dir="ltr" class=""><<a href="mailto:mehdi.amini@apple.com" target="_blank" class="">mehdi.amini@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Dec 9, 2015, at 7:58 AM, Preston Briggs <<a href="mailto:briggs@reservoir.com" target="_blank" class="">briggs@reservoir.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class="">I'm trying to make the IR "better", in a machine-independent fashion,<div class="">without having to do any lowering.</div></div></div></blockquote><div class=""><br class=""></div></span><div class=""><div class="">The question is “would the IR be more canonical” with the representation you suggest? Why would the optimizer benefit from this representation instead of the current one in general?</div></div><div class="">Right now this GEP reads as an offset from a constant global, which seems pretty optimal to me.</div><div class=""><br class=""></div><div class=""><div class=""><div class="">My impression is that when you reach a point where the “better” is target specific, this is part of the lowering (I’m using lowering in the sense that you go away from the canonical representation the optimizer expects). I believe it is pretty common that targets need to do this kind of lowering.</div><div class=""><br class=""></div></div></div><div class="">— </div><span class=""><font color="#888888" class=""><div class="">Mehdi</div></font></span><div class=""><div class=""><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">I've written code that rewrites GEPs as simple adds and multiplies,</div><div class="">which helps a lot, but there's still some sort of re-canonicalization</div><div class="">that's getting in my way. Is there perhaps a way to suppress it?</div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Preston</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Dec 9, 2015 at 7:47 AM, Mehdi Amini <span dir="ltr" class=""><<a href="mailto:mehdi.amini@apple.com" target="_blank" class="">mehdi.amini@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">I guess is has to be done as part of the lowering for such a target, either during CodegenPrepare or during something like MachineLICM.<div class=""><br class=""></div><div class="">— </div><span class=""><font color="#888888" class=""><div class="">Mehdi</div></font></span><div class=""><div class=""><div class=""><br class=""></div><div class=""><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 9, 2015, at 7:13 AM, Preston Briggs <<a href="mailto:briggs@reservoir.com" target="_blank" class="">briggs@reservoir.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class="">On some targets with limited addressing modes,<div class="">getting that 64-bit relocatable but loop-invariant value into a register</div><div class="">requires several instructions. I'd like those several instruction outside</div><div class="">the loop, where they belong.</div><div class=""><br class=""></div><div class="">Yes, my experience is that something (I assume instcombine) recanonicalizes.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Preston</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, Dec 8, 2015 at 11:21 PM, Mehdi Amini <span dir="ltr" class=""><<a href="mailto:mehdi.amini@apple.com" target="_blank" class="">mehdi.amini@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Hi Preston,<div class=""><div class=""><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 8, 2015, at 10:56 PM, Preston Briggs via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class="">When I compile two different modules using<div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><font face="monospace, monospace" class="">clang -O -S -emit-llvm</font></div></blockquote><div class=""><br class=""></div><div class="">I get different .ll files, no surprise.</div><div class=""><br class=""></div><div class="">The first looks like</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><div class=""><font face="monospace, monospace" class="">double *v;</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">double zap(long n) {</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  double sum = 0;</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  for (long i = 0; i < n; i++)</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">    sum += v[i];</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  return sum;</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">}</font></div></div></blockquote><div class=""><br class=""></div><div class="">yielding</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><div class=""><font face="monospace, monospace" class="">@v = common global double* null, align 8</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">; Function Attrs: nounwind readonly uwtable</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">define double @zap(i64 %n) #0 {</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">entry:</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %cmp4 = icmp sgt i64 %n, 0</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  br i1 %cmp4, label %<a href="http://for.body.lr.ph/" target="_blank" class="">for.body.lr.ph</a>, label %for.end</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><a href="http://for.body.lr.ph/" target="_blank" class="">for.body.lr.ph</a>:                                   ; preds = %entry</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %0 = load double** @v, align 8, !tbaa !1</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  br label %for.body</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">for.body:                                         ; preds = %for.body, %<a href="http://for.body.lr.ph/" target="_blank" class="">for.body.lr.ph</a></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %i.06 = phi i64 [ 0, %<a href="http://for.body.lr.ph/" target="_blank" class="">for.body.lr.ph</a> ], [ %inc, %for.body ]</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %sum.05 = phi double [ 0.000000e+00, %<a href="http://for.body.lr.ph/" target="_blank" class="">for.body.lr.ph</a> ], [ %add, %for.body ]</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %arrayidx = getelementptr inbounds double* %0, i64 %i.06</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %1 = load double* %arrayidx, align 8, !tbaa !5</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %add = fadd double %sum.05, %1</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %inc = add nsw i64 %i.06, 1</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  </font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">%exitcond = icmp eq i64 %inc, %n</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  br i1 %exitcond, label %for.end, label %for.body</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">for.end:                                          ; preds = %for.body, %entry</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %sum.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add, %for.body ]</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  ret double %sum.0.lcssa</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">}</font></div></div></blockquote><div class=""><br class=""></div><div class="">and the second looks like</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><div class=""><font face="monospace, monospace" class="">double v[10000];</font></div></div><div class=""><div class=""><br class=""></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><div class=""><font face="monospace, monospace" class="">double zap(long n) {</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  double sum = 0;</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  for (long i = 0; i < n; i++)</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">    sum += v[i];</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  return sum;</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">}</font></div></div></blockquote><div class=""><br class=""></div><div class="">yielding</div><div class=""><br class=""></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px" class=""><div class=""><div class=""><font face="monospace, monospace" class="">; ModuleID = 'z.c'</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64-S128"</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">target triple = "x86_64-unknown-linux-gnu"</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">@v = common global [10000 x double] zeroinitializer, align 16</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">; Function Attrs: nounwind readonly uwtable</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">define double @zap(i64 %n) #0 {</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">entry:</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %cmp4 = icmp sgt i64 %n, 0</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  br i1 %cmp4, label %for.body, label %for.end</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">for.body:                                         ; preds = %entry, %for.body</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %i.06 = phi i64 [ %inc, %for.body ], [ 0, %entry ]</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %sum.05 = phi double [ %add, %for.body ], [ 0.000000e+00, %entry ]</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %arrayidx = getelementptr inbounds [10000 x double]* @v, i64 0, i64 %i.06</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %0 = load double* %arrayidx, align 8, !tbaa !1</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %add = fadd double %sum.05, %0</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %inc = add nsw i64 %i.06, 1</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %exitcond = icmp eq i64 %inc, %n</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  br i1 %exitcond, label %for.end, label %for.body</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">for.end:                                          ; preds = %for.body, %entry</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  %sum.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add, %for.body ]</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  ret double %sum.0.lcssa</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">attributes #0 = { nounwind readonly uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">!llvm.ident = !{!0}</font></div></div><div class=""><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">!0 = metadata !{metadata !"Clang Front-End version 3.4.1 (tags/RELEASE_34/final)"}</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">!1 = metadata !{metadata !2, metadata !2, i64 0}</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">!2 = metadata !{metadata !"double", metadata !3, i64 0}</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}</font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">!4 = metadata !{metadata !"Simple C/C++ TBAA"}</font></div></div></blockquote><div class=""><br class=""></div><div class="">(I included all the metadata and such for the 2nd case, on the off chance it matters.)</div><div class=""><br class=""></div><div class="">Is there any way I can convince licm (or something) to rip open the GEP and hoist the reference to @v outside the loop, similar to the first example?</div></div></div></blockquote><div class=""><br class=""></div></div><br class=""></div></div><div class="">I believe that in the second case, there is no need to load the address of v as it is constant. However you have a constant address to an array, which is represented by [10000 x double]* @v in the IR, which requires to use the two-level GEP. </div></div><div class=""><br class=""></div><div class="">You “could” manage to represent it this way:</div><div class=""><br class=""></div><div class=""><span class="">define double @zap(i64 %n) #0 {<br class="">entry:<br class=""></span>  %cmp6 = icmp sgt i64 %n, 0<br class="">  %hoisted = bitcast [10000 x double]* @v to double*<br class="">  br i1 %cmp6, label %for.body.preheader, label %for.cond.cleanup<br class=""><br class="">for.body.preheader:                               ; preds = %entry<br class="">  br label %for.body<br class=""><br class="">for.cond.cleanup.loopexit:                        ; preds = %for.body<br class="">  %add.lcssa = phi double [ %add, %for.body ]<br class="">  br label %for.cond.cleanup<br class=""><br class="">for.cond.cleanup:                                 ; preds = %for.cond.cleanup.loopexit, %entry<br class="">  %sum.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add.lcssa, %for.cond.cleanup.loopexit ]<br class="">  ret double %sum.0.lcssa<br class=""><br class="">for.body:                                         ; preds = %for.body.preheader, %for.body<br class="">  %i.08 = phi i64 [ %inc, %for.body ], [ 0, %for.body.preheader ]<br class="">  %sum.07 = phi double [ %add, %for.body ], [ 0.000000e+00, %for.body.preheader ]<br class="">  %arrayidx = getelementptr double, double* %hoisted, i64 %i.08<br class="">  %0 = load double, double* %arrayidx, align 8, !tbaa !2<br class="">  %add = fadd double %sum.07, %0<br class="">  %inc = add nuw nsw i64 %i.08, 1<span class=""><br class="">  %exitcond = icmp eq i64 %inc, %n<br class=""></span>  br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body<br class="">}</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">However instcombine will recanonicalize it like it was originally.</div><div class=""><br class=""></div><div class="">Since it is a GEP that operate on a constant address, this shouldn’t matter, why would you want to split this? </div><div class=""><br class=""></div><div class="">Best,</div><div class=""><br class=""></div><div class="">— </div><span class=""><font color="#888888" class=""><div class="">Mehdi</div><div class=""><br class=""></div></font></span></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></div></div></div></div></blockquote></div><br class=""></div>
</div></blockquote></div></div></div><br class=""></div></blockquote></div><br class=""></div>
</div></blockquote></div></div></div><br class=""></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>