<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=""><div class="">BTW, I think this thread should be on LLVM-dev, and I’d also CC Arnold, Hal, and Nadav - their feedback would be very valuable here.</div><div class=""><br class=""></div><div class="">Michael</div><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 28, 2015, at 12:21 PM, Mikhail Zolotukhin <<a href="mailto:mzolotukhin@apple.com" class="">mzolotukhin@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" 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;">Hi James,</div><div class="" 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;"><br class=""></div><div class="" 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;">Thanks for your comments!</div><br class="" 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;"><div 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;" class=""><blockquote type="cite" class=""><div class="">On Jul 28, 2015, at 1:08 AM, James Molloy <<a href="mailto:james@jamesmolloy.co.uk" class="">james@jamesmolloy.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi Michael,<div class=""><br class=""></div><div class="">Thanks for the feedback.</div><div class=""><br class=""></div><div class="">> <span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">As a show-case, how does it help to simplify the aforementioned createEmptyBlock?</span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;"><br class=""></span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">That's a good example. If you look at </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D11530&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=qAnL6bTqqIMSShV37rwv8Mx16Gx9vqpiJyJCildoAlM&s=BvuL7TIv3VOTxrvSju89n6ny59rlMUdhG_ZrqIu4vcs&e=" class="">http://reviews.llvm.org/D11530</a><span class="Apple-converted-space"> </span>line 916 in the .cpp file, there's a function "versionWidenAndInterleaveLoop" that does basically createEmptyBlock(). It also does more stuff - it performs the loop interleave too - but as an example showcase it should do.</div><div class=""><br class=""></div><div class="">For the vectorizer, I think the cleanest thing would be to add a delegate hook that's called whenever an instruction is about to be cloned. Then, the vectorizer could override that hook and provide its own implementation (instead of cloning an instruction completely, it'd replace it with a vector variant. So the entire main body of the vectorizer would look something like this:</div><div class=""><br class=""></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">struct Delegate : public LoopEditor::Delegate {</span><br class=""></div><div class="">  Value *hookCloneInstruction(Instruction *OldI, IRBuilder<> &IRB) {</div><div class="">    if (isControlFlowInst(OldI)) return IRB.CreateExtractElement; // Don't vectorize branches</div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">    return createVectorVersionOfInstruction(OldI, VF, IRB); // Defined somewhere in LoopVectorize</span><br class=""></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">  }</span></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">};</span></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">BasicBlock *PredBB;</span></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">Delegate D;</span></div><div class=""><div class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">LoopEditor LE(L, DT, SE, LI);</div></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">LoopEditor VectorLE = LE.versionWidenAndInterleaveLoop(UF, PredBB, &D);</span></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">VectorLE.widen(VF); // Widen further, so it's widened by VF*UF. Only affects induction variable steps and trip count.</span></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;"><br class=""></span></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">How does that look to you?</span></div></div></div></blockquote>That looks good, I always wanted to factor this stuff out too:)<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;"><br class=""></span></div><div class=""><span class="" style="line-height: 1.5; font-size: 13.1999998092651px;">> </span><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">Also, I think it’s very important to explicitly define requirements for loops we can handle, and what we do with other loops. E.g. what do we do if a loop has multiple back-edges? What do we do if a loop body has complicated control-flow?</span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;"><br class=""></span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">Good point, agreed. I think we need to handle loops in LoopSimplify form and LCSSA form at least. Some functions may not be able to handle arbitrary control flow but most should be agnostic to it (for example making sure control flow is correct in a vectorized loop, should be the user's job not LoopEditor's). But defining exactly what loop type each function supports and ensuring it does support that is a good idea.</span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;"><br class=""></span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">I'm also trying to work out what's the best way of getting this in-tree. It's a lot of code and I don't want to dump it in one go, but getting pre-commit review on every little step would make it take forever. Do you have any suggestions as to methodology? I was thinking getting review on the header (API), then committing that with stub implementations and implementing them bit by bit from there...</span></div></div></div></blockquote>I agree, and this way seems reasonable to me. However, it's really tempting to see what we end up with before we commit to it - so, if you have some final patch with this API applied to most of its users (even if this patch is huge), it would be cool if you share it.</div><div 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;" class=""><br class=""></div><div 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;" class="">Also, how will we test it? Should we create a dummy-pass that will invoke these transforms on a given loop (without any cost models, just doing what you ask it to do)?</div><div 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;" class=""><br class=""></div><div 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;" class="">Michael<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;"><br class=""></span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">Cheers,</span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;"><br class=""></span></div><div class=""><span class="" style="font-size: 13.1999998092651px; line-height: 19.7999992370605px;">James</span></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Mon, 27 Jul 2015 at 20:23 Michael Zolotukhin <<a href="mailto:mzolotukhin@apple.com" class="">mzolotukhin@apple.com</a>> wrote:<br class=""></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 class="" style="word-wrap: break-word;">Hi James,<div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Jul 27, 2015, at 10:04 AM, James Molloy <<a href="mailto:james@jamesmolloy.co.uk" target="_blank" class="">james@jamesmolloy.co.uk</a>> wrote:</div><br class=""></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">Hi all,<div class=""><br class=""></div><div class="">LLVM currently lacks a single coherent way to edit, modify and transform loops. We have the Loop abstraction that provides some functionality, and we have a cluster of functions and abstractions in LoopUtils, but each is fairly cumbersome to use. There's also VersionedLoop, but that's quite specific and not really extendable/composable.</div><div class=""><br class=""></div><div class="">I've recently been trying to do some prototyping of a high level loop optimization (unroll-and-jam) and ended up with quite a bit of spaghetti code doing what should be simple transforms (as another example, look at LoopVectorize::createEmptyBlock()!)</div></div></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""></blockquote>Totally agree here!<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""></div></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">So I decided to prototype an API for performing more high level operations on LLVM Loops - cloning, widening, interleaving, stitching the output of one loop into another loop, setting loop trip counts, peeling... and all while keeping loopinfo, domtree and SCEV updated.</div><div class=""><br class=""></div></div></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">I've uploaded my current prototype to Phab here: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D11530&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=3t7gCOgkqnA-65i6cez_eslTon3hxx5XJKhMBw98kv0&s=yCaxJfCogeqwUH-wlsdHFPHktniLwG3-cZnq1yciR04&e=" target="_blank" class="">http://reviews.llvm.org/D11530</a></div></div></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">It's still at the prototype stage so there are lots of things that need fixing - sorting out the testing story being top of my list. But I'm looking for feedback on:</div><div class="">  * Is this a useful abstraction? Is it something the community would like to see in-tree (eventually)?</div></div></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""></div></div></blockquote>I think it could be very useful - depending on how easy it would be to use. As a show-case, how does it help to simplify the aforementioned createEmptyBlock?</div><div class=""></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">  * Does the API design make sense? Are there obvious things I've missed that people need?</div></div></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class="">From the first glance, it seems reasonable. One probably missing thing: we have peelAfter, but we may also need peelBefore (it would be helpful if we create prologues for alignment for instance).</div><div class=""><br class=""></div><div class="">Also, I think it’s very important to explicitly define requirements for loops we can handle, and what we do with other loops. E.g. what do we do if a loop has multiple back-edges? What do we do if a loop body has complicated control-flow?</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Michael</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">I've thought about the use cases of the loop vectorizer, loop distribution, loop unrolling, loop versioning, and I think the current design can solve their use cases fairly elegantly. I've used this API to write a fairly sophisticated unroll-and-jam transform in very few lines too.</div><div class=""><br class=""></div><div class="">Any feedback would be gratefully appreciated!</div><div class=""><br class=""></div><div class="">Cheers,</div><div class=""><br class=""></div><div class="">James</div></div></div></blockquote></div></div></div><div class="" style="word-wrap: break-word;"><div class=""><div class=""><blockquote type="cite" class=""><div class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank" class="">llvm-commits@cs.uiuc.edu</a><br class=""><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a></div></blockquote></div></div></div></blockquote></div></div></blockquote></div></div></blockquote></div><br class=""></body></html>