Alex Susu via llvm-dev
2017-Mar-03 03:07 UTC
[llvm-dev] Specifying conditional blocks for the back end
Hello. For my back end for the Connex SIMD research processor I want to implement conditional blocks (I guess the better term is predicated blocks). Predicated blocks are bordered by two instructions WHEREEQ (or WHERELT, etc) and ENDWHERE. For example, the following code executes the instructions inside the WHERE block only for the lanes where R0 == R1: EQ R0, R1; WHEREEQ vector_asm_instr1; ... vector_asm_instrk; ENDWHERE I was able to generate at instruction selection such a block by writing custom C++ selection code, but I don't know how can I inform the back end that the instructions inside the WHERE block get executed conditionally, not always. This matters it seems only for optimization levels in llc -O1/2/3, but not for O0. For levels of optimization O1/2/3, I experienced cases where the WHEREEQ and ENDWHERE instructions were simply removed and the vector_asm_instr1..k became executed unconditionally, etc - and this is NOT good. Could you please tell me how can I inform the back end that the instructions inside my WHERE blocks get executed conditionally, not always. Thank you very much, Alex
Friedman, Eli via llvm-dev
2017-Mar-03 18:59 UTC
[llvm-dev] Specifying conditional blocks for the back end
On 3/2/2017 7:07 PM, Alex Susu via llvm-dev wrote:> Hello. > For my back end for the Connex SIMD research processor I want to > implement conditional blocks (I guess the better term is predicated > blocks). Predicated blocks are bordered by two instructions WHEREEQ > (or WHERELT, etc) and ENDWHERE. > For example, the following code executes the instructions inside > the WHERE block only for the lanes where R0 == R1: > EQ R0, R1; > WHEREEQ > vector_asm_instr1; > ... > vector_asm_instrk; > ENDWHERE > > I was able to generate at instruction selection such a block by > writing custom C++ selection code, but I don't know how can I inform > the back end that the instructions inside the WHERE block get executed > conditionally, not always. > This matters it seems only for optimization levels in llc -O1/2/3, > but not for O0. For levels of optimization O1/2/3, I experienced cases > where the WHEREEQ and ENDWHERE instructions were simply removed and > the vector_asm_instr1..k became executed unconditionally, etc - and > this is NOT good. > > Could you please tell me how can I inform the back end that the > instructions inside my WHERE blocks get executed conditionally, not > always.There's some existing infrastructure in the backend for predication; see lib/CodeGen/IfConversion.cpp (and the target hooks PredicateInstruction etc.). For forming blocks, you might want to follow what the ARM backend does for Thumb2; see Thumb2ITBlockPass.cpp . -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Alex Susu via llvm-dev
2017-Mar-07 06:12 UTC
[llvm-dev] Specifying conditional blocks for the back end
Hello. Because I experience optimizations (DCE, OoO schedule) which mess the correct semantics of the list of instructions lowered in ISelLowering from the VSELECT LLVM instruction, and these bad transformations happen even before scheduling, at later I-sel subpasses, I try to fix this problem by lowering VSELECT to only one pseudo-instruction and LATER translate it to a list of instructions and use bundles and maybe also PredicateInstruction(), which is employed also in IfConversion.cpp. More exactly I'm trying to use a pseudo-instruction that will get translated to a sequence of 4 MachineInstr, namely: // These 4 instructions replace the pseudo-instruction I use for LLVM's VSELECT R31 = OR srcVselectFalse, srcVselectFalse WHEREEQ R31 = OR srcVselectTrue, srcVselectTrue ENDWHERE I plan to do this as early as possible, in a pass registered in addInstSelector() normally, which gets executed immediately after the first scheduling phase. If anybody sees a problem with this, please let me know. I think it is OK to specify an empty semantics (empty DAG pattern in TableGen) for my WHEREEQ/ENDWHERE instructions delimiting the predication/conditional block. Eli, thank you for the pointers. The "it" ARM Thumb2 instruction is very interesting, maybe even unique among mainstream processors, handling predicated execution of 2 contiguous blocks of instructions; I found some specs for it at https://community.arm.com/processors/b/blog/posts/condition-codes-3-conditional-execution-in-thumb-2. This instruction is quite similar to my conditional-block instructions WHERExy/ENDWHERE (xy can be EQ, LT, CRY). Thank you, Alex On 3/3/2017 8:59 PM, Friedman, Eli wrote:> On 3/2/2017 7:07 PM, Alex Susu via llvm-dev wrote: >> Hello. >> For my back end for the Connex SIMD research processor I want to implement >> conditional blocks (I guess the better term is predicated blocks). Predicated blocks are >> bordered by two instructions WHEREEQ (or WHERELT, etc) and ENDWHERE. >> For example, the following code executes the instructions inside the WHERE block >> only for the lanes where R0 == R1: >> EQ R0, R1; >> WHEREEQ >> vector_asm_instr1; >> ... >> vector_asm_instrk; >> ENDWHERE >> >> I was able to generate at instruction selection such a block by writing custom C++ >> selection code, but I don't know how can I inform the back end that the instructions >> inside the WHERE block get executed conditionally, not always. >> This matters it seems only for optimization levels in llc -O1/2/3, but not for O0. >> For levels of optimization O1/2/3, I experienced cases where the WHEREEQ and ENDWHERE >> instructions were simply removed and the vector_asm_instr1..k became executed >> unconditionally, etc - and this is NOT good. >> >> Could you please tell me how can I inform the back end that the instructions inside >> my WHERE blocks get executed conditionally, not always. > > There's some existing infrastructure in the backend for predication; see > lib/CodeGen/IfConversion.cpp (and the target hooks PredicateInstruction etc.). For > forming blocks, you might want to follow what the ARM backend does for Thumb2; see > Thumb2ITBlockPass.cpp . > > -Eli >