9#ifndef LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
10#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
19#include "llvm/ADT/STLForwardCompat.h"
20#include "llvm/IR/FPEnv.h"
21#include "llvm/Support/ErrorHandling.h"
23#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
24#include "mlir/IR/Builders.h"
25#include "mlir/IR/BuiltinAttributes.h"
26#include "mlir/IR/Location.h"
27#include "mlir/IR/OperationSupport.h"
28#include "mlir/IR/Types.h"
41 llvm::to_underlying(b));
46 llvm::to_underlying(b));
69 :
mlir::OpBuilder(&mlirContext) {}
76 llvm::RoundingMode::NearestTiesToEven;
79 const llvm::APInt &val) {
80 return cir::ConstantOp::create(*
this, loc, cir::IntAttr::get(typ, val));
83 cir::ConstantOp
getConstant(mlir::Location loc, mlir::TypedAttr attr) {
84 return cir::ConstantOp::create(*
this, loc, attr);
89 return getConstant(loc, cir::IntAttr::get(ty, value));
92 mlir::Value
getSignedInt(mlir::Location loc, int64_t val,
unsigned numBits) {
93 auto type = cir::IntType::get(getContext(), numBits,
true);
95 llvm::APInt(numBits, val,
true));
100 auto type = cir::IntType::get(getContext(), numBits,
false);
110 assert(mlir::isa<cir::PointerType>(t) &&
"expected cir.ptr");
115 return cir::DataMemberAttr::get(ty);
119 if (
auto bitFieldTy = mlir::dyn_cast<cir::BitFieldType>(ty)) {
120 assert(bitFieldTy.ownsBytes() &&
121 "a zero-width bit-field takes no initializer");
124 if (mlir::isa<cir::IntType>(ty))
125 return cir::IntAttr::get(ty, 0);
126 if (cir::isAnyFloatingPointType(ty))
127 return cir::FPAttr::getZero(ty);
128 if (
auto complexType = mlir::dyn_cast<cir::ComplexType>(ty))
129 return cir::ZeroAttr::get(complexType);
130 if (
auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
131 return cir::ZeroAttr::get(arrTy);
132 if (
auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
133 return cir::ZeroAttr::get(vecTy);
134 if (
auto matrixTy = mlir::dyn_cast<cir::MatrixType>(ty))
135 return cir::ZeroAttr::get(matrixTy);
136 if (
auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
138 if (
auto recordTy = mlir::dyn_cast<cir::RecordType>(ty))
139 return cir::ZeroAttr::get(recordTy);
140 if (
auto dataMemberTy = mlir::dyn_cast<cir::DataMemberType>(ty))
142 if (
auto methodTy = mlir::dyn_cast<cir::MethodType>(ty))
144 if (
auto vptrTy = mlir::dyn_cast<cir::VPtrType>(ty))
145 return cir::ZeroAttr::get(vptrTy);
146 if (mlir::isa<cir::BoolType>(ty)) {
150 llvm_unreachable(
"Zero initializer for given type is NYI");
153 cir::ConstantOp
getBool(
bool state, mlir::Location loc) {
154 return cir::ConstantOp::create(*
this, loc,
getCIRBoolAttr(state));
159 cir::BoolType
getBoolTy() {
return cir::BoolType::get(getContext()); }
160 cir::VoidType
getVoidTy() {
return cir::VoidType::get(getContext()); }
163 return cir::IntType::get(getContext(), n,
false);
167 if (
auto intType = mlir::dyn_cast<cir::IntTypeInterface>(eltTy))
168 return intType.getWidth();
169 if (
auto floatType = mlir::dyn_cast<cir::FPTypeInterface>(eltTy))
170 return floatType.getWidth();
172 llvm_unreachable(
"Unsupported type in getCIRIntOrFloatBitWidth");
175 return cir::IntType::get(getContext(), n,
true);
179 return cir::PointerType::get(ty);
183 mlir::ptr::MemorySpaceAttrInterface as) {
184 return cir::PointerType::get(ty, as);
191 mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr =
197 return getPointerTo(cir::VoidType::get(getContext()), langAS);
200 cir::PointerType
getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface as) {
201 return getPointerTo(cir::VoidType::get(getContext()), as);
204 cir::MethodAttr
getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
205 auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
206 return cir::MethodAttr::get(ty, methodFuncSymbolRef);
210 return cir::MethodAttr::get(ty);
214 return cir::BoolAttr::get(getContext(), state);
263 cir::FPDynamicRoundingMode roundingMode;
265 case llvm::RoundingMode::NearestTiesToEven:
266 roundingMode = cir::FPDynamicRoundingMode::ToNearest;
268 case llvm::RoundingMode::TowardNegative:
269 roundingMode = cir::FPDynamicRoundingMode::Downward;
271 case llvm::RoundingMode::TowardPositive:
272 roundingMode = cir::FPDynamicRoundingMode::Upward;
274 case llvm::RoundingMode::TowardZero:
275 roundingMode = cir::FPDynamicRoundingMode::UpwardZero;
277 case llvm::RoundingMode::NearestTiesToAway:
278 roundingMode = cir::FPDynamicRoundingMode::ToNearestAway;
280 case llvm::RoundingMode::Dynamic:
281 roundingMode = cir::FPDynamicRoundingMode::Unknown;
284 llvm_unreachable(
"unexpected constrained rounding mode");
287 cir::FPExceptionMode exceptMode;
291 exceptMode = cir::FPExceptionMode::Masked;
292 strictExcept =
false;
295 exceptMode = cir::FPExceptionMode::Unknown;
296 strictExcept =
false;
299 exceptMode = cir::FPExceptionMode::Unknown;
303 llvm_unreachable(
"unexpected constrained exception mode");
306 return cir::FenvAttr::get(getContext(), roundingMode, exceptMode,
307 mlir::BoolAttr::get(getContext(), strictExcept));
312 auto resultComplexTy = cir::ComplexType::get(real.getType());
313 return cir::ComplexCreateOp::create(*
this, loc, resultComplexTy, real,
318 auto resultType = operand.getType();
319 if (
auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
320 resultType = complexResultType.getElementType();
321 return cir::ComplexRealOp::create(*
this, loc, resultType, operand);
325 auto resultType = operand.getType();
326 if (
auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
327 resultType = complexResultType.getElementType();
328 return cir::ComplexImagOp::create(*
this, loc, resultType, operand);
333 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
334 if (cir::isAnyFloatingPointType(complexTy.getElementType())) {
336 return cir::ComplexFAddOp::create(*
this, loc, lhs, rhs, fenv);
338 return cir::ComplexAddOp::create(*
this, loc, lhs, rhs);
343 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
344 if (cir::isAnyFloatingPointType(complexTy.getElementType())) {
346 return cir::ComplexFSubOp::create(*
this, loc, lhs, rhs, fenv);
348 return cir::ComplexSubOp::create(*
this, loc, lhs, rhs);
353 cir::ComplexRangeKind rangeKind) {
354 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
355 if (cir::isAnyFloatingPointType(complexTy.getElementType()))
356 return cir::ComplexFMulOp::create(*
this, loc, lhs, rhs, rangeKind);
357 return cir::ComplexMulOp::create(*
this, loc, lhs, rhs);
362 cir::ComplexRangeKind rangeKind) {
363 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
364 if (cir::isAnyFloatingPointType(complexTy.getElementType()))
365 return cir::ComplexFDivOp::create(*
this, loc, lhs, rhs, rangeKind);
366 return cir::ComplexDivOp::create(*
this, loc, lhs, rhs);
370 return cir::ComplexConjOp::create(*
this, loc, operand.getType(), operand);
374 bool isVolatile =
false, uint64_t alignment = 0,
375 bool isNontemporal =
false) {
377 return cir::LoadOp::create(*
this, loc, ptr,
false, isVolatile,
378 isNontemporal, alignmentAttr,
379 cir::SyncScopeKindAttr{}, cir::MemOrderAttr{},
384 uint64_t alignment) {
385 return createLoad(loc, ptr,
false, alignment);
388 mlir::Value
createNot(mlir::Location loc, mlir::Value value) {
389 return cir::NotOp::create(*
this, loc, value);
399 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
400 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
401 return cir::DoWhileOp::create(*
this, loc, condBuilder, bodyBuilder);
407 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
408 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
409 return cir::WhileOp::create(*
this, loc, condBuilder, bodyBuilder);
415 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
416 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
417 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)>
419 cir::CleanupKind cleanupKind) {
420 return cir::WhileOp::create(*
this, loc, condBuilder, bodyBuilder,
421 cleanupBuilder, cleanupKind);
427 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
428 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
429 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> stepBuilder) {
430 return cir::ForOp::create(*
this, loc, condBuilder, bodyBuilder,
437 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
438 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
439 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> stepBuilder,
440 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)>
442 cir::CleanupKind cleanupKind) {
443 return cir::ForOp::create(*
this, loc, condBuilder, bodyBuilder, stepBuilder,
444 cleanupBuilder, cleanupKind);
449 return cir::BreakOp::create(*
this, loc);
454 return cir::ContinueOp::create(*
this, loc);
457 mlir::Value
createInc(mlir::Location loc, mlir::Value input,
459 return cir::IncOp::create(*
this, loc, input, nsw);
462 mlir::Value
createDec(mlir::Location loc, mlir::Value input,
464 return cir::DecOp::create(*
this, loc, input, nsw);
469 return cir::MinusOp::create(*
this, loc, input, nsw);
473 return cir::ConstPtrAttr::get(type, getI64IntegerAttr(value));
476 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
477 llvm::StringRef name, mlir::IntegerAttr alignment,
478 mlir::Value dynAllocSize) {
479 return cir::AllocaOp::create(*
this, loc, addrType, name, alignment,
483 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
484 mlir::Type type, llvm::StringRef name,
486 mlir::Value dynAllocSize) {
488 return createAlloca(loc, addrType, name, alignmentAttr, dynAllocSize);
491 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
492 llvm::StringRef name, mlir::IntegerAttr alignment) {
493 return cir::AllocaOp::create(*
this, loc, addrType, name, alignment);
496 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
499 return createAlloca(loc, addrType, name, alignmentAttr);
505 mlir::ArrayAttr indices = {}) {
506 cir::PointerType type =
getPointerTo(globalOp.getSymType());
512 cir::GlobalOp globalOp,
513 mlir::ArrayAttr indices = {},
514 bool addressPoint =
false) {
515 auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr());
516 return cir::GlobalViewAttr::get(type, symbol, indices, addressPoint);
522 cir::GlobalOp globalOp,
524 bool addressPoint =
false) {
526 for (int64_t ind : indices)
527 attrs.push_back(getI64IntegerAttr(ind));
528 mlir::ArrayAttr arAttr = mlir::ArrayAttr::get(getContext(), attrs);
533 bool threadLocal =
false) {
534 return cir::GetGlobalOp::create(
536 getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
537 global.getSymNameAttr(), threadLocal);
541 bool threadLocal =
false) {
547 bool isVolatile =
false,
548 bool skipTailPadding =
false) {
549 return cir::CopyOp::create(*
this, dst.getLoc(), dst, src,
551 isVolatile, skipTailPadding);
554 cir::StoreOp
createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
555 bool isVolatile =
false,
bool isNontemporal =
false,
556 mlir::IntegerAttr align = {},
557 cir::SyncScopeKindAttr scope = {},
558 cir::MemOrderAttr order = {}) {
559 if (mlir::cast<cir::PointerType>(dst.getType()).getPointee() !=
562 return cir::StoreOp::create(*
this, loc, val, dst, isVolatile, isNontemporal,
563 align, scope, order);
569 if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee())
575 mlir::Value flag =
getBool(val, loc);
579 [[nodiscard]] cir::GlobalOp
581 mlir::StringRef name, mlir::Type type,
bool isConstant,
582 cir::GlobalLinkageKind linkage,
583 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
584 mlir::OpBuilder::InsertionGuard guard(*
this);
585 setInsertionPointToStart(mlirModule.getBody());
586 return cir::GlobalOp::create(*
this, loc, name, type, isConstant, addrSpace,
591 mlir::Value base, llvm::StringRef name,
593 return cir::GetMemberOp::create(*
this, loc, resultTy, base, name, index);
600 return cir::LoadOp::create(*
this, loc, addr,
false,
608 mlir::Value stride) {
609 return cir::PtrStrideOp::create(*
this, loc, base.getType(), base, stride);
616 cir::CallOp
createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
617 mlir::Type returnType, mlir::ValueRange operands,
621 cir::CallingConv callingConv = cir::CallingConv::C) {
622 auto op = cir::CallOp::create(*
this, loc, callee, returnType, operands);
624 if (callingConv != cir::CallingConv::C)
625 op.setCallingConv(callingConv);
627 if (!argAttrs.empty()) {
628 llvm::SmallVector<mlir::Attribute> argDictAttrs;
629 argDictAttrs.reserve(argAttrs.size());
632 argAttrs, std::back_inserter(argDictAttrs),
633 [
this](llvm::ArrayRef<mlir::NamedAttribute> singleArgAttrs) {
634 return mlir::DictionaryAttr::get(getContext(), singleArgAttrs);
637 op.setArgAttrsAttr(mlir::ArrayAttr::get(getContext(), argDictAttrs));
640 if (!resAttrs.empty()) {
641 auto resultDictAttr = mlir::DictionaryAttr::get(getContext(), resAttrs);
642 op.setResAttrsAttr(mlir::ArrayAttr::get(getContext(), resultDictAttr));
648 mlir::ValueRange operands,
652 cir::CallingConv callingConv = cir::CallingConv::C) {
653 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
654 callee.getFunctionType().getReturnType(), operands,
655 attrs, argAttrs, resAttrs, callingConv);
660 cir::FuncType funcType, mlir::ValueRange operands,
664 cir::CallingConv callingConv = cir::CallingConv::C) {
665 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
666 resOperands.append(operands.begin(), operands.end());
668 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
669 resOperands, attrs, argAttrs, resAttrs, callingConv);
672 cir::CallOp
createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
673 mlir::ValueRange operands = mlir::ValueRange(),
677 return createCallOp(loc, callee, cir::VoidType(), operands, attrs, argAttrs,
686 mlir::Value src, mlir::Type newTy) {
687 if (newTy == src.getType())
689 return cir::CastOp::create(*
this, loc, newTy,
kind, src);
694 if (newTy == src.getType())
701 if (newTy == src.getType())
709 return createCast(cir::CastKind::integral, src, newTy);
714 return cir::BuiltinIntCastOp::create(*
this, loc, newTy, src);
722 return createCast(cir::CastKind::int_to_ptr, src, newTy);
726 return createCast(cir::CastKind::ptr_to_int, src, newTy);
734 return createCast(cir::CastKind::bool_to_int, src, newTy);
738 return createCast(cir::CastKind::bitcast, src, newTy);
743 return createCast(loc, cir::CastKind::bitcast, src, newTy);
747 assert(mlir::isa<cir::PointerType>(src.getType()) &&
"expected ptr src");
748 cir::PointerType srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
754 mlir::Value nullPtr =
getNullPtr(ptr.getType(), ptr.getLoc());
755 return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr);
759 mlir::Value nullPtr =
getNullPtr(ptr.getType(), ptr.getLoc());
760 return createCompare(ptr.getLoc(), cir::CmpOpKind::ne, ptr, nullPtr);
765 return createCast(loc, cir::CastKind::address_space, src, newTy);
780 return cir::VecExtractOp::create(*
this, loc, vec, idxVal);
784 mlir::Value newElt, uint64_t idx) {
787 return cir::VecInsertOp::create(*
this, loc, vec, newElt, idxVal);
791 auto resTy = cir::BoolType::get(getContext());
792 return cir::SignBitOp::create(*
this, loc, resTy, val);
801 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
802 auto type = cir::IntType::get(getContext(), size,
false);
806 mlir::Value
createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
807 return cir::AndOp::create(*
this, loc, lhs, rhs);
810 mlir::Value
createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
811 return cir::OrOp::create(*
this, loc, lhs, rhs);
815 mlir::Value trueValue, mlir::Value falseValue) {
816 assert(trueValue.getType() == falseValue.getType() &&
817 "trueValue and falseValue should have the same type");
818 return cir::SelectOp::create(*
this, loc, trueValue.getType(),
condition,
819 trueValue, falseValue);
832 mlir::Value
createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
834 auto op = cir::MulOp::create(*
this, loc, lhs, rhs);
848 mlir::Value
createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
850 auto op = cir::SubOp::create(*
this, loc, lhs, rhs);
867 mlir::Value
createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
869 auto op = cir::AddOp::create(*
this, loc, lhs, rhs);
886 mlir::Value
createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
887 return cir::DivOp::create(*
this, loc, lhs, rhs);
890 mlir::Value
createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
891 return cir::RemOp::create(*
this, loc, lhs, rhs);
894 mlir::Value
createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
900 mlir::Value
createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
906 mlir::Value
createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
912 mlir::Value
createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
918 mlir::Value
createFRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
924 mlir::Value
createFNeg(mlir::Location loc, mlir::Value operand) {
925 assert(cir::isFPOrVectorOfFPType(operand.getType()) &&
926 "expected floating-point or vector-of-float type");
931 return cir::FNegOp::create(*
this, loc, operand);
934 mlir::Value
createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
935 return cir::XorOp::create(*
this, loc, lhs, rhs);
938 mlir::Value
createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
939 return cir::MaxOp::create(*
this, loc, lhs, rhs);
942 mlir::Value
createMin(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
943 return cir::MinOp::create(*
this, loc, lhs, rhs);
947 mlir::Value lhs, mlir::Value rhs) {
949 if (cir::isAnyFloatingPointType(lhs.getType()))
951 return cir::CmpOp::create(*
this, loc,
kind, lhs, rhs, fenv);
959 mlir::Value lhs, mlir::Value rhs) {
960 VectorType vecCast = mlir::cast<VectorType>(lhs.getType());
961 mlir::Type elemTy = vecCast.getElementType();
962 assert(!(mlir::isa<cir::FPTypeInterface>(elemTy) &&
963 &mlir::cast<cir::FPTypeInterface>(elemTy).getFloatSemantics() ==
964 &llvm::APFloat::x87DoubleExtended()) &&
965 "an FP80 vector compare must name its result type");
968 cir::VectorType::get(integralTy, vecCast.getSize()),
977 cir::CmpOpKind
kind, mlir::Value lhs,
979 assert(mlir::cast<VectorType>(lhs.getType()).getSize() ==
980 resultTy.getSize() &&
981 cir::isIntOrBoolType(resultTy.getElementType()) &&
982 "vector compare result must be an int or bool vector of the "
985 if (cir::isFPOrVectorOfFPType(lhs.getType()))
987 return cir::VecCmpOp::create(*
this, loc, resultTy,
kind, lhs, rhs, fenv);
990 mlir::Value
createIsNaN(mlir::Location loc, mlir::Value operand) {
991 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
994 mlir::Value
createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
996 return cir::ShiftOp::create(*
this, loc, lhs.getType(), lhs, rhs,
1001 const llvm::APInt &rhs,
bool isShiftLeft) {
1006 mlir::Value
createShift(mlir::Location loc, mlir::Value lhs,
unsigned bits,
1008 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
1009 auto shift = llvm::APInt(width, bits);
1035 return cir::FuncType::get(llvm::to_vector(argTypes),
getVoidTy());
1049 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
1050 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
1053 if (last != block->rend())
1054 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
1055 return OpBuilder::InsertPoint(block, block->begin());
1076 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
1102 cir::YieldOp
createYield(mlir::Location loc, mlir::ValueRange value = {}) {
1103 return cir::YieldOp::create(*
this, loc, value);
1112 mlir::Value objectPtr) {
1115 mlir::cast<cir::MethodType>(method.getType()).getMemberFuncTy();
1116 auto methodFuncInputTypes = methodFuncTy.getInputs();
1118 auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
1119 mlir::Type adjustedThisTy =
getVoidPtrTy(objectPtrTy.getAddrSpace());
1124 if (methodFuncInputTypes.size() > 1)
1125 calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
1126 methodFuncInputTypes.begin() + 1,
1127 methodFuncInputTypes.end());
1128 cir::FuncType calleeFuncTy =
1129 methodFuncTy.clone(calleeFuncInputTypes, methodFuncTy.getReturnType());
1132 cir::PointerType calleeTy =
getPointerTo(calleeFuncTy);
1134 auto op = cir::GetMethodOp::create(*
this, loc, calleeTy, adjustedThisTy,
1136 return {op.getCallee(), op.getAdjustedThis()};
Provides definitions for the various language-specific address spaces.
Defines the clang::LangOptions interface.
*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)
mlir::Value createComplexMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, cir::ComplexRangeKind rangeKind)
cir::VecCmpOp createVecCompare(mlir::Location loc, VectorType resultTy, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
Compares lhs and rhs element-wise, producing resultTy, which must be a vector of integers or bools wi...
cir::BreakOp createBreak(mlir::Location loc)
Create a break operation.
mlir::TypedAttr getConstNullPtrAttr(mlir::Type t)
cir::FenvAttr getConstrainedFPAttr()
Build the #cir.fenv attribute describing the constrained floating-point environment currently in effe...
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)
mlir::Value createBuiltinIntCast(mlir::Value src, mlir::Type newTy)
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.
clang::LangOptions::FPExceptionModeKind getDefaultConstrainedExcept() const
Get the exception handling used with constrained floating point.
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::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, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> cleanupBuilder, cir::CleanupKind cleanupKind)
Create a for operation with a per-iteration cleanup region.
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.
cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, mlir::ArrayAttr indices={}, bool addressPoint=false)
Get constant address of a global variable as an MLIR attribute.
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 createComplexSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, llvm::StringRef name, clang::CharUnits alignment)
mlir::Value createNot(mlir::Value value)
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={}, cir::CallingConv callingConv=cir::CallingConv::C)
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::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::CallingConv callingConv=cir::CallingConv::C)
cir::GetGlobalOp createGetGlobal(cir::GlobalOp global, bool threadLocal=false)
cir::IntType getUIntNTy(int n)
mlir::Value createComplexDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, cir::ComplexRangeKind rangeKind)
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)
cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr, bool isVolatile=false, uint64_t alignment=0, bool isNontemporal=false)
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)
cir::WhileOp createWhile(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)> cleanupBuilder, cir::CleanupKind cleanupKind)
Create a while operation with a per-iteration cleanup region.
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)
Compares lhs and rhs element-wise.
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
mlir::Value createInsertElement(mlir::Location loc, mlir::Value vec, mlir::Value newElt, uint64_t idx)
cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, llvm::ArrayRef< int64_t > indices, bool addressPoint=false)
Get constant address of a global variable as an MLIR attribute.
llvm::RoundingMode defaultConstrainedRounding
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)
mlir::Value createBuiltinIntCast(mlir::Location loc, mlir::Value src, mlir::Type newTy)
clang::LangOptions::FPExceptionModeKind defaultConstrainedExcept
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::CallingConv callingConv=cir::CallingConv::C)
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)
void setIsFPConstrained(bool isCon)
Enable/Disable use of constrained floating point math.
mlir::Value createMin(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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.
llvm::RoundingMode getDefaultConstrainedRounding() const
Get the rounding mode handling used with constrained floating point.
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)
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::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)
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)
void setDefaultConstrainedExcept(clang::LangOptions::FPExceptionModeKind newExcept)
Set the exception handling to be used with constrained floating point.
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr, uint64_t alignment)
bool getIsFPConstrained() const
Query for the use of constrained floating point math.
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
mlir::Value createAddrSpaceCast(mlir::Location loc, mlir::Value src, mlir::Type newTy)
mlir::Value createDummyValue(mlir::Location loc, mlir::Type type, clang::CharUnits alignment)
cir::BoolAttr getFalseAttr()
void setDefaultConstrainedRounding(llvm::RoundingMode newRounding)
Set the rounding mode handling to be used with constrained floating point.
mlir::Value createShiftRight(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::LoadOp createFlagLoad(mlir::Location loc, mlir::Value addr)
Emit a load from an boolean flag variable.
cir::BoolType getBoolTy()
mlir::Value createComplexAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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)
This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
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.
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 fastMathFlags()