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