brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · da4443d Raw
89 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "mlir/Conversion/LLVMCommon/PrintCallHelper.h"10#include "mlir/Conversion/LLVMCommon/TypeConverter.h"11#include "mlir/Dialect/LLVMIR/FunctionCallUtils.h"12#include "mlir/Dialect/LLVMIR/LLVMDialect.h"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 is22/// returned. Otherwise, a unique and yet unused identifier is computed starting23/// from the requested one.24static std::string25ensureSymbolNameIsUnique(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 48LogicalResult mlir::LLVM::createPrintStrCall(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());78  SmallVector<LLVM::GEPArg> indices(1, 0);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}89