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);
112 LLVM::AsmDialect::AD_ATT);
114 auto resultTypes = interfaceOp->getResultTypes();
117 if (!registerConstraints.empty() &&
118 registerConstraints[registerConstraints.size() - 1] ==
',')
119 registerConstraints.pop_back();
121 std::string ptxInstruction = interfaceOp.getPtx();
124 if (interfaceOp.getPredicate().has_value() &&
125 interfaceOp.getPredicate().value()) {
126 std::string predicateStr =
"@%";
127 predicateStr += std::to_string((ptxOperands.size() - 1));
128 ptxInstruction = predicateStr +
" " + ptxInstruction;
133 std::replace(ptxInstruction.begin(), ptxInstruction.end(),
'%',
'$');
135 return rewriter.
create<LLVM::InlineAsmOp>(
136 interfaceOp->getLoc(),
139 llvm::StringRef(ptxInstruction),
140 registerConstraints.data(),
141 interfaceOp.hasSideEffect(),
148 LLVM::InlineAsmOp inlineAsmOp =
build();
149 LLVM_DEBUG(
DBGS() <<
"\n Generated PTX \n\t" << inlineAsmOp <<
"\n");
150 if (inlineAsmOp->getNumResults() == interfaceOp->getNumResults()) {
151 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...