1 | //====- LowerToLLVM.h- Lowering from CIR to LLVM --------------------------===// |
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 | // This file declares an interface for converting CIR modules to LLVM IR. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | #ifndef CLANG_CIR_LOWERTOLLVM_H |
13 | #define CLANG_CIR_LOWERTOLLVM_H |
14 | |
15 | #include "mlir/Dialect/LLVMIR/LLVMAttrs.h" |
16 | #include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
17 | #include "mlir/Transforms/DialectConversion.h" |
18 | #include "clang/CIR/Dialect/IR/CIRDialect.h" |
19 | |
20 | namespace cir { |
21 | |
22 | namespace direct { |
23 | |
24 | /// Convert a CIR attribute to an LLVM attribute. May use the datalayout for |
25 | /// lowering attributes to-be-stored in memory. |
26 | mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr, |
27 | mlir::ConversionPatternRewriter &rewriter, |
28 | const mlir::TypeConverter *converter); |
29 | |
30 | mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage); |
31 | |
32 | class CIRToLLVMBrCondOpLowering |
33 | : public mlir::OpConversionPattern<cir::BrCondOp> { |
34 | public: |
35 | using mlir::OpConversionPattern<cir::BrCondOp>::OpConversionPattern; |
36 | |
37 | mlir::LogicalResult |
38 | matchAndRewrite(cir::BrCondOp op, OpAdaptor, |
39 | mlir::ConversionPatternRewriter &) const override; |
40 | }; |
41 | |
42 | class CIRToLLVMCastOpLowering : public mlir::OpConversionPattern<cir::CastOp> { |
43 | mlir::DataLayout const &dataLayout; |
44 | |
45 | mlir::Type convertTy(mlir::Type ty) const; |
46 | |
47 | public: |
48 | CIRToLLVMCastOpLowering(const mlir::TypeConverter &typeConverter, |
49 | mlir::MLIRContext *context, |
50 | mlir::DataLayout const &dataLayout) |
51 | : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {} |
52 | |
53 | mlir::LogicalResult |
54 | matchAndRewrite(cir::CastOp op, OpAdaptor, |
55 | mlir::ConversionPatternRewriter &) const override; |
56 | }; |
57 | |
58 | class CIRToLLVMReturnOpLowering |
59 | : public mlir::OpConversionPattern<cir::ReturnOp> { |
60 | public: |
61 | using mlir::OpConversionPattern<cir::ReturnOp>::OpConversionPattern; |
62 | |
63 | mlir::LogicalResult |
64 | matchAndRewrite(cir::ReturnOp op, OpAdaptor, |
65 | mlir::ConversionPatternRewriter &) const override; |
66 | }; |
67 | |
68 | class CIRToLLVMCallOpLowering : public mlir::OpConversionPattern<cir::CallOp> { |
69 | public: |
70 | using mlir::OpConversionPattern<cir::CallOp>::OpConversionPattern; |
71 | |
72 | mlir::LogicalResult |
73 | matchAndRewrite(cir::CallOp op, OpAdaptor adaptor, |
74 | mlir::ConversionPatternRewriter &rewriter) const override; |
75 | }; |
76 | |
77 | class CIRToLLVMAllocaOpLowering |
78 | : public mlir::OpConversionPattern<cir::AllocaOp> { |
79 | mlir::DataLayout const &dataLayout; |
80 | |
81 | public: |
82 | CIRToLLVMAllocaOpLowering(mlir::TypeConverter const &typeConverter, |
83 | mlir::MLIRContext *context, |
84 | mlir::DataLayout const &dataLayout) |
85 | : OpConversionPattern<cir::AllocaOp>(typeConverter, context), |
86 | dataLayout(dataLayout) {} |
87 | |
88 | using mlir::OpConversionPattern<cir::AllocaOp>::OpConversionPattern; |
89 | |
90 | mlir::LogicalResult |
91 | matchAndRewrite(cir::AllocaOp op, OpAdaptor, |
92 | mlir::ConversionPatternRewriter &) const override; |
93 | }; |
94 | |
95 | class CIRToLLVMLoadOpLowering : public mlir::OpConversionPattern<cir::LoadOp> { |
96 | mlir::DataLayout const &dataLayout; |
97 | |
98 | public: |
99 | CIRToLLVMLoadOpLowering(const mlir::TypeConverter &typeConverter, |
100 | mlir::MLIRContext *context, |
101 | mlir::DataLayout const &dataLayout) |
102 | : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {} |
103 | |
104 | mlir::LogicalResult |
105 | matchAndRewrite(cir::LoadOp op, OpAdaptor, |
106 | mlir::ConversionPatternRewriter &) const override; |
107 | }; |
108 | |
109 | class CIRToLLVMStoreOpLowering |
110 | : public mlir::OpConversionPattern<cir::StoreOp> { |
111 | mlir::DataLayout const &dataLayout; |
112 | |
113 | public: |
114 | CIRToLLVMStoreOpLowering(const mlir::TypeConverter &typeConverter, |
115 | mlir::MLIRContext *context, |
116 | mlir::DataLayout const &dataLayout) |
117 | : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {} |
118 | |
119 | mlir::LogicalResult |
120 | matchAndRewrite(cir::StoreOp op, OpAdaptor, |
121 | mlir::ConversionPatternRewriter &) const override; |
122 | }; |
123 | |
124 | class CIRToLLVMConstantOpLowering |
125 | : public mlir::OpConversionPattern<cir::ConstantOp> { |
126 | public: |
127 | CIRToLLVMConstantOpLowering(const mlir::TypeConverter &typeConverter, |
128 | mlir::MLIRContext *context) |
129 | : OpConversionPattern(typeConverter, context) { |
130 | setHasBoundedRewriteRecursion(); |
131 | } |
132 | |
133 | mlir::LogicalResult |
134 | matchAndRewrite(cir::ConstantOp op, OpAdaptor, |
135 | mlir::ConversionPatternRewriter &) const override; |
136 | }; |
137 | |
138 | class CIRToLLVMFuncOpLowering : public mlir::OpConversionPattern<cir::FuncOp> { |
139 | static mlir::StringRef getLinkageAttrNameString() { return "linkage" ; } |
140 | |
141 | void lowerFuncAttributes( |
142 | cir::FuncOp func, bool filterArgAndResAttrs, |
143 | mlir::SmallVectorImpl<mlir::NamedAttribute> &result) const; |
144 | |
145 | public: |
146 | using mlir::OpConversionPattern<cir::FuncOp>::OpConversionPattern; |
147 | |
148 | mlir::LogicalResult |
149 | matchAndRewrite(cir::FuncOp op, OpAdaptor, |
150 | mlir::ConversionPatternRewriter &) const override; |
151 | }; |
152 | |
153 | class CIRToLLVMSwitchFlatOpLowering |
154 | : public mlir::OpConversionPattern<cir::SwitchFlatOp> { |
155 | public: |
156 | using mlir::OpConversionPattern<cir::SwitchFlatOp>::OpConversionPattern; |
157 | |
158 | mlir::LogicalResult |
159 | matchAndRewrite(cir::SwitchFlatOp op, OpAdaptor, |
160 | mlir::ConversionPatternRewriter &) const override; |
161 | }; |
162 | |
163 | class CIRToLLVMGetGlobalOpLowering |
164 | : public mlir::OpConversionPattern<cir::GetGlobalOp> { |
165 | public: |
166 | using mlir::OpConversionPattern<cir::GetGlobalOp>::OpConversionPattern; |
167 | |
168 | mlir::LogicalResult |
169 | matchAndRewrite(cir::GetGlobalOp op, OpAdaptor, |
170 | mlir::ConversionPatternRewriter &) const override; |
171 | }; |
172 | |
173 | class CIRToLLVMGlobalOpLowering |
174 | : public mlir::OpConversionPattern<cir::GlobalOp> { |
175 | const mlir::DataLayout &dataLayout; |
176 | |
177 | public: |
178 | CIRToLLVMGlobalOpLowering(const mlir::TypeConverter &typeConverter, |
179 | mlir::MLIRContext *context, |
180 | const mlir::DataLayout &dataLayout) |
181 | : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) { |
182 | setHasBoundedRewriteRecursion(); |
183 | } |
184 | |
185 | mlir::LogicalResult |
186 | matchAndRewrite(cir::GlobalOp op, OpAdaptor adaptor, |
187 | mlir::ConversionPatternRewriter &rewriter) const override; |
188 | |
189 | private: |
190 | mlir::LogicalResult matchAndRewriteRegionInitializedGlobal( |
191 | cir::GlobalOp op, mlir::Attribute init, |
192 | mlir::ConversionPatternRewriter &rewriter) const; |
193 | |
194 | void setupRegionInitializedLLVMGlobalOp( |
195 | cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const; |
196 | |
197 | mutable mlir::LLVM::ComdatOp comdatOp = nullptr; |
198 | mlir::SymbolRefAttr getComdatAttr(cir::GlobalOp &op, |
199 | mlir::OpBuilder &builder) const; |
200 | }; |
201 | |
202 | class CIRToLLVMUnaryOpLowering |
203 | : public mlir::OpConversionPattern<cir::UnaryOp> { |
204 | public: |
205 | using mlir::OpConversionPattern<cir::UnaryOp>::OpConversionPattern; |
206 | |
207 | mlir::LogicalResult |
208 | matchAndRewrite(cir::UnaryOp op, OpAdaptor, |
209 | mlir::ConversionPatternRewriter &) const override; |
210 | }; |
211 | |
212 | class CIRToLLVMBinOpLowering : public mlir::OpConversionPattern<cir::BinOp> { |
213 | mlir::LLVM::IntegerOverflowFlags getIntOverflowFlag(cir::BinOp op) const; |
214 | |
215 | public: |
216 | using mlir::OpConversionPattern<cir::BinOp>::OpConversionPattern; |
217 | |
218 | mlir::LogicalResult |
219 | matchAndRewrite(cir::BinOp op, OpAdaptor, |
220 | mlir::ConversionPatternRewriter &) const override; |
221 | }; |
222 | |
223 | class CIRToLLVMCmpOpLowering : public mlir::OpConversionPattern<cir::CmpOp> { |
224 | public: |
225 | CIRToLLVMCmpOpLowering(const mlir::TypeConverter &typeConverter, |
226 | mlir::MLIRContext *context) |
227 | : OpConversionPattern(typeConverter, context) { |
228 | setHasBoundedRewriteRecursion(); |
229 | } |
230 | |
231 | mlir::LogicalResult |
232 | matchAndRewrite(cir::CmpOp op, OpAdaptor, |
233 | mlir::ConversionPatternRewriter &) const override; |
234 | }; |
235 | |
236 | class CIRToLLVMShiftOpLowering |
237 | : public mlir::OpConversionPattern<cir::ShiftOp> { |
238 | public: |
239 | using mlir::OpConversionPattern<cir::ShiftOp>::OpConversionPattern; |
240 | |
241 | mlir::LogicalResult |
242 | matchAndRewrite(cir::ShiftOp op, OpAdaptor, |
243 | mlir::ConversionPatternRewriter &) const override; |
244 | }; |
245 | |
246 | class CIRToLLVMSelectOpLowering |
247 | : public mlir::OpConversionPattern<cir::SelectOp> { |
248 | public: |
249 | using mlir::OpConversionPattern<cir::SelectOp>::OpConversionPattern; |
250 | |
251 | mlir::LogicalResult |
252 | matchAndRewrite(cir::SelectOp op, OpAdaptor, |
253 | mlir::ConversionPatternRewriter &) const override; |
254 | }; |
255 | |
256 | class CIRToLLVMBrOpLowering : public mlir::OpConversionPattern<cir::BrOp> { |
257 | public: |
258 | using mlir::OpConversionPattern<cir::BrOp>::OpConversionPattern; |
259 | |
260 | mlir::LogicalResult |
261 | matchAndRewrite(cir::BrOp op, OpAdaptor, |
262 | mlir::ConversionPatternRewriter &) const override; |
263 | }; |
264 | |
265 | class CIRToLLVMGetMemberOpLowering |
266 | : public mlir::OpConversionPattern<cir::GetMemberOp> { |
267 | public: |
268 | using mlir::OpConversionPattern<cir::GetMemberOp>::OpConversionPattern; |
269 | |
270 | mlir::LogicalResult |
271 | matchAndRewrite(cir::GetMemberOp op, OpAdaptor, |
272 | mlir::ConversionPatternRewriter &) const override; |
273 | }; |
274 | |
275 | class CIRToLLVMTrapOpLowering : public mlir::OpConversionPattern<cir::TrapOp> { |
276 | public: |
277 | using mlir::OpConversionPattern<cir::TrapOp>::OpConversionPattern; |
278 | |
279 | mlir::LogicalResult |
280 | matchAndRewrite(cir::TrapOp op, OpAdaptor, |
281 | mlir::ConversionPatternRewriter &) const override; |
282 | }; |
283 | |
284 | class CIRToLLVMPtrStrideOpLowering |
285 | : public mlir::OpConversionPattern<cir::PtrStrideOp> { |
286 | mlir::DataLayout const &dataLayout; |
287 | |
288 | public: |
289 | CIRToLLVMPtrStrideOpLowering(const mlir::TypeConverter &typeConverter, |
290 | mlir::MLIRContext *context, |
291 | mlir::DataLayout const &dataLayout) |
292 | : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {} |
293 | using mlir::OpConversionPattern<cir::PtrStrideOp>::OpConversionPattern; |
294 | |
295 | mlir::LogicalResult |
296 | matchAndRewrite(cir::PtrStrideOp op, OpAdaptor, |
297 | mlir::ConversionPatternRewriter &) const override; |
298 | }; |
299 | |
300 | class CIRToLLVMBaseClassAddrOpLowering |
301 | : public mlir::OpConversionPattern<cir::BaseClassAddrOp> { |
302 | public: |
303 | using mlir::OpConversionPattern<cir::BaseClassAddrOp>::OpConversionPattern; |
304 | |
305 | mlir::LogicalResult |
306 | matchAndRewrite(cir::BaseClassAddrOp op, OpAdaptor, |
307 | mlir::ConversionPatternRewriter &) const override; |
308 | }; |
309 | |
310 | class CIRToLLVMStackSaveOpLowering |
311 | : public mlir::OpConversionPattern<cir::StackSaveOp> { |
312 | public: |
313 | using mlir::OpConversionPattern<cir::StackSaveOp>::OpConversionPattern; |
314 | |
315 | mlir::LogicalResult |
316 | matchAndRewrite(cir::StackSaveOp op, OpAdaptor, |
317 | mlir::ConversionPatternRewriter &) const override; |
318 | }; |
319 | |
320 | class CIRToLLVMStackRestoreOpLowering |
321 | : public mlir::OpConversionPattern<cir::StackRestoreOp> { |
322 | public: |
323 | using OpConversionPattern<cir::StackRestoreOp>::OpConversionPattern; |
324 | |
325 | mlir::LogicalResult |
326 | matchAndRewrite(cir::StackRestoreOp op, OpAdaptor adaptor, |
327 | mlir::ConversionPatternRewriter &rewriter) const override; |
328 | }; |
329 | |
330 | class CIRToLLVMVecCreateOpLowering |
331 | : public mlir::OpConversionPattern<cir::VecCreateOp> { |
332 | public: |
333 | using mlir::OpConversionPattern<cir::VecCreateOp>::OpConversionPattern; |
334 | |
335 | mlir::LogicalResult |
336 | matchAndRewrite(cir::VecCreateOp op, OpAdaptor, |
337 | mlir::ConversionPatternRewriter &) const override; |
338 | }; |
339 | |
340 | class |
341 | : public mlir::OpConversionPattern<cir::VecExtractOp> { |
342 | public: |
343 | using mlir::OpConversionPattern<cir::VecExtractOp>::OpConversionPattern; |
344 | |
345 | mlir::LogicalResult |
346 | matchAndRewrite(cir::VecExtractOp op, OpAdaptor, |
347 | mlir::ConversionPatternRewriter &) const override; |
348 | }; |
349 | |
350 | class CIRToLLVMVecInsertOpLowering |
351 | : public mlir::OpConversionPattern<cir::VecInsertOp> { |
352 | public: |
353 | using mlir::OpConversionPattern<cir::VecInsertOp>::OpConversionPattern; |
354 | |
355 | mlir::LogicalResult |
356 | matchAndRewrite(cir::VecInsertOp op, OpAdaptor, |
357 | mlir::ConversionPatternRewriter &) const override; |
358 | }; |
359 | |
360 | class CIRToLLVMVecCmpOpLowering |
361 | : public mlir::OpConversionPattern<cir::VecCmpOp> { |
362 | public: |
363 | using mlir::OpConversionPattern<cir::VecCmpOp>::OpConversionPattern; |
364 | |
365 | mlir::LogicalResult |
366 | matchAndRewrite(cir::VecCmpOp op, OpAdaptor, |
367 | mlir::ConversionPatternRewriter &) const override; |
368 | }; |
369 | |
370 | class CIRToLLVMVecSplatOpLowering |
371 | : public mlir::OpConversionPattern<cir::VecSplatOp> { |
372 | public: |
373 | using mlir::OpConversionPattern<cir::VecSplatOp>::OpConversionPattern; |
374 | |
375 | mlir::LogicalResult |
376 | matchAndRewrite(cir::VecSplatOp op, OpAdaptor, |
377 | mlir::ConversionPatternRewriter &) const override; |
378 | }; |
379 | |
380 | class CIRToLLVMVecShuffleOpLowering |
381 | : public mlir::OpConversionPattern<cir::VecShuffleOp> { |
382 | public: |
383 | using mlir::OpConversionPattern<cir::VecShuffleOp>::OpConversionPattern; |
384 | |
385 | mlir::LogicalResult |
386 | matchAndRewrite(cir::VecShuffleOp op, OpAdaptor, |
387 | mlir::ConversionPatternRewriter &) const override; |
388 | }; |
389 | |
390 | class CIRToLLVMVecShuffleDynamicOpLowering |
391 | : public mlir::OpConversionPattern<cir::VecShuffleDynamicOp> { |
392 | public: |
393 | using mlir::OpConversionPattern< |
394 | cir::VecShuffleDynamicOp>::OpConversionPattern; |
395 | |
396 | mlir::LogicalResult |
397 | matchAndRewrite(cir::VecShuffleDynamicOp op, OpAdaptor, |
398 | mlir::ConversionPatternRewriter &) const override; |
399 | }; |
400 | |
401 | class CIRToLLVMVecTernaryOpLowering |
402 | : public mlir::OpConversionPattern<cir::VecTernaryOp> { |
403 | public: |
404 | using mlir::OpConversionPattern<cir::VecTernaryOp>::OpConversionPattern; |
405 | |
406 | mlir::LogicalResult |
407 | matchAndRewrite(cir::VecTernaryOp op, OpAdaptor, |
408 | mlir::ConversionPatternRewriter &) const override; |
409 | }; |
410 | |
411 | } // namespace direct |
412 | } // namespace cir |
413 | |
414 | #endif // CLANG_CIR_LOWERTOLLVM_H |
415 | |