1 | //===-- LowLevelIntrinsics.cpp --------------------------------------------===// |
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 | // |
9 | // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | // |
13 | // Low level intrinsic functions. |
14 | // |
15 | // These include LLVM intrinsic calls and standard C library calls. |
16 | // Target-specific calls, such as OS functions, should be factored in other |
17 | // file(s). |
18 | // |
19 | //===----------------------------------------------------------------------===// |
20 | |
21 | #include "flang/Optimizer/Builder/LowLevelIntrinsics.h" |
22 | #include "flang/Optimizer/Builder/FIRBuilder.h" |
23 | |
24 | mlir::func::FuncOp fir::factory::getLlvmMemcpy(fir::FirOpBuilder &builder) { |
25 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
26 | llvm::SmallVector<mlir::Type> args = {ptrTy, ptrTy, builder.getI64Type(), |
27 | builder.getI1Type()}; |
28 | auto memcpyTy = |
29 | mlir::FunctionType::get(builder.getContext(), args, std::nullopt); |
30 | return builder.createFunction(builder.getUnknownLoc(), |
31 | "llvm.memcpy.p0.p0.i64" , memcpyTy); |
32 | } |
33 | |
34 | mlir::func::FuncOp fir::factory::getLlvmMemmove(fir::FirOpBuilder &builder) { |
35 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
36 | llvm::SmallVector<mlir::Type> args = {ptrTy, ptrTy, builder.getI64Type(), |
37 | builder.getI1Type()}; |
38 | auto memmoveTy = |
39 | mlir::FunctionType::get(builder.getContext(), args, std::nullopt); |
40 | return builder.createFunction(builder.getUnknownLoc(), |
41 | "llvm.memmove.p0.p0.i64" , memmoveTy); |
42 | } |
43 | |
44 | mlir::func::FuncOp fir::factory::getLlvmMemset(fir::FirOpBuilder &builder) { |
45 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
46 | llvm::SmallVector<mlir::Type> args = {ptrTy, ptrTy, builder.getI64Type(), |
47 | builder.getI1Type()}; |
48 | auto memsetTy = |
49 | mlir::FunctionType::get(builder.getContext(), args, std::nullopt); |
50 | return builder.createFunction(builder.getUnknownLoc(), |
51 | "llvm.memset.p0.p0.i64" , memsetTy); |
52 | } |
53 | |
54 | mlir::func::FuncOp fir::factory::getRealloc(fir::FirOpBuilder &builder) { |
55 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
56 | llvm::SmallVector<mlir::Type> args = {ptrTy, builder.getI64Type()}; |
57 | auto reallocTy = mlir::FunctionType::get(builder.getContext(), args, {ptrTy}); |
58 | return builder.createFunction(builder.getUnknownLoc(), "realloc" , reallocTy); |
59 | } |
60 | |
61 | mlir::func::FuncOp |
62 | fir::factory::getLlvmGetRounding(fir::FirOpBuilder &builder) { |
63 | auto int32Ty = builder.getIntegerType(32); |
64 | auto funcTy = |
65 | mlir::FunctionType::get(builder.getContext(), std::nullopt, {int32Ty}); |
66 | return builder.createFunction(builder.getUnknownLoc(), "llvm.get.rounding" , |
67 | funcTy); |
68 | } |
69 | |
70 | mlir::func::FuncOp |
71 | fir::factory::getLlvmSetRounding(fir::FirOpBuilder &builder) { |
72 | auto int32Ty = builder.getIntegerType(32); |
73 | auto funcTy = |
74 | mlir::FunctionType::get(builder.getContext(), {int32Ty}, std::nullopt); |
75 | return builder.createFunction(builder.getUnknownLoc(), "llvm.set.rounding" , |
76 | funcTy); |
77 | } |
78 | |
79 | mlir::func::FuncOp fir::factory::getLlvmStackSave(fir::FirOpBuilder &builder) { |
80 | // FIXME: This should query the target alloca address space |
81 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
82 | auto funcTy = |
83 | mlir::FunctionType::get(builder.getContext(), std::nullopt, {ptrTy}); |
84 | return builder.createFunction(builder.getUnknownLoc(), "llvm.stacksave.p0" , |
85 | funcTy); |
86 | } |
87 | |
88 | mlir::func::FuncOp |
89 | fir::factory::getLlvmStackRestore(fir::FirOpBuilder &builder) { |
90 | // FIXME: This should query the target alloca address space |
91 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
92 | auto funcTy = |
93 | mlir::FunctionType::get(builder.getContext(), {ptrTy}, std::nullopt); |
94 | return builder.createFunction(builder.getUnknownLoc(), "llvm.stackrestore.p0" , |
95 | funcTy); |
96 | } |
97 | |
98 | mlir::func::FuncOp |
99 | fir::factory::getLlvmInitTrampoline(fir::FirOpBuilder &builder) { |
100 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
101 | auto funcTy = mlir::FunctionType::get(builder.getContext(), |
102 | {ptrTy, ptrTy, ptrTy}, std::nullopt); |
103 | return builder.createFunction(builder.getUnknownLoc(), "llvm.init.trampoline" , |
104 | funcTy); |
105 | } |
106 | |
107 | mlir::func::FuncOp |
108 | fir::factory::getLlvmAdjustTrampoline(fir::FirOpBuilder &builder) { |
109 | auto ptrTy = builder.getRefType(builder.getIntegerType(8)); |
110 | auto funcTy = mlir::FunctionType::get(builder.getContext(), {ptrTy}, {ptrTy}); |
111 | return builder.createFunction(builder.getUnknownLoc(), |
112 | "llvm.adjust.trampoline" , funcTy); |
113 | } |
114 | |
115 | mlir::func::FuncOp fir::factory::getFeclearexcept(fir::FirOpBuilder &builder) { |
116 | auto int32Ty = builder.getIntegerType(32); |
117 | auto funcTy = |
118 | mlir::FunctionType::get(builder.getContext(), {int32Ty}, {int32Ty}); |
119 | return builder.createFunction(builder.getUnknownLoc(), "feclearexcept" , |
120 | funcTy); |
121 | } |
122 | |
123 | mlir::func::FuncOp |
124 | fir::factory::getFedisableexcept(fir::FirOpBuilder &builder) { |
125 | auto int32Ty = builder.getIntegerType(32); |
126 | auto funcTy = |
127 | mlir::FunctionType::get(builder.getContext(), {int32Ty}, {int32Ty}); |
128 | return builder.createFunction(builder.getUnknownLoc(), "fedisableexcept" , |
129 | funcTy); |
130 | } |
131 | |
132 | mlir::func::FuncOp fir::factory::getFeenableexcept(fir::FirOpBuilder &builder) { |
133 | auto int32Ty = builder.getIntegerType(32); |
134 | auto funcTy = |
135 | mlir::FunctionType::get(builder.getContext(), {int32Ty}, {int32Ty}); |
136 | return builder.createFunction(builder.getUnknownLoc(), "feenableexcept" , |
137 | funcTy); |
138 | } |
139 | |
140 | mlir::func::FuncOp fir::factory::getFegetexcept(fir::FirOpBuilder &builder) { |
141 | auto int32Ty = builder.getIntegerType(32); |
142 | auto funcTy = |
143 | mlir::FunctionType::get(builder.getContext(), std::nullopt, {int32Ty}); |
144 | return builder.createFunction(builder.getUnknownLoc(), "fegetexcept" , funcTy); |
145 | } |
146 | |
147 | mlir::func::FuncOp fir::factory::getFeraiseexcept(fir::FirOpBuilder &builder) { |
148 | auto int32Ty = builder.getIntegerType(32); |
149 | auto funcTy = |
150 | mlir::FunctionType::get(builder.getContext(), {int32Ty}, {int32Ty}); |
151 | return builder.createFunction(builder.getUnknownLoc(), "feraiseexcept" , |
152 | funcTy); |
153 | } |
154 | |
155 | mlir::func::FuncOp fir::factory::getFetestexcept(fir::FirOpBuilder &builder) { |
156 | auto int32Ty = builder.getIntegerType(32); |
157 | auto funcTy = |
158 | mlir::FunctionType::get(builder.getContext(), {int32Ty}, {int32Ty}); |
159 | return builder.createFunction(builder.getUnknownLoc(), "fetestexcept" , |
160 | funcTy); |
161 | } |
162 | |