Thanks to visit codestin.com
Credit goes to clang.llvm.org

clang 22.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/Support/ErrorHandling.h"
20
21#include "mlir/IR/Builders.h"
22#include "mlir/IR/BuiltinAttributes.h"
23#include "mlir/IR/Location.h"
24#include "mlir/IR/Types.h"
25
26namespace cir {
27
28enum class OverflowBehavior {
29 None = 0,
30 NoSignedWrap = 1 << 0,
32 Saturated = 1 << 2,
33};
34
36 return static_cast<OverflowBehavior>(llvm::to_underlying(a) |
37 llvm::to_underlying(b));
38}
39
41 return static_cast<OverflowBehavior>(llvm::to_underlying(a) &
42 llvm::to_underlying(b));
43}
44
47 a = a | b;
48 return a;
49}
50
53 a = a & b;
54 return a;
55}
56
57class CIRBaseBuilderTy : public mlir::OpBuilder {
58
59public:
60 CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
61 : mlir::OpBuilder(&mlirContext) {}
62 CIRBaseBuilderTy(mlir::OpBuilder &builder) : mlir::OpBuilder(builder) {}
63
64 mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ,
65 const llvm::APInt &val) {
66 return cir::ConstantOp::create(*this, loc, cir::IntAttr::get(typ, val));
67 }
68
69 cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) {
70 return cir::ConstantOp::create(*this, loc, attr);
71 }
72
73 cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty,
74 int64_t value) {
75 return getConstant(loc, cir::IntAttr::get(ty, value));
76 }
77
78 mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits) {
79 auto type = cir::IntType::get(getContext(), numBits, /*isSigned=*/true);
80 return getConstAPInt(loc, type,
81 llvm::APInt(numBits, val, /*isSigned=*/true));
82 }
83
84 mlir::Value getUnsignedInt(mlir::Location loc, uint64_t val,
85 unsigned numBits) {
86 auto type = cir::IntType::get(getContext(), numBits, /*isSigned=*/false);
87 return getConstAPInt(loc, type, llvm::APInt(numBits, val));
88 }
89
90 // Creates constant null value for integral type ty.
91 cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc) {
92 return getConstant(loc, getZeroInitAttr(ty));
93 }
94
95 mlir::TypedAttr getConstNullPtrAttr(mlir::Type t) {
96 assert(mlir::isa<cir::PointerType>(t) && "expected cir.ptr");
97 return getConstPtrAttr(t, 0);
98 }
99
100 mlir::TypedAttr getZeroInitAttr(mlir::Type ty) {
101 if (mlir::isa<cir::IntType>(ty))
102 return cir::IntAttr::get(ty, 0);
103 if (cir::isAnyFloatingPointType(ty))
104 return cir::FPAttr::getZero(ty);
105 if (auto complexType = mlir::dyn_cast<cir::ComplexType>(ty))
106 return cir::ZeroAttr::get(complexType);
107 if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
108 return cir::ZeroAttr::get(arrTy);
109 if (auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
110 return cir::ZeroAttr::get(vecTy);
111 if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
112 return getConstNullPtrAttr(ptrTy);
113 if (auto recordTy = mlir::dyn_cast<cir::RecordType>(ty))
114 return cir::ZeroAttr::get(recordTy);
115 if (mlir::isa<cir::BoolType>(ty)) {
116 return getFalseAttr();
117 }
118 llvm_unreachable("Zero initializer for given type is NYI");
119 }
120
121 cir::ConstantOp getBool(bool state, mlir::Location loc) {
122 return cir::ConstantOp::create(*this, loc, getCIRBoolAttr(state));
123 }
124 cir::ConstantOp getFalse(mlir::Location loc) { return getBool(false, loc); }
125 cir::ConstantOp getTrue(mlir::Location loc) { return getBool(true, loc); }
126
127 cir::BoolType getBoolTy() { return cir::BoolType::get(getContext()); }
128 cir::VoidType getVoidTy() { return cir::VoidType::get(getContext()); }
129
130 cir::PointerType getPointerTo(mlir::Type ty) {
131 return cir::PointerType::get(ty);
132 }
133
134 cir::PointerType getPointerTo(mlir::Type ty, cir::TargetAddressSpaceAttr as) {
135 return cir::PointerType::get(ty, as);
136 }
137
138 cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
139 if (langAS == clang::LangAS::Default) // Default address space.
140 return getPointerTo(ty);
141
142 if (clang::isTargetAddressSpace(langAS)) {
143 unsigned addrSpace = clang::toTargetAddressSpace(langAS);
144 auto asAttr = cir::TargetAddressSpaceAttr::get(
145 getContext(), getUI32IntegerAttr(addrSpace));
146 return getPointerTo(ty, asAttr);
147 }
148
149 llvm_unreachable("language-specific address spaces NYI");
150 }
151
153 return getPointerTo(cir::VoidType::get(getContext()), langAS);
154 }
155
156 cir::PointerType getVoidPtrTy(cir::TargetAddressSpaceAttr as) {
157 return getPointerTo(cir::VoidType::get(getContext()), as);
158 }
159
160 cir::BoolAttr getCIRBoolAttr(bool state) {
161 return cir::BoolAttr::get(getContext(), state);
162 }
163
164 cir::BoolAttr getTrueAttr() { return getCIRBoolAttr(true); }
165 cir::BoolAttr getFalseAttr() { return getCIRBoolAttr(false); }
166
167 mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real,
168 mlir::Value imag) {
169 auto resultComplexTy = cir::ComplexType::get(real.getType());
170 return cir::ComplexCreateOp::create(*this, loc, resultComplexTy, real,
171 imag);
172 }
173
174 mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand) {
175 auto resultType = operand.getType();
176 if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
177 resultType = complexResultType.getElementType();
178 return cir::ComplexRealOp::create(*this, loc, resultType, operand);
179 }
180
181 mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand) {
182 auto resultType = operand.getType();
183 if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
184 resultType = complexResultType.getElementType();
185 return cir::ComplexImagOp::create(*this, loc, resultType, operand);
186 }
187
188 cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
189 bool isVolatile = false, uint64_t alignment = 0) {
190 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
191 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
192 alignmentAttr, cir::MemOrderAttr{});
193 }
194
195 mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
196 uint64_t alignment) {
197 return createLoad(loc, ptr, /*isVolatile=*/false, alignment);
198 }
199
200 mlir::Value createNot(mlir::Value value) {
201 return cir::UnaryOp::create(*this, value.getLoc(), value.getType(),
202 cir::UnaryOpKind::Not, value);
203 }
204
205 /// Create a do-while operation.
206 cir::DoWhileOp createDoWhile(
207 mlir::Location loc,
208 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
209 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
210 return cir::DoWhileOp::create(*this, loc, condBuilder, bodyBuilder);
211 }
212
213 /// Create a while operation.
214 cir::WhileOp createWhile(
215 mlir::Location loc,
216 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
217 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
218 return cir::WhileOp::create(*this, loc, condBuilder, bodyBuilder);
219 }
220
221 /// Create a for operation.
222 cir::ForOp createFor(
223 mlir::Location loc,
224 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> condBuilder,
225 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
226 llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)> stepBuilder) {
227 return cir::ForOp::create(*this, loc, condBuilder, bodyBuilder,
228 stepBuilder);
229 }
230
231 /// Create a break operation.
232 cir::BreakOp createBreak(mlir::Location loc) {
233 return cir::BreakOp::create(*this, loc);
234 }
235
236 /// Create a continue operation.
237 cir::ContinueOp createContinue(mlir::Location loc) {
238 return cir::ContinueOp::create(*this, loc);
239 }
240
241 mlir::Value createUnaryOp(mlir::Location loc, cir::UnaryOpKind kind,
242 mlir::Value operand) {
243 return cir::UnaryOp::create(*this, loc, kind, operand);
244 }
245
246 mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) {
247 return cir::ConstPtrAttr::get(type, getI64IntegerAttr(value));
248 }
249
250 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
251 mlir::Type type, llvm::StringRef name,
252 mlir::IntegerAttr alignment,
253 mlir::Value dynAllocSize) {
254 return cir::AllocaOp::create(*this, loc, addrType, type, name, alignment,
255 dynAllocSize);
256 }
257
258 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
259 mlir::Type type, llvm::StringRef name,
260 clang::CharUnits alignment,
261 mlir::Value dynAllocSize) {
262 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
263 return createAlloca(loc, addrType, type, name, alignmentAttr, dynAllocSize);
264 }
265
266 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
267 mlir::Type type, llvm::StringRef name,
268 mlir::IntegerAttr alignment) {
269 return cir::AllocaOp::create(*this, loc, addrType, type, name, alignment);
270 }
271
272 mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
273 mlir::Type type, llvm::StringRef name,
274 clang::CharUnits alignment) {
275 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
276 return createAlloca(loc, addrType, type, name, alignmentAttr);
277 }
278
279 /// Get constant address of a global variable as an MLIR attribute.
280 /// This wrapper infers the attribute type through the global op.
281 cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp,
282 mlir::ArrayAttr indices = {}) {
283 cir::PointerType type = getPointerTo(globalOp.getSymType());
284 return getGlobalViewAttr(type, globalOp, indices);
285 }
286
287 /// Get constant address of a global variable as an MLIR attribute.
288 cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type,
289 cir::GlobalOp globalOp,
290 mlir::ArrayAttr indices = {}) {
291 auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr());
292 return cir::GlobalViewAttr::get(type, symbol, indices);
293 }
294
295 mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) {
297 return cir::GetGlobalOp::create(
298 *this, loc, getPointerTo(global.getSymType()), global.getSymName());
299 }
300
301 mlir::Value createGetGlobal(cir::GlobalOp global) {
302 return createGetGlobal(global.getLoc(), global);
303 }
304
305 /// Create a copy with inferred length.
306 cir::CopyOp createCopy(mlir::Value dst, mlir::Value src) {
307 return cir::CopyOp::create(*this, dst.getLoc(), dst, src);
308 }
309
310 cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
311 bool isVolatile = false,
312 mlir::IntegerAttr align = {},
313 cir::MemOrderAttr order = {}) {
314 return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order);
315 }
316
317 [[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
318 mlir::Location loc,
319 mlir::StringRef name,
320 mlir::Type type, bool isConstant,
321 cir::GlobalLinkageKind linkage) {
322 mlir::OpBuilder::InsertionGuard guard(*this);
323 setInsertionPointToStart(mlirModule.getBody());
324 return cir::GlobalOp::create(*this, loc, name, type, isConstant, linkage);
325 }
326
327 cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy,
328 mlir::Value base, llvm::StringRef name,
329 unsigned index) {
330 return cir::GetMemberOp::create(*this, loc, resultTy, base, name, index);
331 }
332
333 mlir::Value createDummyValue(mlir::Location loc, mlir::Type type,
334 clang::CharUnits alignment) {
335 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
336 auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
337 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
338 /*isVolatile=*/false, alignmentAttr,
339 /*mem_order=*/{});
340 }
341
342 cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
343 mlir::Value stride) {
344 return cir::PtrStrideOp::create(*this, loc, base.getType(), base, stride);
345 }
346
347 //===--------------------------------------------------------------------===//
348 // Call operators
349 //===--------------------------------------------------------------------===//
350
351 cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
352 mlir::Type returnType, mlir::ValueRange operands,
354 auto op = cir::CallOp::create(*this, loc, callee, returnType, operands);
355 op->setAttrs(attrs);
356 return op;
357 }
358
359 cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee,
360 mlir::ValueRange operands,
362 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
363 callee.getFunctionType().getReturnType(), operands,
364 attrs);
365 }
366
367 cir::CallOp
368 createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget,
369 cir::FuncType funcType, mlir::ValueRange operands,
371 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
372 resOperands.append(operands.begin(), operands.end());
373 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
374 resOperands, attrs);
375 }
376
377 cir::CallOp createTryCallOp(
378 mlir::Location loc, mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(),
379 mlir::Type returnType = cir::VoidType(),
380 mlir::ValueRange operands = mlir::ValueRange(),
381 [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
384 return createCallOp(loc, callee, returnType, operands);
385 }
386
387 cir::CallOp createTryCallOp(
388 mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands,
389 [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
392 return createTryCallOp(loc, mlir::SymbolRefAttr::get(callee),
393 callee.getFunctionType().getReturnType(), operands);
394 }
395
396 //===--------------------------------------------------------------------===//
397 // Cast/Conversion Operators
398 //===--------------------------------------------------------------------===//
399
400 mlir::Value createCast(mlir::Location loc, cir::CastKind kind,
401 mlir::Value src, mlir::Type newTy) {
402 if (newTy == src.getType())
403 return src;
404 return cir::CastOp::create(*this, loc, newTy, kind, src);
405 }
406
407 mlir::Value createCast(cir::CastKind kind, mlir::Value src,
408 mlir::Type newTy) {
409 if (newTy == src.getType())
410 return src;
411 return createCast(src.getLoc(), kind, src, newTy);
412 }
413
414 mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) {
415 return createCast(cir::CastKind::integral, src, newTy);
416 }
417
418 mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) {
419 return createCast(cir::CastKind::int_to_ptr, src, newTy);
420 }
421
422 mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) {
423 return createCast(cir::CastKind::ptr_to_int, src, newTy);
424 }
425
426 mlir::Value createPtrToBoolCast(mlir::Value v) {
427 return createCast(cir::CastKind::ptr_to_bool, v, getBoolTy());
428 }
429
430 mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
431 return createCast(cir::CastKind::bool_to_int, src, newTy);
432 }
433
434 mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) {
435 return createCast(cir::CastKind::bitcast, src, newTy);
436 }
437
438 mlir::Value createBitcast(mlir::Location loc, mlir::Value src,
439 mlir::Type newTy) {
440 return createCast(loc, cir::CastKind::bitcast, src, newTy);
441 }
442
443 mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy) {
444 assert(mlir::isa<cir::PointerType>(src.getType()) && "expected ptr src");
445 return createBitcast(src, getPointerTo(newPointeeTy));
446 }
447
448 //===--------------------------------------------------------------------===//
449 // Binary Operators
450 //===--------------------------------------------------------------------===//
451
452 mlir::Value createBinop(mlir::Location loc, mlir::Value lhs,
453 cir::BinOpKind kind, mlir::Value rhs) {
454 return cir::BinOp::create(*this, loc, lhs.getType(), kind, lhs, rhs);
455 }
456
457 mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
458 unsigned bits) {
459 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
460 auto type = cir::IntType::get(getContext(), size, /*isSigned=*/false);
461 return getConstAPInt(loc, type, val);
462 }
463
464 mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
465 return createBinop(loc, lhs, cir::BinOpKind::And, rhs);
466 }
467
468 mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
469 return createBinop(loc, lhs, cir::BinOpKind::Or, rhs);
470 }
471
472 mlir::Value createSelect(mlir::Location loc, mlir::Value condition,
473 mlir::Value trueValue, mlir::Value falseValue) {
474 assert(trueValue.getType() == falseValue.getType() &&
475 "trueValue and falseValue should have the same type");
476 return cir::SelectOp::create(*this, loc, trueValue.getType(), condition,
477 trueValue, falseValue);
478 }
479
480 mlir::Value createLogicalAnd(mlir::Location loc, mlir::Value lhs,
481 mlir::Value rhs) {
482 return createSelect(loc, lhs, rhs, getBool(false, loc));
483 }
484
485 mlir::Value createLogicalOr(mlir::Location loc, mlir::Value lhs,
486 mlir::Value rhs) {
487 return createSelect(loc, lhs, getBool(true, loc), rhs);
488 }
489
490 mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
492 auto op = cir::BinOp::create(*this, loc, lhs.getType(), cir::BinOpKind::Mul,
493 lhs, rhs);
494 op.setNoUnsignedWrap(
495 llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
496 op.setNoSignedWrap(
497 llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
498 return op;
499 }
500 mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs,
501 mlir::Value rhs) {
502 return createMul(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
503 }
504 mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs,
505 mlir::Value rhs) {
506 return createMul(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
507 }
508
509 mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
511 auto op = cir::BinOp::create(*this, loc, lhs.getType(), cir::BinOpKind::Sub,
512 lhs, rhs);
513 op.setNoUnsignedWrap(
514 llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
515 op.setNoSignedWrap(
516 llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
517 op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated));
518 return op;
519 }
520
521 mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs,
522 mlir::Value rhs) {
523 return createSub(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
524 }
525
526 mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs,
527 mlir::Value rhs) {
528 return createSub(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
529 }
530
531 mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
533 auto op = cir::BinOp::create(*this, loc, lhs.getType(), cir::BinOpKind::Add,
534 lhs, rhs);
535 op.setNoUnsignedWrap(
536 llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
537 op.setNoSignedWrap(
538 llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
539 op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated));
540 return op;
541 }
542
543 mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs,
544 mlir::Value rhs) {
545 return createAdd(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
546 }
547
548 mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs,
549 mlir::Value rhs) {
550 return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
551 }
552
553 cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind,
554 mlir::Value lhs, mlir::Value rhs) {
555 return cir::CmpOp::create(*this, loc, getBoolTy(), kind, lhs, rhs);
556 }
557
558 mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) {
559 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
560 }
561
562 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
563 bool isShiftLeft) {
564 return cir::ShiftOp::create(*this, loc, lhs.getType(), lhs, rhs,
565 isShiftLeft);
566 }
567
568 mlir::Value createShift(mlir::Location loc, mlir::Value lhs,
569 const llvm::APInt &rhs, bool isShiftLeft) {
570 return createShift(loc, lhs, getConstAPInt(loc, lhs.getType(), rhs),
571 isShiftLeft);
572 }
573
574 mlir::Value createShift(mlir::Location loc, mlir::Value lhs, unsigned bits,
575 bool isShiftLeft) {
576 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
577 auto shift = llvm::APInt(width, bits);
578 return createShift(loc, lhs, shift, isShiftLeft);
579 }
580
581 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
582 unsigned bits) {
583 return createShift(loc, lhs, bits, true);
584 }
585
586 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
587 unsigned bits) {
588 return createShift(loc, lhs, bits, false);
589 }
590
591 mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs,
592 mlir::Value rhs) {
593 return createShift(loc, lhs, rhs, true);
594 }
595
596 mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs,
597 mlir::Value rhs) {
598 return createShift(loc, lhs, rhs, false);
599 }
600
601 //
602 // Block handling helpers
603 // ----------------------
604 //
605 static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block) {
606 auto last =
607 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
608 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
609 });
610
611 if (last != block->rend())
612 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
613 return OpBuilder::InsertPoint(block, block->begin());
614 };
615
616 //
617 // Alignment and size helpers
618 //
619
620 // Note that mlir::IntegerType is used instead of cir::IntType here because we
621 // don't need sign information for these to be useful, so keep it simple.
622
623 // For 0 alignment, any overload of `getAlignmentAttr` returns an empty
624 // attribute.
625 mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment) {
626 return getAlignmentAttr(alignment.getQuantity());
627 }
628
629 mlir::IntegerAttr getAlignmentAttr(llvm::Align alignment) {
630 return getAlignmentAttr(alignment.value());
631 }
632
633 mlir::IntegerAttr getAlignmentAttr(int64_t alignment) {
634 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
635 }
636
637 mlir::IntegerAttr getSizeFromCharUnits(clang::CharUnits size) {
638 return getI64IntegerAttr(size.getQuantity());
639 }
640
641 /// Create a loop condition.
642 cir::ConditionOp createCondition(mlir::Value condition) {
643 return cir::ConditionOp::create(*this, condition.getLoc(), condition);
644 }
645
646 /// Create a yield operation.
647 cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value = {}) {
648 return cir::YieldOp::create(*this, loc, value);
649 }
650};
651
652} // namespace cir
653
654#endif
Provides definitions for the various language-specific address spaces.
__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::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.
cir::BreakOp createBreak(mlir::Location loc)
Create a break operation.
mlir::TypedAttr getConstNullPtrAttr(mlir::Type t)
mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global)
mlir::IntegerAttr getAlignmentAttr(int64_t alignment)
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)
cir::ConditionOp createCondition(mlir::Value condition)
Create a loop condition.
mlir::Value createLowBitsSet(mlir::Location loc, unsigned size, unsigned bits)
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::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)
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 createShiftLeft(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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)
cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={})
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)
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)
mlir::Value createGetGlobal(cir::GlobalOp global)
cir::PointerType getVoidPtrTy(cir::TargetAddressSpaceAttr as)
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::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, mlir::Type returnType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={})
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
cir::CallOp createTryCallOp(mlir::Location loc, mlir::SymbolRefAttr callee=mlir::SymbolRefAttr(), mlir::Type returnType=cir::VoidType(), mlir::ValueRange operands=mlir::ValueRange(), cir::SideEffect sideEffect=cir::SideEffect::All)
mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs, unsigned bits)
mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::Saturated)
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 createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS)
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
cir::CallOp createTryCallOp(mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands, cir::SideEffect sideEffect=cir::SideEffect::All)
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::GlobalOp createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc, mlir::StringRef name, mlir::Type type, bool isConstant, cir::GlobalLinkageKind linkage)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment)
mlir::Value createBinop(mlir::Location loc, mlir::Value lhs, cir::BinOpKind kind, mlir::Value rhs)
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)
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)
cir::CallOp createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget, cir::FuncType funcType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={})
CIRBaseBuilderTy(mlir::OpBuilder &builder)
cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, int64_t value)
mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real, mlir::Value imag)
cir::PointerType getPointerTo(mlir::Type ty, cir::TargetAddressSpaceAttr as)
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src)
Create a copy with inferred length.
mlir::Value createPtrToBoolCast(mlir::Value v)
cir::BoolAttr getTrueAttr()
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs, unsigned bits)
mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand)
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr, uint64_t alignment)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
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::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
mlir::Value createLogicalAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createUnaryOp(mlir::Location loc, cir::UnaryOpKind kind, mlir::Value operand)
mlir::IntegerAttr getAlignmentAttr(llvm::Align alignment)
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)
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)
OverflowBehavior
bool isTargetAddressSpace(LangAS AS)
unsigned toTargetAddressSpace(LangAS AS)
LangAS
Defines the address space values used by the address space qualifier of QualType.
static bool addressSpace()
static bool opCallSideEffect()
static bool opCallCallConv()