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 (mlir::isa<cir::BoolType>(ty)) {
131 return getFalseAttr();
132 }
133 llvm_unreachable("Zero initializer for given type is NYI");
134 }
135
136 cir::ConstantOp getBool(bool state, mlir::Location loc) {
137 return cir::ConstantOp::create(*this, loc, getCIRBoolAttr(state));
138 }
139 cir::ConstantOp getFalse(mlir::Location loc) { return getBool(false, loc); }
140 cir::ConstantOp getTrue(mlir::Location loc) { return getBool(true, loc); }
141
142 cir::BoolType getBoolTy() { return cir::BoolType::get(getContext()); }
143 cir::VoidType getVoidTy() { return cir::VoidType::get(getContext()); }
144
145 cir::IntType getUIntNTy(int n) {
146 return cir::IntType::get(getContext(), n, false);
147 }
148
149 static unsigned getCIRIntOrFloatBitWidth(mlir::Type eltTy) {
150 if (auto intType = mlir::dyn_cast<cir::IntTypeInterface>(eltTy))
151 return intType.getWidth();
152 if (auto floatType = mlir::dyn_cast<cir::FPTypeInterface>(eltTy))
153 return floatType.getWidth();
154
155 llvm_unreachable("Unsupported type in getCIRIntOrFloatBitWidth");
156 }
157 cir::IntType getSIntNTy(int n) {
158 return cir::IntType::get(getContext(), n, true);
159 }
160
161 cir::PointerType getPointerTo(mlir::Type ty) {
162 return cir::PointerType::get(ty);
163 }
164
165 cir::PointerType getPointerTo(mlir::Type ty,
166 mlir::ptr::MemorySpaceAttrInterface as) {
167 return cir::PointerType::get(ty, as);
168 }
169
170 cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
171 if (langAS == clang::LangAS::Default)
172 return getPointerTo(ty);
173
174 mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr =
175 cir::toCIRAddressSpaceAttr(*getContext(), langAS);
176 return getPointerTo(ty, addrSpaceAttr);
177 }
178
180 return getPointerTo(cir::VoidType::get(getContext()), langAS);
181 }
182
183 cir::PointerType getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface as) {
184 return getPointerTo(cir::VoidType::get(getContext()), as);
185 }
186
187 cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
188 auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
189 return cir::MethodAttr::get(ty, methodFuncSymbolRef);
190 }
191
192 cir::MethodAttr getNullMethodAttr(cir::MethodType ty) {
193 return cir::MethodAttr::get(ty);
194 }
195
196 cir::BoolAttr getCIRBoolAttr(bool state) {
197 return cir::BoolAttr::get(getContext(), state);
198 }
199
200 cir::BoolAttr getTrueAttr() { return getCIRBoolAttr(true); }
201 cir::BoolAttr getFalseAttr() { return getCIRBoolAttr(false); }
202
203 mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real,
204 mlir::Value imag) {
205 auto resultComplexTy = cir::ComplexType::get(real.getType());
206 return cir::ComplexCreateOp::create(*this, loc, resultComplexTy, real,
207 imag);
208 }
209
210 mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand) {
211 auto resultType = operand.getType();
212 if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
213 resultType = complexResultType.getElementType();
214 return cir::ComplexRealOp::create(*this, loc, resultType, operand);
215 }
216
217 mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand) {
218 auto resultType = operand.getType();
219 if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
220 resultType = complexResultType.getElementType();
221 return cir::ComplexImagOp::create(*this, loc, resultType, operand);
222 }
223
224 cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
225 bool isVolatile = false, uint64_t alignment = 0) {
226 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
227 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
228 alignmentAttr, cir::SyncScopeKindAttr{},
229 cir::MemOrderAttr{});
230 }
231
232 mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
233 uint64_t alignment) {
234 return createLoad(loc, ptr, /*isVolatile=*/false, alignment);
235 }
236
237 mlir::Value createNot(mlir::Location loc, mlir::Value value) {
238 return cir::NotOp::create(*this, loc, value);
239 }
240
241 mlir::Value createNot(mlir::Value value) {
242 return createNot(value.getLoc(), value);
243 }
244
245 /// Create a do-while operation.
246 cir::DoWhileOp createDoWhile(
247 mlir::Location loc,
248 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
249 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
250 return cir::DoWhileOp::create(*this, loc, condBuilder, bodyBuilder);
251 }
252
253 /// Create a while operation.
254 cir::WhileOp createWhile(
255 mlir::Location loc,
256 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
257 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
258 return cir::WhileOp::create(*this, loc, condBuilder, bodyBuilder);
259 }
260
261 /// Create a for operation.
262 cir::ForOp createFor(
263 mlir::Location loc,
264 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
265 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
266 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> stepBuilder) {
267 return cir::ForOp::create(*this, loc, condBuilder, bodyBuilder,
268 stepBuilder);
269 }
270
271 /// Create a break operation.
272 cir::BreakOp createBreak(mlir::Location loc) {
273 return cir::BreakOp::create(*this, loc);
274 }
275
276 /// Create a continue operation.
277 cir::ContinueOp createContinue(mlir::Location loc) {
278 return cir::ContinueOp::create(*this, loc);
279 }
280
281 mlir::Value createInc(mlir::Location loc, mlir::Value input,
282 bool nsw = false) {
283 return cir::IncOp::create(*this, loc, input, nsw);
284 }
285
286 mlir::Value createDec(mlir::Location loc, mlir::Value input,
287 bool nsw = false) {
288 return cir::DecOp::create(*this, loc, input, nsw);
289 }
290
291 mlir::Value createMinus(mlir::Location loc, mlir::Value input,
292 bool nsw = false) {
293 return cir::MinusOp::create(*this, loc, input, nsw);
294 }
295
296 mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) {
297 return cir::ConstPtrAttr::get(type, getI64IntegerAttr(value));
298 }
299
300 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
301 mlir::Type type, llvm::StringRef name,
302 mlir::IntegerAttr alignment,
303 mlir::Value dynAllocSize) {
304 return cir::AllocaOp::create(*this, loc, addrType, type, name, alignment,
305 dynAllocSize);
306 }
307
308 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
309 mlir::Type type, llvm::StringRef name,
310 clang::CharUnits alignment,
311 mlir::Value dynAllocSize) {
312 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
313 return createAlloca(loc, addrType, type, name, alignmentAttr, dynAllocSize);
314 }
315
316 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
317 mlir::Type type, llvm::StringRef name,
318 mlir::IntegerAttr alignment) {
319 return cir::AllocaOp::create(*this, loc, addrType, type, name, alignment);
320 }
321
322 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
323 mlir::Type type, llvm::StringRef name,
324 clang::CharUnits alignment) {
325 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
326 return createAlloca(loc, addrType, type, name, alignmentAttr);
327 }
328
329 /// Get constant address of a global variable as an MLIR attribute.
330 /// This wrapper infers the attribute type through the global op.
331 cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp,
332 mlir::ArrayAttr indices = {}) {
333 cir::PointerType type = getPointerTo(globalOp.getSymType());
334 return getGlobalViewAttr(type, globalOp, indices);
335 }
336
337 /// Get constant address of a global variable as an MLIR attribute.
338 cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type,
339 cir::GlobalOp globalOp,
340 mlir::ArrayAttr indices = {}) {
341 auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr());
342 return cir::GlobalViewAttr::get(type, symbol, indices);
343 }
344
345 /// Get constant address of a global variable as an MLIR attribute.
346 /// This overload converts raw int64_t indices to an ArrayAttr.
347 cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type,
348 cir::GlobalOp globalOp,
349 llvm::ArrayRef<int64_t> indices) {
351 for (int64_t ind : indices)
352 attrs.push_back(getI64IntegerAttr(ind));
353 mlir::ArrayAttr arAttr = mlir::ArrayAttr::get(getContext(), attrs);
354 return getGlobalViewAttr(type, globalOp, arAttr);
355 }
356
357 mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global,
358 bool threadLocal = false) {
360 return cir::GetGlobalOp::create(*this, loc,
361 getPointerTo(global.getSymType()),
362 global.getSymNameAttr(), threadLocal);
363 }
364
365 mlir::Value createGetGlobal(cir::GlobalOp global, bool threadLocal = false) {
366 return createGetGlobal(global.getLoc(), global, threadLocal);
367 }
368
369 /// Create a copy with inferred length.
370 cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
371 bool isVolatile = false,
372 bool skipTailPadding = false) {
373 return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile,
374 skipTailPadding);
375 }
376
377 cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
378 bool isVolatile = false,
379 mlir::IntegerAttr align = {},
380 cir::SyncScopeKindAttr scope = {},
381 cir::MemOrderAttr order = {}) {
382 if (mlir::cast<cir::PointerType>(dst.getType()).getPointee() !=
383 val.getType())
384 dst = createPtrBitcast(dst, val.getType());
385 return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, scope,
386 order);
387 }
388
389 /// Emit a load from an boolean flag variable.
390 cir::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr) {
391 mlir::Type boolTy = getBoolTy();
392 if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee())
393 addr = createPtrBitcast(addr, boolTy);
394 return createLoad(loc, addr, /*isVolatile=*/false, /*alignment=*/1);
395 }
396
397 cir::StoreOp createFlagStore(mlir::Location loc, bool val, mlir::Value dst) {
398 mlir::Value flag = getBool(val, loc);
399 return CIRBaseBuilderTy::createStore(loc, flag, dst);
400 }
401
402 [[nodiscard]] cir::GlobalOp
403 createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc,
404 mlir::StringRef name, mlir::Type type, bool isConstant,
405 cir::GlobalLinkageKind linkage,
406 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
407 mlir::OpBuilder::InsertionGuard guard(*this);
408 setInsertionPointToStart(mlirModule.getBody());
409 return cir::GlobalOp::create(*this, loc, name, type, isConstant, addrSpace,
410 linkage);
411 }
412
413 cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy,
414 mlir::Value base, llvm::StringRef name,
415 unsigned index) {
416 return cir::GetMemberOp::create(*this, loc, resultTy, base, name, index);
417 }
418
419 mlir::Value createDummyValue(mlir::Location loc, mlir::Type type,
420 clang::CharUnits alignment) {
421 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
422 auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
423 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
424 /*isVolatile=*/false, alignmentAttr,
425 /*sync_scope=*/{}, /*mem_order=*/{});
426 }
427
428 cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
429 mlir::Value stride) {
430 return cir::PtrStrideOp::create(*this, loc, base.getType(), base, stride);
431 }
432
433 //===--------------------------------------------------------------------===//
434 // Call operators
435 //===--------------------------------------------------------------------===//
436
437 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
438 mlir::Type returnType, mlir::ValueRange operands,
442 auto op = cir::CallOp::create(*this, loc, callee, returnType, operands);
443 op->setAttrs(attrs);
444
445 if (!argAttrs.empty()) {
446 llvm::SmallVector<mlir::Attribute> argDictAttrs;
447 argDictAttrs.reserve(argAttrs.size());
448
449 llvm::transform(
450 argAttrs, std::back_inserter(argDictAttrs),
451 [this](llvm::ArrayRef<mlir::NamedAttribute> singleArgAttrs) {
452 return mlir::DictionaryAttr::get(getContext(), singleArgAttrs);
453 });
454
455 op.setArgAttrsAttr(mlir::ArrayAttr::get(getContext(), argDictAttrs));
456 }
457
458 if (!resAttrs.empty()) {
459 auto resultDictAttr = mlir::DictionaryAttr::get(getContext(), resAttrs);
460 op.setResAttrsAttr(mlir::ArrayAttr::get(getContext(), resultDictAttr));
461 }
462 return op;
463 }
464
465 cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee,
466 mlir::ValueRange operands,
470 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
471 callee.getFunctionType().getReturnType(), operands,
472 attrs, argAttrs, resAttrs);
473 }
474
475 cir::CallOp
476 createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget,
477 cir::FuncType funcType, mlir::ValueRange operands,
481 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
482 resOperands.append(operands.begin(), operands.end());
483
484 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
485 resOperands, attrs, argAttrs, resAttrs);
486 }
487
488 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
489 mlir::ValueRange operands = mlir::ValueRange(),
493 return createCallOp(loc, callee, cir::VoidType(), operands, attrs, argAttrs,
494 resAttrs);
495 }
496
497 //===--------------------------------------------------------------------===//
498 // Cast/Conversion Operators
499 //===--------------------------------------------------------------------===//
500
501 mlir::Value createCast(mlir::Location loc, cir::CastKind kind,
502 mlir::Value src, mlir::Type newTy) {
503 if (newTy == src.getType())
504 return src;
505 return cir::CastOp::create(*this, loc, newTy, kind, src);
506 }
507
508 mlir::Value createCast(cir::CastKind kind, mlir::Value src,
509 mlir::Type newTy) {
510 if (newTy == src.getType())
511 return src;
512 return createCast(src.getLoc(), kind, src, newTy);
513 }
514
515 mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) {
516 return createCast(cir::CastKind::integral, src, newTy);
517 }
518
519 mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) {
520 return createCast(cir::CastKind::int_to_ptr, src, newTy);
521 }
522
523 mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) {
524 return createCast(cir::CastKind::ptr_to_int, src, newTy);
525 }
526
527 mlir::Value createPtrToBoolCast(mlir::Value v) {
528 return createCast(cir::CastKind::ptr_to_bool, v, getBoolTy());
529 }
530
531 mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
532 return createCast(cir::CastKind::bool_to_int, src, newTy);
533 }
534
535 mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) {
536 return createCast(cir::CastKind::bitcast, src, newTy);
537 }
538
539 mlir::Value createBitcast(mlir::Location loc, mlir::Value src,
540 mlir::Type newTy) {
541 return createCast(loc, cir::CastKind::bitcast, src, newTy);
542 }
543
544 mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy) {
545 assert(mlir::isa<cir::PointerType>(src.getType()) && "expected ptr src");
546 return createBitcast(src, getPointerTo(newPointeeTy));
547 }
548
549 mlir::Value createPtrIsNull(mlir::Value ptr) {
550 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
551 return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr);
552 }
553
554 mlir::Value createPtrIsNotNull(mlir::Value ptr) {
555 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
556 return createCompare(ptr.getLoc(), cir::CmpOpKind::ne, ptr, nullPtr);
557 }
558
559 mlir::Value createAddrSpaceCast(mlir::Location loc, mlir::Value src,
560 mlir::Type newTy) {
561 return createCast(loc, cir::CastKind::address_space, src, newTy);
562 }
563
564 mlir::Value createAddrSpaceCast(mlir::Value src, mlir::Type newTy) {
565 return createAddrSpaceCast(src.getLoc(), src, newTy);
566 }
567
568 //===--------------------------------------------------------------------===//
569 // Other Instructions
570 //===--------------------------------------------------------------------===//
571
572 mlir::Value createExtractElement(mlir::Location loc, mlir::Value vec,
573 uint64_t idx) {
574 mlir::Value idxVal =
575 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
576 return cir::VecExtractOp::create(*this, loc, vec, idxVal);
577 }
578
579 mlir::Value createInsertElement(mlir::Location loc, mlir::Value vec,
580 mlir::Value newElt, uint64_t idx) {
581 mlir::Value idxVal =
582 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
583 return cir::VecInsertOp::create(*this, loc, vec, newElt, idxVal);
584 }
585
586 cir::SignBitOp createSignBit(mlir::Location loc, mlir::Value val) {
587 auto resTy = cir::BoolType::get(getContext());
588 return cir::SignBitOp::create(*this, loc, resTy, val);
589 }
590
591 //===--------------------------------------------------------------------===//
592 // Binary Operators
593 //===--------------------------------------------------------------------===//
594
595 mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
596 unsigned bits) {
597 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
598 auto type = cir::IntType::get(getContext(), size, /*isSigned=*/false);
599 return getConstAPInt(loc, type, val);
600 }
601
602 mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
603 return cir::AndOp::create(*this, loc, lhs, rhs);
604 }
605
606 mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
607 return cir::OrOp::create(*this, loc, lhs, rhs);
608 }
609
610 mlir::Value createSelect(mlir::Location loc, mlir::Value condition,
611 mlir::Value trueValue, mlir::Value falseValue) {
612 assert(trueValue.getType() == falseValue.getType() &&
613 "trueValue and falseValue should have the same type");
614 return cir::SelectOp::create(*this, loc, trueValue.getType(), condition,
615 trueValue, falseValue);
616 }
617
618 mlir::Value createLogicalAnd(mlir::Location loc, mlir::Value lhs,
619 mlir::Value rhs) {
620 return createSelect(loc, lhs, rhs, getBool(false, loc));
621 }
622
623 mlir::Value createLogicalOr(mlir::Location loc, mlir::Value lhs,
624 mlir::Value rhs) {
625 return createSelect(loc, lhs, getBool(true, loc), rhs);
626 }
627
628 mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
630 auto op = cir::MulOp::create(*this, loc, lhs, rhs);
631 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
632 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
633 return op;
634 }
635 mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs,
636 mlir::Value rhs) {
637 return createMul(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
638 }
639 mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs,
640 mlir::Value rhs) {
641 return createMul(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
642 }
643
644 mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
646 auto op = cir::SubOp::create(*this, loc, lhs, rhs);
647 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
648 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
649 op.setSaturated(testFlag(ob, OverflowBehavior::Saturated));
650 return op;
651 }
652
653 mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs,
654 mlir::Value rhs) {
655 return createSub(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
656 }
657
658 mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs,
659 mlir::Value rhs) {
660 return createSub(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
661 }
662
663 mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
665 auto op = cir::AddOp::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 createNSWAdd(mlir::Location loc, mlir::Value lhs,
673 mlir::Value rhs) {
674 return createAdd(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
675 }
676
677 mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs,
678 mlir::Value rhs) {
679 return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
680 }
681
682 mlir::Value createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
683 return cir::DivOp::create(*this, loc, lhs, rhs);
684 }
685
686 mlir::Value createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
687 return cir::RemOp::create(*this, loc, lhs, rhs);
688 }
689
690 mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
691 return cir::XorOp::create(*this, loc, lhs, rhs);
692 }
693
694 mlir::Value createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
695 return cir::MaxOp::create(*this, loc, lhs, rhs);
696 }
697
698 cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind,
699 mlir::Value lhs, mlir::Value rhs) {
700 return cir::CmpOp::create(*this, loc, kind, lhs, rhs);
701 }
702
703 cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind,
704 mlir::Value lhs, mlir::Value rhs) {
705 VectorType vecCast = mlir::cast<VectorType>(lhs.getType());
706 IntType integralTy =
707 getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType()));
708 VectorType integralVecTy =
709 cir::VectorType::get(integralTy, vecCast.getSize());
710 return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs);
711 }
712
713 mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) {
714 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
715 }
716
717 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
718 bool isShiftLeft) {
719 return cir::ShiftOp::create(*this, loc, lhs.getType(), lhs, rhs,
720 isShiftLeft);
721 }
722
723 mlir::Value createShift(mlir::Location loc, mlir::Value lhs,
724 const llvm::APInt &rhs, bool isShiftLeft) {
725 return createShift(loc, lhs, getConstAPInt(loc, lhs.getType(), rhs),
726 isShiftLeft);
727 }
728
729 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, unsigned bits,
730 bool isShiftLeft) {
731 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
732 auto shift = llvm::APInt(width, bits);
733 return createShift(loc, lhs, shift, isShiftLeft);
734 }
735
736 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
737 unsigned bits) {
738 return createShift(loc, lhs, bits, true);
739 }
740
741 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
742 unsigned bits) {
743 return createShift(loc, lhs, bits, false);
744 }
745
746 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
747 mlir::Value rhs) {
748 return createShift(loc, lhs, rhs, true);
749 }
750
751 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
752 mlir::Value rhs) {
753 return createShift(loc, lhs, rhs, false);
754 }
755
756 //
757 // Block handling helpers
758 // ----------------------
759 //
760 static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block) {
761 auto last =
762 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
763 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
764 });
765
766 if (last != block->rend())
767 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
768 return OpBuilder::InsertPoint(block, block->begin());
769 };
770
771 //
772 // Alignment and size helpers
773 //
774
775 // Note that mlir::IntegerType is used instead of cir::IntType here because we
776 // don't need sign information for these to be useful, so keep it simple.
777
778 // For 0 alignment, any overload of `getAlignmentAttr` returns an empty
779 // attribute.
780 mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment) {
781 return getAlignmentAttr(alignment.getQuantity());
782 }
783
784 mlir::IntegerAttr getAlignmentAttr(llvm::Align alignment) {
785 return getAlignmentAttr(alignment.value());
786 }
787
788 mlir::IntegerAttr getAlignmentAttr(int64_t alignment) {
789 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
790 }
791
792 mlir::IntegerAttr getSizeFromCharUnits(clang::CharUnits size) {
793 return getI64IntegerAttr(size.getQuantity());
794 }
795
796 // Creates constant nullptr for pointer type ty.
797 cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
799 return cir::ConstantOp::create(*this, loc, getConstPtrAttr(ty, 0));
800 }
801
802 /// Create a loop condition.
803 cir::ConditionOp createCondition(mlir::Value condition) {
804 return cir::ConditionOp::create(*this, condition.getLoc(), condition);
805 }
806
807 /// Create a yield operation.
808 cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value = {}) {
809 return cir::YieldOp::create(*this, loc, value);
810 }
811
813 mlir::Value callee;
814 mlir::Value adjustedThis;
815 };
816
817 GetMethodResults createGetMethod(mlir::Location loc, mlir::Value method,
818 mlir::Value objectPtr) {
819 // Build the callee function type.
820 auto methodFuncTy =
821 mlir::cast<cir::MethodType>(method.getType()).getMemberFuncTy();
822 auto methodFuncInputTypes = methodFuncTy.getInputs();
823
824 auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
825 mlir::Type adjustedThisTy = getVoidPtrTy(objectPtrTy.getAddrSpace());
826
827 llvm::SmallVector<mlir::Type> calleeFuncInputTypes{adjustedThisTy};
828 calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
829 methodFuncInputTypes.begin(),
830 methodFuncInputTypes.end());
831 cir::FuncType calleeFuncTy =
832 methodFuncTy.clone(calleeFuncInputTypes, methodFuncTy.getReturnType());
833 // TODO(cir): consider the address space of the callee.
835 cir::PointerType calleeTy = getPointerTo(calleeFuncTy);
836
837 auto op = cir::GetMethodOp::create(*this, loc, calleeTy, adjustedThisTy,
838 method, objectPtr);
839 return {op.getCallee(), op.getAdjustedThis()};
840 }
841};
842
843} // namespace cir
844
845#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
__device__ __2f16 b
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)
mlir::Value createGetGlobal(cir::GlobalOp global, bool threadLocal=false)
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::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 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 createNot(mlir::Value value)
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::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)
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)
CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
mlir::Value createBitcast(mlir::Location loc, mlir::Value src, mlir::Type newTy)
mlir::TypedAttr getNullDataMemberAttr(cir::DataMemberType ty)
mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global, bool threadLocal=false)
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 createAddrSpaceCast(mlir::Value src, mlir::Type newTy)
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 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.
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)
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 addressSpace()
static bool targetCodeGenInfoGetNullPointer()