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 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
234 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
235 alignmentAttr, cir::SyncScopeKindAttr{},
236 cir::MemOrderAttr{});
237 }
238
239 mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
240 uint64_t alignment) {
241 return createLoad(loc, ptr, /*isVolatile=*/false, alignment);
242 }
243
244 mlir::Value createNot(mlir::Location loc, mlir::Value value) {
245 return cir::NotOp::create(*this, loc, value);
246 }
247
248 mlir::Value createNot(mlir::Value value) {
249 return createNot(value.getLoc(), value);
250 }
251
252 /// Create a do-while operation.
253 cir::DoWhileOp createDoWhile(
254 mlir::Location loc,
255 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
256 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
257 return cir::DoWhileOp::create(*this, loc, condBuilder, bodyBuilder);
258 }
259
260 /// Create a while operation.
261 cir::WhileOp createWhile(
262 mlir::Location loc,
263 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
264 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
265 return cir::WhileOp::create(*this, loc, condBuilder, bodyBuilder);
266 }
267
268 /// Create a for operation.
269 cir::ForOp createFor(
270 mlir::Location loc,
271 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
272 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
273 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> stepBuilder) {
274 return cir::ForOp::create(*this, loc, condBuilder, bodyBuilder,
275 stepBuilder);
276 }
277
278 /// Create a break operation.
279 cir::BreakOp createBreak(mlir::Location loc) {
280 return cir::BreakOp::create(*this, loc);
281 }
282
283 /// Create a continue operation.
284 cir::ContinueOp createContinue(mlir::Location loc) {
285 return cir::ContinueOp::create(*this, loc);
286 }
287
288 mlir::Value createInc(mlir::Location loc, mlir::Value input,
289 bool nsw = false) {
290 return cir::IncOp::create(*this, loc, input, nsw);
291 }
292
293 mlir::Value createDec(mlir::Location loc, mlir::Value input,
294 bool nsw = false) {
295 return cir::DecOp::create(*this, loc, input, nsw);
296 }
297
298 mlir::Value createMinus(mlir::Location loc, mlir::Value input,
299 bool nsw = false) {
300 return cir::MinusOp::create(*this, loc, input, nsw);
301 }
302
303 mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) {
304 return cir::ConstPtrAttr::get(type, getI64IntegerAttr(value));
305 }
306
307 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
308 mlir::Type type, llvm::StringRef name,
309 mlir::IntegerAttr alignment,
310 mlir::Value dynAllocSize) {
311 return cir::AllocaOp::create(*this, loc, addrType, type, name, alignment,
312 dynAllocSize);
313 }
314
315 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
316 mlir::Type type, llvm::StringRef name,
317 clang::CharUnits alignment,
318 mlir::Value dynAllocSize) {
319 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
320 return createAlloca(loc, addrType, type, name, alignmentAttr, dynAllocSize);
321 }
322
323 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
324 mlir::Type type, llvm::StringRef name,
325 mlir::IntegerAttr alignment) {
326 return cir::AllocaOp::create(*this, loc, addrType, type, name, alignment);
327 }
328
329 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
330 mlir::Type type, llvm::StringRef name,
331 clang::CharUnits alignment) {
332 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
333 return createAlloca(loc, addrType, type, name, alignmentAttr);
334 }
335
336 /// Get constant address of a global variable as an MLIR attribute.
337 /// This wrapper infers the attribute type through the global op.
338 cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp,
339 mlir::ArrayAttr indices = {}) {
340 cir::PointerType type = getPointerTo(globalOp.getSymType());
341 return getGlobalViewAttr(type, globalOp, indices);
342 }
343
344 /// Get constant address of a global variable as an MLIR attribute.
345 cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type,
346 cir::GlobalOp globalOp,
347 mlir::ArrayAttr indices = {}) {
348 auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr());
349 return cir::GlobalViewAttr::get(type, symbol, indices);
350 }
351
352 /// Get constant address of a global variable as an MLIR attribute.
353 /// This overload converts raw int64_t indices to an ArrayAttr.
354 cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type,
355 cir::GlobalOp globalOp,
356 llvm::ArrayRef<int64_t> indices) {
358 for (int64_t ind : indices)
359 attrs.push_back(getI64IntegerAttr(ind));
360 mlir::ArrayAttr arAttr = mlir::ArrayAttr::get(getContext(), attrs);
361 return getGlobalViewAttr(type, globalOp, arAttr);
362 }
363
364 cir::GetGlobalOp createGetGlobal(mlir::Location loc, cir::GlobalOp global,
365 bool threadLocal = false) {
367 return cir::GetGlobalOp::create(*this, loc,
368 getPointerTo(global.getSymType()),
369 global.getSymNameAttr(), threadLocal);
370 }
371
372 cir::GetGlobalOp createGetGlobal(cir::GlobalOp global,
373 bool threadLocal = false) {
374 return createGetGlobal(global.getLoc(), global, threadLocal);
375 }
376
377 /// Create a copy with inferred length.
378 cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
379 bool isVolatile = false,
380 bool skipTailPadding = false) {
381 return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile,
382 skipTailPadding);
383 }
384
385 cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
386 bool isVolatile = 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, align, scope,
394 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), type, {}, alignmentAttr);
431 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
432 /*isVolatile=*/false, alignmentAttr,
433 /*sync_scope=*/{}, /*mem_order=*/{});
434 }
435
436 cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
437 mlir::Value stride) {
438 return cir::PtrStrideOp::create(*this, loc, base.getType(), base, stride);
439 }
440
441 //===--------------------------------------------------------------------===//
442 // Call operators
443 //===--------------------------------------------------------------------===//
444
445 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
446 mlir::Type returnType, mlir::ValueRange operands,
450 auto op = cir::CallOp::create(*this, loc, callee, returnType, operands);
451 op->setAttrs(attrs);
452
453 if (!argAttrs.empty()) {
454 llvm::SmallVector<mlir::Attribute> argDictAttrs;
455 argDictAttrs.reserve(argAttrs.size());
456
457 llvm::transform(
458 argAttrs, std::back_inserter(argDictAttrs),
459 [this](llvm::ArrayRef<mlir::NamedAttribute> singleArgAttrs) {
460 return mlir::DictionaryAttr::get(getContext(), singleArgAttrs);
461 });
462
463 op.setArgAttrsAttr(mlir::ArrayAttr::get(getContext(), argDictAttrs));
464 }
465
466 if (!resAttrs.empty()) {
467 auto resultDictAttr = mlir::DictionaryAttr::get(getContext(), resAttrs);
468 op.setResAttrsAttr(mlir::ArrayAttr::get(getContext(), resultDictAttr));
469 }
470 return op;
471 }
472
473 cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee,
474 mlir::ValueRange operands,
478 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
479 callee.getFunctionType().getReturnType(), operands,
480 attrs, argAttrs, resAttrs);
481 }
482
483 cir::CallOp
484 createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget,
485 cir::FuncType funcType, mlir::ValueRange operands,
489 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
490 resOperands.append(operands.begin(), operands.end());
491
492 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
493 resOperands, attrs, argAttrs, resAttrs);
494 }
495
496 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
497 mlir::ValueRange operands = mlir::ValueRange(),
501 return createCallOp(loc, callee, cir::VoidType(), operands, attrs, argAttrs,
502 resAttrs);
503 }
504
505 //===--------------------------------------------------------------------===//
506 // Cast/Conversion Operators
507 //===--------------------------------------------------------------------===//
508
509 mlir::Value createCast(mlir::Location loc, cir::CastKind kind,
510 mlir::Value src, mlir::Type newTy) {
511 if (newTy == src.getType())
512 return src;
513 return cir::CastOp::create(*this, loc, newTy, kind, src);
514 }
515
516 mlir::Value createCast(cir::CastKind kind, mlir::Value src,
517 mlir::Type newTy) {
518 if (newTy == src.getType())
519 return src;
520 return createCast(src.getLoc(), kind, src, newTy);
521 }
522
523 // Creates a cast from bool or int to an integer type.
524 mlir::Value createBoolIntToIntCast(mlir::Value src, mlir::Type newTy) {
525 if (newTy == src.getType())
526 return src;
527 if (src.getType() == getBoolTy())
528 return createBoolToInt(src, newTy);
529 return createIntCast(src, newTy);
530 }
531
532 mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) {
533 return createCast(cir::CastKind::integral, src, newTy);
534 }
535
536 mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) {
537 return createCast(cir::CastKind::int_to_ptr, src, newTy);
538 }
539
540 mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) {
541 return createCast(cir::CastKind::ptr_to_int, src, newTy);
542 }
543
544 mlir::Value createPtrToBoolCast(mlir::Value v) {
545 return createCast(cir::CastKind::ptr_to_bool, v, getBoolTy());
546 }
547
548 mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
549 return createCast(cir::CastKind::bool_to_int, src, newTy);
550 }
551
552 mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) {
553 return createCast(cir::CastKind::bitcast, src, newTy);
554 }
555
556 mlir::Value createBitcast(mlir::Location loc, mlir::Value src,
557 mlir::Type newTy) {
558 return createCast(loc, cir::CastKind::bitcast, src, newTy);
559 }
560
561 mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy) {
562 assert(mlir::isa<cir::PointerType>(src.getType()) && "expected ptr src");
563 cir::PointerType srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
564 return createBitcast(src,
565 getPointerTo(newPointeeTy, srcPtrTy.getAddrSpace()));
566 }
567
568 mlir::Value createPtrIsNull(mlir::Value ptr) {
569 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
570 return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr);
571 }
572
573 mlir::Value createPtrIsNotNull(mlir::Value ptr) {
574 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
575 return createCompare(ptr.getLoc(), cir::CmpOpKind::ne, ptr, nullPtr);
576 }
577
578 mlir::Value createAddrSpaceCast(mlir::Location loc, mlir::Value src,
579 mlir::Type newTy) {
580 return createCast(loc, cir::CastKind::address_space, src, newTy);
581 }
582
583 mlir::Value createAddrSpaceCast(mlir::Value src, mlir::Type newTy) {
584 return createAddrSpaceCast(src.getLoc(), src, newTy);
585 }
586
587 //===--------------------------------------------------------------------===//
588 // Other Instructions
589 //===--------------------------------------------------------------------===//
590
591 mlir::Value createExtractElement(mlir::Location loc, mlir::Value vec,
592 uint64_t idx) {
593 mlir::Value idxVal =
594 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
595 return cir::VecExtractOp::create(*this, loc, vec, idxVal);
596 }
597
598 mlir::Value createInsertElement(mlir::Location loc, mlir::Value vec,
599 mlir::Value newElt, uint64_t idx) {
600 mlir::Value idxVal =
601 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
602 return cir::VecInsertOp::create(*this, loc, vec, newElt, idxVal);
603 }
604
605 cir::SignBitOp createSignBit(mlir::Location loc, mlir::Value val) {
606 auto resTy = cir::BoolType::get(getContext());
607 return cir::SignBitOp::create(*this, loc, resTy, val);
608 }
609
610 //===--------------------------------------------------------------------===//
611 // Binary Operators
612 //===--------------------------------------------------------------------===//
613
614 mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
615 unsigned bits) {
616 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
617 auto type = cir::IntType::get(getContext(), size, /*isSigned=*/false);
618 return getConstAPInt(loc, type, val);
619 }
620
621 mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
622 return cir::AndOp::create(*this, loc, lhs, rhs);
623 }
624
625 mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
626 return cir::OrOp::create(*this, loc, lhs, rhs);
627 }
628
629 mlir::Value createSelect(mlir::Location loc, mlir::Value condition,
630 mlir::Value trueValue, mlir::Value falseValue) {
631 assert(trueValue.getType() == falseValue.getType() &&
632 "trueValue and falseValue should have the same type");
633 return cir::SelectOp::create(*this, loc, trueValue.getType(), condition,
634 trueValue, falseValue);
635 }
636
637 mlir::Value createLogicalAnd(mlir::Location loc, mlir::Value lhs,
638 mlir::Value rhs) {
639 return createSelect(loc, lhs, rhs, getBool(false, loc));
640 }
641
642 mlir::Value createLogicalOr(mlir::Location loc, mlir::Value lhs,
643 mlir::Value rhs) {
644 return createSelect(loc, lhs, getBool(true, loc), rhs);
645 }
646
647 mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
649 auto op = cir::MulOp::create(*this, loc, lhs, rhs);
650 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
651 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
652 return op;
653 }
654 mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs,
655 mlir::Value rhs) {
656 return createMul(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
657 }
658 mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs,
659 mlir::Value rhs) {
660 return createMul(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
661 }
662
663 mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
665 auto op = cir::SubOp::create(*this, loc, lhs, rhs);
666 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
667 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
668 op.setSaturated(testFlag(ob, OverflowBehavior::Saturated));
669 return op;
670 }
671
672 mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs,
673 mlir::Value rhs) {
674 return createSub(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
675 }
676
677 mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs,
678 mlir::Value rhs) {
679 return createSub(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
680 }
681
682 mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
684 auto op = cir::AddOp::create(*this, loc, lhs, rhs);
685 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
686 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
687 op.setSaturated(testFlag(ob, OverflowBehavior::Saturated));
688 return op;
689 }
690
691 mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs,
692 mlir::Value rhs) {
693 return createAdd(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
694 }
695
696 mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs,
697 mlir::Value rhs) {
698 return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
699 }
700
701 mlir::Value createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
702 return cir::DivOp::create(*this, loc, lhs, rhs);
703 }
704
705 mlir::Value createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
706 return cir::RemOp::create(*this, loc, lhs, rhs);
707 }
708
709 mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
713 return cir::FAddOp::create(*this, loc, lhs, rhs);
714 }
715
716 mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
720 return cir::FSubOp::create(*this, loc, lhs, rhs);
721 }
722
723 mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
727 return cir::FMulOp::create(*this, loc, lhs, rhs);
728 }
729
730 mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
734 return cir::FDivOp::create(*this, loc, lhs, rhs);
735 }
736
737 mlir::Value createFRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
741 return cir::FRemOp::create(*this, loc, lhs, rhs);
742 }
743
744 mlir::Value createFNeg(mlir::Location loc, mlir::Value operand) {
745 assert(cir::isFPOrVectorOfFPType(operand.getType()) &&
746 "expected floating-point or vector-of-float type");
750 return cir::FNegOp::create(*this, loc, operand);
751 }
752
753 mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
754 return cir::XorOp::create(*this, loc, lhs, rhs);
755 }
756
757 mlir::Value createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
758 return cir::MaxOp::create(*this, loc, lhs, rhs);
759 }
760
761 cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind,
762 mlir::Value lhs, mlir::Value rhs) {
763 return cir::CmpOp::create(*this, loc, kind, lhs, rhs);
764 }
765
766 cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind,
767 mlir::Value lhs, mlir::Value rhs) {
768 VectorType vecCast = mlir::cast<VectorType>(lhs.getType());
769 IntType integralTy =
770 getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType()));
771 VectorType integralVecTy =
772 cir::VectorType::get(integralTy, vecCast.getSize());
773 return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs);
774 }
775
776 mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) {
777 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
778 }
779
780 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
781 bool isShiftLeft) {
782 return cir::ShiftOp::create(*this, loc, lhs.getType(), lhs, rhs,
783 isShiftLeft);
784 }
785
786 mlir::Value createShift(mlir::Location loc, mlir::Value lhs,
787 const llvm::APInt &rhs, bool isShiftLeft) {
788 return createShift(loc, lhs, getConstAPInt(loc, lhs.getType(), rhs),
789 isShiftLeft);
790 }
791
792 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, unsigned bits,
793 bool isShiftLeft) {
794 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
795 auto shift = llvm::APInt(width, bits);
796 return createShift(loc, lhs, shift, isShiftLeft);
797 }
798
799 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
800 unsigned bits) {
801 return createShift(loc, lhs, bits, true);
802 }
803
804 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
805 unsigned bits) {
806 return createShift(loc, lhs, bits, false);
807 }
808
809 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
810 mlir::Value rhs) {
811 return createShift(loc, lhs, rhs, true);
812 }
813
814 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
815 mlir::Value rhs) {
816 return createShift(loc, lhs, rhs, false);
817 }
818
819 /// Returns `void (T...)` as a cir::FuncType.
820 cir::FuncType getVoidFnTy(mlir::TypeRange argTypes = {}) {
821 return cir::FuncType::get(llvm::to_vector(argTypes), getVoidTy());
822 }
823
824 /// Returns `void (*)(T...)` as a cir::PointerType.
825 cir::PointerType getVoidFnPtrTy(mlir::TypeRange argTypes = {}) {
826 return getPointerTo(getVoidFnTy(argTypes));
827 }
828
829 //
830 // Block handling helpers
831 // ----------------------
832 //
833 static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block) {
834 auto last =
835 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
836 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
837 });
838
839 if (last != block->rend())
840 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
841 return OpBuilder::InsertPoint(block, block->begin());
842 };
843
844 //
845 // Alignment and size helpers
846 //
847
848 // Note that mlir::IntegerType is used instead of cir::IntType here because we
849 // don't need sign information for these to be useful, so keep it simple.
850
851 // For 0 alignment, any overload of `getAlignmentAttr` returns an empty
852 // attribute.
853 mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment) {
854 return getAlignmentAttr(alignment.getQuantity());
855 }
856
857 mlir::IntegerAttr getAlignmentAttr(llvm::Align alignment) {
858 return getAlignmentAttr(alignment.value());
859 }
860
861 mlir::IntegerAttr getAlignmentAttr(int64_t alignment) {
862 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
863 }
864
865 // Materialize an alignment value as a CIR integer constant of the given
866 // integer type.
867 cir::ConstantOp getAlignment(mlir::Location loc, mlir::Type t,
868 clang::CharUnits alignment) {
869 return getConstantInt(loc, t, alignment.getQuantity());
870 }
871
872 mlir::IntegerAttr getSizeFromCharUnits(clang::CharUnits size) {
873 return getI64IntegerAttr(size.getQuantity());
874 }
875
876 // Creates constant nullptr for pointer type ty.
877 cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
879 return cir::ConstantOp::create(*this, loc, getConstPtrAttr(ty, 0));
880 }
881
882 /// Create a loop condition.
883 cir::ConditionOp createCondition(mlir::Value condition) {
884 return cir::ConditionOp::create(*this, condition.getLoc(), condition);
885 }
886
887 /// Create a yield operation.
888 cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value = {}) {
889 return cir::YieldOp::create(*this, loc, value);
890 }
891
893 mlir::Value callee;
894 mlir::Value adjustedThis;
895 };
896
897 GetMethodResults createGetMethod(mlir::Location loc, mlir::Value method,
898 mlir::Value objectPtr) {
899 // Build the callee function type.
900 auto methodFuncTy =
901 mlir::cast<cir::MethodType>(method.getType()).getMemberFuncTy();
902 auto methodFuncInputTypes = methodFuncTy.getInputs();
903
904 auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
905 mlir::Type adjustedThisTy = getVoidPtrTy(objectPtrTy.getAddrSpace());
906
907 llvm::SmallVector<mlir::Type> calleeFuncInputTypes{adjustedThisTy};
908 // The member function type's first parameter is the implicit 'this'
909 // pointer. The callee takes an adjusted void* receiver instead.
910 if (methodFuncInputTypes.size() > 1)
911 calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
912 methodFuncInputTypes.begin() + 1,
913 methodFuncInputTypes.end());
914 cir::FuncType calleeFuncTy =
915 methodFuncTy.clone(calleeFuncInputTypes, methodFuncTy.getReturnType());
916 // TODO(cir): consider the address space of the callee.
918 cir::PointerType calleeTy = getPointerTo(calleeFuncTy);
919
920 auto op = cir::GetMethodOp::create(*this, loc, calleeTy, adjustedThisTy,
921 method, objectPtr);
922 return {op.getCallee(), op.getAdjustedThis()};
923 }
924};
925
926} // namespace cir
927
928#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)
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)
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 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, 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)
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 createAlloca(mlir::Location loc, cir::PointerType addrType, mlir::Type type, llvm::StringRef name, mlir::IntegerAttr alignment)
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)
cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr, bool isVolatile=false, uint64_t alignment=0)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, mlir::Type type, llvm::StringRef name, clang::CharUnits alignment)
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)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
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::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr)
Emit a load from an boolean flag variable.
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, mlir::Type type, llvm::StringRef name, mlir::IntegerAttr alignment, mlir::Value dynAllocSize)
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()