9#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
10#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
15#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
16#include "mlir/IR/Attributes.h"
17#include "mlir/IR/Builders.h"
18#include "mlir/IR/BuiltinAttributes.h"
19#include "mlir/Support/LLVM.h"
25#include "llvm/ADT/APFloat.h"
26#include "llvm/ADT/STLExtras.h"
27#include "llvm/IR/FPEnv.h"
34 llvm::StringMap<unsigned> recordNames;
35 llvm::StringMap<unsigned> globalsVersioning;
44 mlir::Attribute
getString(llvm::StringRef str, mlir::Type eltTy,
45 std::optional<size_t> size,
46 bool ensureNullTerm =
true) {
47 size_t finalSize = size.value_or(str.size());
49 size_t lastNonZeroPos = str.find_last_not_of(
'\0');
52 if (lastNonZeroPos == llvm::StringRef::npos) {
53 auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
54 return cir::ZeroAttr::get(arrayTy);
60 size_t trailingZerosNum = finalSize - lastNonZeroPos - 1;
61 auto truncatedArrayTy =
62 cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
63 auto strAttr = mlir::StringAttr::get(str.drop_back(trailingZerosNum),
70 finalSize += (ensureNullTerm && trailingZerosNum == 0);
72 auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
73 return cir::ConstArrayAttr::get(fullArrayTy, strAttr);
77 cir::ArrayType arrayTy)
const {
78 return cir::ConstArrayAttr::get(arrayTy, attrs);
86 for (
auto &f : arrayAttr) {
87 auto ta = mlir::cast<mlir::TypedAttr>(f);
88 members.push_back(ta.getType());
93 return cir::ConstRecordAttr::get(sTy, arrayAttr);
98 return cir::TypeInfoAttr::get(anonRecord.getType(), fieldsAttr);
104 auto it = recordNames.find(baseName);
105 if (it == recordNames.end()) {
106 recordNames[baseName] = 0;
110 return baseName +
"." + std::to_string(recordNames[baseName]++);
114 if (&
format == &llvm::APFloat::IEEEdouble())
115 return cir::LongDoubleType::get(getContext(), typeCache.doubleTy);
116 if (&
format == &llvm::APFloat::x87DoubleExtended())
117 return cir::LongDoubleType::get(getContext(), typeCache.fP80Ty);
118 if (&
format == &llvm::APFloat::IEEEquad())
119 return cir::LongDoubleType::get(getContext(), typeCache.fP128Ty);
120 if (&
format == &llvm::APFloat::PPCDoubleDouble())
121 llvm_unreachable(
"NYI: PPC double-double format for long double");
122 llvm_unreachable(
"Unsupported format for long double");
130 bool isVarArg =
false) {
131 return cir::FuncType::get(params, retTy, isVarArg);
153 const auto nameAttr = getStringAttr(name);
157 auto type = cir::StructType::get(getContext(), members, nameAttr, packed,
162 assert(!
type.isIncomplete() ||
163 (
type.getMembers() == members &&
type.getPacked() == packed));
167 type.complete(members, packed, memberKinds);
177 const mlir::StringAttr nameAttr = getStringAttr(name);
179 return cir::UnionType::get(getContext(), nameAttr);
181 return cir::StructType::get(getContext(), nameAttr, is_class);
190 bool skipTailPadding =
false) {
200 return cir::MemCpyOp::create(
207 mlir::Value src, mlir::Value len) {
208 return cir::MemMoveOp::create(*
this, loc, dst, src, len);
212 mlir::Value val, mlir::Value len) {
214 return cir::MemSetOp::create(*
this, loc, dst, {}, val, len);
221 return cir::MemSetOp::create(*
this, loc, dst.
getPointer(), align, val, len);
227 return cir::DataMemberAttr::get(ty, path);
231 return cir::DataMemberAttr::get(ty);
237 if (mlir::isa<cir::ZeroAttr>(
attr))
240 if (
const auto ptrVal = mlir::dyn_cast<cir::ConstPtrAttr>(
attr))
241 return ptrVal.isNullValue();
243 if (
const auto intVal = mlir::dyn_cast<cir::IntAttr>(
attr))
244 return intVal.isNullValue();
246 if (
const auto boolVal = mlir::dyn_cast<cir::BoolAttr>(
attr))
247 return !boolVal.getValue();
249 if (
auto fpAttr = mlir::dyn_cast<cir::FPAttr>(
attr)) {
250 auto fpVal = fpAttr.getValue();
252 llvm::APFloat fv(+0.0);
253 fv.convert(fpVal.getSemantics(), llvm::APFloat::rmNearestTiesToEven,
255 return fv.bitwiseIsEqual(fpVal);
257 if (
const auto recordVal = mlir::dyn_cast<cir::ConstRecordAttr>(
attr)) {
258 for (
const auto elt : recordVal.getMembers()) {
260 if (mlir::isa<mlir::StringAttr>(elt))
268 if (
const auto arrayVal = mlir::dyn_cast<cir::ConstArrayAttr>(
attr)) {
269 if (mlir::isa<mlir::StringAttr>(arrayVal.getElts()))
273 mlir::cast<mlir::ArrayAttr>(arrayVal.getElts()),
274 [&](
const mlir::Attribute &elt) { return isNullValue(elt); });
294 return cir::IntType::get(getContext(), n,
false);
309 return cir::IntType::get(getContext(), n,
true);
332 cir::ConstantOp
getConstInt(mlir::Location loc, llvm::APSInt intVal);
334 cir::ConstantOp
getConstInt(mlir::Location loc, llvm::APInt intVal,
337 cir::ConstantOp
getConstInt(mlir::Location loc, mlir::Type t, uint64_t c);
339 cir::ConstantOp
getConstFP(mlir::Location loc, mlir::Type t,
340 llvm::APFloat fpVal);
343 return i == typeCache.uInt8Ty || i == typeCache.sInt8Ty;
346 return i == typeCache.uInt16Ty || i == typeCache.sInt16Ty;
349 return i == typeCache.uInt32Ty || i == typeCache.sInt32Ty;
352 return i == typeCache.uInt64Ty || i == typeCache.sInt64Ty;
354 bool isInt(mlir::Type i) {
return mlir::isa<cir::IntType>(i); }
357 switch (ty.getWidth()) {
359 return isSigned ? typeCache.sInt16Ty : typeCache.uInt16Ty;
361 return isSigned ? typeCache.sInt32Ty : typeCache.uInt32Ty;
363 return isSigned ? typeCache.sInt64Ty : typeCache.uInt64Ty;
365 llvm_unreachable(
"NYI");
370 switch (ty.getWidth()) {
372 return isSigned ? typeCache.sInt8Ty : typeCache.uInt8Ty;
374 return isSigned ? typeCache.sInt16Ty : typeCache.uInt16Ty;
376 return isSigned ? typeCache.sInt32Ty : typeCache.uInt32Ty;
378 llvm_unreachable(
"NYI");
384 bool isSigned =
false) {
385 auto elementTy = mlir::dyn_cast_or_null<cir::IntType>(vt.getElementType());
386 assert(elementTy &&
"expected int vector");
387 return cir::VectorType::get(isExtended
401 return cir::StructType::get(getContext(), members, packed,
414 cir::ConstantOp
getSInt64(uint64_t c, mlir::Location loc) {
417 cir::ConstantOp
getUInt64(uint64_t c, mlir::Location loc) {
421 cir::ConstantOp
getZero(mlir::Location loc, mlir::Type ty) {
423 assert((mlir::isa<cir::RecordType>(ty) || mlir::isa<cir::ArrayType>(ty) ||
424 mlir::isa<cir::VectorType>(ty)) &&
425 "NYI for other types");
426 return cir::ConstantOp::create(*
this, loc, cir::ZeroAttr::get(ty));
432 mlir::Value
createNeg(mlir::Location loc, mlir::Value value,
435 if (
auto intTy = mlir::dyn_cast<cir::IntType>(value.getType())) {
437 if (intTy.isUnsigned())
442 llvm_unreachable(
"negation for the given type is NYI");
452 return cir::CastOp::create(*
this, v.getLoc(), destType,
453 cir::CastKind::floating, v,
458 cir::PointerType destType,
bool isRefCast,
459 cir::DynamicCastInfoAttr info) {
461 isRefCast ? cir::DynamicCastKind::Ref : cir::DynamicCastKind::Ptr;
462 return cir::DynamicCastOp::create(*
this, loc, destType, castKind, src, info,
467 bool vtableUseRelativeLayout) {
471 return cir::DynamicCastOp::create(
472 *
this, loc, destTy, cir::DynamicCastKind::Ptr, src,
473 cir::DynamicCastInfoAttr{}, vtableUseRelativeLayout);
480 mlir::Type destType,
unsigned offset,
481 bool assumeNotNull) {
487 cir::BaseClassAddrOp::create(*
this, loc, ptrTy, addr.
getPointer(),
488 mlir::APInt(64, offset), assumeNotNull);
493 mlir::Type destType,
unsigned offset,
494 bool assumeNotNull) {
500 cir::DerivedClassAddrOp::create(*
this, loc, ptrTy, addr.
getPointer(),
501 mlir::APInt(64, offset), assumeNotNull);
509 mlir::Value addr, uint64_t offset) {
510 return cir::VTTAddrPointOp::create(*
this, loc, retTy,
511 mlir::FlatSymbolRefAttr{}, addr, offset);
515 mlir::FlatSymbolRefAttr sym, uint64_t offset) {
516 return cir::VTTAddrPointOp::create(*
this, loc, retTy, sym, mlir::Value{},
524 cir::FPClassTest flags) {
530 assert((raw & ~
all) == 0 &&
"FPClassTest mask has bits outside 0-9");
531 flags =
static_cast<cir::FPClassTest
>(raw &
all);
532 return cir::IsFPClassOp::create(*
this, loc, src, flags);
538 mlir::Type destType) {
542 auto srcPtrTy = mlir::cast<cir::PointerType>(addr.
getPointer().getType());
543 auto ptrTy =
getPointerTo(destType, srcPtrTy.getAddrSpace());
549 bool isVolatile =
false,
bool isNontemporal =
false) {
551 return cir::LoadOp::create(*
this, loc, addr.
getPointer(),
false,
552 isVolatile, isNontemporal,
554 cir::SyncScopeKindAttr{},
560 mlir::Value ptr, llvm::MaybeAlign align) {
561 if (ty != mlir::cast<cir::PointerType>(ptr.getType()).getPointee())
563 uint64_t alignment = align ? align->value() : 0;
565 return cir::LoadOp::create(*
this, loc, ptr,
false,
568 cir::SyncScopeKindAttr{},
580 bool isVolatile =
false,
bool isNontemporal =
false,
581 mlir::IntegerAttr align = {},
582 cir::SyncScopeKindAttr scope = {},
583 cir::MemOrderAttr order = {}) {
587 isNontemporal, align, scope, order);
593 auto srcPtrTy = mlir::cast<cir::PointerType>(value.getType());
594 auto srcComplexTy = mlir::cast<cir::ComplexType>(srcPtrTy.getPointee());
595 return cir::ComplexRealPtrOp::create(
596 *
this, loc,
getPointerTo(srcComplexTy.getElementType()), value);
608 auto srcPtrTy = mlir::cast<cir::PointerType>(value.getType());
609 auto srcComplexTy = mlir::cast<cir::ComplexType>(srcPtrTy.getPointee());
610 return cir::ComplexImagPtrOp::create(
611 *
this, loc,
getPointerTo(srcComplexTy.getElementType()), value);
621 llvm::StringRef name,
unsigned index) {
622 auto recordTy = mlir::cast<cir::RecordType>(base.
getElementType());
624 assert(
index < recordTy.getMembers().size() &&
625 "member index out of bounds");
626 mlir::Type memberTy = recordTy.getMembers()[
index];
630 getInsertionBlock()->getParentOp()->getParentOfType<mlir::ModuleOp>();
631 mlir::DataLayout layout(moduleOp);
635 mlir::Value memberPtr =
637 return Address(memberPtr, memberTy,
643 mlir::Value objectPtr,
644 mlir::Value memberPtr) {
645 auto memberPtrTy = mlir::cast<cir::DataMemberType>(memberPtr.getType());
649 cir::PointerType resultTy =
getPointerTo(memberPtrTy.getMemberTy());
651 return cir::GetRuntimeMemberOp::create(*
this, loc, resultTy, objectPtr,
659 mlir::Location arrayLocEnd, mlir::Value arrayPtr,
660 mlir::Type eltTy, mlir::Value idx,
690 [[nodiscard]] cir::GlobalOp
692 mlir::StringRef name, mlir::Type
type,
bool isConstant,
693 cir::GlobalLinkageKind linkage,
694 mlir::ptr::MemorySpaceAttrInterface addrSpace = {}) {
696 std::string uniqueName;
697 if (
unsigned version = globalsVersioning[name.str()]++)
698 uniqueName = name.str() +
"." + std::to_string(version);
700 uniqueName = name.str();
707 return cir::StackSaveOp::create(*
this, loc, ty);
711 return cir::StackRestoreOp::create(*
this, loc, v);
715 mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
716 const llvm::APSInt <Res,
const llvm::APSInt &eqRes,
717 const llvm::APSInt >Res, cir::CmpOrdering ordering) {
718 assert(ltRes.getBitWidth() == eqRes.getBitWidth() &&
719 ltRes.getBitWidth() == gtRes.getBitWidth() &&
720 "the three comparison results must have the same bit width");
721 assert((ordering == cir::CmpOrdering::Strong ||
722 ordering == cir::CmpOrdering::Weak) &&
723 "total ordering must be strong or weak");
724 cir::IntType cmpResultTy =
getSIntNTy(ltRes.getBitWidth());
725 auto infoAttr = cir::CmpThreeWayInfoAttr::get(
726 getContext(), ordering, ltRes.getSExtValue(), eqRes.getSExtValue(),
727 gtRes.getSExtValue());
728 return cir::CmpThreeWayOp::create(*
this, loc, cmpResultTy, lhs, rhs,
733 mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
734 const llvm::APSInt <Res,
const llvm::APSInt &eqRes,
735 const llvm::APSInt >Res,
const llvm::APSInt &unorderedRes) {
736 assert(ltRes.getBitWidth() == eqRes.getBitWidth() &&
737 ltRes.getBitWidth() == gtRes.getBitWidth() &&
738 ltRes.getBitWidth() == unorderedRes.getBitWidth() &&
739 "the four comparison results must have the same bit width");
740 cir::IntType cmpResultTy =
getSIntNTy(ltRes.getBitWidth());
741 auto infoAttr = cir::CmpThreeWayInfoAttr::get(
742 getContext(), ltRes.getSExtValue(), eqRes.getSExtValue(),
743 gtRes.getSExtValue(), unorderedRes.getSExtValue());
744 return cir::CmpThreeWayOp::create(*
this, loc, cmpResultTy, lhs, rhs,
749 Address dstAddr, mlir::Type storageType,
751 bool isLvalueVolatile,
bool useVolatile) {
752 unsigned offset = useVolatile ? info.volatileOffset : info.offset;
757 useVolatile ? cir::IntType::get(storageType.getContext(),
758 info.volatileStorageSize, info.isSigned)
760 return cir::SetBitfieldOp::create(
761 *
this, loc, resultType, dstAddr.
getPointer(), storageType, src,
762 info.name, info.size, offset, info.isSigned, isLvalueVolatile,
767 Address addr, mlir::Type storageType,
769 bool isLvalueVolatile,
bool useVolatile) {
770 unsigned offset = useVolatile ? info.volatileOffset : info.offset;
775 useVolatile ? cir::IntType::get(storageType.getContext(),
776 info.volatileStorageSize, info.isSigned)
778 return cir::GetBitfieldOp::create(*
this, loc, resultType, addr.
getPointer(),
779 storageType, info.name, info.size, offset,
780 info.isSigned, isLvalueVolatile,
785 mlir::Value ptr, llvm::Align alignment,
786 mlir::Value mask, mlir::Value passThru) {
787 assert(mlir::isa<cir::VectorType>(ty) &&
"Type should be vector");
788 assert(mask &&
"Mask should not be all-ones (null)");
791 passThru = this->
getConstant(loc, cir::PoisonAttr::get(ty));
794 this->getI64IntegerAttr(
static_cast<int64_t
>(alignment.value()));
796 return cir::VecMaskedLoadOp::create(*
this, loc, ty, ptr, mask, passThru,
803 auto vecType = mlir::cast<cir::VectorType>(vec1.getType());
805 cir::VectorType::get(vecType.getElementType(), maskAttrs.size());
806 return cir::VecShuffleOp::create(*
this, loc, resultTy, vec1, vec2,
807 getArrayAttr(maskAttrs));
813 auto maskAttrs = llvm::to_vector_of<mlir::Attribute>(
814 llvm::map_range(mask, [&](
int32_t idx) {
824 cir::ConstantOp poison =
825 getConstant(loc, cir::PoisonAttr::get(vec1.getType()));
832 mlir::Value columnIdx) {
833 return cir::MatrixExtractOp::create(*
this, loc, matrix, rowIdx, columnIdx);
837 mlir::Value matrix, mlir::Value rowIdx,
838 mlir::Value columnIdx) {
839 return cir::MatrixInsertOp::create(*
this, loc, value, matrix, rowIdx,
848 return cir::MatrixColumnMajorLoadOp::create(*
this, loc, resultTy, value,
854 mlir::Value lhs, mlir::Value rhs) {
855 auto lhsTy = mlir::cast<cir::MatrixType>(lhs.getType());
856 auto rhsTy = mlir::cast<cir::MatrixType>(rhs.getType());
857 auto resultTy = cir::MatrixType::get(
858 lhsTy.getElementType(), lhsTy.getNumRows(), rhsTy.getNumColumns());
859 return cir::MatrixMultiplyOp::create(*
this, loc, resultTy, lhs, rhs);
863 mlir::Value matrix) {
864 auto inputTy = mlir::cast<cir::MatrixType>(matrix.getType());
866 cir::MatrixType::get(inputTy.getElementType(), inputTy.getNumColumns(),
867 inputTy.getNumRows());
868 return cir::MatrixTransposeOp::create(*
this, loc, resultTy, matrix);
876 return cir::MatrixColumnMajorStoreOp::create(*
this, loc, matrix, data,
880 std::pair<mlir::Value, mlir::Value>
883 assert(mlir::isa<cir::MatrixType>(lhs.getType()) ||
884 mlir::isa<cir::MatrixType>(rhs.getType()));
886 if (!mlir::isa<cir::MatrixType>(lhs.getType()))
887 lhs = cir::VecSplatOp::create(*
this, loc, rhs.getType(), lhs);
888 else if (!mlir::isa<cir::MatrixType>(rhs.getType()))
889 rhs = cir::VecSplatOp::create(*
this, loc, lhs.getType(), rhs);
894 template <
typename... Operands>
896 const mlir::Type &resTy, Operands &&...op) {
897 return cir::LLVMIntrinsicCallOp::create(*
this, loc,
898 this->getStringAttr(str), resTy,
899 std::forward<Operands>(op)...)
903 template <
typename... Operands>
905 const mlir::Type &resTy,
906 cir::FastMathFlagsAttr fastmath,
908 return cir::LLVMIntrinsicCallOp::create(
909 *
this, loc, this->getStringAttr(str), resTy,
910 std::forward<Operands>(op)..., fastmath)
static bool isUnsigned(SValBuilder &SVB, NonLoc Value)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src, bool isVolatile=false, bool skipTailPadding=false)
Create a copy with inferred length.
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy, mlir::Value base, llvm::StringRef name, unsigned index)
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::FenvAttr getConstrainedFPAttr()
Build the #cir.fenv attribute describing the constrained floating-point environment currently in effe...
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment)
mlir::Value createMinus(mlir::Location loc, mlir::Value input, bool nsw=false)
cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, int64_t value)
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc, mlir::StringRef name, mlir::Type type, bool isConstant, cir::GlobalLinkageKind linkage, mlir::ptr::MemorySpaceAttrInterface addrSpace)
C++ view class that accepts both !cir.struct and !cir.union types.
static llvm::SmallVector< RecordMemberKind > getAllDataKinds(llvm::ArrayRef< mlir::Type > members)
One Data kind per member.
bool isKnownNonNull() const
Whether the pointer is known not to be null.
mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
mlir::Value getBasePointer() const
cir::MemMoveOp createMemMove(mlir::Location loc, mlir::Value dst, mlir::Value src, mlir::Value len)
cir::StackSaveOp createStackSave(mlir::Location loc, mlir::Type ty)
cir::IntType getUInt64Ty()
cir::IntType getUInt8Ty()
std::pair< mlir::Value, mlir::Value > splatMatrixOpOperandsIfNecessary(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::BF16Type getBfloat16Ty()
cir::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::CmpThreeWayOp createThreeWayCmpTotalOrdering(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, const llvm::APSInt <Res, const llvm::APSInt &eqRes, const llvm::APSInt >Res, cir::CmpOrdering ordering)
mlir::Value createComplexRealPtr(mlir::Location loc, mlir::Value value)
Create a cir.complex.real_ptr operation that derives a pointer to the real part of the complex value ...
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1, mlir::Value vec2, llvm::ArrayRef< int64_t > mask)
cir::ConstantOp getUInt64(uint64_t c, mlir::Location loc)
mlir::Value emitIntrinsicCallOp(mlir::Location loc, const llvm::StringRef str, const mlir::Type &resTy, Operands &&...op)
cir::IntType getSIntNTy(int n)
cir::DataMemberAttr getDataMemberAttr(cir::DataMemberType ty, llvm::ArrayRef< int32_t > path)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::IntType getTruncatedIntTy(cir::IntType ty, bool isSigned)
cir::IntType getBoolMemoryTy()
cir::RecordType getIncompleteRecordTy(llvm::StringRef name, const clang::RecordDecl *rd)
Get an incomplete CIR record type.
cir::ConstantOp getUInt32(uint32_t c, mlir::Location loc)
Address createGetMember(mlir::Location loc, Address base, llvm::StringRef name, unsigned index)
cir::MatrixColumnMajorStoreOp createMatrixColumnMajorStore(mlir::Location loc, mlir::Value matrix, mlir::Value data, mlir::Value stride, bool isVolatile)
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1, mlir::Value vec2, llvm::ArrayRef< mlir::Attribute > maskAttrs)
mlir::Value createNeg(mlir::Location loc, mlir::Value value, bool nsw=false)
cir::MatrixExtractOp createMatrixExtract(mlir::Location loc, mlir::Value matrix, mlir::Value rowIdx, mlir::Value columnIdx)
cir::PointerType getUInt8PtrTy()
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, cir::RecordType recordTy)
cir::RecordType getCompleteNamedRecordType(llvm::ArrayRef< mlir::Type > members, bool packed, llvm::StringRef name, llvm::ArrayRef< cir::RecordMemberKind > memberKinds)
Get a CIR named record type.
std::string getUniqueRecordName(const std::string &baseName)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false, bool isNontemporal=false)
cir::CmpThreeWayOp createThreeWayCmpPartialOrdering(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, const llvm::APSInt <Res, const llvm::APSInt &eqRes, const llvm::APSInt >Res, const llvm::APSInt &unorderedRes)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::FlatSymbolRefAttr sym, uint64_t offset)
mlir::Value createMaskedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, llvm::Align alignment, mlir::Value mask, mlir::Value passThru)
Address createBaseClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)
mlir::Value createComplexImagPtr(mlir::Location loc, mlir::Value value)
Create a cir.complex.imag_ptr operation that derives a pointer to the imaginary part of the complex v...
mlir::Value maybeBuildArrayDecay(mlir::Location loc, mlir::Value arrayPtr, mlir::Type eltTy)
Returns a decayed pointer to the first element of the array pointed to by arrayPtr.
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, llvm::MaybeAlign align)
cir::ConstantOp getConstFP(mlir::Location loc, mlir::Type t, llvm::APFloat fpVal)
mlir::Value createFloatingCast(mlir::Value v, mlir::Type destType)
cir::FuncType getFuncType(llvm::ArrayRef< mlir::Type > params, mlir::Type retTy, bool isVarArg=false)
cir::MemSetOp createMemSet(mlir::Location loc, Address dst, mlir::Value val, mlir::Value len)
cir::FP16Type getFp16Ty()
cir::IntType getExtendedIntTy(cir::IntType ty, bool isSigned)
cir::SingleType getSingleTy()
Address createDerivedClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)
static bool tagKindIsUnion(const clang::TagTypeKind kind)
Returns true if the tag kind is a union.
std::string getUniqueAnonRecordName()
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
cir::MatrixTransposeOp createMatrixTranspose(mlir::Location loc, mlir::Value matrix)
cir::GetRuntimeMemberOp createGetIndirectMember(mlir::Location loc, mlir::Value objectPtr, mlir::Value memberPtr)
Address createElementBitCast(mlir::Location loc, Address addr, mlir::Type destType)
Cast the element type of the given address to a different type, preserving information like the align...
cir::MatrixMultiplyOp createMatrixMultiply(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
Multiply an MxK matrix by a KxN matrix, producing an MxN matrix.
cir::IntType getSInt8Ty()
cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr)
bool isInt16Ty(mlir::Type i)
bool isInt32Ty(mlir::Type i)
static bool tagKindIsClass(const clang::TagTypeKind kind)
Get a CIR record kind from a AST declaration tag.
cir::MatrixInsertOp createMatrixInsert(mlir::Location loc, mlir::Value value, mlir::Value matrix, mlir::Value rowIdx, mlir::Value columnIdx)
mlir::Value createDynCastToVoid(mlir::Location loc, mlir::Value src, bool vtableUseRelativeLayout)
cir::ConstantOp getZero(mlir::Location loc, mlir::Type ty)
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1, llvm::ArrayRef< int64_t > mask)
cir::IntType getUInt16Ty()
cir::MemCpyOp createMemCpy(mlir::Location loc, Address dst, Address src, mlir::Value len)
mlir::Value createDynCast(mlir::Location loc, mlir::Value src, cir::PointerType destType, bool isRefCast, cir::DynamicCastInfoAttr info)
mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType, Address addr, mlir::Type storageType, const CIRGenBitFieldInfo &info, bool isLvalueVolatile, bool useVolatile)
bool isNullValue(mlir::Attribute attr) const
bool isInt64Ty(mlir::Type i)
cir::StackRestoreOp createStackRestore(mlir::Location loc, mlir::Value v)
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType, Address dstAddr, mlir::Type storageType, mlir::Value src, const CIRGenBitFieldInfo &info, bool isLvalueVolatile, bool useVolatile)
Address createComplexRealPtr(mlir::Location loc, Address addr)
cir::GlobalOp createVersionedGlobal(mlir::ModuleOp module, mlir::Location loc, mlir::StringRef name, mlir::Type type, bool isConstant, cir::GlobalLinkageKind linkage, mlir::ptr::MemorySpaceAttrInterface addrSpace={})
Creates a versioned global variable.
cir::MatrixColumnMajorLoadOp createMatrixColumnMajorLoad(mlir::Location loc, mlir::Type resultTy, mlir::Value value, mlir::Value stride, bool isVolatile)
cir::StructType getAnonRecordTy(llvm::ArrayRef< mlir::Type > members, bool packed, llvm::ArrayRef< cir::RecordMemberKind > memberKinds)
Get a CIR anonymous struct type.
mlir::Value emitIntrinsicCallOp(mlir::Location loc, const llvm::StringRef str, const mlir::Type &resTy, cir::FastMathFlagsAttr fastmath, Operands &&...op)
CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
cir::IsFPClassOp createIsFPClass(mlir::Location loc, mlir::Value src, cir::FPClassTest flags)
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size, bool ensureNullTerm=true)
Get a cir::ConstArrayAttr for a string literal.
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
cir::VoidType getVoidTy()
cir::IntType getUInt32Ty()
mlir::Type getPtrToVPtrType()
cir::IntType getSInt32Ty()
Address createComplexImagPtr(mlir::Location loc, Address addr)
cir::VectorType getExtendedOrTruncatedElementVectorType(cir::VectorType vt, bool isExtended, bool isSigned=false)
cir::IntType getSInt64Ty()
cir::DataMemberAttr getNullDataMemberAttr(cir::DataMemberType ty)
cir::ConstantOp getSInt32(int32_t c, mlir::Location loc)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::Value addr, uint64_t offset)
cir::MemSetOp createMemSet(mlir::Location loc, mlir::Value dst, mlir::Value val, mlir::Value len)
cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const
cir::CopyOp createCopy(Address dst, Address src, bool isVolatile=false, bool skipTailPadding=false)
cir::IntType getSInt16Ty()
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
cir::IntType getUIntNTy(int n)
mlir::Value getArrayElement(mlir::Location arrayLocBegin, mlir::Location arrayLocEnd, mlir::Value arrayPtr, mlir::Type eltTy, mlir::Value idx, bool shouldDecay)
Create a cir.ptr_stride operation to get access to an array element.
bool isInt8Ty(mlir::Type i)
bool computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, clang::CharUnits align=clang::CharUnits::One())
cir::DoubleType getDoubleTy()
This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Represents a struct/union/class.
TagKind getTagKind() const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
TagTypeKind
The kind of a tag type.
@ Class
The "class" keyword.
@ Union
The "union" keyword.
int __ovld __cnfn all(char)
Returns 1 if the most significant bit in all components of x is set; otherwise returns 0.
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t
static bool addressSpace()
static bool astRecordDeclAttr()
Record with information about how a bitfield should be accessed.
This structure provides a set of types that are commonly used during IR emission.