16 #define DEBUG_TYPE "ptx-builder"
17 #define DBGS() (llvm::dbgs() << "[" DEBUG_TYPE "]: ")
18 #define DBGSNL() (llvm::dbgs() << "\n")
24 #include "mlir/Dialect/LLVMIR/BasicPtxBuilderInterface.cpp.inc"
44 if (
auto ptr = dyn_cast<LLVM::LLVMPointerType>(type)) {
52 llvm_unreachable(
"The register type could not deduced from MLIR type");
63 LLVM_DEBUG(
DBGS() << v <<
"\t Modifier : " << &itype <<
"\n");
64 auto getModifier = [&]() ->
const char * {
66 assert(
false &&
"Read-Write modifier is not supported. Try setting the "
67 "same value as Write and Read separately.");
75 auto addValue = [&](
Value v) {
77 ptxOperands.push_back(v);
81 ptxOperands.push_back(v);
85 llvm::raw_string_ostream ss(registerConstraints);
87 if (
auto stype = dyn_cast<LLVM::LLVMStructType>(v.
getType())) {
93 Value extractValue = rewriter.
create<LLVM::ExtractValueOp>(
94 interfaceOp->getLoc(), v, idx);
95 addValue(extractValue);
114 LLVM::AsmDialect::AD_ATT);
116 auto resultTypes = interfaceOp->getResultTypes();
119 if (!registerConstraints.empty() &&
120 registerConstraints[registerConstraints.size() - 1] ==
',')
121 registerConstraints.pop_back();
123 std::string ptxInstruction = interfaceOp.getPtx();
126 if (interfaceOp.getPredicate().has_value() &&
127 interfaceOp.getPredicate().value()) {
128 std::string predicateStr =
"@%";
129 predicateStr += std::to_string((ptxOperands.size() - 1));
130 ptxInstruction = predicateStr +
" " + ptxInstruction;
135 std::replace(ptxInstruction.begin(), ptxInstruction.end(),
'%',
'$');
137 return rewriter.
create<LLVM::InlineAsmOp>(
138 interfaceOp->getLoc(),
141 llvm::StringRef(ptxInstruction),
142 registerConstraints.data(),
143 interfaceOp.hasSideEffect(),
150 LLVM::InlineAsmOp inlineAsmOp =
build();
151 LLVM_DEBUG(
DBGS() <<
"\n Generated PTX \n\t" << inlineAsmOp <<
"\n");
152 if (inlineAsmOp->getNumResults() == interfaceOp->getNumResults()) {
153 rewriter.
replaceOp(interfaceOp, inlineAsmOp);
static char getRegisterType(Type type)
void insertValue(Value v, PTXRegisterMod itype=PTXRegisterMod::Read)
Add an operand with the read/write input type.
LLVM::InlineAsmOp build()
Builds the inline assembly Op and returns it.
void buildAndReplaceOp()
Shortcut to build the inline assembly Op and replace or erase the original op with.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool isInteger() const
Return true if this is an integer type (with the specified width).
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
PTXRegisterMod
Register read/write modifier to build constraint string for PTX inline https://docs....
@ Write
Read register with '+' modifier.
@ ReadWrite
Read register with '=' modifier.
@ Read
Read register with no modifier.
@ kSharedMemorySpace
Shared memory space identifier.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...