<div dir="ltr">Hi, <span style="font-size:14px">Gaël,</span><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">Thanks for your detailed reply. I tried the pattern matching first, however, the intrinsic function is matching with a normal function call.</span></div><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">For example, I have the following IR, which contains intrinsic function "foo":</span></div><div><span style="font-size:14px">*****************************************************************************************</span></div><div><div style=""><span style="font-size:14px"><i>define i32 @test_func() {</i></span></div><div style=""><span style="font-size:14px"><i>EntryBlock:</i></span></div><div style=""><span style="font-size:14px"><i> %0 = call i32 @llvm.foo.i32.i32(i32 2, i32 3)</i></span></div><div style=""><span style="font-size:14px"><i> ret i32 %0</i></span></div><div style=""><span style="font-size:14px"><i>}</i></span></div><div style=""><span style="font-size:14px"><i><br></i></span></div><div style=""><span style="font-size:14px"><i>declare i32 @llvm.foo.i32.i32(i32, i32)</i></span></div></div><div style=""><span style="font-size:14px"><i>*****************************************************************************************</i></span></div><div style=""><span style="font-size:14px">In InstroInfo.td, I define a pseudo instruction like this :</span></div><div style=""><span style="font-size:14px">******************************************************************************************</span></div><div><i>let isPseudo = 1 in {</i></div><div><i> def FOO : MyPseudoInst<(outs GRRegs:$dst) , (ins GRRegs:$src1, GRRegs:$src2),</i></div><div><i> "foo $dst, $src1, $src2",</i></div><div><i> [(set i32:$dst, (int_foo i32:$src1, i32:$src2))]> {</i></div><div><i> }</i></div><div style=""><i>}<span style="font-size:14px"> </span></i></div><div style=""><span style="font-size:14px"><i>******************************************************************************************</i></span></div><div style=""><span style="font-size:14px"><i><br></i></span></div><div style=""><span style="font-size:14px">I want to check the pattern matching first, so I have not implement the part of instruction lowering. Actually, I'm planing to make a source-to-source compiler, so the Pseudo instruction is enough for me. Then I use llc to dump the asm file. However, it gives me </span></div><div style=""><span style="font-size:14px"><div>*******************************************************************************************</div><div> ....</div><div><i> invoke llvm.foo.i32.i32, v0, v1</i></div><div><i> return v0</i></div><div>*******************************************************************************************</div></span></div><div style="">As you can see, it matchs with function call (the invoke instruction). Do you have any idea how I can fix this? Thanks a lot.</div><div style=""><br></div><div style="">Regards,</div><div style=""><br></div><div style="">Xiangyang</div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-10-22 11:51 GMT-04:00 Gaël Jobin via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>Hi Xiangyang,</div><div><br></div><div>When your intrinsic is passed to the back-end, it will be converted into DAG nodes automatically (like for a function call). Then the back-end need to know how to convert it into real instructions or at least how to manage it through instruction selection pass. An intrinsic cannot exist inside the backend (it is IR code) but can be converted into pseudo-instruction instead (at least for the X86 backend). Then, there's many ways to handle pseudo-instructions inside a backend. </div><div><br></div><div>I will take the X86 backend as an example.</div><div><br></div><div>First, your intrinsics:</div><span class=""><div><br></div><div><font face="monospace">def int_foo : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadArgMem]>;</font></div><div><font face="monospace"></font><br></div></span><div>It will be converted into DAG nodes. Then, you can handle it manually inside the code or using TableGen mechanism. For the latter, you should define a pseudo-instruction that match your intrinsic-translated-into-dag-node. The pseudo-instruction definition should look like this:</div><div><br></div><div><font face="monospace">let isPseudo = 1 in {</font></div><div><font face="monospace">def FOO : PseudoI<(outs i32mem:$dst), (ins i32mem:$src1, i32mem:$src2, ), [(set i32mem:$dst, (int_foo i32mem:$src1, i32mem:$src2))]>;</font></div><div><font face="monospace">}</font></div><div><br></div><div>First, you should always set isPeudo to 1 if it is a pseudo-instruction. Then, if it has some side effect, you should define them. For example, set Defs = [EFLAGS] if it impacts EFLAGS value.</div><div>The tricky part is the pattern matching for dag nodes. I'm not sure it's correct. I'm used to enable debug pass in Clang to have the resulted dag node representation of my intrinsics and then create my pseudo-instruction definition based on it.</div><div><br></div><div>When your intrinsic is correctly translated into pseudo-instruction, you can use it where you want. If you need to convert it into real instructions, there's some common place to do it.</div><div><br></div><div>You have the ExpandISelPseudos pass which is called at the beginning of addMachinePasses. Its operation is relatively simple since it browses the MachineInstr by looking for pseudo-instructions and then calls TargetLowering::EmitInstrWithCustomeInserter for each of them. This last method being abstract, it is implemented by each backend that wants it like in X86TargetLowering for the x86 backend. Due to its location, this solution offers the advantage that no optimization has already taken place. Thus, the added machine code will be optimized in the same way than any other options of the program. Moreover, you still have the virtual register abstraction allowing you to be more flexibility in your implementation.</div><div><br></div><div>You also have ExpandPostRA pass. This one commes right after register allocation and the addition of the prolog-epilog. It calls TargetInstrInfo::expandPostRAPseudo() giving a chance to the target to extend the pseudo-instruction encountered. For the backend X86, the TargetInstrInfo concrete implementation is in X86InstrInfo. As register allocation and the majority of previous optimizations have already been done, this solution ensures that the added code will not be altered afterwards.</div><div><br></div><div>Finally, it the two previous passes are not suitable for a particular reason, other more generic ways exist. Simply create a new MachineFunctionPass and call it when you need it. For example from:</div><div>- addPreRegAlloc</div><div>- addPostRegAlloc</div><div>- addPreSched2</div><div>- addPreEmitPass</div><div><br></div><div>I don't have a big LLVM background but thus are my findings when I was playing with the middle-end/back-end some time ago.</div><div><br></div><div>Regards,</div><div>Gaël</div><div><br></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>