<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><html>On 2008-03-21, at 03:22, Erick Tryzelaar wrote:</html><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">I just grepped through all the llvm and clang code, and there were literally 13 references to "SetInsertPoint", including the definitions. So what does everyone do instead?</span></blockquote><div><br></div><div>1. The constructor for <font class="Apple-style-span" face="Courier">LLVM{,Folding}Builder</font> is a convenience for <font class="Apple-style-span" face="Courier">SetInsertPoint</font>.</div><div>2. The instruction constructors all have overloads which accept <font class="Apple-style-span" face="Courier">Instruction *InsertBefore</font> and <font class="Apple-style-span" face="Courier">BasicBlock *InsertAtEnd</font>. This is more convenient when building one or two instructions, and is how <font class="Apple-style-span" face="'Andale Mono'">LLVM{,Folding}Builder</font> are implemented.</div><div><br></div><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; "><blockquote type="cite">On Thu, Mar 20, 2008 at 1:50 PM, Gordon Henriksen<br><<a href="mailto:gordonhenriksen@mac.com">gordonhenriksen@mac.com</a>> wrote:</blockquote></span><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; "><blockquote type="cite"><br></blockquote></span><blockquote type="cite"><blockquote type="cite"><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">Actually, analysis and transformation algorithms would be well-served initial_instr/terminator bindings which raise Not_found instead of yielding None. This would serve well such clients since they would not have to explicitly handle the case of an empty block or one with with no terminator, neither of which occur in valid IR.</span></blockquote></blockquote><blockquote type="cite"><br>Is that true? Because what if you're at the terminator and you take "next_instr" on it?</blockquote><div><br></div><div>Hm? Being able to write an algorithm that groks the CFG requires (1) knowing the terminator [which must always be present in valid IR] and its type and (2) discovering the predecessor blocks, which are operands to the terminator.<br></div><br><blockquote type="cite">Another thing that may or may not be interesting is that we could plug the "next_instr" into an ocaml stream (they've got a constructor for unit -> 'a option), and use the camlp4 pattern matching on it. We'd have to figure out how to pattern match instructions, though.<br></blockquote><div><br></div><div>We'd probably have to write things like</div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><span class="Apple-style-span" style="font-family: Courier; ">| _ as i where is_call i & is_function (param 0 i) -></span></blockquote><div><div><br></div><div>I suppose it would be possible to deconstruct the instruction into a variant, but that would be rather elaborate and likely wasteful.</div><div><br></div><blockquote type="cite"><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">Do you think it'd be useful to also be able to iterate from an arbitrary starting position and to iterate in reverse?</span></blockquote><div><br></div><div>It's possible to build those if necessary from the 4 basic navigation functions.</div><br><blockquote type="cite"><blockquote type="cite">I was trying to avoid this n x m explosion, although it is probably bounded <span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">at 8 = {builder,position}_{before,after,at_end,at_start}. In its place, I advocate the composable concepts of:</span></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">• IR navigation (first, next, last, prev). This is useful in other contexts.</blockquote></blockquote><blockquote type="cite"><blockquote type="cite">• A pair of builder positioning functions (builder_at, position_builder) that <span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">are as expressive as LLVMBuilder(BasicBlock*, BasicBlock::iterator).</span></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Your first e-mail implied you were for such a concept, although I think you <span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">over engineered it slightly. A perfect functional concept for LLVM's ilist iterator would be thus:</span></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">type 'a 'b llposition =<br></blockquote><blockquote type="cite">| Before of 'a<br></blockquote><blockquote type="cite">| At_end of 'b<br></blockquote><br>I actually changed my mind against this, because <span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">the usage of it would be either: "position_at (Before i)" or "position_before i" which is nearly the same.</span></blockquote></div><div><div><br></div><div>Yup, they're similar in simple cases. The difference being that the iterator concept handles all the cases uniformly.</div><br><blockquote type="cite">The primitives "position_before" and "position_at_end" really represent all possibilities<span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">, so we'd only have to bind those two.</span></blockquote><div><br></div><div>This is what I'm getting at. This gets back to, in C++, the 2 possible states of an <font class="Apple-style-span" face="Courier">ilist</font> <font class="Apple-style-span" face="Courier">iterator</font>:</div><div><br></div><div>before an instruction: <font class="Apple-style-span" face="Courier">i != bb->end()</font>, <font class="Apple-style-span" face="Courier">*i</font> is a valid <font class="Apple-style-span" face="Courier">Instruction*</font>; <font class="Apple-style-span" face="Courier">i</font> is a thin wrapper around an <font class="Apple-style-span" face="Courier">Instruction*</font></div><div>at the end of a basic block: <font class="Apple-style-span" face="Courier">i == bb->end()</font>, <font class="Apple-style-span" face="Courier">*i</font> asserts; <font class="Apple-style-span" face="Courier">i</font> wraps a non-<font class="Apple-style-span" face="Courier">Instruction</font> tail node owned by the <font class="Apple-style-span" face="Courier">BasicBlock</font></div><div><br></div><div>These are the only two necessary states. The types <font class="Apple-style-span" face="Courier">(llbasicblock * llvalue option)</font> and <font class="Apple-style-span" face="Courier">(<i>Before</i> llvalue | <i>At_end</i> llbasicblock)</font> both encapsulate this as well, the former with the possibility for inconsistency if <font class="Apple-style-span" face="Courier">instr_parent i</font> ≠ <font class="Apple-style-span" face="Courier">bb</font>.</div><div><br></div><div>In C++, a (<font class="Apple-style-span" face="Courier">BasicBlock*</font>, <font class="Apple-style-span" face="Courier">BasicBlock::iterator</font>) tuple is used in places because the end iterator doesn't have a <font class="Apple-style-span" face="Courier">getParent</font> facility.</div><div><br></div><div><blockquote type="cite"><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">It'd also be faster than having to box and unbox instructions. Everything else is convenience.</span></blockquote></div><blockquote type="cite"><br>Now, we could add a convenience function that was like:<br><br>type 'a 'b llposition =<br>  | Before of 'a<br>  | After of 'a<br>  | At_front of 'b<br>  | At_end of 'b<br><br>val position_builder: llbuilder -> (llvalue, llbasicblock) llposition -> unit<br><br>Which would use "position_before" and "position_at_end" to capture all the variants. Is that what you intended?<br></blockquote><div><br></div><div>Nope, the example I wrote is what I intended. :) Let me repaste it:</div><div><br></div><div><blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "></blockquote></div><blockquote type="cite"><div><blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "></blockquote></div><blockquote type="cite"><div><blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span class="Apple-style-span" style="font-family: Courier; "><font class="Apple-style-span" color="#0000FF">external</font> builder : unit -> llbuilder</span></blockquote><blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><font class="Apple-style-span" face="Courier"><span class="Apple-style-span" style="font-family: 'Trebuchet MS'; "><span class="Apple-style-span" style="font-family: Courier; "><font class="Apple-style-span" color="#0000FF">external</font> position_builder : llvalue llbasicblock llposition -> llbuilder</span><div><font class="Apple-style-span" face="Courier"><br></font></div></span></font></blockquote><blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><font class="Apple-style-span" face="Courier"><font class="Apple-style-span" color="#0000FF">let</font> builder_at ip =<br>  <font class="Apple-style-span" color="#0000FF">let</font> b = builder () in<br>  position_builder ip b;<br>  b<br><br><font class="Apple-style-span" color="#0000FF">let</font> builder_at_end bb = builder_at (<i>At_end</i> bb)<br><font class="Apple-style-span" color="#0000FF">let</font> builder_before i = builder_at (<i>Before</i> i)<br><span class="Apple-style-span" style="color: rgb(0, 0, 255); ">let</span> builder_at_start bb = builder_at (first_instr bb)<br><span class="Apple-style-span" style="color: rgb(0, 0, 255); ">let</span> builder_after i = builder_at (succ_instr i)<br><span class="Apple-style-span" style="color: rgb(0, 0, 255); ">let</span> position_at_end bb = position_builder (<i>At_end</i> bb)<br><span class="Apple-style-span" style="color: rgb(0, 0, 255); ">let</span> position_before i = position_builder (<i>Before</i> i)<br><span class="Apple-style-span" style="color: rgb(0, 0, 255); ">let</span> position_at_start bb = position_builder (first_instr bb)<br><span class="Apple-style-span" style="color: rgb(0, 0, 255); ">let</span> position_after i = position_builder (succ_instr i)</font></blockquote><div></div></div></blockquote><blockquote type="cite"></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">One thing though is that this still won't let you call "position_builder b (first_instr bb)", you'd have to unbox the option and rebox in "position_builder b (At_front i)".</blockquote><div><br></div><div>If we provide <font class="Apple-style-span" face="Courier">'a 'b position</font>, then the navigation functions should return those instead of <font class="Apple-style-span" face="Courier">'a option</font> precisely so that such conversion is not necessary. See my example.</div><div><br></div><div>A different set of names might less imply that they actually return instructions directly. Perhaps</div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" color="#0022ED" face="Courier"><span class="Apple-style-span" style="background-color: transparent;">val</span></font><font class="Apple-style-span" face="Courier"> instr</font><font class="Apple-style-span" color="#000000" face="Courier">_begin : llbasicblock -> llvalue llbasicblock llposition</font><br><font class="Apple-style-span" color="#0022ED" face="Courier"><span class="Apple-style-span" style="background-color: transparent;">val</span></font><font class="Apple-style-span" face="Courier"> instr</font><font class="Apple-style-span" color="#000000" face="Courier">_end : llbasicblock -> llvalue llbasicblock llposition</font><br><font class="Apple-style-span" color="#0022ED" face="Courier"><span class="Apple-style-span" style="background-color: transparent;">val</span></font><span class="Apple-style-span" style="font-family: Courier; "> instr_succ : llvalue -> llvalue llbasicblock llposition</span></blockquote><div><div><br></div><div><font class="Apple-style-span" face="Courier">instr_pred</font> is an oddity, though, now that I start to type it out. It's the <font class="Apple-style-span" face="Courier">reverse_iterator</font> problem. C++ solves this by essentially saying…</div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" color="#0000FF"><font class="Apple-style-span" face="Courier">type</font></font><font class="Apple-style-span" face="Courier"> 'a 'b reverse_iterator =<br>| </font><i><font class="Apple-style-span" face="Courier">After</font></i><font class="Apple-style-span" face="Courier"> of 'a option<br>| </font><i><font class="Apple-style-span" face="Courier">At_start</font></i><font class="Apple-style-span" face="Courier"> of 'b option</font></blockquote><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" face="Courier"><span class="Apple-style-span" style="font-family: 'Trebuchet MS'; "><br><font class="Apple-style-span" color="#0022ED" face="Courier">val</font><font class="Apple-style-span" face="Courier"> instr</font><font class="Apple-style-span" color="#000000" face="Courier">_end : llbasicblock -> llvalue llbasicblock reverse_iterator</font></span></font></blockquote><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" face="Courier"><span class="Apple-style-span" style="font-family: 'Trebuchet MS'; "><font class="Apple-style-span" color="#000000" face="Courier"><span class="Apple-style-span" style="font-family: 'Trebuchet MS'; "><font class="Apple-style-span" color="#0022ED" face="Courier">val</font><span class="Apple-style-span" style="font-family: Courier; "> instr_pred : llvalue -> llvalue llbasicblock reverse_iterator</span></span></font></span></font></blockquote><div><div><br></div><div><font class="Apple-style-span" face="Courier">instr_end</font> and <font class="Apple-style-span" face="Courier">instr_pred</font> would need to operate on these values, and they spoil my utopian grand-unified iterator concept a bit. Although do note that <font class="Apple-style-span" face="Courier"><i>Before</i> i</font> and <font class="Apple-style-span" face="Courier"><i>At_end</i> bb</font> likely obviate the need to use these functions for anything but reverse iteration, and conversion between the forms is not complicated. Could work…</div><div><br></div><blockquote type="cite">Now we could make the type:<br><br>type 'a 'b llposition =<br>  | Before of 'a option<br>  | After of 'a option<br>  | At_front of 'b option<br>  | At_end of 'b option<br><br>But then it seems to be getting a little overly complicated.<br></blockquote><div><br></div><div>It is.</div><div><br></div><div><font class="Apple-style-span" face="Courier"><i>Before</i> (<i>None</i>) | <i>After</i> (<i>None</i>) | <i>At_front</i> (<i>None</i>) | <i>At_end</i> </font><span class="Apple-style-span" style="font-family: Courier; ">(<i>None</i>)</span> are invalid.</div><div><font class="Apple-style-span" face="Courier"><i>After</i> (<i>Some</i> _) | <i>At_front</i> (<i>Some</i> _)</font> are redundant.</div><div><br></div><div><div><blockquote type="cite">it'll be a little more complicated to pull the data out of a variant in C,</blockquote><div><br></div><div>It's not bad at all with the minimal variant <font class="Apple-style-span" face="Courier">(Before of 'a | At_end of 'b)</font> that directly corresponds to the C++ iterator. I think this is the extent of it:</div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span class="Apple-style-span" style="font-family: Courier; "><font class="Apple-style-span" color="#0000FF">if</font> (!Tag_val(i, 0))</span><br><span class="Apple-style-span" style="font-family: Courier; ">  (LLVMValueRef) Op_val(Field(i, 0)); <font class="Apple-style-span" color="#008040">// Before of llvalue</font></span><br><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Courier; ">else</span><br><span class="Apple-style-span" style="font-family: Courier; ">  (LLVMBasicBlockRef) Op_val(Field(i, 0)); <font class="Apple-style-span" color="#008040">// At_end of llbasicblock</font></span></blockquote><div><div><div><br></div></div></div></div><div><br></div><div><br></div><div>Thanks Erick.</div></div><div apple-content-edited="true"><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Trebuchet MS; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Trebuchet MS; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Trebuchet MS; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Trebuchet MS; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Trebuchet MS; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Trebuchet MS; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div><div><br></div></div><div>— Gordon</div></span></span></span></span></span><br></div></span> </div><br></body></html>