MLIR 22.0.0git
PrintCallHelper.cpp
Go to the documentation of this file.
1//===- PrintCallHelper.cpp - Helper to emit runtime print calls -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
13#include "mlir/IR/Builders.h"
14#include "mlir/IR/BuiltinOps.h"
15#include "llvm/ADT/ArrayRef.h"
16
17using namespace mlir;
18using namespace llvm;
19
20/// Check if a given symbol name is already in use within the module operation.
21/// If no symbol with such name is present, then the same identifier is
22/// returned. Otherwise, a unique and yet unused identifier is computed starting
23/// from the requested one.
24static std::string
25ensureSymbolNameIsUnique(ModuleOp moduleOp, StringRef symbolName,
26 SymbolTableCollection *symbolTables = nullptr) {
27 if (symbolTables) {
28 SymbolTable &symbolTable = symbolTables->getSymbolTable(moduleOp);
29 unsigned counter = 0;
30 SmallString<128> uniqueName = symbolTable.generateSymbolName<128>(
31 symbolName,
32 [&](const SmallString<128> &tentativeName) {
33 return symbolTable.lookupSymbolIn(moduleOp, tentativeName) != nullptr;
34 },
35 counter);
36
37 return static_cast<std::string>(uniqueName);
38 }
39
40 static int counter = 0;
41 std::string uniqueName = std::string(symbolName);
42 while (moduleOp.lookupSymbol(uniqueName)) {
43 uniqueName = std::string(symbolName) + "_" + std::to_string(counter++);
44 }
45 return uniqueName;
46}
47
49 OpBuilder &builder, Location loc, ModuleOp moduleOp, StringRef symbolName,
50 StringRef string, const LLVMTypeConverter &typeConverter, bool addNewline,
51 std::optional<StringRef> runtimeFunctionName,
52 SymbolTableCollection *symbolTables) {
53 auto ip = builder.saveInsertionPoint();
54 builder.setInsertionPointToStart(moduleOp.getBody());
55 MLIRContext *ctx = builder.getContext();
56
57 // Create a zero-terminated byte representation and allocate global symbol.
58 SmallVector<uint8_t> elementVals;
59 elementVals.append(string.begin(), string.end());
60 if (addNewline)
61 elementVals.push_back('\n');
62 elementVals.push_back('\0');
63 auto dataAttrType = RankedTensorType::get(
64 {static_cast<int64_t>(elementVals.size())}, builder.getI8Type());
65 auto dataAttr =
66 DenseElementsAttr::get(dataAttrType, llvm::ArrayRef(elementVals));
67 auto arrayTy =
68 LLVM::LLVMArrayType::get(IntegerType::get(ctx, 8), elementVals.size());
69 auto globalOp = LLVM::GlobalOp::create(
70 builder, loc, arrayTy, /*isConstant=*/true, LLVM::Linkage::Private,
71 ensureSymbolNameIsUnique(moduleOp, symbolName, symbolTables), dataAttr);
72
73 auto ptrTy = LLVM::LLVMPointerType::get(builder.getContext());
74 // Emit call to `printStr` in runtime library.
75 builder.restoreInsertionPoint(ip);
76 auto msgAddr =
77 LLVM::AddressOfOp::create(builder, loc, ptrTy, globalOp.getName());
79 Value gep =
80 LLVM::GEPOp::create(builder, loc, ptrTy, arrayTy, msgAddr, indices);
81 FailureOr<LLVM::LLVMFuncOp> printer =
82 LLVM::lookupOrCreatePrintStringFn(builder, moduleOp, runtimeFunctionName);
83 if (failed(printer))
84 return failure();
85 LLVM::CallOp::create(builder, loc, TypeRange(),
86 SymbolRefAttr::get(printer.value()), gep);
87 return success();
88}
return success()
static std::string ensureSymbolNameIsUnique(ModuleOp moduleOp, StringRef symbolName, SymbolTableCollection *symbolTables=nullptr)
Check if a given symbol name is already in use within the module operation.
MLIRContext * getContext() const
Definition Builders.h:56
IntegerType getI8Type()
Definition Builders.cpp:59
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
Conversion from types to the LLVM IR dialect.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
This class helps build Operations.
Definition Builders.h:207
InsertPoint saveInsertionPoint() const
Return a saved insertion point.
Definition Builders.h:385
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
Definition Builders.h:431
void restoreInsertionPoint(InsertPoint ip)
Restore the insert point to a previously saved point.
Definition Builders.h:390
This class represents a collection of SymbolTables.
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
Definition SymbolTable.h:24
static SmallString< N > generateSymbolName(StringRef name, UniqueChecker uniqueChecker, unsigned &uniquingCounter)
Generate a unique symbol name.
static Operation * lookupSymbolIn(Operation *op, StringAttr symbol)
Returns the operation registered with the given symbol name with the regions of 'symbolTableOp'.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:229
FailureOr< LLVM::LLVMFuncOp > lookupOrCreatePrintStringFn(OpBuilder &b, Operation *moduleOp, std::optional< StringRef > runtimeFunctionName={}, SymbolTableCollection *symbolTables=nullptr)
Declares a function to print a C-string.
LogicalResult createPrintStrCall(OpBuilder &builder, Location loc, ModuleOp moduleOp, StringRef symbolName, StringRef string, const LLVMTypeConverter &typeConverter, bool addNewline=true, std::optional< StringRef > runtimeFunctionName={}, SymbolTableCollection *symbolTables=nullptr)
Generate IR that prints the given string to stdout.
Include the generated interface declarations.