================
@@ -0,0 +1,146 @@
+//===- LowerToLLVMOffloadPrintf.cpp - Lower cir.offload.printf 
------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file lowers cir.offload.printf to the printf runtime interface of each
+// device target. The expansions follow the lowerings of the GPU dialect's
+// gpu.printf in mlir/lib/Conversion/GPUCommon/GPUOpsLowering.cpp.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LowerToLLVM.h"
+
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace cir {
+namespace direct {
+
+namespace {
+
+// vprintf takes two args: A format string, and a pointer to a buffer 
containing
+// the varargs.
+//
+// For example, the call
+//
+//   printf("format string", arg1, arg2, arg3);
+//
+// is converted into something resembling
+//
+//   struct Tmp {
+//     Arg1 a1;
+//     Arg2 a2;
+//     Arg3 a3;
+//   };
+//   char* buf = alloca(sizeof(Tmp));
+//   *(Tmp*)buf = {a1, a2, a3};
+//   vprintf("format string", buf);
+//
+// `buf` is aligned to the max of {alignof(Arg1), ...}. Furthermore, each of
+// the args is itself aligned to its ABI alignment.
+//
+// Note that by the time this function runs, the arguments have already
+// undergone the standard C vararg promotion (short -> int, float -> double
+// etc). In this function we pack the arguments into the buffer described 
above.
+mlir::Value
+packArgsIntoNVPTXFormatBuffer(cir::OffloadPrintfOp op, mlir::ValueRange args,
+                              mlir::ConversionPatternRewriter &rewriter,
+                              const mlir::DataLayout &dataLayout) {
+  mlir::Location loc = op.getLoc();
+  auto ptrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
+
+  if (args.empty())
+    // If there are no arguments other than the format string,
+    // pass a nullptr to vprintf.
+    return mlir::LLVM::ZeroOp::create(rewriter, loc, ptrTy);
+
+  // We can directly store the arguments into a struct, and the alignment
+  // would automatically be correct. That's because vprintf does not
+  // accept aggregates.
+  auto allocaTy = mlir::LLVM::LLVMStructType::getLiteral(
+      rewriter.getContext(), llvm::to_vector(args.getTypes()));
+
+  // Allocate the buffer in the entry block, so that a printf in a loop does
+  // not grow the stack on every iteration.
+  mlir::Value alloca;
+  {
+    mlir::OpBuilder::InsertionGuard guard(rewriter);
+    auto fn = op->getParentOfType<mlir::LLVM::LLVMFuncOp>();
----------------
steffenlarsen wrote:

Ah, fair point. I wouldn't expect it to move earlier, but for safeties sake I 
have added the assert. That should catch the case if it ever happens and we can 
adjust accordingly.

https://github.com/llvm/llvm-project/pull/230517
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to