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) {}
86 llvm::RoundingMode::NearestTiesToEven;
90 const llvm::APInt &val) {
91 return cir::ConstantOp::create(*
this, loc, cir::IntAttr::get(typ, val));
94 cir::ConstantOp
getConstant(mlir::Location loc, mlir::TypedAttr attr) {
95 return cir::ConstantOp::create(*
this, loc, attr);
100 return getConstant(loc, cir::IntAttr::get(ty, value));
104 auto type = cir::IntType::get(getContext(), numBits,
true);
106 llvm::APInt(numBits, val,
true));
111 auto type = cir::IntType::get(getContext(), numBits,
false);
121 assert(mlir::isa<cir::PointerType>(t) &&
"expected cir.ptr");
126 return cir::DataMemberAttr::get(ty);
130 if (
auto bitFieldTy = mlir::dyn_cast<cir::BitFieldType>(ty)) {
131 assert(bitFieldTy.ownsBytes() &&
132 "a zero-width bit-field takes no initializer");
135 if (mlir::isa<cir::IntType>(ty))
136 return cir::IntAttr::get(ty, 0);
137 if (cir::isAnyFloatingPointType(ty))
138 return cir::FPAttr::getZero(ty);
139 if (
auto complexType = mlir::dyn_cast<cir::ComplexType>(ty))
140 return cir::ZeroAttr::get(complexType);
141 if (
auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
142 return cir::ZeroAttr::get(arrTy);
143 if (
auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
144 return cir::ZeroAttr::get(vecTy);
145 if (
auto matrixTy = mlir::dyn_cast<cir::MatrixType>(ty))
146 return cir::ZeroAttr::get(matrixTy);
147 if (
auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
149 if (
auto recordTy = mlir::dyn_cast<cir::RecordType>(ty))
150 return cir::ZeroAttr::get(recordTy);
151 if (
auto dataMemberTy = mlir::dyn_cast<cir::DataMemberType>(ty))
153 if (
auto methodTy = mlir::dyn_cast<cir::MethodType>(ty))
155 if (
auto vptrTy = mlir::dyn_cast<cir::VPtrType>(ty))
156 return cir::ZeroAttr::get(vptrTy);
157 if (mlir::isa<cir::BoolType>(ty)) {
161 llvm_unreachable(
"Zero initializer for given type is NYI");
164 cir::ConstantOp
getBool(
bool state, mlir::Location loc) {
165 return cir::ConstantOp::create(*
this, loc,
getCIRBoolAttr(state));
170 cir::BoolType
getBoolTy() {
return cir::BoolType::get(getContext()); }
171 cir::VoidType
getVoidTy() {
return cir::VoidType::get(getContext()); }
174 return cir::IntType::get(getContext(), n,
false);
178 if (
auto intType = mlir::dyn_cast<cir::IntTypeInterface>(eltTy))
179 return intType.getWidth();
180 if (
auto floatType = mlir::dyn_cast<cir::FPTypeInterface>(eltTy))
181 return floatType.getWidth();
183 llvm_unreachable(
"Unsupported type in getCIRIntOrFloatBitWidth");
186 return cir::IntType::get(getContext(), n,
true);
190 return cir::PointerType::get(ty);
194 mlir::ptr::MemorySpaceAttrInterface as) {
195 return cir::PointerType::get(ty, as);
202 mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr =
208 return getPointerTo(cir::VoidType::get(getContext()), langAS);
211 cir::PointerType
getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface as) {
212 return getPointerTo(cir::VoidType::get(getContext()), as);
215 cir::MethodAttr
getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
216 auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
217 return cir::MethodAttr::get(ty, methodFuncSymbolRef);
221 return cir::MethodAttr::get(ty);
225 return cir::BoolAttr::get(getContext(), state);
275 return cir::FastMathFlagsAttr::get(getContext(),
fastMathFlags);
287 cir::FPDynamicRoundingMode roundingMode;
289 case llvm::RoundingMode::NearestTiesToEven:
290 roundingMode = cir::FPDynamicRoundingMode::ToNearest;
292 case llvm::RoundingMode::TowardNegative:
293 roundingMode = cir::FPDynamicRoundingMode::Downward;
295 case llvm::RoundingMode::TowardPositive:
296 roundingMode = cir::FPDynamicRoundingMode::Upward;
298 case llvm::RoundingMode::TowardZero:
299 roundingMode = cir::FPDynamicRoundingMode::UpwardZero;
301 case llvm::RoundingMode::NearestTiesToAway:
302 roundingMode = cir::FPDynamicRoundingMode::ToNearestAway;
304 case llvm::RoundingMode::Dynamic:
305 roundingMode = cir::FPDynamicRoundingMode::Unknown;
308 llvm_unreachable(
"unexpected constrained rounding mode");
311 cir::FPExceptionMode exceptMode;
315 exceptMode = cir::FPExceptionMode::Masked;
316 strictExcept =
false;
319 exceptMode = cir::FPExceptionMode::Unknown;
320 strictExcept =
false;
323 exceptMode = cir::FPExceptionMode::Unknown;
327 llvm_unreachable(
"unexpected constrained exception mode");
330 return cir::FenvAttr::get(getContext(), roundingMode, exceptMode,
331 mlir::BoolAttr::get(getContext(), strictExcept));
336 auto resultComplexTy = cir::ComplexType::get(real.getType());
337 return cir::ComplexCreateOp::create(*
this, loc, resultComplexTy, real,
342 auto resultType = operand.getType();
343 if (
auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
344 resultType = complexResultType.getElementType();
345 return cir::ComplexRealOp::create(*
this, loc, resultType, operand);
349 auto resultType = operand.getType();
350 if (
auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
351 resultType = complexResultType.getElementType();
352 return cir::ComplexImagOp::create(*
this, loc, resultType, operand);
357 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
358 if (cir::isAnyFloatingPointType(complexTy.getElementType())) {
360 return cir::ComplexFAddOp::create(*
this, loc, lhs, rhs, fenv);
362 return cir::ComplexAddOp::create(*
this, loc, lhs, rhs);
367 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
368 if (cir::isAnyFloatingPointType(complexTy.getElementType())) {
370 return cir::ComplexFSubOp::create(*
this, loc, lhs, rhs, fenv);
372 return cir::ComplexSubOp::create(*
this, loc, lhs, rhs);
377 cir::ComplexRangeKind rangeKind) {
378 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
379 if (cir::isAnyFloatingPointType(complexTy.getElementType()))
380 return cir::ComplexFMulOp::create(*
this, loc, lhs, rhs, rangeKind);
381 return cir::ComplexMulOp::create(*
this, loc, lhs, rhs);
386 cir::ComplexRangeKind rangeKind) {
387 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
388 if (cir::isAnyFloatingPointType(complexTy.getElementType()))
389 return cir::ComplexFDivOp::create(*
this, loc, lhs, rhs, rangeKind);
390 return cir::ComplexDivOp::create(*
this, loc, lhs, rhs);
394 return cir::ComplexConjOp::create(*
this, loc, operand.getType(), operand);
398 bool isVolatile =
false, uint64_t alignment = 0,
399 bool isNontemporal =
false) {
401 return cir::LoadOp::create(*
this, loc, ptr,
false, isVolatile,
402 isNontemporal, alignmentAttr,
403 cir::SyncScopeKindAttr{}, cir::MemOrderAttr{},
408 uint64_t alignment) {
409 return createLoad(loc, ptr,
false, alignment);
412 mlir::Value
createNot(mlir::Location loc, mlir::Value value) {
413 return cir::NotOp::create(*
this, loc, value);
423 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
424 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
425 return cir::DoWhileOp::create(*
this, loc, condBuilder, bodyBuilder);
431 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
432 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
433 return cir::WhileOp::create(*
this, loc, condBuilder, bodyBuilder);
439 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
440 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
441 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)>
443 cir::CleanupKind cleanupKind) {
444 return cir::WhileOp::create(*
this, loc, condBuilder, bodyBuilder,
445 cleanupBuilder, cleanupKind);
451 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
452 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
453 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> stepBuilder) {
454 return cir::ForOp::create(*
this, loc, condBuilder, bodyBuilder,
461 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
462 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
463 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> stepBuilder,
464 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)>
466 cir::CleanupKind cleanupKind) {
467 return cir::ForOp::create(*
this, loc, condBuilder, bodyBuilder, stepBuilder,
468 cleanupBuilder, cleanupKind);
473 return cir::BreakOp::create(*
this, loc);
478 return cir::ContinueOp::create(*
this, loc);
481 mlir::Value
createInc(mlir::Location loc, mlir::Value input,
483 return cir::IncOp::create(*
this, loc, input, nsw);
486 mlir::Value
createDec(mlir::Location loc, mlir::Value input,
488 return cir::DecOp::create(*
this, loc, input, nsw);
493 return cir::MinusOp::create(*
this, loc, input, nsw);
497 return cir::ConstPtrAttr::get(type, getI64IntegerAttr(value));
500 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
501 llvm::StringRef name, mlir::IntegerAttr alignment,
502 mlir::Value dynAllocSize) {
503 return cir::AllocaOp::create(*
this, loc, addrType, name, alignment,
507 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
508 mlir::Type type, llvm::StringRef name,
510 mlir::Value dynAllocSize) {
512 return createAlloca(loc, addrType, name, alignmentAttr, dynAllocSize);
515 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
516 llvm::StringRef name, mlir::IntegerAttr alignment) {
517 return cir::AllocaOp::create(*
this, loc, addrType, name, alignment);
520 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
523 return createAlloca(loc, addrType, name, alignmentAttr);
529 mlir::ArrayAttr indices = {}) {
530 cir::PointerType type =
getPointerTo(globalOp.getSymType());
536 cir::GlobalOp globalOp,
537 mlir::ArrayAttr indices = {},
538 bool addressPoint =
false) {
539 auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr());
540 return cir::GlobalViewAttr::get(type, symbol, indices, addressPoint);
546 cir::GlobalOp globalOp,
548 bool addressPoint =
false) {
551 attrs.push_back(getI64IntegerAttr(ind));
552 mlir::ArrayAttr arAttr = mlir::ArrayAttr::get(getContext(), attrs);
557 bool threadLocal =
false) {
558 return cir::GetGlobalOp::create(
560 getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
561 global.getSymNameAttr(), threadLocal);
565 bool threadLocal =
false) {
571 bool isVolatile =
false,
572 bool skipTailPadding =
false) {
573 return cir::CopyOp::create(*
this, dst.getLoc(), dst, src,
575 isVolatile, skipTailPadding);
578 cir::StoreOp
createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
579 bool isVolatile =
false,
bool isNontemporal =
false,
580 mlir::IntegerAttr align = {},
581 cir::SyncScopeKindAttr scope = {},
582 cir::MemOrderAttr order = {}) {
583 if (mlir::cast<cir::PointerType>(dst.getType()).getPointee() !=
586 return cir::StoreOp::create(*
this, loc, val, dst, isVolatile, isNontemporal,
587 align, scope, order);
593 if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee())
599 mlir::Value flag =
getBool(val, loc);
603 [[nodiscard]] cir::GlobalOp
605 mlir::StringRef name, mlir::Type type,
bool isConstant,
606 cir::GlobalLinkageKind linkage,
607 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
608 mlir::OpBuilder::InsertionGuard guard(*
this);
609 setInsertionPointToStart(mlirModule.getBody());
610 return cir::GlobalOp::create(*
this, loc, name, type, isConstant, addrSpace,
615 mlir::Value base, llvm::StringRef name,
617 return cir::GetMemberOp::create(*
this, loc, resultTy, base, name, index);
624 return cir::LoadOp::create(*
this, loc, addr,
false,
632 mlir::Value stride) {
633 return cir::PtrStrideOp::create(*
this, loc, base.getType(), base, stride);
640 cir::CallOp
createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
641 mlir::Type returnType, mlir::ValueRange operands,
645 cir::CallingConv callingConv = cir::CallingConv::C) {
646 auto op = cir::CallOp::create(*
this, loc, callee, returnType, operands);
648 if (callingConv != cir::CallingConv::C)
649 op.setCallingConv(callingConv);
651 if (!argAttrs.empty()) {
652 llvm::SmallVector<mlir::Attribute> argDictAttrs;
653 argDictAttrs.reserve(argAttrs.size());
656 argAttrs, std::back_inserter(argDictAttrs),
657 [
this](llvm::ArrayRef<mlir::NamedAttribute> singleArgAttrs) {
658 return mlir::DictionaryAttr::get(getContext(), singleArgAttrs);
661 op.setArgAttrsAttr(mlir::ArrayAttr::get(getContext(), argDictAttrs));
664 if (!resAttrs.empty()) {
665 auto resultDictAttr = mlir::DictionaryAttr::get(getContext(), resAttrs);
666 op.setResAttrsAttr(mlir::ArrayAttr::get(getContext(), resultDictAttr));
672 mlir::ValueRange operands,
676 cir::CallingConv callingConv = cir::CallingConv::C) {
677 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
678 callee.getFunctionType().getReturnType(), operands,
679 attrs, argAttrs, resAttrs, callingConv);
684 cir::FuncType funcType, mlir::ValueRange operands,
688 cir::CallingConv callingConv = cir::CallingConv::C) {
689 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
690 resOperands.append(operands.begin(), operands.end());
692 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
693 resOperands, attrs, argAttrs, resAttrs, callingConv);
696 cir::CallOp
createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
697 mlir::ValueRange operands = mlir::ValueRange(),
701 return createCallOp(loc, callee, cir::VoidType(), operands, attrs, argAttrs,
710 mlir::Value src, mlir::Type newTy) {
711 if (newTy == src.getType())
713 return cir::CastOp::create(*
this, loc, newTy,
kind, src);
718 if (newTy == src.getType())
725 if (newTy == src.getType())
733 return createCast(cir::CastKind::integral, src, newTy);
738 return cir::BuiltinIntCastOp::create(*
this, loc, newTy, src);
746 return createCast(cir::CastKind::int_to_ptr, src, newTy);
750 return createCast(cir::CastKind::ptr_to_int, src, newTy);
758 return createCast(cir::CastKind::bool_to_int, src, newTy);
762 return createCast(cir::CastKind::bitcast, src, newTy);
767 return createCast(loc, cir::CastKind::bitcast, src, newTy);
771 assert(mlir::isa<cir::PointerType>(src.getType()) &&
"expected ptr src");
772 cir::PointerType srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
778 mlir::Value nullPtr =
getNullPtr(ptr.getType(), ptr.getLoc());
779 return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr);
783 mlir::Value nullPtr =
getNullPtr(ptr.getType(), ptr.getLoc());
784 return createCompare(ptr.getLoc(), cir::CmpOpKind::ne, ptr, nullPtr);
789 return createCast(loc, cir::CastKind::address_space, src, newTy);
804 return cir::VecExtractOp::create(*
this, loc, vec, idxVal);
808 mlir::Value newElt, uint64_t idx) {
811 return cir::VecInsertOp::create(*
this, loc, vec, newElt, idxVal);
815 auto resTy = cir::BoolType::get(getContext());
816 return cir::SignBitOp::create(*
this, loc, resTy, val);
825 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
826 auto type = cir::IntType::get(getContext(), size,
false);
830 mlir::Value
createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
831 return cir::AndOp::create(*
this, loc, lhs, rhs);
834 mlir::Value
createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
835 return cir::OrOp::create(*
this, loc, lhs, rhs);
839 mlir::Value trueValue, mlir::Value falseValue) {
840 assert(trueValue.getType() == falseValue.getType() &&
841 "trueValue and falseValue should have the same type");
842 return cir::SelectOp::create(*
this, loc, trueValue.getType(),
condition,
843 trueValue, falseValue);
856 mlir::Value
createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
858 auto op = cir::MulOp::create(*
this, loc, lhs, rhs);
872 mlir::Value
createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
874 auto op = cir::SubOp::create(*
this, loc, lhs, rhs);
891 mlir::Value
createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
893 auto op = cir::AddOp::create(*
this, loc, lhs, rhs);
910 mlir::Value
createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
911 return cir::DivOp::create(*
this, loc, lhs, rhs);
914 mlir::Value
createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
915 return cir::RemOp::create(*
this, loc, lhs, rhs);
918 template <
typename OpTy>
926 mlir::Value
createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
930 mlir::Value
createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
934 mlir::Value
createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
938 mlir::Value
createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
942 mlir::Value
createFRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
946 mlir::Value
createFNeg(mlir::Location loc, mlir::Value operand) {
947 assert(cir::isFPOrVectorOfFPType(operand.getType()) &&
948 "expected floating-point or vector-of-float type");
953 return cir::FNegOp::create(*
this, loc, operand);
956 mlir::Value
createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
957 return cir::XorOp::create(*
this, loc, lhs, rhs);
960 mlir::Value
createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
961 return cir::MaxOp::create(*
this, loc, lhs, rhs);
964 mlir::Value
createMin(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
965 return cir::MinOp::create(*
this, loc, lhs, rhs);
969 mlir::Value lhs, mlir::Value rhs) {
971 if (cir::isAnyFloatingPointType(lhs.getType()))
973 return cir::CmpOp::create(*
this, loc,
kind, lhs, rhs, fenv);
981 mlir::Value lhs, mlir::Value rhs) {
982 VectorType vecCast = mlir::cast<VectorType>(lhs.getType());
983 mlir::Type elemTy = vecCast.getElementType();
984 assert(!(mlir::isa<cir::FPTypeInterface>(elemTy) &&
985 &mlir::cast<cir::FPTypeInterface>(elemTy).getFloatSemantics() ==
986 &llvm::APFloat::x87DoubleExtended()) &&
987 "an FP80 vector compare must name its result type");
990 cir::VectorType::get(integralTy, vecCast.getSize()),
999 cir::CmpOpKind
kind, mlir::Value lhs,
1001 assert(mlir::cast<VectorType>(lhs.getType()).getSize() ==
1002 resultTy.getSize() &&
1003 cir::isIntOrBoolType(resultTy.getElementType()) &&
1004 "vector compare result must be an int or bool vector of the "
1007 if (cir::isFPOrVectorOfFPType(lhs.getType()))
1009 return cir::VecCmpOp::create(*
this, loc, resultTy,
kind, lhs, rhs, fenv);
1013 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
1016 mlir::Value
createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
1018 return cir::ShiftOp::create(*
this, loc, lhs.getType(), lhs, rhs,
1023 const llvm::APInt &rhs,
bool isShiftLeft) {
1028 mlir::Value
createShift(mlir::Location loc, mlir::Value lhs,
unsigned bits,
1030 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
1031 auto shift = llvm::APInt(width, bits);
1057 return cir::FuncType::get(llvm::to_vector(argTypes),
getVoidTy());
1071 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
1072 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
1075 if (last != block->rend())
1076 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
1077 return OpBuilder::InsertPoint(block, block->begin());
1098 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
1124 cir::YieldOp
createYield(mlir::Location loc, mlir::ValueRange value = {}) {
1125 return cir::YieldOp::create(*
this, loc, value);
1134 mlir::Value objectPtr) {
1137 mlir::cast<cir::MethodType>(method.getType()).getMemberFuncTy();
1138 auto methodFuncInputTypes = methodFuncTy.getInputs();
1140 auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
1141 mlir::Type adjustedThisTy =
getVoidPtrTy(objectPtrTy.getAddrSpace());
1146 if (methodFuncInputTypes.size() > 1)
1147 calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
1148 methodFuncInputTypes.begin() + 1,
1149 methodFuncInputTypes.end());
1150 cir::FuncType calleeFuncTy =
1151 methodFuncTy.clone(calleeFuncInputTypes, methodFuncTy.getReturnType());
1154 cir::PointerType calleeTy =
getPointerTo(calleeFuncTy);
1156 auto op = cir::GetMethodOp::create(*
this, loc, calleeTy, adjustedThisTy,
1158 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::FloatType getTF32Type()=delete
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::FastMathFlags getFastMathFlags() const
Get the fast-math flags attached to floating-point operations.
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::FloatType getF80Type()=delete
mlir::Value createPtrIsNull(mlir::Value ptr)
mlir::Value createShiftLeft(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createFPBinOp(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.
mlir::FloatType getF64Type()=delete
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)
mlir::FloatType getF16Type()=delete
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
cir::FastMathFlagsAttr getFastMathFlagsAttr()
Returns a null attribute when no fast-math flags are set.
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::FloatType getF32Type()=delete
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)
cir::FastMathFlags fastMathFlags
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::FloatType getBF16Type()=delete
mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::FloatType getF128Type()=delete
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)
void setFastMathFlags(cir::FastMathFlags flags)
Set the fast-math flags attached to floating-point operations.
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.
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
static bool metaDataNode()
static bool addressSpace()
static bool targetCodeGenInfoGetNullPointer()
static bool fastMathFlags()