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 cir::GetGlobalOp 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 cir::GetGlobalOp createGetGlobal(cir::GlobalOp global,
366 bool threadLocal = false) {
367 return createGetGlobal(global.getLoc(), global, threadLocal);
368 }
369
370 /// Create a copy with inferred length.
371 cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
372 bool isVolatile = false,
373 bool skipTailPadding = false) {
374 return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile,
375 skipTailPadding);
376 }
377
378 cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
379 bool isVolatile = false,
380 mlir::IntegerAttr align = {},
381 cir::SyncScopeKindAttr scope = {},
382 cir::MemOrderAttr order = {}) {
383 if (mlir::cast<cir::PointerType>(dst.getType()).getPointee() !=
384 val.getType())
385 dst = createPtrBitcast(dst, val.getType());
386 return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, scope,
387 order);
388 }
389
390 /// Emit a load from an boolean flag variable.
391 cir::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr) {
392 mlir::Type boolTy = getBoolTy();
393 if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee())
394 addr = createPtrBitcast(addr, boolTy);
395 return createLoad(loc, addr, /*isVolatile=*/false, /*alignment=*/1);
396 }
397
398 cir::StoreOp createFlagStore(mlir::Location loc, bool val, mlir::Value dst) {
399 mlir::Value flag = getBool(val, loc);
400 return CIRBaseBuilderTy::createStore(loc, flag, dst);
401 }
402
403 [[nodiscard]] cir::GlobalOp
404 createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc,
405 mlir::StringRef name, mlir::Type type, bool isConstant,
406 cir::GlobalLinkageKind linkage,
407 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
408 mlir::OpBuilder::InsertionGuard guard(*this);
409 setInsertionPointToStart(mlirModule.getBody());
410 return cir::GlobalOp::create(*this, loc, name, type, isConstant, addrSpace,
411 linkage);
412 }
413
414 cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy,
415 mlir::Value base, llvm::StringRef name,
416 unsigned index) {
417 return cir::GetMemberOp::create(*this, loc, resultTy, base, name, index);
418 }
419
420 mlir::Value createDummyValue(mlir::Location loc, mlir::Type type,
421 clang::CharUnits alignment) {
422 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
423 auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
424 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
425 /*isVolatile=*/false, alignmentAttr,
426 /*sync_scope=*/{}, /*mem_order=*/{});
427 }
428
429 cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
430 mlir::Value stride) {
431 return cir::PtrStrideOp::create(*this, loc, base.getType(), base, stride);
432 }
433
434 //===--------------------------------------------------------------------===//
435 // Call operators
436 //===--------------------------------------------------------------------===//
437
438 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
439 mlir::Type returnType, mlir::ValueRange operands,
443 auto op = cir::CallOp::create(*this, loc, callee, returnType, operands);
444 op->setAttrs(attrs);
445
446 if (!argAttrs.empty()) {
447 llvm::SmallVector<mlir::Attribute> argDictAttrs;
448 argDictAttrs.reserve(argAttrs.size());
449
450 llvm::transform(
451 argAttrs, std::back_inserter(argDictAttrs),
452 [this](llvm::ArrayRef<mlir::NamedAttribute> singleArgAttrs) {
453 return mlir::DictionaryAttr::get(getContext(), singleArgAttrs);
454 });
455
456 op.setArgAttrsAttr(mlir::ArrayAttr::get(getContext(), argDictAttrs));
457 }
458
459 if (!resAttrs.empty()) {
460 auto resultDictAttr = mlir::DictionaryAttr::get(getContext(), resAttrs);
461 op.setResAttrsAttr(mlir::ArrayAttr::get(getContext(), resultDictAttr));
462 }
463 return op;
464 }
465
466 cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee,
467 mlir::ValueRange operands,
471 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
472 callee.getFunctionType().getReturnType(), operands,
473 attrs, argAttrs, resAttrs);
474 }
475
476 cir::CallOp
477 createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget,
478 cir::FuncType funcType, mlir::ValueRange operands,
482 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
483 resOperands.append(operands.begin(), operands.end());
484
485 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
486 resOperands, attrs, argAttrs, resAttrs);
487 }
488
489 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
490 mlir::ValueRange operands = mlir::ValueRange(),
494 return createCallOp(loc, callee, cir::VoidType(), operands, attrs, argAttrs,
495 resAttrs);
496 }
497
498 //===--------------------------------------------------------------------===//
499 // Cast/Conversion Operators
500 //===--------------------------------------------------------------------===//
501
502 mlir::Value createCast(mlir::Location loc, cir::CastKind kind,
503 mlir::Value src, mlir::Type newTy) {
504 if (newTy == src.getType())
505 return src;
506 return cir::CastOp::create(*this, loc, newTy, kind, src);
507 }
508
509 mlir::Value createCast(cir::CastKind kind, mlir::Value src,
510 mlir::Type newTy) {
511 if (newTy == src.getType())
512 return src;
513 return createCast(src.getLoc(), kind, src, newTy);
514 }
515
516 mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) {
517 return createCast(cir::CastKind::integral, src, newTy);
518 }
519
520 mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) {
521 return createCast(cir::CastKind::int_to_ptr, src, newTy);
522 }
523
524 mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) {
525 return createCast(cir::CastKind::ptr_to_int, src, newTy);
526 }
527
528 mlir::Value createPtrToBoolCast(mlir::Value v) {
529 return createCast(cir::CastKind::ptr_to_bool, v, getBoolTy());
530 }
531
532 mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
533 return createCast(cir::CastKind::bool_to_int, src, newTy);
534 }
535
536 mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) {
537 return createCast(cir::CastKind::bitcast, src, newTy);
538 }
539
540 mlir::Value createBitcast(mlir::Location loc, mlir::Value src,
541 mlir::Type newTy) {
542 return createCast(loc, cir::CastKind::bitcast, src, newTy);
543 }
544
545 mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy) {
546 assert(mlir::isa<cir::PointerType>(src.getType()) && "expected ptr src");
547 return createBitcast(src, getPointerTo(newPointeeTy));
548 }
549
550 mlir::Value createPtrIsNull(mlir::Value ptr) {
551 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
552 return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr);
553 }
554
555 mlir::Value createPtrIsNotNull(mlir::Value ptr) {
556 mlir::Value nullPtr = getNullPtr(ptr.getType(), ptr.getLoc());
557 return createCompare(ptr.getLoc(), cir::CmpOpKind::ne, ptr, nullPtr);
558 }
559
560 mlir::Value createAddrSpaceCast(mlir::Location loc, mlir::Value src,
561 mlir::Type newTy) {
562 return createCast(loc, cir::CastKind::address_space, src, newTy);
563 }
564
565 mlir::Value createAddrSpaceCast(mlir::Value src, mlir::Type newTy) {
566 return createAddrSpaceCast(src.getLoc(), src, newTy);
567 }
568
569 //===--------------------------------------------------------------------===//
570 // Other Instructions
571 //===--------------------------------------------------------------------===//
572
573 mlir::Value createExtractElement(mlir::Location loc, mlir::Value vec,
574 uint64_t idx) {
575 mlir::Value idxVal =
576 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
577 return cir::VecExtractOp::create(*this, loc, vec, idxVal);
578 }
579
580 mlir::Value createInsertElement(mlir::Location loc, mlir::Value vec,
581 mlir::Value newElt, uint64_t idx) {
582 mlir::Value idxVal =
583 getConstAPInt(loc, getUIntNTy(64), llvm::APInt(64, idx));
584 return cir::VecInsertOp::create(*this, loc, vec, newElt, idxVal);
585 }
586
587 cir::SignBitOp createSignBit(mlir::Location loc, mlir::Value val) {
588 auto resTy = cir::BoolType::get(getContext());
589 return cir::SignBitOp::create(*this, loc, resTy, val);
590 }
591
592 //===--------------------------------------------------------------------===//
593 // Binary Operators
594 //===--------------------------------------------------------------------===//
595
596 mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
597 unsigned bits) {
598 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
599 auto type = cir::IntType::get(getContext(), size, /*isSigned=*/false);
600 return getConstAPInt(loc, type, val);
601 }
602
603 mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
604 return cir::AndOp::create(*this, loc, lhs, rhs);
605 }
606
607 mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
608 return cir::OrOp::create(*this, loc, lhs, rhs);
609 }
610
611 mlir::Value createSelect(mlir::Location loc, mlir::Value condition,
612 mlir::Value trueValue, mlir::Value falseValue) {
613 assert(trueValue.getType() == falseValue.getType() &&
614 "trueValue and falseValue should have the same type");
615 return cir::SelectOp::create(*this, loc, trueValue.getType(), condition,
616 trueValue, falseValue);
617 }
618
619 mlir::Value createLogicalAnd(mlir::Location loc, mlir::Value lhs,
620 mlir::Value rhs) {
621 return createSelect(loc, lhs, rhs, getBool(false, loc));
622 }
623
624 mlir::Value createLogicalOr(mlir::Location loc, mlir::Value lhs,
625 mlir::Value rhs) {
626 return createSelect(loc, lhs, getBool(true, loc), rhs);
627 }
628
629 mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
631 auto op = cir::MulOp::create(*this, loc, lhs, rhs);
632 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
633 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
634 return op;
635 }
636 mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs,
637 mlir::Value rhs) {
638 return createMul(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
639 }
640 mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs,
641 mlir::Value rhs) {
642 return createMul(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
643 }
644
645 mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
647 auto op = cir::SubOp::create(*this, loc, lhs, rhs);
648 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
649 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
650 op.setSaturated(testFlag(ob, OverflowBehavior::Saturated));
651 return op;
652 }
653
654 mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs,
655 mlir::Value rhs) {
656 return createSub(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
657 }
658
659 mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs,
660 mlir::Value rhs) {
661 return createSub(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
662 }
663
664 mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
666 auto op = cir::AddOp::create(*this, loc, lhs, rhs);
667 op.setNoUnsignedWrap(testFlag(ob, OverflowBehavior::NoUnsignedWrap));
668 op.setNoSignedWrap(testFlag(ob, OverflowBehavior::NoSignedWrap));
669 op.setSaturated(testFlag(ob, OverflowBehavior::Saturated));
670 return op;
671 }
672
673 mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs,
674 mlir::Value rhs) {
675 return createAdd(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
676 }
677
678 mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs,
679 mlir::Value rhs) {
680 return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
681 }
682
683 mlir::Value createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
684 return cir::DivOp::create(*this, loc, lhs, rhs);
685 }
686
687 mlir::Value createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
688 return cir::RemOp::create(*this, loc, lhs, rhs);
689 }
690
691 mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
692 return cir::XorOp::create(*this, loc, lhs, rhs);
693 }
694
695 mlir::Value createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
696 return cir::MaxOp::create(*this, loc, lhs, rhs);
697 }
698
699 cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind,
700 mlir::Value lhs, mlir::Value rhs) {
701 return cir::CmpOp::create(*this, loc, kind, lhs, rhs);
702 }
703
704 cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind,
705 mlir::Value lhs, mlir::Value rhs) {
706 VectorType vecCast = mlir::cast<VectorType>(lhs.getType());
707 IntType integralTy =
708 getSIntNTy(getCIRIntOrFloatBitWidth(vecCast.getElementType()));
709 VectorType integralVecTy =
710 cir::VectorType::get(integralTy, vecCast.getSize());
711 return cir::VecCmpOp::create(*this, loc, integralVecTy, kind, lhs, rhs);
712 }
713
714 mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) {
715 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
716 }
717
718 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
719 bool isShiftLeft) {
720 return cir::ShiftOp::create(*this, loc, lhs.getType(), lhs, rhs,
721 isShiftLeft);
722 }
723
724 mlir::Value createShift(mlir::Location loc, mlir::Value lhs,
725 const llvm::APInt &rhs, bool isShiftLeft) {
726 return createShift(loc, lhs, getConstAPInt(loc, lhs.getType(), rhs),
727 isShiftLeft);
728 }
729
730 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, unsigned bits,
731 bool isShiftLeft) {
732 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
733 auto shift = llvm::APInt(width, bits);
734 return createShift(loc, lhs, shift, isShiftLeft);
735 }
736
737 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
738 unsigned bits) {
739 return createShift(loc, lhs, bits, true);
740 }
741
742 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
743 unsigned bits) {
744 return createShift(loc, lhs, bits, false);
745 }
746
747 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
748 mlir::Value rhs) {
749 return createShift(loc, lhs, rhs, true);
750 }
751
752 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
753 mlir::Value rhs) {
754 return createShift(loc, lhs, rhs, false);
755 }
756
757 /// Returns `void (T...)` as a cir::FuncType.
758 cir::FuncType getVoidFnTy(mlir::TypeRange argTypes = {}) {
759 return cir::FuncType::get(llvm::to_vector(argTypes), getVoidTy());
760 }
761
762 /// Returns `void (*)(T...)` as a cir::PointerType.
763 cir::PointerType getVoidFnPtrTy(mlir::TypeRange argTypes = {}) {
764 return getPointerTo(getVoidFnTy(argTypes));
765 }
766
767 //
768 // Block handling helpers
769 // ----------------------
770 //
771 static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block) {
772 auto last =
773 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
774 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
775 });
776
777 if (last != block->rend())
778 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
779 return OpBuilder::InsertPoint(block, block->begin());
780 };
781
782 //
783 // Alignment and size helpers
784 //
785
786 // Note that mlir::IntegerType is used instead of cir::IntType here because we
787 // don't need sign information for these to be useful, so keep it simple.
788
789 // For 0 alignment, any overload of `getAlignmentAttr` returns an empty
790 // attribute.
791 mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment) {
792 return getAlignmentAttr(alignment.getQuantity());
793 }
794
795 mlir::IntegerAttr getAlignmentAttr(llvm::Align alignment) {
796 return getAlignmentAttr(alignment.value());
797 }
798
799 mlir::IntegerAttr getAlignmentAttr(int64_t alignment) {
800 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
801 }
802
803 mlir::IntegerAttr getSizeFromCharUnits(clang::CharUnits size) {
804 return getI64IntegerAttr(size.getQuantity());
805 }
806
807 // Creates constant nullptr for pointer type ty.
808 cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
810 return cir::ConstantOp::create(*this, loc, getConstPtrAttr(ty, 0));
811 }
812
813 /// Create a loop condition.
814 cir::ConditionOp createCondition(mlir::Value condition) {
815 return cir::ConditionOp::create(*this, condition.getLoc(), condition);
816 }
817
818 /// Create a yield operation.
819 cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value = {}) {
820 return cir::YieldOp::create(*this, loc, value);
821 }
822
824 mlir::Value callee;
825 mlir::Value adjustedThis;
826 };
827
828 GetMethodResults createGetMethod(mlir::Location loc, mlir::Value method,
829 mlir::Value objectPtr) {
830 // Build the callee function type.
831 auto methodFuncTy =
832 mlir::cast<cir::MethodType>(method.getType()).getMemberFuncTy();
833 auto methodFuncInputTypes = methodFuncTy.getInputs();
834
835 auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
836 mlir::Type adjustedThisTy = getVoidPtrTy(objectPtrTy.getAddrSpace());
837
838 llvm::SmallVector<mlir::Type> calleeFuncInputTypes{adjustedThisTy};
839 calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
840 methodFuncInputTypes.begin(),
841 methodFuncInputTypes.end());
842 cir::FuncType calleeFuncTy =
843 methodFuncTy.clone(calleeFuncInputTypes, methodFuncTy.getReturnType());
844 // TODO(cir): consider the address space of the callee.
846 cir::PointerType calleeTy = getPointerTo(calleeFuncTy);
847
848 auto op = cir::GetMethodOp::create(*this, loc, calleeTy, adjustedThisTy,
849 method, objectPtr);
850 return {op.getCallee(), op.getAdjustedThis()};
851 }
852};
853
854} // namespace cir
855
856#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)
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 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::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)
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 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()