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