clang 23.0.0git
CIRBaseBuilder.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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#ifndef LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
10#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
11
12#include "clang/AST/CharUnits.h"
18#include "llvm/ADT/STLForwardCompat.h"
19#include "llvm/IR/FPEnv.h"
20#include "llvm/Support/ErrorHandling.h"
21
22#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
23#include "mlir/IR/Builders.h"
24#include "mlir/IR/BuiltinAttributes.h"
25#include "mlir/IR/Location.h"
26#include "mlir/IR/OperationSupport.h"
27#include "mlir/IR/Types.h"
28
29namespace cir {
30
31enum class OverflowBehavior {
32 None = 0,
33 NoSignedWrap = 1 << 0,
35 Saturated = 1 << 2,
36};
37
39 return static_cast<OverflowBehavior>(llvm::to_underlying(a) |
40 llvm::to_underlying(b));
41}
42
44 return static_cast<OverflowBehavior>(llvm::to_underlying(a) &
45 llvm::to_underlying(b));
46}
47
50 a = a | b;
51 return a;
52}
53
56 a = a & b;
57 return a;
58}
59
60constexpr bool testFlag(OverflowBehavior ob, OverflowBehavior flag) {
61 return (ob & flag) != OverflowBehavior::None;
62}
63
64class CIRBaseBuilderTy : public mlir::OpBuilder {
65
66public:
67 CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
68 : mlir::OpBuilder(&mlirContext) {}
69 CIRBaseBuilderTy(mlir::OpBuilder &builder) : mlir::OpBuilder(builder) {}
70
71 mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ,
72 const llvm::APInt &val) {
73 return cir::ConstantOp::create(*this, loc, cir::IntAttr::get(typ, val));
74 }
75
76 cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) {
77 return cir::ConstantOp::create(*this, loc, attr);
78 }
79
80 cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty,
81 int64_t value) {
82 return getConstant(loc, cir::IntAttr::get(ty, value));
83 }
84
85 mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits) {
86 auto type = cir::IntType::get(getContext(), numBits, /*isSigned=*/true);
87 return getConstAPInt(loc, type,
88 llvm::APInt(numBits, val, /*isSigned=*/true));
89 }
90
91 mlir::Value getUnsignedInt(mlir::Location loc, uint64_t val,
92 unsigned numBits) {
93 auto type = cir::IntType::get(getContext(), numBits, /*isSigned=*/false);
94 return getConstAPInt(loc, type, llvm::APInt(numBits, val));
95 }
96
97 // Creates constant null value for integral type ty.
98 cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc) {
99 return getConstant(loc, getZeroInitAttr(ty));
100 }
101
102 mlir::TypedAttr getConstNullPtrAttr(mlir::Type t) {
103 assert(mlir::isa<cir::PointerType>(t) && "expected cir.ptr");
104 return getConstPtrAttr(t, 0);
105 }
106
107 mlir::TypedAttr getNullDataMemberAttr(cir::DataMemberType ty) {
108 return cir::DataMemberAttr::get(ty);
109 }
110
111 mlir::TypedAttr getZeroInitAttr(mlir::Type ty) {
112 if (mlir::isa<cir::IntType>(ty))
113 return cir::IntAttr::get(ty, 0);
114 if (cir::isAnyFloatingPointType(ty))
115 return cir::FPAttr::getZero(ty);
116 if (auto complexType = mlir::dyn_cast<cir::ComplexType>(ty))
117 return cir::ZeroAttr::get(complexType);
118 if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
119 return cir::ZeroAttr::get(arrTy);
120 if (auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
121 return cir::ZeroAttr::get(vecTy);
122 if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
123 return getConstNullPtrAttr(ptrTy);
124 if (auto recordTy = mlir::dyn_cast<cir::RecordType>(ty))
125 return cir::ZeroAttr::get(recordTy);
126 if (auto dataMemberTy = mlir::dyn_cast<cir::DataMemberType>(ty))
127 return getNullDataMemberAttr(dataMemberTy);
128 if (auto methodTy = mlir::dyn_cast<cir::MethodType>(ty))
129 return getNullMethodAttr(methodTy);
130 if (auto vptrTy = mlir::dyn_cast<cir::VPtrType>(ty))
131 return cir::ZeroAttr::get(vptrTy);
132 if (mlir::isa<cir::BoolType>(ty)) {
133 return getFalseAttr();
134 }
135
136 llvm_unreachable("Zero initializer for given type is NYI");
137 }
138
139 cir::ConstantOp getBool(bool state, mlir::Location loc) {
140 return cir::ConstantOp::create(*this, loc, getCIRBoolAttr(state));
141 }
142 cir::ConstantOp getFalse(mlir::Location loc) { return getBool(false, loc); }
143 cir::ConstantOp getTrue(mlir::Location loc) { return getBool(true, loc); }
144
145 cir::BoolType getBoolTy() { return cir::BoolType::get(getContext()); }
146 cir::VoidType getVoidTy() { return cir::VoidType::get(getContext()); }
147
148 cir::IntType getUIntNTy(int n) {
149 return cir::IntType::get(getContext(), n, false);
150 }
151
152 static unsigned getCIRIntOrFloatBitWidth(mlir::Type eltTy) {
153 if (auto intType = mlir::dyn_cast<cir::IntTypeInterface>(eltTy))
154 return intType.getWidth();
155 if (auto floatType = mlir::dyn_cast<cir::FPTypeInterface>(eltTy))
156 return floatType.getWidth();
157
158 llvm_unreachable("Unsupported type in getCIRIntOrFloatBitWidth");
159 }
160 cir::IntType getSIntNTy(int n) {
161 return cir::IntType::get(getContext(), n, true);
162 }
163
164 cir::PointerType getPointerTo(mlir::Type ty) {
165 return cir::PointerType::get(ty);
166 }
167
168 cir::PointerType getPointerTo(mlir::Type ty,
169 mlir::ptr::MemorySpaceAttrInterface as) {
170 return cir::PointerType::get(ty, as);
171 }
172
173 cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
174 if (langAS == clang::LangAS::Default)
175 return getPointerTo(ty);
176
177 mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr =
178 cir::toCIRAddressSpaceAttr(*getContext(), langAS);
179 return getPointerTo(ty, addrSpaceAttr);
180 }
181
183 return getPointerTo(cir::VoidType::get(getContext()), langAS);
184 }
185
186 cir::PointerType getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface as) {
187 return getPointerTo(cir::VoidType::get(getContext()), as);
188 }
189
190 cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
191 auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
192 return cir::MethodAttr::get(ty, methodFuncSymbolRef);
193 }
194
195 cir::MethodAttr getNullMethodAttr(cir::MethodType ty) {
196 return cir::MethodAttr::get(ty);
197 }
198
199 cir::BoolAttr getCIRBoolAttr(bool state) {
200 return cir::BoolAttr::get(getContext(), state);
201 }
202
203 cir::BoolAttr getTrueAttr() { return getCIRBoolAttr(true); }
204 cir::BoolAttr getFalseAttr() { return getCIRBoolAttr(false); }
205
206 mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real,
207 mlir::Value imag) {
208 auto resultComplexTy = cir::ComplexType::get(real.getType());
209 return cir::ComplexCreateOp::create(*this, loc, resultComplexTy, real,
210 imag);
211 }
212
213 mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand) {
214 auto resultType = operand.getType();
215 if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
216 resultType = complexResultType.getElementType();
217 return cir::ComplexRealOp::create(*this, loc, resultType, operand);
218 }
219
220 mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand) {
221 auto resultType = operand.getType();
222 if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
223 resultType = complexResultType.getElementType();
224 return cir::ComplexImagOp::create(*this, loc, resultType, operand);
225 }
226
227 mlir::Value createComplexConj(mlir::Location loc, mlir::Value operand) {
228 return cir::ComplexConjOp::create(*this, loc, operand.getType(), operand);
229 }
230
231 cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
232 bool isVolatile = false, uint64_t alignment = 0,
233 bool isNontemporal = false) {
234 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
235 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
236 isNontemporal, alignmentAttr,
237 cir::SyncScopeKindAttr{}, cir::MemOrderAttr{},
238 /*invariant=*/false);
239 }
240
241 mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
242 uint64_t alignment) {
243 return createLoad(loc, ptr, /*isVolatile=*/false, alignment);
244 }
245
246 mlir::Value createNot(mlir::Location loc, mlir::Value value) {
247 return cir::NotOp::create(*this, loc, value);
248 }
249
250 mlir::Value createNot(mlir::Value value) {
251 return createNot(value.getLoc(), value);
252 }
253
254 /// Create a do-while operation.
255 cir::DoWhileOp createDoWhile(
256 mlir::Location loc,
257 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
258 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
259 return cir::DoWhileOp::create(*this, loc, condBuilder, bodyBuilder);
260 }
261
262 /// Create a while operation.
263 cir::WhileOp createWhile(
264 mlir::Location loc,
265 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
266 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
267 return cir::WhileOp::create(*this, loc, condBuilder, bodyBuilder);
268 }
269
270 /// Create a for operation.
271 cir::ForOp createFor(
272 mlir::Location loc,
273 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
274 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
275 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> stepBuilder) {
276 return cir::ForOp::create(*this, loc, condBuilder, bodyBuilder,
277 stepBuilder);
278 }
279
280 /// Create a break operation.
281 cir::BreakOp createBreak(mlir::Location loc) {
282 return cir::BreakOp::create(*this, loc);
283 }
284
285 /// Create a continue operation.
286 cir::ContinueOp createContinue(mlir::Location loc) {
287 return cir::ContinueOp::create(*this, loc);
288 }
289
290 mlir::Value createInc(mlir::Location loc, mlir::Value input,
291 bool nsw = false) {
292 return cir::IncOp::create(*this, loc, input, nsw);
293 }
294
295 mlir::Value createDec(mlir::Location loc, mlir::Value input,
296 bool nsw = false) {
297 return cir::DecOp::create(*this, loc, input, nsw);
298 }
299
300 mlir::Value createMinus(mlir::Location loc, mlir::Value input,
301 bool nsw = false) {
302 return cir::MinusOp::create(*this, loc, input, nsw);
303 }
304
305 mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) {
306 return cir::ConstPtrAttr::get(type, getI64IntegerAttr(value));
307 }
308
309 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
310 llvm::StringRef name, mlir::IntegerAttr alignment,
311 mlir::Value dynAllocSize) {
312 return cir::AllocaOp::create(*this, loc, addrType, name, alignment,
313 dynAllocSize);
314 }
315
316 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
317 mlir::Type type, llvm::StringRef name,
318 clang::CharUnits alignment,
319 mlir::Value dynAllocSize) {
320 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
321 return createAlloca(loc, addrType, name, alignmentAttr, dynAllocSize);
322 }
323
324 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
325 llvm::StringRef name, mlir::IntegerAttr alignment) {
326 return cir::AllocaOp::create(*this, loc, addrType, name, alignment);
327 }
328
329 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
330 llvm::StringRef name, clang::CharUnits alignment) {
331 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
332 return createAlloca(loc, addrType, name, alignmentAttr);
333 }
334
335 /// Get constant address of a global variable as an MLIR attribute.
336 /// This wrapper infers the attribute type through the global op.
337 cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp,
338 mlir::ArrayAttr indices = {}) {
339 cir::PointerType type = getPointerTo(globalOp.getSymType());
340 return getGlobalViewAttr(type, globalOp, indices);
341 }
342
343 /// Get constant address of a global variable as an MLIR attribute.
344 cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type,
345 cir::GlobalOp globalOp,
346 mlir::ArrayAttr indices = {}) {
347 auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr());
348 return cir::GlobalViewAttr::get(type, symbol, indices);
349 }
350
351 /// Get constant address of a global variable as an MLIR attribute.
352 /// This overload converts raw int64_t indices to an ArrayAttr.
353 cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type,
354 cir::GlobalOp globalOp,
355 llvm::ArrayRef<int64_t> indices) {
357 for (int64_t ind : indices)
358 attrs.push_back(getI64IntegerAttr(ind));
359 mlir::ArrayAttr arAttr = mlir::ArrayAttr::get(getContext(), attrs);
360 return getGlobalViewAttr(type, globalOp, arAttr);
361 }
362
363 cir::GetGlobalOp createGetGlobal(mlir::Location loc, cir::GlobalOp global,
364 bool threadLocal = false) {
366 return cir::GetGlobalOp::create(*this, loc,
367 getPointerTo(global.getSymType()),
368 global.getSymNameAttr(), threadLocal);
369 }
370
371 cir::GetGlobalOp createGetGlobal(cir::GlobalOp global,
372 bool threadLocal = false) {
373 return createGetGlobal(global.getLoc(), global, threadLocal);
374 }
375
376 /// Create a copy with inferred length.
377 cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
378 bool isVolatile = false,
379 bool skipTailPadding = false) {
380 return cir::CopyOp::create(*this, dst.getLoc(), dst, src,
381 /*dst_alignment=*/{}, /*src_alignment=*/{},
382 isVolatile, skipTailPadding);
383 }
384
385 cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
386 bool isVolatile = false, bool isNontemporal = false,
387 mlir::IntegerAttr align = {},
388 cir::SyncScopeKindAttr scope = {},
389 cir::MemOrderAttr order = {}) {
390 if (mlir::cast<cir::PointerType>(dst.getType()).getPointee() !=
391 val.getType())
392 dst = createPtrBitcast(dst, val.getType());
393 return cir::StoreOp::create(*this, loc, val, dst, isVolatile, isNontemporal,
394 align, scope, order);
395 }
396
397 /// Emit a load from an boolean flag variable.
398 cir::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr) {
399 mlir::Type boolTy = getBoolTy();
400 if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee())
401 addr = createPtrBitcast(addr, boolTy);
402 return createLoad(loc, addr, /*isVolatile=*/false, /*alignment=*/1);
403 }
404
405 cir::StoreOp createFlagStore(mlir::Location loc, bool val, mlir::Value dst) {
406 mlir::Value flag = getBool(val, loc);
407 return CIRBaseBuilderTy::createStore(loc, flag, dst);
408 }
409
410 [[nodiscard]] cir::GlobalOp
411 createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc,
412 mlir::StringRef name, mlir::Type type, bool isConstant,
413 cir::GlobalLinkageKind linkage,
414 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
415 mlir::OpBuilder::InsertionGuard guard(*this);
416 setInsertionPointToStart(mlirModule.getBody());
417 return cir::GlobalOp::create(*this, loc, name, type, isConstant, addrSpace,
418 linkage);
419 }
420
421 cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy,
422 mlir::Value base, llvm::StringRef name,
423 unsigned index) {
424 return cir::GetMemberOp::create(*this, loc, resultTy, base, name, index);
425 }
426
427 mlir::Value createDummyValue(mlir::Location loc, mlir::Type type,
428 clang::CharUnits alignment) {
429 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
430 auto addr = createAlloca(loc, getPointerTo(type), {}, alignmentAttr);
431 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
432 /*isVolatile=*/false, /*nontemporal=*/false,
433 alignmentAttr,
434 /*sync_scope=*/{}, /*mem_order=*/{},
435 /*invariant=*/false);
436 }
437
438 cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
439 mlir::Value stride) {
440 return cir::PtrStrideOp::create(*this, loc, base.getType(), base, stride);
441 }
442
443 //===--------------------------------------------------------------------===//
444 // Call operators
445 //===--------------------------------------------------------------------===//
446
447 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
448 mlir::Type returnType, mlir::ValueRange operands,
452 auto op = cir::CallOp::create(*this, loc, callee, returnType, operands);
453 op->setAttrs(attrs);
454
455 if (!argAttrs.empty()) {
456 llvm::SmallVector<mlir::Attribute> argDictAttrs;
457 argDictAttrs.reserve(argAttrs.size());
458
459 llvm::transform(
460 argAttrs, std::back_inserter(argDictAttrs),
461 [this](llvm::ArrayRef<mlir::NamedAttribute> singleArgAttrs) {
462 return mlir::DictionaryAttr::get(getContext(), singleArgAttrs);
463 });
464
465 op.setArgAttrsAttr(mlir::ArrayAttr::get(getContext(), argDictAttrs));
466 }
467
468 if (!resAttrs.empty()) {
469 auto resultDictAttr = mlir::DictionaryAttr::get(getContext(), resAttrs);
470 op.setResAttrsAttr(mlir::ArrayAttr::get(getContext(), resultDictAttr));
471 }
472 return op;
473 }
474
475 cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee,
476 mlir::ValueRange operands,
480 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
481 callee.getFunctionType().getReturnType(), operands,
482 attrs, argAttrs, resAttrs);
483 }
484
485 cir::CallOp
486 createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget,
487 cir::FuncType funcType, mlir::ValueRange operands,
491 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
492 resOperands.append(operands.begin(), operands.end());
493
494 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
495 resOperands, attrs, argAttrs, resAttrs);
496 }
497
498 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
499 mlir::ValueRange operands = mlir::ValueRange(),
503 return createCallOp(loc, callee, cir::VoidType(), operands, attrs, argAttrs,
504 resAttrs);
505 }
506
507 //===--------------------------------------------------------------------===//
508 // Cast/Conversion Operators
509 //===--------------------------------------------------------------------===//
510
511 mlir::Value createCast(mlir::Location loc, cir::CastKind kind,
512 mlir::Value src, mlir::Type newTy) {
513 if (newTy == src.getType())
514 return src;
515 return cir::CastOp::create(*this, loc, newTy, kind, src);
516 }
517
518 mlir::Value createCast(cir::CastKind kind, mlir::Value src,
519 mlir::Type newTy) {
520 if (newTy == src.getType())
521 return src;
522 return createCast(src.getLoc(), kind, src, newTy);
523 }
524
525 // Creates a cast from bool or int to an integer type.
526 mlir::Value createBoolIntToIntCast(mlir::Value src, mlir::Type newTy) {
527 if (newTy == src.getType())
528 return src;
529 if (src.getType() == getBoolTy())
530 return createBoolToInt(src, newTy);
531 return createIntCast(src, newTy);
532 }
533
534 mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) {
535 return createCast(cir::CastKind::integral, src, newTy);
536 }
537
538 mlir::Value createBuiltinIntCast(mlir::Location loc, mlir::Value src,
539 mlir::Type newTy) {
540 return cir::BuiltinIntCastOp::create(*this, loc, newTy, src);
541 }
542
543 mlir::Value createBuiltinIntCast(mlir::Value src, mlir::Type newTy) {
544 return createBuiltinIntCast(src.getLoc(), src, newTy);
545 }
546
547 mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) {
548 return createCast(cir::CastKind::int_to_ptr, src, newTy);
549 }
550
551 mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) {
552 return createCast(cir::CastKind::ptr_to_int, src, newTy);
553 }
554
555 mlir::Value createPtrToBoolCast(mlir::Value v) {
556 return createCast(cir::CastKind::ptr_to_bool, v, getBoolTy());
557 }
558
559 mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
560 return createCast(cir::CastKind::bool_to_int, src, newTy);
561 }
562
563 mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) {
564 return createCast(cir::CastKind::bitcast, src, newTy);
565 }
566
567 mlir::Value createBitcast(mlir::Location loc, mlir::Value src,
568 mlir::Type newTy) {
569 return createCast(loc, cir::CastKind::bitcast, src, newTy);
570 }
571
572 mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy) {
573 assert(mlir::isa<cir::PointerType>(src.getType()) && "expected ptr src");
574 cir::PointerType srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
575 return createBitcast(src,
576 getPointerTo(newPointeeTy, srcPtrTy.getAddrSpace()));
577 }
578
579 mlir::Value createPtrIsNull(mlir::Value ptr) {
580 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
581 return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr);
582 }
583
584 mlir::Value createPtrIsNotNull(mlir::Value ptr) {
585 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
586 return createCompare(ptr.getLoc(), cir::CmpOpKind::ne, ptr, nullPtr);
587 }
588
589 mlir::Value createAddrSpaceCast(mlir::Location loc, mlir::Value src,
590 mlir::Type newTy) {
591 return createCast(loc, cir::CastKind::address_space, src, newTy);
592 }
593
594 mlir::Value createAddrSpaceCast(mlir::Value src, mlir::Type newTy) {
595 return createAddrSpaceCast(src.getLoc(), src, newTy);
596 }
597
598 //===--------------------------------------------------------------------===//
599 // Other Instructions
600 //===--------------------------------------------------------------------===//
601
602 mlir::Value createExtractElement(mlir::Location loc, mlir::Value vec,
603 uint64_t idx) {
604 mlir::Value idxVal =
605 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
606 return cir::VecExtractOp::create(*this, loc, vec, idxVal);
607 }
608
609 mlir::Value createInsertElement(mlir::Location loc, mlir::Value vec,
610 mlir::Value newElt, uint64_t idx) {
611 mlir::Value idxVal =
612 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
613 return cir::VecInsertOp::create(*this, loc, vec, newElt, idxVal);
614 }
615
616 cir::SignBitOp createSignBit(mlir::Location loc, mlir::Value val) {
617 auto resTy = cir::BoolType::get(getContext());
618 return cir::SignBitOp::create(*this, loc, resTy, val);
619 }
620
621 //===--------------------------------------------------------------------===//
622 // Binary Operators
623 //===--------------------------------------------------------------------===//
624
625 mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
626 unsigned bits) {
627 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
628 auto type = cir::IntType::get(getContext(), size, /*isSigned=*/false);
629 return getConstAPInt(loc, type, val);
630 }
631
632 mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
633 return cir::AndOp::create(*this, loc, lhs, rhs);
634 }
635
636 mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
637 return cir::OrOp::create(*this, loc, lhs, rhs);
638 }
639
640 mlir::Value createSelect(mlir::Location loc, mlir::Value condition,
641 mlir::Value trueValue, mlir::Value falseValue) {
642 assert(trueValue.getType() == falseValue.getType() &&
643 "trueValue and falseValue should have the same type");
644 return cir::SelectOp::create(*this, loc, trueValue.getType(), condition,
645 trueValue, falseValue);
646 }
647
648 mlir::Value createLogicalAnd(mlir::Location loc, mlir::Value lhs,
649 mlir::Value rhs) {
650 return createSelect(loc, lhs, rhs, getBool(false, loc));
651 }
652
653 mlir::Value createLogicalOr(mlir::Location loc, mlir::Value lhs,
654 mlir::Value rhs) {
655 return createSelect(loc, lhs, getBool(true, loc), rhs);
656 }
657
658 mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
660 auto op = cir::MulOp::create(*this, loc, lhs, rhs);
661 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
662 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
663 return op;
664 }
665 mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs,
666 mlir::Value rhs) {
667 return createMul(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
668 }
669 mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs,
670 mlir::Value rhs) {
671 return createMul(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
672 }
673
674 mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
676 auto op = cir::SubOp::create(*this, loc, lhs, rhs);
677 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
678 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
679 op.setSaturated(testFlag(ob, OverflowBehavior::Saturated));
680 return op;
681 }
682
683 mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs,
684 mlir::Value rhs) {
685 return createSub(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
686 }
687
688 mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs,
689 mlir::Value rhs) {
690 return createSub(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
691 }
692
693 mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
695 auto op = cir::AddOp::create(*this, loc, lhs, rhs);
696 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
697 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
698 op.setSaturated(testFlag(ob, OverflowBehavior::Saturated));
699 return op;
700 }
701
702 mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs,
703 mlir::Value rhs) {
704 return createAdd(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
705 }
706
707 mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs,
708 mlir::Value rhs) {
709 return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
710 }
711
712 mlir::Value createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
713 return cir::DivOp::create(*this, loc, lhs, rhs);
714 }
715
716 mlir::Value createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
717 return cir::RemOp::create(*this, loc, lhs, rhs);
718 }
719
720 mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
724 return cir::FAddOp::create(*this, loc, lhs, rhs);
725 }
726
727 mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
731 return cir::FSubOp::create(*this, loc, lhs, rhs);
732 }
733
734 mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
738 return cir::FMulOp::create(*this, loc, lhs, rhs);
739 }
740
741 mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
745 return cir::FDivOp::create(*this, loc, lhs, rhs);
746 }
747
748 mlir::Value createFRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
752 return cir::FRemOp::create(*this, loc, lhs, rhs);
753 }
754
755 mlir::Value createFNeg(mlir::Location loc, mlir::Value operand) {
756 assert(cir::isFPOrVectorOfFPType(operand.getType()) &&
757 "expected floating-point or vector-of-float type");
761 return cir::FNegOp::create(*this, loc, operand);
762 }
763
764 mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
765 return cir::XorOp::create(*this, loc, lhs, rhs);
766 }
767
768 mlir::Value createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
769 return cir::MaxOp::create(*this, loc, lhs, rhs);
770 }
771
772 cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind,
773 mlir::Value lhs, mlir::Value rhs) {
774 return cir::CmpOp::create(*this, loc, kind, lhs, rhs);
775 }
776
777 cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind,
778 mlir::Value lhs, mlir::Value rhs) {
779 VectorType vecCast = mlir::cast<VectorType>(lhs.getType());
780 IntType integralTy =
781 getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType()));
782 VectorType integralVecTy =
783 cir::VectorType::get(integralTy, vecCast.getSize());
784 return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs);
785 }
786
787 mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) {
788 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
789 }
790
791 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
792 bool isShiftLeft) {
793 return cir::ShiftOp::create(*this, loc, lhs.getType(), lhs, rhs,
794 isShiftLeft);
795 }
796
797 mlir::Value createShift(mlir::Location loc, mlir::Value lhs,
798 const llvm::APInt &rhs, bool isShiftLeft) {
799 return createShift(loc, lhs, getConstAPInt(loc, lhs.getType(), rhs),
800 isShiftLeft);
801 }
802
803 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, unsigned bits,
804 bool isShiftLeft) {
805 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
806 auto shift = llvm::APInt(width, bits);
807 return createShift(loc, lhs, shift, isShiftLeft);
808 }
809
810 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
811 unsigned bits) {
812 return createShift(loc, lhs, bits, true);
813 }
814
815 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
816 unsigned bits) {
817 return createShift(loc, lhs, bits, false);
818 }
819
820 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
821 mlir::Value rhs) {
822 return createShift(loc, lhs, rhs, true);
823 }
824
825 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
826 mlir::Value rhs) {
827 return createShift(loc, lhs, rhs, false);
828 }
829
830 /// Returns `void (T...)` as a cir::FuncType.
831 cir::FuncType getVoidFnTy(mlir::TypeRange argTypes = {}) {
832 return cir::FuncType::get(llvm::to_vector(argTypes), getVoidTy());
833 }
834
835 /// Returns `void (*)(T...)` as a cir::PointerType.
836 cir::PointerType getVoidFnPtrTy(mlir::TypeRange argTypes = {}) {
837 return getPointerTo(getVoidFnTy(argTypes));
838 }
839
840 //
841 // Block handling helpers
842 // ----------------------
843 //
844 static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block) {
845 auto last =
846 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
847 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
848 });
849
850 if (last != block->rend())
851 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
852 return OpBuilder::InsertPoint(block, block->begin());
853 };
854
855 //
856 // Alignment and size helpers
857 //
858
859 // Note that mlir::IntegerType is used instead of cir::IntType here because we
860 // don't need sign information for these to be useful, so keep it simple.
861
862 // For 0 alignment, any overload of `getAlignmentAttr` returns an empty
863 // attribute.
864 mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment) {
865 return getAlignmentAttr(alignment.getQuantity());
866 }
867
868 mlir::IntegerAttr getAlignmentAttr(llvm::Align alignment) {
869 return getAlignmentAttr(alignment.value());
870 }
871
872 mlir::IntegerAttr getAlignmentAttr(int64_t alignment) {
873 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
874 }
875
876 // Materialize an alignment value as a CIR integer constant of the given
877 // integer type.
878 cir::ConstantOp getAlignment(mlir::Location loc, mlir::Type t,
879 clang::CharUnits alignment) {
880 return getConstantInt(loc, t, alignment.getQuantity());
881 }
882
883 mlir::IntegerAttr getSizeFromCharUnits(clang::CharUnits size) {
884 return getI64IntegerAttr(size.getQuantity());
885 }
886
887 // Creates constant nullptr for pointer type ty.
888 cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
890 return cir::ConstantOp::create(*this, loc, getConstPtrAttr(ty, 0));
891 }
892
893 /// Create a loop condition.
894 cir::ConditionOp createCondition(mlir::Value condition) {
895 return cir::ConditionOp::create(*this, condition.getLoc(), condition);
896 }
897
898 /// Create a yield operation.
899 cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value = {}) {
900 return cir::YieldOp::create(*this, loc, value);
901 }
902
904 mlir::Value callee;
905 mlir::Value adjustedThis;
906 };
907
908 GetMethodResults createGetMethod(mlir::Location loc, mlir::Value method,
909 mlir::Value objectPtr) {
910 // Build the callee function type.
911 auto methodFuncTy =
912 mlir::cast<cir::MethodType>(method.getType()).getMemberFuncTy();
913 auto methodFuncInputTypes = methodFuncTy.getInputs();
914
915 auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
916 mlir::Type adjustedThisTy = getVoidPtrTy(objectPtrTy.getAddrSpace());
917
918 llvm::SmallVector<mlir::Type> calleeFuncInputTypes{adjustedThisTy};
919 // The member function type's first parameter is the implicit 'this'
920 // pointer. The callee takes an adjusted void* receiver instead.
921 if (methodFuncInputTypes.size() > 1)
922 calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
923 methodFuncInputTypes.begin() + 1,
924 methodFuncInputTypes.end());
925 cir::FuncType calleeFuncTy =
926 methodFuncTy.clone(calleeFuncInputTypes, methodFuncTy.getReturnType());
927 // TODO(cir): consider the address space of the callee.
929 cir::PointerType calleeTy = getPointerTo(calleeFuncTy);
930
931 auto op = cir::GetMethodOp::create(*this, loc, calleeTy, adjustedThisTy,
932 method, objectPtr);
933 return {op.getCallee(), op.getAdjustedThis()};
934 }
935};
936
937} // namespace cir
938
939#endif
Provides definitions for the various language-specific address spaces.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a an optional score condition
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::ConstantOp getBool(bool state, mlir::Location loc)
mlir::Value createShift(mlir::Location loc, mlir::Value lhs, unsigned bits, bool isShiftLeft)
cir::StoreOp createFlagStore(mlir::Location loc, bool val, mlir::Value dst)
cir::WhileOp createWhile(mlir::Location loc, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> condBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> bodyBuilder)
Create a while operation.
mlir::Value createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, llvm::StringRef name, mlir::IntegerAttr alignment)
cir::BreakOp createBreak(mlir::Location loc)
Create a break operation.
mlir::TypedAttr getConstNullPtrAttr(mlir::Type t)
cir::PointerType getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface as)
mlir::IntegerAttr getAlignmentAttr(int64_t alignment)
mlir::Value createDec(mlir::Location loc, mlir::Value input, bool nsw=false)
mlir::Value createShift(mlir::Location loc, mlir::Value lhs, const llvm::APInt &rhs, bool isShiftLeft)
mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val)
mlir::Value createBuiltinIntCast(mlir::Value src, mlir::Type newTy)
cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
mlir::Value createCast(cir::CastKind kind, mlir::Value src, mlir::Type newTy)
mlir::Value createLogicalOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, bool isShiftLeft)
mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
cir::ConditionOp createCondition(mlir::Value condition)
Create a loop condition.
mlir::Value createLowBitsSet(mlir::Location loc, unsigned size, unsigned bits)
mlir::Value createInc(mlir::Location loc, mlir::Value input, bool nsw=false)
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src, bool isVolatile=false, bool skipTailPadding=false)
Create a copy with inferred length.
mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp)
cir::VoidType getVoidTy()
cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc)
cir::BoolAttr getCIRBoolAttr(bool state)
mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy)
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
cir::MethodAttr getNullMethodAttr(cir::MethodType ty)
mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createPtrIsNull(mlir::Value ptr)
mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::SignBitOp createSignBit(mlir::Location loc, mlir::Value val)
mlir::Value createCast(mlir::Location loc, cir::CastKind kind, mlir::Value src, mlir::Type newTy)
mlir::IntegerAttr getSizeFromCharUnits(clang::CharUnits size)
cir::PointerType getVoidFnPtrTy(mlir::TypeRange argTypes={})
Returns void (*)(T...) as a cir::PointerType.
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy)
mlir::Value createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::ForOp createFor(mlir::Location loc, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> condBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> bodyBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> stepBuilder)
Create a for operation.
static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block)
mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy)
mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::ConstantOp getFalse(mlir::Location loc)
cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, mlir::ValueRange operands=mlir::ValueRange(), llvm::ArrayRef< mlir::NamedAttribute > attrs={}, llvm::ArrayRef< mlir::NamedAttrList > argAttrs={}, llvm::ArrayRef< mlir::NamedAttribute > resAttrs={})
mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy, mlir::Value base, llvm::StringRef name, unsigned index)
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createFNeg(mlir::Location loc, mlir::Value operand)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, llvm::StringRef name, clang::CharUnits alignment)
mlir::Value createNot(mlir::Value value)
mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand)
cir::ConstantOp getTrue(mlir::Location loc)
mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
cir::GetGlobalOp createGetGlobal(cir::GlobalOp global, bool threadLocal=false)
cir::IntType getUIntNTy(int n)
cir::DoWhileOp createDoWhile(mlir::Location loc, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> condBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> bodyBuilder)
Create a do-while operation.
mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
cir::GetGlobalOp createGetGlobal(mlir::Location loc, cir::GlobalOp global, bool threadLocal=false)
mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs, unsigned bits)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, llvm::StringRef name, mlir::IntegerAttr alignment, mlir::Value dynAllocSize)
cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr, bool isVolatile=false, uint64_t alignment=0, bool isNontemporal=false)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, mlir::Type type, llvm::StringRef name, clang::CharUnits alignment, mlir::Value dynAllocSize)
mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits)
mlir::Value createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS)
mlir::Value createExtractElement(mlir::Location loc, mlir::Value vec, uint64_t idx)
cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
mlir::Value createInsertElement(mlir::Location loc, mlir::Value vec, mlir::Value newElt, uint64_t idx)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
mlir::Value createBitcast(mlir::Location loc, mlir::Value src, mlir::Type newTy)
cir::FuncType getVoidFnTy(mlir::TypeRange argTypes={})
Returns void (T...) as a cir::FuncType.
mlir::TypedAttr getNullDataMemberAttr(cir::DataMemberType ty)
mlir::Value createBuiltinIntCast(mlir::Location loc, mlir::Value src, mlir::Type newTy)
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment)
mlir::Value createNot(mlir::Location loc, mlir::Value value)
mlir::Value createSelect(mlir::Location loc, mlir::Value condition, mlir::Value trueValue, mlir::Value falseValue)
cir::ContinueOp createContinue(mlir::Location loc)
Create a continue operation.
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
cir::PointerType getPointerTo(mlir::Type ty, mlir::ptr::MemorySpaceAttrInterface as)
mlir::TypedAttr getZeroInitAttr(mlir::Type ty)
mlir::Value createMinus(mlir::Location loc, mlir::Value input, bool nsw=false)
CIRBaseBuilderTy(mlir::OpBuilder &builder)
mlir::Value createPtrIsNotNull(mlir::Value ptr)
static unsigned getCIRIntOrFloatBitWidth(mlir::Type eltTy)
cir::CallOp createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget, cir::FuncType funcType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, llvm::ArrayRef< mlir::NamedAttrList > argAttrs={}, llvm::ArrayRef< mlir::NamedAttribute > resAttrs={})
cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, int64_t value)
mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real, mlir::Value imag)
mlir::Value createBoolIntToIntCast(mlir::Value src, mlir::Type newTy)
mlir::Value createAddrSpaceCast(mlir::Value src, mlir::Type newTy)
mlir::Value createComplexConj(mlir::Location loc, mlir::Value operand)
mlir::Value createPtrToBoolCast(mlir::Value v)
cir::BoolAttr getTrueAttr()
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, llvm::ArrayRef< int64_t > indices)
Get constant address of a global variable as an MLIR attribute.
mlir::Value createFRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs, unsigned bits)
mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand)
cir::IntType getSIntNTy(int n)
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr, uint64_t alignment)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
mlir::Value createAddrSpaceCast(mlir::Location loc, mlir::Value src, mlir::Type newTy)
cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, mlir::Type returnType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, llvm::ArrayRef< mlir::NamedAttrList > argAttrs={}, llvm::ArrayRef< mlir::NamedAttribute > resAttrs={})
mlir::Value createDummyValue(mlir::Location loc, mlir::Type type, clang::CharUnits alignment)
cir::BoolAttr getFalseAttr()
mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={}, llvm::ArrayRef< mlir::NamedAttrList > argAttrs={}, llvm::ArrayRef< mlir::NamedAttribute > resAttrs={})
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
cir::ConstantOp getAlignment(mlir::Location loc, mlir::Type t, clang::CharUnits alignment)
mlir::Value createLogicalAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc, mlir::StringRef name, mlir::Type type, bool isConstant, cir::GlobalLinkageKind linkage, mlir::ptr::MemorySpaceAttrInterface addrSpace)
mlir::IntegerAttr getAlignmentAttr(llvm::Align alignment)
mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr)
Emit a load from an boolean flag variable.
cir::BoolType getBoolTy()
mlir::Value getUnsignedInt(mlir::Location loc, uint64_t val, unsigned numBits)
GetMethodResults createGetMethod(mlir::Location loc, mlir::Value method, mlir::Value objectPtr)
mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand)
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
constexpr OverflowBehavior operator|(OverflowBehavior a, OverflowBehavior b)
constexpr OverflowBehavior operator&(OverflowBehavior a, OverflowBehavior b)
constexpr OverflowBehavior & operator|=(OverflowBehavior &a, OverflowBehavior b)
constexpr OverflowBehavior & operator&=(OverflowBehavior &a, OverflowBehavior b)
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
OverflowBehavior
constexpr bool testFlag(OverflowBehavior ob, OverflowBehavior flag)
LangAS
Defines the address space values used by the address space qualifier of QualType.
static bool metaDataNode()
static bool addressSpace()
static bool targetCodeGenInfoGetNullPointer()
static bool fpConstraints()
static bool fastMathFlags()