9#ifndef LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
10#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
19#include "llvm/ADT/BitmaskEnum.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"
48 :
mlir::OpBuilder(&mlirContext) {}
65 llvm::RoundingMode::NearestTiesToEven;
69 const llvm::APInt &val) {
70 return cir::ConstantOp::create(*
this, loc, cir::IntAttr::get(typ, val));
73 cir::ConstantOp
getConstant(mlir::Location loc, mlir::TypedAttr attr) {
74 return cir::ConstantOp::create(*
this, loc, attr);
79 return getConstant(loc, cir::IntAttr::get(ty, value));
83 auto type = cir::IntType::get(getContext(), numBits,
true);
85 llvm::APInt(numBits, val,
true));
90 auto type = cir::IntType::get(getContext(), numBits,
false);
100 assert(mlir::isa<cir::PointerType>(t) &&
"expected cir.ptr");
105 return cir::DataMemberAttr::get(ty);
109 if (
auto bitFieldTy = mlir::dyn_cast<cir::BitFieldType>(ty)) {
110 assert(bitFieldTy.ownsBytes() &&
111 "a zero-width bit-field takes no initializer");
114 if (mlir::isa<cir::IntType>(ty))
115 return cir::IntAttr::get(ty, 0);
116 if (cir::isAnyFloatingPointType(ty))
117 return cir::FPAttr::getZero(ty);
118 if (
auto complexType = mlir::dyn_cast<cir::ComplexType>(ty))
119 return cir::ZeroAttr::get(complexType);
120 if (
auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
121 return cir::ZeroAttr::get(arrTy);
122 if (
auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
123 return cir::ZeroAttr::get(vecTy);
124 if (
auto matrixTy = mlir::dyn_cast<cir::MatrixType>(ty))
125 return cir::ZeroAttr::get(matrixTy);
126 if (
auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty))
128 if (
auto recordTy = mlir::dyn_cast<cir::RecordType>(ty))
129 return cir::ZeroAttr::get(recordTy);
130 if (
auto dataMemberTy = mlir::dyn_cast<cir::DataMemberType>(ty))
132 if (
auto methodTy = mlir::dyn_cast<cir::MethodType>(ty))
134 if (
auto vptrTy = mlir::dyn_cast<cir::VPtrType>(ty))
135 return cir::ZeroAttr::get(vptrTy);
136 if (mlir::isa<cir::BoolType>(ty)) {
140 llvm_unreachable(
"Zero initializer for given type is NYI");
143 cir::ConstantOp
getBool(
bool state, mlir::Location loc) {
144 return cir::ConstantOp::create(*
this, loc,
getCIRBoolAttr(state));
149 cir::BoolType
getBoolTy() {
return cir::BoolType::get(getContext()); }
150 cir::VoidType
getVoidTy() {
return cir::VoidType::get(getContext()); }
153 return cir::IntType::get(getContext(), n,
false);
157 if (
auto intType = mlir::dyn_cast<cir::IntTypeInterface>(eltTy))
158 return intType.getWidth();
159 if (
auto floatType = mlir::dyn_cast<cir::FPTypeInterface>(eltTy))
160 return floatType.getWidth();
162 llvm_unreachable(
"Unsupported type in getCIRIntOrFloatBitWidth");
165 return cir::IntType::get(getContext(), n,
true);
169 return cir::PointerType::get(ty);
173 mlir::ptr::MemorySpaceAttrInterface as) {
174 return cir::PointerType::get(ty, as);
181 mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr =
187 return getPointerTo(cir::VoidType::get(getContext()), langAS);
190 cir::PointerType
getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface as) {
191 return getPointerTo(cir::VoidType::get(getContext()), as);
194 cir::MethodAttr
getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
195 auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
196 return cir::MethodAttr::get(ty, methodFuncSymbolRef);
200 return cir::MethodAttr::get(ty);
204 return cir::BoolAttr::get(getContext(), state);
254 return cir::FastMathFlagsAttr::get(getContext(),
fastMathFlags);
266 cir::FPDynamicRoundingMode roundingMode;
268 case llvm::RoundingMode::NearestTiesToEven:
269 roundingMode = cir::FPDynamicRoundingMode::ToNearest;
271 case llvm::RoundingMode::TowardNegative:
272 roundingMode = cir::FPDynamicRoundingMode::Downward;
274 case llvm::RoundingMode::TowardPositive:
275 roundingMode = cir::FPDynamicRoundingMode::Upward;
277 case llvm::RoundingMode::TowardZero:
278 roundingMode = cir::FPDynamicRoundingMode::UpwardZero;
280 case llvm::RoundingMode::NearestTiesToAway:
281 roundingMode = cir::FPDynamicRoundingMode::ToNearestAway;
283 case llvm::RoundingMode::Dynamic:
284 roundingMode = cir::FPDynamicRoundingMode::Unknown;
287 llvm_unreachable(
"unexpected constrained rounding mode");
290 cir::FPExceptionMode exceptMode;
294 exceptMode = cir::FPExceptionMode::Masked;
295 strictExcept =
false;
298 exceptMode = cir::FPExceptionMode::Unknown;
299 strictExcept =
false;
302 exceptMode = cir::FPExceptionMode::Unknown;
306 llvm_unreachable(
"unexpected constrained exception mode");
309 return cir::FenvAttr::get(getContext(), roundingMode, exceptMode,
310 mlir::BoolAttr::get(getContext(), strictExcept));
315 auto resultComplexTy = cir::ComplexType::get(real.getType());
316 return cir::ComplexCreateOp::create(*
this, loc, resultComplexTy, real,
321 auto resultType = operand.getType();
322 if (
auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
323 resultType = complexResultType.getElementType();
324 return cir::ComplexRealOp::create(*
this, loc, resultType, operand);
328 auto resultType = operand.getType();
329 if (
auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
330 resultType = complexResultType.getElementType();
331 return cir::ComplexImagOp::create(*
this, loc, resultType, operand);
336 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
337 if (cir::isAnyFloatingPointType(complexTy.getElementType())) {
339 return cir::ComplexFAddOp::create(*
this, loc, lhs, rhs, fenv);
341 return cir::ComplexAddOp::create(*
this, loc, lhs, rhs);
346 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
347 if (cir::isAnyFloatingPointType(complexTy.getElementType())) {
349 return cir::ComplexFSubOp::create(*
this, loc, lhs, rhs, fenv);
351 return cir::ComplexSubOp::create(*
this, loc, lhs, rhs);
356 cir::ComplexRangeKind rangeKind) {
357 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
358 if (cir::isAnyFloatingPointType(complexTy.getElementType()))
359 return cir::ComplexFMulOp::create(*
this, loc, lhs, rhs, rangeKind);
360 return cir::ComplexMulOp::create(*
this, loc, lhs, rhs);
365 cir::ComplexRangeKind rangeKind) {
366 auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType());
367 if (cir::isAnyFloatingPointType(complexTy.getElementType()))
368 return cir::ComplexFDivOp::create(*
this, loc, lhs, rhs, rangeKind);
369 return cir::ComplexDivOp::create(*
this, loc, lhs, rhs);
373 return cir::ComplexConjOp::create(*
this, loc, operand.getType(), operand);
377 bool isVolatile =
false,
uint64_t alignment = 0,
378 bool isNontemporal =
false) {
380 return cir::LoadOp::create(*
this, loc, ptr,
false, isVolatile,
381 isNontemporal, alignmentAttr,
382 cir::SyncScopeKindAttr{}, cir::MemOrderAttr{},
388 return createLoad(loc, ptr,
false, alignment);
391 mlir::Value
createNot(mlir::Location loc, mlir::Value value) {
392 return cir::NotOp::create(*
this, loc, value);
402 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
403 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
404 return cir::DoWhileOp::create(*
this, loc, condBuilder, bodyBuilder);
410 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
411 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder) {
412 return cir::WhileOp::create(*
this, loc, condBuilder, bodyBuilder);
418 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
419 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
420 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)>
422 cir::CleanupKind cleanupKind) {
423 return cir::WhileOp::create(*
this, loc, condBuilder, bodyBuilder,
424 cleanupBuilder, cleanupKind);
430 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
431 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
432 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> stepBuilder) {
433 return cir::ForOp::create(*
this, loc, condBuilder, bodyBuilder,
440 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> condBuilder,
441 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> bodyBuilder,
442 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)> stepBuilder,
443 llvm::function_ref<
void(mlir::OpBuilder &, mlir::Location)>
445 cir::CleanupKind cleanupKind) {
446 return cir::ForOp::create(*
this, loc, condBuilder, bodyBuilder, stepBuilder,
447 cleanupBuilder, cleanupKind);
452 return cir::BreakOp::create(*
this, loc);
457 return cir::ContinueOp::create(*
this, loc);
460 mlir::Value
createInc(mlir::Location loc, mlir::Value input,
462 return cir::IncOp::create(*
this, loc, input, nsw);
465 mlir::Value
createDec(mlir::Location loc, mlir::Value input,
467 return cir::DecOp::create(*
this, loc, input, nsw);
472 return cir::MinusOp::create(*
this, loc, input, nsw);
476 return cir::ConstPtrAttr::get(type, getI64IntegerAttr(value));
479 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
480 llvm::StringRef name, mlir::IntegerAttr alignment,
481 mlir::Value dynAllocSize) {
482 return cir::AllocaOp::create(*
this, loc, addrType, name, alignment,
486 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
487 mlir::Type type, llvm::StringRef name,
489 mlir::Value dynAllocSize) {
491 return createAlloca(loc, addrType, name, alignmentAttr, dynAllocSize);
494 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
495 llvm::StringRef name, mlir::IntegerAttr alignment) {
496 return cir::AllocaOp::create(*
this, loc, addrType, name, alignment);
499 mlir::Value
createAlloca(mlir::Location loc, cir::PointerType addrType,
502 return createAlloca(loc, addrType, name, alignmentAttr);
508 mlir::ArrayAttr indices = {}) {
509 cir::PointerType type =
getPointerTo(globalOp.getSymType());
515 cir::GlobalOp globalOp,
516 mlir::ArrayAttr indices = {},
517 bool addressPoint =
false) {
518 auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr());
519 return cir::GlobalViewAttr::get(type, symbol, indices, addressPoint);
525 cir::GlobalOp globalOp,
527 bool addressPoint =
false) {
530 attrs.push_back(getI64IntegerAttr(ind));
531 mlir::ArrayAttr arAttr = mlir::ArrayAttr::get(getContext(), attrs);
536 bool threadLocal =
false) {
537 return cir::GetGlobalOp::create(
539 getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
540 global.getSymNameAttr(), threadLocal);
544 bool threadLocal =
false) {
550 bool isVolatile =
false,
551 bool skipTailPadding =
false) {
552 return cir::CopyOp::create(*
this, dst.getLoc(), dst, src,
554 isVolatile, skipTailPadding);
557 cir::StoreOp
createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
558 bool isVolatile =
false,
bool isNontemporal =
false,
559 mlir::IntegerAttr align = {},
560 cir::SyncScopeKindAttr scope = {},
561 cir::MemOrderAttr order = {}) {
562 if (mlir::cast<cir::PointerType>(dst.getType()).getPointee() !=
565 return cir::StoreOp::create(*
this, loc, val, dst, isVolatile, isNontemporal,
566 align, scope, order);
572 if (boolTy != mlir::cast<cir::PointerType>(addr.getType()).getPointee())
578 mlir::Value flag =
getBool(val, loc);
582 [[nodiscard]] cir::GlobalOp
584 mlir::StringRef name, mlir::Type type,
bool isConstant,
585 cir::GlobalLinkageKind linkage,
586 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
587 mlir::OpBuilder::InsertionGuard guard(*
this);
588 setInsertionPointToStart(mlirModule.getBody());
589 return cir::GlobalOp::create(*
this, loc, name, type, isConstant, addrSpace,
594 mlir::Value base, llvm::StringRef name,
596 return cir::GetMemberOp::create(*
this, loc, resultTy, base, name, index);
603 return cir::LoadOp::create(*
this, loc, addr,
false,
611 mlir::Value stride) {
612 return cir::PtrStrideOp::create(*
this, loc, base.getType(), base, stride);
619 cir::CallOp
createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
620 mlir::Type returnType, mlir::ValueRange operands,
624 cir::CallingConv callingConv = cir::CallingConv::C) {
625 auto op = cir::CallOp::create(*
this, loc, callee, returnType, operands);
627 if (callingConv != cir::CallingConv::C)
628 op.setCallingConv(callingConv);
630 if (!argAttrs.empty()) {
631 llvm::SmallVector<mlir::Attribute> argDictAttrs;
632 argDictAttrs.reserve(argAttrs.size());
635 argAttrs, std::back_inserter(argDictAttrs),
636 [
this](llvm::ArrayRef<mlir::NamedAttribute> singleArgAttrs) {
637 return mlir::DictionaryAttr::get(getContext(), singleArgAttrs);
640 op.setArgAttrsAttr(mlir::ArrayAttr::get(getContext(), argDictAttrs));
643 if (!resAttrs.empty()) {
644 auto resultDictAttr = mlir::DictionaryAttr::get(getContext(), resAttrs);
645 op.setResAttrsAttr(mlir::ArrayAttr::get(getContext(), resultDictAttr));
651 mlir::ValueRange operands,
655 cir::CallingConv callingConv = cir::CallingConv::C) {
656 return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
657 callee.getFunctionType().getReturnType(), operands,
658 attrs, argAttrs, resAttrs, callingConv);
663 cir::FuncType funcType, mlir::ValueRange operands,
667 cir::CallingConv callingConv = cir::CallingConv::C) {
668 llvm::SmallVector<mlir::Value> resOperands{indirectTarget};
669 resOperands.append(operands.begin(), operands.end());
671 return createCallOp(loc, mlir::SymbolRefAttr(), funcType.getReturnType(),
672 resOperands, attrs, argAttrs, resAttrs, callingConv);
675 cir::CallOp
createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
676 mlir::ValueRange operands = mlir::ValueRange(),
680 return createCallOp(loc, callee, cir::VoidType(), operands, attrs, argAttrs,
689 mlir::Value src, mlir::Type newTy) {
690 if (newTy == src.getType())
692 return cir::CastOp::create(*
this, loc, newTy,
kind, src);
697 if (newTy == src.getType())
704 if (newTy == src.getType())
712 return createCast(cir::CastKind::integral, src, newTy);
717 return cir::BuiltinIntCastOp::create(*
this, loc, newTy, src);
725 return createCast(cir::CastKind::int_to_ptr, src, newTy);
729 return createCast(cir::CastKind::ptr_to_int, src, newTy);
737 return createCast(cir::CastKind::bool_to_int, src, newTy);
741 return createCast(cir::CastKind::bitcast, src, newTy);
746 return createCast(loc, cir::CastKind::bitcast, src, newTy);
750 assert(mlir::isa<cir::PointerType>(src.getType()) &&
"expected ptr src");
751 cir::PointerType srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
757 mlir::Value nullPtr =
getNullPtr(ptr.getType(), ptr.getLoc());
758 return createCompare(ptr.getLoc(), cir::CmpOpKind::eq, ptr, nullPtr);
762 mlir::Value nullPtr =
getNullPtr(ptr.getType(), ptr.getLoc());
763 return createCompare(ptr.getLoc(), cir::CmpOpKind::ne, ptr, nullPtr);
768 return createCast(loc, cir::CastKind::address_space, src, newTy);
783 return cir::VecExtractOp::create(*
this, loc, vec, idxVal);
790 return cir::VecInsertOp::create(*
this, loc, vec, newElt, idxVal);
794 auto resTy = cir::BoolType::get(getContext());
795 return cir::SignBitOp::create(*
this, loc, resTy, val);
804 llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
805 auto type = cir::IntType::get(getContext(), size,
false);
809 mlir::Value
createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
810 return cir::AndOp::create(*
this, loc, lhs, rhs);
813 mlir::Value
createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
814 return cir::OrOp::create(*
this, loc, lhs, rhs);
818 mlir::Value trueValue, mlir::Value falseValue) {
819 assert(trueValue.getType() == falseValue.getType() &&
820 "trueValue and falseValue should have the same type");
821 return cir::SelectOp::create(*
this, loc, trueValue.getType(),
condition,
822 trueValue, falseValue);
835 mlir::Value
createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
836 OverflowFlags flags = OverflowFlags::None) {
837 return cir::MulOp::create(*
this, loc, lhs, rhs, flags);
841 return createMul(loc, lhs, rhs, OverflowFlags::NoSignedWrap);
845 return createMul(loc, lhs, rhs, OverflowFlags::NoUnsignedWrap);
850 return cir::AddSatOp::create(*
this, loc, lhs, rhs);
855 return cir::SubSatOp::create(*
this, loc, lhs, rhs);
858 mlir::Value
createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
859 OverflowFlags flags = OverflowFlags::None) {
860 return cir::SubOp::create(*
this, loc, lhs, rhs, flags);
865 return createSub(loc, lhs, rhs, OverflowFlags::NoSignedWrap);
870 return createSub(loc, lhs, rhs, OverflowFlags::NoUnsignedWrap);
873 mlir::Value
createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
874 OverflowFlags flags = OverflowFlags::None) {
875 return cir::AddOp::create(*
this, loc, lhs, rhs, flags);
880 return createAdd(loc, lhs, rhs, OverflowFlags::NoSignedWrap);
885 return createAdd(loc, lhs, rhs, OverflowFlags::NoUnsignedWrap);
888 mlir::Value
createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
889 return cir::DivOp::create(*
this, loc, lhs, rhs);
892 mlir::Value
createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
893 return cir::RemOp::create(*
this, loc, lhs, rhs);
896 template <
typename OpTy>
904 mlir::Value
createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
908 mlir::Value
createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
912 mlir::Value
createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
916 mlir::Value
createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
920 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);
995 mlir::Value lhs, mlir::Value rhs,
996 bool signaling =
false) {
997 VectorType vecCast = mlir::cast<VectorType>(lhs.getType());
998 mlir::Type elemTy = vecCast.getElementType();
999 assert(!(mlir::isa<cir::FPTypeInterface>(elemTy) &&
1000 &mlir::cast<cir::FPTypeInterface>(elemTy).getFloatSemantics() ==
1001 &llvm::APFloat::x87DoubleExtended()) &&
1002 "an FP80 vector compare must name its result type");
1004 auto resTy = cir::VectorType::get(integralTy, vecCast.getSize());
1005 return cir::VecFCmpOp::create(*
this, loc, resTy,
kind, lhs, rhs, signaling,
1014 cir::FCmpOpKind
kind, mlir::Value lhs,
1015 mlir::Value rhs,
bool signaling =
false) {
1016 assert(mlir::cast<VectorType>(lhs.getType()).getSize() ==
1017 resultTy.getSize() &&
1018 cir::isIntOrBoolType(resultTy.getElementType()) &&
1019 "vector compare result must be an int or bool vector of the "
1021 return cir::VecFCmpOp::create(*
this, loc, resultTy,
kind, lhs, rhs,
1026 return createCompare(loc, cir::CmpOpKind::ne, operand, operand);
1029 mlir::Value
createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
1031 return cir::ShiftOp::create(*
this, loc, lhs.getType(), lhs, rhs,
1036 const llvm::APInt &rhs,
bool isShiftLeft) {
1041 mlir::Value
createShift(mlir::Location loc, mlir::Value lhs,
unsigned bits,
1043 auto width = mlir::dyn_cast<cir::IntType>(lhs.getType()).getWidth();
1044 auto shift = llvm::APInt(width, bits);
1070 return cir::FuncType::get(llvm::to_vector(argTypes),
getVoidTy());
1084 std::find_if(block->rbegin(), block->rend(), [](mlir::Operation &op) {
1085 return mlir::isa<cir::AllocaOp, cir::LabelOp>(&op);
1088 if (last != block->rend())
1089 return OpBuilder::InsertPoint(block, ++mlir::Block::iterator(&*last));
1090 return OpBuilder::InsertPoint(block, block->begin());
1111 return alignment ? getI64IntegerAttr(alignment) : mlir::IntegerAttr();
1137 cir::YieldOp
createYield(mlir::Location loc, mlir::ValueRange value = {}) {
1138 return cir::YieldOp::create(*
this, loc, value);
1147 mlir::Value objectPtr) {
1150 mlir::cast<cir::MethodType>(method.getType()).getMemberFuncTy();
1151 auto methodFuncInputTypes = methodFuncTy.getInputs();
1153 auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
1154 mlir::Type adjustedThisTy =
getVoidPtrTy(objectPtrTy.getAddrSpace());
1159 if (methodFuncInputTypes.size() > 1)
1160 calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
1161 methodFuncInputTypes.begin() + 1,
1162 methodFuncInputTypes.end());
1163 cir::FuncType calleeFuncTy =
1164 methodFuncTy.clone(calleeFuncInputTypes, methodFuncTy.getReturnType());
1167 cir::PointerType calleeTy =
getPointerTo(calleeFuncTy);
1169 auto op = cir::GetMethodOp::create(*
this, loc, calleeTy, adjustedThisTy,
1171 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
cir::VecFCmpOp createVecFCompare(mlir::Location loc, VectorType resultTy, cir::FCmpOpKind kind, mlir::Value lhs, mlir::Value rhs, bool signaling=false)
Compares lhs and rhs element-wise, producing resultTy, which must be a vector of integers or bools wi...
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 createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowFlags flags=OverflowFlags::None)
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, OverflowFlags flags=OverflowFlags::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={})
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy, mlir::Value base, llvm::StringRef name, unsigned index)
cir::PointerType getPointerTo(mlir::Type ty)
cir::VecFCmpOp createVecFCompare(mlir::Location loc, cir::FCmpOpKind kind, mlir::Value lhs, mlir::Value rhs, bool signaling=false)
Compares lhs and rhs element-wise.
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 createAddSat(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowFlags flags=OverflowFlags::None)
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::Value createSubSat(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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.
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.
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
PtrOffsetFlags
No-wrap flags of a pointer offset computation: the subset of llvm::GEPNoWrapFlags that cir....
LangAS
Defines the address space values used by the address space qualifier of QualType.
__builtin_riscv_nclipru_u32 int64_t
static bool metaDataNode()
static bool addressSpace()
static bool targetCodeGenInfoGetNullPointer()
static bool fastMathFlags()