Hello.
Hal, the source file you mention (lib/Target/PowerPC/PPCCTRLoops.cpp) makes use of LLVM IR intrinsics, in this case defined at [LLVM_repo]/llvm/include/llvm/IR/IntrinsicsPowerPC.td, such as:
// Intrinsics used to generate ctr-based loops. These should only be
// generated by the PowerPC backend!
def int_ppc_mtctr : Intrinsic<, [llvm_anyint_ty], >;
def int_ppc_is_decremented_ctr_nonzero : Intrinsic<[llvm_i1_ty], , >;
And these intrinsics are instantiated in the LLVM program, for example with the following code in PPCCTRLoops.cpp:
IRBuilder<> CountBuilder(Preheader->getTerminator());
Module *M = Preheader->getParent()->getParent();
Value *MTCTRFunc = Intrinsic::getDeclaration(M, Intrinsic::ppc_mtctr,CountType);
CountBuilder.CreateCall(MTCTRFunc, ECValue);
I have defined also some intrinsics for my loop instructions in my file Intrinsics_Connex.td: 1 intrinsic for REPEAT_X_TIMES and 1 for END_REPEAT.
/* following Intrinsics.td:
class Intrinsic<list<LLVMType> ret_types,
list<LLVMType> param_types = ,
list<IntrinsicProperty> properties = ,
string name = "">
*/
def int_connex_repeat_x_times : Intrinsic<, , >;
def int_connex_end_repeat : Intrinsic<[llvm_i1_ty], , >;
and added C++ code doing CreateCall() like the one above.
I'm looking now at http://llvm.org/docs/ExtendingLLVM.html on how to specify the instruction selection of this intrinsic. They write there:
"Once the intrinsic has been added to the system, you must add code generator support for it. Generally you must do the following steps:
Add support to the .td file for the target(s) of your choice in lib/Target/*/*.td.
This is usually a matter of adding a pattern to the .td file that matches the intrinsic, though it may obviously require adding the instructions you want to generate as well. There are lots of examples in the PowerPC and X86 backend to follow."
Then in my pass I create a call to the respective intrinsic:
/* See http://llvm.org/docs/doxygen/html/classllvm_1_1TargetIntrinsicInfo.html : "Create or insert an LLVM Function declaration for an intrinsic, and return it."
* This creates a line in the LLVM program like: declare void @llvm.connex.repeat.x.times() #2 .
* This line is required, otherwise llc will complain:
* <<error: use of undefined value '@llvm.connex.repeat.x.times'
call void @llvm.connex.repeat.x.times()>>
*/
Value *repeatFunc = Intrinsic::getDeclaration(M,
Intrinsic::connex_repeat_x_times);
// See http://llvm.org/docs/doxygen/html/classllvm_1_1IRBuilder.html
aB.CreateCall(repeatFunc); //, ECValue);
Then, in the back end, in InstrInfo.td I write:
let hasSideEffects = 1, isCodeGenOnly = 1 in {
//let Pattern = [(int_connex_repeat_x_times)] in
def REPEAT_X_TIMES : ImmediateInstruction< 0b111111,
(outs),
(ins),
"REPEAT_X_TIMES(1001)",
[(int_connex_repeat_x_times)] >;
}
Then, when I run opt and llc I obtain the expected behavior.
Thank you,
Alex