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
20namespace cir {
21
22namespace direct {
23
24/// Convert a CIR attribute to an LLVM attribute. May use the datalayout for
25/// lowering attributes to-be-stored in memory.
26mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr,
27 mlir::ConversionPatternRewriter &rewriter,
28 const mlir::TypeConverter *converter);
29
30mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage);
31
32class CIRToLLVMBrCondOpLowering
33 : public mlir::OpConversionPattern<cir::BrCondOp> {
34public:
35 using mlir::OpConversionPattern<cir::BrCondOp>::OpConversionPattern;
36
37 mlir::LogicalResult
38 matchAndRewrite(cir::BrCondOp op, OpAdaptor,
39 mlir::ConversionPatternRewriter &) const override;
40};
41
42class CIRToLLVMCastOpLowering : public mlir::OpConversionPattern<cir::CastOp> {
43 mlir::DataLayout const &dataLayout;
44
45 mlir::Type convertTy(mlir::Type ty) const;
46
47public:
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
58class CIRToLLVMReturnOpLowering
59 : public mlir::OpConversionPattern<cir::ReturnOp> {
60public:
61 using mlir::OpConversionPattern<cir::ReturnOp>::OpConversionPattern;
62
63 mlir::LogicalResult
64 matchAndRewrite(cir::ReturnOp op, OpAdaptor,
65 mlir::ConversionPatternRewriter &) const override;
66};
67
68class CIRToLLVMCallOpLowering : public mlir::OpConversionPattern<cir::CallOp> {
69public:
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
77class CIRToLLVMAllocaOpLowering
78 : public mlir::OpConversionPattern<cir::AllocaOp> {
79 mlir::DataLayout const &dataLayout;
80
81public:
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
95class CIRToLLVMLoadOpLowering : public mlir::OpConversionPattern<cir::LoadOp> {
96 mlir::DataLayout const &dataLayout;
97
98public:
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
109class CIRToLLVMStoreOpLowering
110 : public mlir::OpConversionPattern<cir::StoreOp> {
111 mlir::DataLayout const &dataLayout;
112
113public:
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
124class CIRToLLVMConstantOpLowering
125 : public mlir::OpConversionPattern<cir::ConstantOp> {
126public:
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
138class 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
145public:
146 using mlir::OpConversionPattern<cir::FuncOp>::OpConversionPattern;
147
148 mlir::LogicalResult
149 matchAndRewrite(cir::FuncOp op, OpAdaptor,
150 mlir::ConversionPatternRewriter &) const override;
151};
152
153class CIRToLLVMSwitchFlatOpLowering
154 : public mlir::OpConversionPattern<cir::SwitchFlatOp> {
155public:
156 using mlir::OpConversionPattern<cir::SwitchFlatOp>::OpConversionPattern;
157
158 mlir::LogicalResult
159 matchAndRewrite(cir::SwitchFlatOp op, OpAdaptor,
160 mlir::ConversionPatternRewriter &) const override;
161};
162
163class CIRToLLVMGetGlobalOpLowering
164 : public mlir::OpConversionPattern<cir::GetGlobalOp> {
165public:
166 using mlir::OpConversionPattern<cir::GetGlobalOp>::OpConversionPattern;
167
168 mlir::LogicalResult
169 matchAndRewrite(cir::GetGlobalOp op, OpAdaptor,
170 mlir::ConversionPatternRewriter &) const override;
171};
172
173class CIRToLLVMGlobalOpLowering
174 : public mlir::OpConversionPattern<cir::GlobalOp> {
175 const mlir::DataLayout &dataLayout;
176
177public:
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
189private:
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
202class CIRToLLVMUnaryOpLowering
203 : public mlir::OpConversionPattern<cir::UnaryOp> {
204public:
205 using mlir::OpConversionPattern<cir::UnaryOp>::OpConversionPattern;
206
207 mlir::LogicalResult
208 matchAndRewrite(cir::UnaryOp op, OpAdaptor,
209 mlir::ConversionPatternRewriter &) const override;
210};
211
212class CIRToLLVMBinOpLowering : public mlir::OpConversionPattern<cir::BinOp> {
213 mlir::LLVM::IntegerOverflowFlags getIntOverflowFlag(cir::BinOp op) const;
214
215public:
216 using mlir::OpConversionPattern<cir::BinOp>::OpConversionPattern;
217
218 mlir::LogicalResult
219 matchAndRewrite(cir::BinOp op, OpAdaptor,
220 mlir::ConversionPatternRewriter &) const override;
221};
222
223class CIRToLLVMCmpOpLowering : public mlir::OpConversionPattern<cir::CmpOp> {
224public:
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
236class CIRToLLVMShiftOpLowering
237 : public mlir::OpConversionPattern<cir::ShiftOp> {
238public:
239 using mlir::OpConversionPattern<cir::ShiftOp>::OpConversionPattern;
240
241 mlir::LogicalResult
242 matchAndRewrite(cir::ShiftOp op, OpAdaptor,
243 mlir::ConversionPatternRewriter &) const override;
244};
245
246class CIRToLLVMSelectOpLowering
247 : public mlir::OpConversionPattern<cir::SelectOp> {
248public:
249 using mlir::OpConversionPattern<cir::SelectOp>::OpConversionPattern;
250
251 mlir::LogicalResult
252 matchAndRewrite(cir::SelectOp op, OpAdaptor,
253 mlir::ConversionPatternRewriter &) const override;
254};
255
256class CIRToLLVMBrOpLowering : public mlir::OpConversionPattern<cir::BrOp> {
257public:
258 using mlir::OpConversionPattern<cir::BrOp>::OpConversionPattern;
259
260 mlir::LogicalResult
261 matchAndRewrite(cir::BrOp op, OpAdaptor,
262 mlir::ConversionPatternRewriter &) const override;
263};
264
265class CIRToLLVMGetMemberOpLowering
266 : public mlir::OpConversionPattern<cir::GetMemberOp> {
267public:
268 using mlir::OpConversionPattern<cir::GetMemberOp>::OpConversionPattern;
269
270 mlir::LogicalResult
271 matchAndRewrite(cir::GetMemberOp op, OpAdaptor,
272 mlir::ConversionPatternRewriter &) const override;
273};
274
275class CIRToLLVMTrapOpLowering : public mlir::OpConversionPattern<cir::TrapOp> {
276public:
277 using mlir::OpConversionPattern<cir::TrapOp>::OpConversionPattern;
278
279 mlir::LogicalResult
280 matchAndRewrite(cir::TrapOp op, OpAdaptor,
281 mlir::ConversionPatternRewriter &) const override;
282};
283
284class CIRToLLVMPtrStrideOpLowering
285 : public mlir::OpConversionPattern<cir::PtrStrideOp> {
286 mlir::DataLayout const &dataLayout;
287
288public:
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
300class CIRToLLVMBaseClassAddrOpLowering
301 : public mlir::OpConversionPattern<cir::BaseClassAddrOp> {
302public:
303 using mlir::OpConversionPattern<cir::BaseClassAddrOp>::OpConversionPattern;
304
305 mlir::LogicalResult
306 matchAndRewrite(cir::BaseClassAddrOp op, OpAdaptor,
307 mlir::ConversionPatternRewriter &) const override;
308};
309
310class CIRToLLVMStackSaveOpLowering
311 : public mlir::OpConversionPattern<cir::StackSaveOp> {
312public:
313 using mlir::OpConversionPattern<cir::StackSaveOp>::OpConversionPattern;
314
315 mlir::LogicalResult
316 matchAndRewrite(cir::StackSaveOp op, OpAdaptor,
317 mlir::ConversionPatternRewriter &) const override;
318};
319
320class CIRToLLVMStackRestoreOpLowering
321 : public mlir::OpConversionPattern<cir::StackRestoreOp> {
322public:
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
330class CIRToLLVMVecCreateOpLowering
331 : public mlir::OpConversionPattern<cir::VecCreateOp> {
332public:
333 using mlir::OpConversionPattern<cir::VecCreateOp>::OpConversionPattern;
334
335 mlir::LogicalResult
336 matchAndRewrite(cir::VecCreateOp op, OpAdaptor,
337 mlir::ConversionPatternRewriter &) const override;
338};
339
340class CIRToLLVMVecExtractOpLowering
341 : public mlir::OpConversionPattern<cir::VecExtractOp> {
342public:
343 using mlir::OpConversionPattern<cir::VecExtractOp>::OpConversionPattern;
344
345 mlir::LogicalResult
346 matchAndRewrite(cir::VecExtractOp op, OpAdaptor,
347 mlir::ConversionPatternRewriter &) const override;
348};
349
350class CIRToLLVMVecInsertOpLowering
351 : public mlir::OpConversionPattern<cir::VecInsertOp> {
352public:
353 using mlir::OpConversionPattern<cir::VecInsertOp>::OpConversionPattern;
354
355 mlir::LogicalResult
356 matchAndRewrite(cir::VecInsertOp op, OpAdaptor,
357 mlir::ConversionPatternRewriter &) const override;
358};
359
360class CIRToLLVMVecCmpOpLowering
361 : public mlir::OpConversionPattern<cir::VecCmpOp> {
362public:
363 using mlir::OpConversionPattern<cir::VecCmpOp>::OpConversionPattern;
364
365 mlir::LogicalResult
366 matchAndRewrite(cir::VecCmpOp op, OpAdaptor,
367 mlir::ConversionPatternRewriter &) const override;
368};
369
370class CIRToLLVMVecSplatOpLowering
371 : public mlir::OpConversionPattern<cir::VecSplatOp> {
372public:
373 using mlir::OpConversionPattern<cir::VecSplatOp>::OpConversionPattern;
374
375 mlir::LogicalResult
376 matchAndRewrite(cir::VecSplatOp op, OpAdaptor,
377 mlir::ConversionPatternRewriter &) const override;
378};
379
380class CIRToLLVMVecShuffleOpLowering
381 : public mlir::OpConversionPattern<cir::VecShuffleOp> {
382public:
383 using mlir::OpConversionPattern<cir::VecShuffleOp>::OpConversionPattern;
384
385 mlir::LogicalResult
386 matchAndRewrite(cir::VecShuffleOp op, OpAdaptor,
387 mlir::ConversionPatternRewriter &) const override;
388};
389
390class CIRToLLVMVecShuffleDynamicOpLowering
391 : public mlir::OpConversionPattern<cir::VecShuffleDynamicOp> {
392public:
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
401class CIRToLLVMVecTernaryOpLowering
402 : public mlir::OpConversionPattern<cir::VecTernaryOp> {
403public:
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

source code of clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h