<HTML><BODY style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><DIV><BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Message: 3</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Date: Fri, 15 Jun 2007 12:24:52 -0700 (PDT)</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">From: Chris Lattner <<A href="mailto:sabre@nondot.org">sabre@nondot.org</A>></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Subject: Re: [LLVMdev] Strategy to compile for LLVM IR</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">To: LLVM Developers Mailing List <<A href="mailto:llvmdev@cs.uiuc.edu">llvmdev@cs.uiuc.edu</A>></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Message-ID: <<A href="mailto:Pine.LNX.4.62.0706151218030.7416@nondot.org">Pine.LNX.4.62.0706151218030.7416@nondot.org</A>></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Content-Type: text/plain; charset="x-unknown"</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">On Fri, 15 Jun 2007, [ISO-8859-1] St?phane Letz wrote:</DIV> <BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">We have a compiler for the Faust language (faust.grame.fr) that</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">currently compiles a C++ class which implements a DSP plug-in with</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">several methods.</DIV> </BLOCKQUOTE><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">ok</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV> <BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Our strategy to compile LLVM IR instead is the following:</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">- use the current Faust ==> C++ compiler to compile a "empty" plug-in</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">that we use as a template C++ class.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">- compile this<SPAN class="Apple-converted-space">  </SPAN>template C++ class using "llvm-g++<SPAN class="Apple-converted-space">  </SPAN>-emit-llvm -c "</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">to get a bytecode file template.bc</DIV> </BLOCKQUOTE><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Ok.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV> <BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">- use "llvm2cpp<SPAN class="Apple-converted-space">  </SPAN>template.bc" to get a<SPAN class="Apple-converted-space">  </SPAN>template.bc.cpp<SPAN class="Apple-converted-space">  </SPAN>of<SPAN class="Apple-converted-space">  </SPAN>C++ code</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">the Faust ==> LLVM IR<SPAN class="Apple-converted-space">  </SPAN>new backend will have to execute to produce</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">the correct bytecode.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">- take this template.bc.cpp code as the "constant" part of the Faust</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">==> LLVM IR backend and add everything needed to produce the</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">"variable" part (that one corresponding to what the real Faust plug-</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">in will do)</DIV> </BLOCKQUOTE><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV> <BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Is there any more common and simple method to achieve the same</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">result? or any other advice?</DIV> </BLOCKQUOTE><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Here's a better way.<SPAN class="Apple-converted-space">  </SPAN>Consider a simple C template like this:</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">void the_template(int X, int Y) {</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">   </SPAN>if (X == 123)</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">     </SPAN>hole1(Y, X*Y);</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">   </SPAN>int *Ptr;</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">   </SPAN>for (...)</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">     </SPAN>hole2(Ptr);</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">}</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">The template can do whatever you want obviously.<SPAN class="Apple-converted-space">  </SPAN>I assume that there are<SPAN class="Apple-converted-space"> </SPAN></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">various pieces that need to be filled in, e.g. the body of a loop.<SPAN class="Apple-converted-space">  </SPAN>In you<SPAN class="Apple-converted-space"> </SPAN></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">C template code, just put simple function calls to external functions<SPAN class="Apple-converted-space"> </SPAN></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">(named hole1/hole2 in this example).</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">At runtime, load the IR for the code above (either from the .bc file, or<SPAN class="Apple-converted-space"> </SPAN></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">statically linked into your app with llvm2cpp).<SPAN class="Apple-converted-space">  </SPAN>Then do the following:</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">1. Create new internal LLVM functions that will be used to fill in the</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">    </SPAN>holes in the template.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">2. Clone the template code, specializing it based on globals or arguments,</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">    </SPAN>or whatever else you want.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">3. Iterate through the cloned code looking for calls to hole*.<SPAN class="Apple-converted-space">  </SPAN>Change the</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">    </SPAN>callinst to call into the new LLVM function you created with #1.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">4. After you iterate through and update the calls, use the InlineFunction</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">    </SPAN>routine in llvm/Transforms/Utils/Cloning.h to inline the calls to the</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><SPAN class="Apple-converted-space">    </SPAN>static functions you built in #1.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">The end result is happy specialized code, but in a nice and maintainable<SPAN class="Apple-converted-space"> </SPAN></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">form.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">-Chris</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><BR class="khtml-block-placeholder"></DIV> </BLOCKQUOTE><BR>Thanks,</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>I will need also to compile new fields in the result C++ class, thus i need a way to get an access on the class struct field part. I  see something like:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">std::vector<</SPAN></FONT><FONT class="Apple-style-span" color="#760F50" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">const</SPAN></FONT><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;"> Type*>StructTy_struct_mydsp_fields;</SPAN></FONT></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">  </SPAN></FONT><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">StructTy_struct_mydsp_fields.push_back(StructTy_struct_dsp);</SPAN></FONT></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">  </SPAN></FONT><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">StructType* StructTy_struct_mydsp = StructType::get(StructTy_struct_mydsp_fields, </SPAN></FONT><FONT class="Apple-style-span" color="#236E25" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">/*isPacked=*/</SPAN></FONT><FONT class="Apple-style-span" color="#760F50" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">false</SPAN></FONT><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">);</SPAN></FONT></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">  </SPAN></FONT><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">mod->addTypeName(</SPAN></FONT><FONT class="Apple-style-span" color="#891315" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">"struct.mydsp"</SPAN></FONT><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">, StructTy_struct_mydsp);</SPAN></FONT></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;"> </SPAN></FONT><BR>in the generated llvm2cpp code, i guess it is possible then to iterate through the cloned code looking for the object with <FONT class="Apple-style-span" color="#891315" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">"struct.mydsp" </SPAN><FONT class="Apple-style-span" color="#000000" face="Helvetica" size="3"><SPAN class="Apple-style-span" style="font-size: 12px;">name and get the associated field struct so that to later do something like : <FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;"> </SPAN></FONT><FONT class="Apple-style-span" face="Monaco" size="2"><SPAN class="Apple-style-span" style="font-size: 10px;">StructTy_struct_mydsp_fields.push_back(Type::FloatTy); <FONT class="Apple-style-span" face="Helvetica" size="3"><SPAN class="Apple-style-span" style="font-size: 12px;">to add new fields?</SPAN></FONT></SPAN></FONT></SPAN></FONT></FONT></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR class="khtml-block-placeholder"></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; ">Thanks</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR class="khtml-block-placeholder"></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; ">Stephane Letz</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR><BR></DIV><BR></BODY></HTML>