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