forked from OSchip/llvm-project
[mlir] Add option to use custom base class for dialect in LLVMIRIntrinsicGen.
Summary: LLVMIRIntrinsicGen is using LLVM_Op as the base class for intrinsics. This works for LLVM intrinsics in the LLVM Dialect, but when we are trying to convert custom intrinsics that originate from a custom LLVM dialect (like NVVM or ROCDL) these usually have a different "cppNamespace" that needs to be applied to these dialect. These dialect specific characteristics (like "cppNamespace") are typically organized by creating a custom op (like NVVM_Op or ROCDL_Op) that passes the correct dialect to the LLVM_OpBase class. It seems natural to allow LLVMIRIntrinsicGen to take that into consideration when generating the conversion code from one of these dialect to a set of target specific intrinsics. Reviewers: rriddle, andydavis1, antiagainst, nicolasvasilache, ftynse Subscribers: jdoerfert, mehdi_amini, jpienaar, burmako, shauheen, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73233
This commit is contained in:
parent
794b8a0329
commit
be9f09c768
|
@ -56,4 +56,10 @@ class LLVM_OpBase<Dialect dialect, string mnemonic, list<OpTrait> traits = []> :
|
|||
class LLVM_Op<string mnemonic, list<OpTrait> traits = []> :
|
||||
LLVM_OpBase<LLVM_Dialect, mnemonic, traits>;
|
||||
|
||||
// Base class for LLVM intrinsics operation. It is the same as an LLVM_Op
|
||||
// but the operation has a ".intr." element in the prefix becoming
|
||||
// "llvm.intr.*".
|
||||
class LLVM_IntrOp<string mnemonic, list<OpTrait> traits = []> :
|
||||
LLVM_Op<"intr."#mnemonic, traits>;
|
||||
|
||||
#endif // LLVMIR_OP_BASE
|
||||
|
|
|
@ -10,16 +10,18 @@
|
|||
//
|
||||
// RUN: cat %S/../../../llvm/include/llvm/IR/Intrinsics.td \
|
||||
// RUN: | grep -v "llvm/IR/Intrinsics" \
|
||||
// RUN: | mlir-tblgen -gen-llvmir-intrinsics -I %S/../../../llvm/include/ --llvmir-intrinsics-filter=is_constant \
|
||||
// RUN: | mlir-tblgen -gen-llvmir-intrinsics -I %S/../../../llvm/include/ --llvmir-intrinsics-filter=ptrmask \
|
||||
// RUN: | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: def LLVM_is_constant
|
||||
// CHECK: LLVM_Op<"intr
|
||||
// CHECK-LABEL: def LLVM_ptrmask
|
||||
// CHECK: LLVM_IntrOp<"ptrmask
|
||||
// CHECK: Arguments<(ins
|
||||
// CHECK: Results<(outs
|
||||
// CHECK: llvm::Function *fn = llvm::Intrinsic::getDeclaration(
|
||||
// CHECK: module, llvm::Intrinsic::is_constant, {
|
||||
// CHECK: module, llvm::Intrinsic::ptrmask, {
|
||||
// CHECK: opInst.getResult(0).getType().cast<LLVM::LLVMType>().getUnderlyingType(),
|
||||
// CHECK: opInst.getOperand(0).getType().cast<LLVM::LLVMType>().getUnderlyingType(),
|
||||
// CHECK: opInst.getOperand(1).getType().cast<LLVM::LLVMType>().getUnderlyingType(),
|
||||
// CHECK: });
|
||||
// CHECK: lookupValues(opInst.getOperands());
|
||||
|
||||
|
@ -36,3 +38,11 @@
|
|||
// RUN: | FileCheck --check-prefix=ODS %s
|
||||
|
||||
// ODS-LABEL: class vastart
|
||||
|
||||
// RUN: cat %S/../../../llvm/include/llvm/IR/Intrinsics.td \
|
||||
// RUN: | grep -v "llvm/IR/Intrinsics" \
|
||||
// RUN: | mlir-tblgen -gen-llvmir-intrinsics -I %S/../../../llvm/include/ --llvmir-intrinsics-filter=ptrmask -dialect-opclass-base My_OpBase \
|
||||
// RUN: | FileCheck %s --check-prefix=DIALECT-OPBASE
|
||||
|
||||
// DIALECT-OPBASE-LABEL: def LLVM_ptrmask
|
||||
// DIALECT-OPBASE: My_OpBase<"ptrmask
|
||||
|
|
|
@ -32,6 +32,12 @@ static llvm::cl::opt<std::string>
|
|||
"substring in their record name"),
|
||||
llvm::cl::cat(IntrinsicGenCat));
|
||||
|
||||
static llvm::cl::opt<std::string>
|
||||
opBaseClass("dialect-opclass-base",
|
||||
llvm::cl::desc("The base class for the ops in the dialect we "
|
||||
"are planning to emit"),
|
||||
llvm::cl::init("LLVM_IntrOp"), llvm::cl::cat(IntrinsicGenCat));
|
||||
|
||||
// Used to represent the indices of overloadable operands/results.
|
||||
using IndicesTy = llvm::SmallBitVector;
|
||||
|
||||
|
@ -84,8 +90,20 @@ public:
|
|||
"LLVM intrinsic names are expected to start with 'int_'");
|
||||
name = name.drop_front(4);
|
||||
llvm::SmallVector<llvm::StringRef, 8> chunks;
|
||||
llvm::StringRef targetPrefix = record.getValueAsString("TargetPrefix");
|
||||
name.split(chunks, '_');
|
||||
return llvm::join(chunks, ".");
|
||||
auto chunksBegin = chunks.begin();
|
||||
// Remove the target prefix from target specific intrinsics.
|
||||
if (!targetPrefix.empty()) {
|
||||
assert(targetPrefix == *chunksBegin &&
|
||||
"Intrinsic has TargetPrefix, but "
|
||||
"record name doesn't begin with it");
|
||||
assert(chunks.size() >= 2 &&
|
||||
"Intrinsic has TargetPrefix, but "
|
||||
"chunks has only one element meaning the intrinsic name is empty");
|
||||
++chunksBegin;
|
||||
}
|
||||
return llvm::join(chunksBegin, chunks.end(), ".");
|
||||
}
|
||||
|
||||
/// Get the name of the record without the "intrinsic" prefix.
|
||||
|
@ -205,8 +223,8 @@ static bool emitIntrinsic(const llvm::Record &record, llvm::raw_ostream &os) {
|
|||
"LLVM_Type");
|
||||
|
||||
// Emit the definition.
|
||||
os << "def LLVM_" << intr.getProperRecordName() << " : LLVM_Op<\"intr."
|
||||
<< intr.getOperationName() << "\", [";
|
||||
os << "def LLVM_" << intr.getProperRecordName() << " : " << opBaseClass
|
||||
<< "<\"" << intr.getOperationName() << "\", [";
|
||||
mlir::interleaveComma(traits, os);
|
||||
os << "]>, Arguments<(ins" << (operands.empty() ? "" : " ");
|
||||
mlir::interleaveComma(operands, os);
|
||||
|
|
Loading…
Reference in New Issue