1e332c22cSNicolas Vasilache //===- FunctionCallUtils.cpp - Utilities for C function calls -------------===//
2e332c22cSNicolas Vasilache //
3e332c22cSNicolas Vasilache // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e332c22cSNicolas Vasilache // See https://llvm.org/LICENSE.txt for license information.
5e332c22cSNicolas Vasilache // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e332c22cSNicolas Vasilache //
7e332c22cSNicolas Vasilache //===----------------------------------------------------------------------===//
8e332c22cSNicolas Vasilache //
9e332c22cSNicolas Vasilache // This file implements helper functions to call common simple C functions in
10e332c22cSNicolas Vasilache // LLVMIR (e.g. amon others to support printing and debugging).
11e332c22cSNicolas Vasilache //
12e332c22cSNicolas Vasilache //===----------------------------------------------------------------------===//
13e332c22cSNicolas Vasilache
14e332c22cSNicolas Vasilache #include "mlir/Dialect/LLVMIR/FunctionCallUtils.h"
15e332c22cSNicolas Vasilache #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
16e332c22cSNicolas Vasilache #include "mlir/IR/Builders.h"
17e332c22cSNicolas Vasilache #include "mlir/IR/OpDefinition.h"
18e332c22cSNicolas Vasilache #include "mlir/Support/LLVM.h"
19e332c22cSNicolas Vasilache
20e332c22cSNicolas Vasilache using namespace mlir;
21e332c22cSNicolas Vasilache using namespace mlir::LLVM;
22e332c22cSNicolas Vasilache
23e332c22cSNicolas Vasilache /// Helper functions to lookup or create the declaration for commonly used
24e332c22cSNicolas Vasilache /// external C function calls. The list of functions provided here must be
25e332c22cSNicolas Vasilache /// implemented separately (e.g. as part of a support runtime library or as
26e332c22cSNicolas Vasilache /// part of the libc).
27e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintI64 = "printI64";
28e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintU64 = "printU64";
29e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintF32 = "printF32";
30e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintF64 = "printF64";
31e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintOpen = "printOpen";
32e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintClose = "printClose";
33e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintComma = "printComma";
34e332c22cSNicolas Vasilache static constexpr llvm::StringRef kPrintNewline = "printNewline";
35d04c2b2fSMehdi Amini static constexpr llvm::StringRef kMalloc = "malloc";
36d04c2b2fSMehdi Amini static constexpr llvm::StringRef kAlignedAlloc = "aligned_alloc";
37d04c2b2fSMehdi Amini static constexpr llvm::StringRef kFree = "free";
38*a8601f11SMichele Scuttari static constexpr llvm::StringRef kGenericAlloc = "_mlir_alloc";
39*a8601f11SMichele Scuttari static constexpr llvm::StringRef kGenericAlignedAlloc = "_mlir_aligned_alloc";
40*a8601f11SMichele Scuttari static constexpr llvm::StringRef kGenericFree = "_mlir_free";
41db2de8d7SStephan Herhut static constexpr llvm::StringRef kMemRefCopy = "memrefCopy";
42e332c22cSNicolas Vasilache
43e332c22cSNicolas Vasilache /// Generic print function lookupOrCreate helper.
lookupOrCreateFn(ModuleOp moduleOp,StringRef name,ArrayRef<Type> paramTypes,Type resultType)44e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreateFn(ModuleOp moduleOp, StringRef name,
45e332c22cSNicolas Vasilache ArrayRef<Type> paramTypes,
46e332c22cSNicolas Vasilache Type resultType) {
47e332c22cSNicolas Vasilache auto func = moduleOp.lookupSymbol<LLVM::LLVMFuncOp>(name);
48e332c22cSNicolas Vasilache if (func)
49e332c22cSNicolas Vasilache return func;
50e332c22cSNicolas Vasilache OpBuilder b(moduleOp.getBodyRegion());
51e332c22cSNicolas Vasilache return b.create<LLVM::LLVMFuncOp>(
52e332c22cSNicolas Vasilache moduleOp->getLoc(), name,
53e332c22cSNicolas Vasilache LLVM::LLVMFunctionType::get(resultType, paramTypes));
54e332c22cSNicolas Vasilache }
55e332c22cSNicolas Vasilache
lookupOrCreatePrintI64Fn(ModuleOp moduleOp)56e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintI64Fn(ModuleOp moduleOp) {
57e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintI64,
58e332c22cSNicolas Vasilache IntegerType::get(moduleOp->getContext(), 64),
59e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
60e332c22cSNicolas Vasilache }
61e332c22cSNicolas Vasilache
lookupOrCreatePrintU64Fn(ModuleOp moduleOp)62e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintU64Fn(ModuleOp moduleOp) {
63e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintU64,
64e332c22cSNicolas Vasilache IntegerType::get(moduleOp->getContext(), 64),
65e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
66e332c22cSNicolas Vasilache }
67e332c22cSNicolas Vasilache
lookupOrCreatePrintF32Fn(ModuleOp moduleOp)68e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintF32Fn(ModuleOp moduleOp) {
69e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintF32,
70e332c22cSNicolas Vasilache Float32Type::get(moduleOp->getContext()),
71e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
72e332c22cSNicolas Vasilache }
73e332c22cSNicolas Vasilache
lookupOrCreatePrintF64Fn(ModuleOp moduleOp)74e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintF64Fn(ModuleOp moduleOp) {
75e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintF64,
76e332c22cSNicolas Vasilache Float64Type::get(moduleOp->getContext()),
77e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
78e332c22cSNicolas Vasilache }
79e332c22cSNicolas Vasilache
lookupOrCreatePrintOpenFn(ModuleOp moduleOp)80e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintOpenFn(ModuleOp moduleOp) {
81e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintOpen, {},
82e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
83e332c22cSNicolas Vasilache }
84e332c22cSNicolas Vasilache
lookupOrCreatePrintCloseFn(ModuleOp moduleOp)85e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintCloseFn(ModuleOp moduleOp) {
86e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintClose, {},
87e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
88e332c22cSNicolas Vasilache }
89e332c22cSNicolas Vasilache
lookupOrCreatePrintCommaFn(ModuleOp moduleOp)90e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintCommaFn(ModuleOp moduleOp) {
91e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintComma, {},
92e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
93e332c22cSNicolas Vasilache }
94e332c22cSNicolas Vasilache
lookupOrCreatePrintNewlineFn(ModuleOp moduleOp)95e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreatePrintNewlineFn(ModuleOp moduleOp) {
96e332c22cSNicolas Vasilache return lookupOrCreateFn(moduleOp, kPrintNewline, {},
97e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
98e332c22cSNicolas Vasilache }
99e332c22cSNicolas Vasilache
lookupOrCreateMallocFn(ModuleOp moduleOp,Type indexType)100e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreateMallocFn(ModuleOp moduleOp,
101e332c22cSNicolas Vasilache Type indexType) {
102e332c22cSNicolas Vasilache return LLVM::lookupOrCreateFn(
103e332c22cSNicolas Vasilache moduleOp, kMalloc, indexType,
104e332c22cSNicolas Vasilache LLVM::LLVMPointerType::get(IntegerType::get(moduleOp->getContext(), 8)));
105e332c22cSNicolas Vasilache }
106e332c22cSNicolas Vasilache
lookupOrCreateAlignedAllocFn(ModuleOp moduleOp,Type indexType)107e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreateAlignedAllocFn(ModuleOp moduleOp,
108e332c22cSNicolas Vasilache Type indexType) {
109e332c22cSNicolas Vasilache return LLVM::lookupOrCreateFn(
110e332c22cSNicolas Vasilache moduleOp, kAlignedAlloc, {indexType, indexType},
111e332c22cSNicolas Vasilache LLVM::LLVMPointerType::get(IntegerType::get(moduleOp->getContext(), 8)));
112e332c22cSNicolas Vasilache }
113e332c22cSNicolas Vasilache
lookupOrCreateFreeFn(ModuleOp moduleOp)114e332c22cSNicolas Vasilache LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreateFreeFn(ModuleOp moduleOp) {
115e332c22cSNicolas Vasilache return LLVM::lookupOrCreateFn(
116e332c22cSNicolas Vasilache moduleOp, kFree,
117e332c22cSNicolas Vasilache LLVM::LLVMPointerType::get(IntegerType::get(moduleOp->getContext(), 8)),
118e332c22cSNicolas Vasilache LLVM::LLVMVoidType::get(moduleOp->getContext()));
119e332c22cSNicolas Vasilache }
120e332c22cSNicolas Vasilache
lookupOrCreateGenericAllocFn(ModuleOp moduleOp,Type indexType)121*a8601f11SMichele Scuttari LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreateGenericAllocFn(ModuleOp moduleOp,
122*a8601f11SMichele Scuttari Type indexType) {
123*a8601f11SMichele Scuttari return LLVM::lookupOrCreateFn(
124*a8601f11SMichele Scuttari moduleOp, kGenericAlloc, indexType,
125*a8601f11SMichele Scuttari LLVM::LLVMPointerType::get(IntegerType::get(moduleOp->getContext(), 8)));
126*a8601f11SMichele Scuttari }
127*a8601f11SMichele Scuttari
128*a8601f11SMichele Scuttari LLVM::LLVMFuncOp
lookupOrCreateGenericAlignedAllocFn(ModuleOp moduleOp,Type indexType)129*a8601f11SMichele Scuttari mlir::LLVM::lookupOrCreateGenericAlignedAllocFn(ModuleOp moduleOp,
130*a8601f11SMichele Scuttari Type indexType) {
131*a8601f11SMichele Scuttari return LLVM::lookupOrCreateFn(
132*a8601f11SMichele Scuttari moduleOp, kGenericAlignedAlloc, {indexType, indexType},
133*a8601f11SMichele Scuttari LLVM::LLVMPointerType::get(IntegerType::get(moduleOp->getContext(), 8)));
134*a8601f11SMichele Scuttari }
135*a8601f11SMichele Scuttari
lookupOrCreateGenericFreeFn(ModuleOp moduleOp)136*a8601f11SMichele Scuttari LLVM::LLVMFuncOp mlir::LLVM::lookupOrCreateGenericFreeFn(ModuleOp moduleOp) {
137*a8601f11SMichele Scuttari return LLVM::lookupOrCreateFn(
138*a8601f11SMichele Scuttari moduleOp, kGenericFree,
139*a8601f11SMichele Scuttari LLVM::LLVMPointerType::get(IntegerType::get(moduleOp->getContext(), 8)),
140*a8601f11SMichele Scuttari LLVM::LLVMVoidType::get(moduleOp->getContext()));
141*a8601f11SMichele Scuttari }
142*a8601f11SMichele Scuttari
14388d5eba1SStephan Herhut LLVM::LLVMFuncOp
lookupOrCreateMemRefCopyFn(ModuleOp moduleOp,Type indexType,Type unrankedDescriptorType)14488d5eba1SStephan Herhut mlir::LLVM::lookupOrCreateMemRefCopyFn(ModuleOp moduleOp, Type indexType,
14588d5eba1SStephan Herhut Type unrankedDescriptorType) {
14688d5eba1SStephan Herhut return LLVM::lookupOrCreateFn(
14788d5eba1SStephan Herhut moduleOp, kMemRefCopy,
14888d5eba1SStephan Herhut ArrayRef<Type>{indexType, unrankedDescriptorType, unrankedDescriptorType},
14988d5eba1SStephan Herhut LLVM::LLVMVoidType::get(moduleOp->getContext()));
15088d5eba1SStephan Herhut }
15188d5eba1SStephan Herhut
createLLVMCall(OpBuilder & b,Location loc,LLVM::LLVMFuncOp fn,ValueRange paramTypes,ArrayRef<Type> resultTypes)152e332c22cSNicolas Vasilache Operation::result_range mlir::LLVM::createLLVMCall(OpBuilder &b, Location loc,
153e332c22cSNicolas Vasilache LLVM::LLVMFuncOp fn,
154e332c22cSNicolas Vasilache ValueRange paramTypes,
155e332c22cSNicolas Vasilache ArrayRef<Type> resultTypes) {
156e332c22cSNicolas Vasilache return b
157faf1c224SChris Lattner .create<LLVM::CallOp>(loc, resultTypes, SymbolRefAttr::get(fn),
158e332c22cSNicolas Vasilache paramTypes)
159e332c22cSNicolas Vasilache ->getResults();
160e332c22cSNicolas Vasilache }
161