17#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
18#include "mlir/IR/BuiltinOps.h"
20#include "llvm/TargetParser/Triple.h"
52packArgsIntoNVPTXFormatBuffer(cir::OffloadPrintfOp op, mlir::ValueRange args,
53 mlir::ConversionPatternRewriter &rewriter,
54 const mlir::DataLayout &dataLayout) {
55 mlir::Location loc = op.getLoc();
56 auto ptrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
61 return mlir::LLVM::ZeroOp::create(rewriter, loc, ptrTy);
66 auto allocaTy = mlir::LLVM::LLVMStructType::getLiteral(
67 rewriter.getContext(), llvm::to_vector(args.getTypes()));
73 mlir::OpBuilder::InsertionGuard guard(rewriter);
74 auto fn = op->getParentOfType<mlir::LLVM::LLVMFuncOp>();
75 assert(fn &&
"lowering expects printf to be inside a function");
76 rewriter.setInsertionPointToStart(&fn.getBody().front());
78 mlir::LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(), 1);
80 mlir::LLVM::AllocaOp::create(rewriter, loc, ptrTy, allocaTy, one,
81 dataLayout.getTypeABIAlignment(allocaTy));
85 mlir::LLVM::GEPNoWrapFlags flags =
86 mlir::LLVM::GEPNoWrapFlags::inbounds | mlir::LLVM::GEPNoWrapFlags::nuw;
87 for (
auto [i, arg] : llvm::enumerate(args)) {
88 mlir::Value
member = mlir::LLVM::GEPOp::create(
89 rewriter, loc, ptrTy, allocaTy, alloca,
90 llvm::ArrayRef<mlir::LLVM::GEPArg>{0,
static_cast<int32_t>(i)}, flags);
91 mlir::LLVM::StoreOp::create(rewriter, loc, arg, member,
92 dataLayout.getTypeABIAlignment(
arg.getType()));
101lowerNVPTXPrintf(cir::OffloadPrintfOp op, mlir::Value format,
102 mlir::ValueRange args,
103 mlir::ConversionPatternRewriter &rewriter,
104 const mlir::DataLayout &dataLayout,
105 mlir::SymbolTableCollection &symbolTables) {
106 mlir::Value packedData =
107 packArgsIntoNVPTXFormatBuffer(op, args, rewriter, dataLayout);
110 auto ptrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
111 mlir::Type i32Ty = rewriter.getI32Type();
112 const llvm::StringRef fnName =
"vprintf";
114 rewriter, symbolTables, op, fnName,
115 mlir::LLVM::LLVMFunctionType::get(i32Ty, {ptrTy, ptrTy}));
118 if (format.getType() != ptrTy)
119 format = mlir::LLVM::AddrSpaceCastOp::create(rewriter, op.getLoc(), ptrTy,
121 rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
122 op, mlir::TypeRange{i32Ty}, fnName, mlir::ValueRange{format, packedData});
123 return mlir::success();
128mlir::LogicalResult CIRToLLVMOffloadPrintfOpLowering::matchAndRewrite(
129 cir::OffloadPrintfOp op, OpAdaptor adaptor,
130 mlir::ConversionPatternRewriter &rewriter)
const {
131 auto mod = op->getParentOfType<mlir::ModuleOp>();
132 llvm::StringRef tripleStr;
133 if (
auto tripleAttr = mod->getAttrOfType<mlir::StringAttr>(
134 cir::CIRDialect::getTripleAttrName()))
135 tripleStr = tripleAttr.getValue();
136 llvm::Triple triple(tripleStr);
138 if (triple.isNVPTX())
139 return lowerNVPTXPrintf(op, adaptor.getFormat(), adaptor.getArgs(),
140 rewriter, dataLayout, symbolTables);
142 return op.emitError() <<
"offload printf lowering is NYI for target '"
void createLLVMFuncOpIfNotExist(mlir::ConversionPatternRewriter &rewriter, mlir::SymbolTableCollection &symbolTables, mlir::Operation *srcOp, llvm::StringRef fnName, mlir::Type fnTy, mlir::ArrayAttr argAttrs, mlir::ArrayAttr resAttrs)
Declare fnName with type fnTy before the function enclosing srcOp, unless the module already has a sy...
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t