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"
33 bool isFPConstrained =
false;
34 llvm::fp::ExceptionBehavior defaultConstrainedExcept = llvm::fp::ebStrict;
35 llvm::RoundingMode defaultConstrainedRounding = llvm::RoundingMode::Dynamic;
37 llvm::StringMap<unsigned> recordNames;
38 llvm::StringMap<unsigned> globalsVersioning;
47 mlir::Attribute
getString(llvm::StringRef str, mlir::Type eltTy,
48 std::optional<size_t> size,
49 bool ensureNullTerm =
true) {
50 size_t finalSize = size.value_or(str.size());
52 size_t lastNonZeroPos = str.find_last_not_of(
'\0');
55 if (lastNonZeroPos == llvm::StringRef::npos) {
56 auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
57 return cir::ZeroAttr::get(arrayTy);
63 size_t trailingZerosNum = finalSize - lastNonZeroPos - 1;
64 auto truncatedArrayTy =
65 cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
66 auto strAttr = mlir::StringAttr::get(str.drop_back(trailingZerosNum),
73 finalSize += (ensureNullTerm && trailingZerosNum == 0);
75 auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
76 return cir::ConstArrayAttr::get(fullArrayTy, strAttr);
80 cir::ArrayType arrayTy)
const {
81 return cir::ConstArrayAttr::get(arrayTy, attrs);
87 mlir::Type
type = {});
94 for (
auto &f : arrayAttr) {
95 auto ta = mlir::cast<mlir::TypedAttr>(f);
96 members.push_back(ta.getType());
102 auto sTy = mlir::cast<cir::RecordType>(ty);
103 return cir::ConstRecordAttr::get(sTy, arrayAttr);
108 return cir::TypeInfoAttr::get(anonRecord.getType(), fieldsAttr);
114 auto it = recordNames.find(baseName);
115 if (it == recordNames.end()) {
116 recordNames[baseName] = 0;
120 return baseName +
"." + std::to_string(recordNames[baseName]++);
138 assert(llvm::convertExceptionBehaviorToStr(newExcept) &&
139 "Garbage strict exception behavior!");
140 defaultConstrainedExcept = newExcept;
145 return defaultConstrainedExcept;
150 assert(llvm::convertRoundingModeToStr(newRounding) &&
151 "Garbage strict rounding mode!");
152 defaultConstrainedRounding = newRounding;
157 return defaultConstrainedRounding;
161 if (&
format == &llvm::APFloat::IEEEdouble())
162 return cir::LongDoubleType::get(getContext(), typeCache.doubleTy);
163 if (&
format == &llvm::APFloat::x87DoubleExtended())
164 return cir::LongDoubleType::get(getContext(), typeCache.fP80Ty);
165 if (&
format == &llvm::APFloat::IEEEquad())
166 return cir::LongDoubleType::get(getContext(), typeCache.fP128Ty);
167 if (&
format == &llvm::APFloat::PPCDoubleDouble())
168 llvm_unreachable(
"NYI: PPC double-double format for long double");
169 llvm_unreachable(
"Unsupported format for long double");
177 bool isVarArg =
false) {
178 return cir::FuncType::get(params, retTy, isVarArg);
185 return cir::RecordType::Class;
187 return cir::RecordType::Struct;
189 return cir::RecordType::Union;
191 llvm_unreachable(
"interface records are NYI");
193 llvm_unreachable(
"enums are not records");
195 llvm_unreachable(
"Unsupported record kind");
203 bool packed,
bool padded,
204 llvm::StringRef name) {
205 const auto nameAttr = getStringAttr(name);
206 auto kind = cir::RecordType::RecordKind::Struct;
215 assert(!
type.isIncomplete() ||
216 (
type.getMembers() == members &&
type.getPacked() == packed &&
217 type.getPadded() == padded));
221 type.complete(members, packed, padded);
229 llvm::StringRef name =
"");
236 const mlir::StringAttr nameAttr = getStringAttr(name);
237 cir::RecordType::RecordKind
kind = cir::RecordType::RecordKind::Struct;
248 mlir::Value src, mlir::Value len) {
249 return cir::MemCpyOp::create(*
this, loc, dst, src, len);
253 mlir::Value src, mlir::Value len) {
254 return cir::MemMoveOp::create(*
this, loc, dst, src, len);
258 mlir::Value val, mlir::Value len) {
260 return cir::MemSetOp::create(*
this, loc, dst, {}, val, len);
267 return cir::MemSetOp::create(*
this, loc, dst.getPointer(), align, val, len);
272 unsigned memberIndex) {
273 return cir::DataMemberAttr::get(ty, memberIndex);
277 return cir::DataMemberAttr::get(ty);
283 if (mlir::isa<cir::ZeroAttr>(
attr))
286 if (
const auto ptrVal = mlir::dyn_cast<cir::ConstPtrAttr>(
attr))
287 return ptrVal.isNullValue();
289 if (
const auto intVal = mlir::dyn_cast<cir::IntAttr>(
attr))
290 return intVal.isNullValue();
292 if (
const auto boolVal = mlir::dyn_cast<cir::BoolAttr>(
attr))
293 return !boolVal.getValue();
295 if (
auto fpAttr = mlir::dyn_cast<cir::FPAttr>(
attr)) {
296 auto fpVal = fpAttr.getValue();
298 llvm::APFloat fv(+0.0);
299 fv.convert(fpVal.getSemantics(), llvm::APFloat::rmNearestTiesToEven,
301 return fv.bitwiseIsEqual(fpVal);
303 if (
const auto recordVal = mlir::dyn_cast<cir::ConstRecordAttr>(
attr)) {
304 for (
const auto elt : recordVal.getMembers()) {
306 if (mlir::isa<mlir::StringAttr>(elt))
314 if (
const auto arrayVal = mlir::dyn_cast<cir::ConstArrayAttr>(
attr)) {
315 if (mlir::isa<mlir::StringAttr>(arrayVal.getElts()))
319 mlir::cast<mlir::ArrayAttr>(arrayVal.getElts()),
320 [&](
const mlir::Attribute &elt) { return isNullValue(elt); });
340 return cir::IntType::get(getContext(), n,
false);
355 return cir::IntType::get(getContext(), n,
true);
376 cir::ConstantOp
getConstInt(mlir::Location loc, llvm::APSInt intVal);
378 cir::ConstantOp
getConstInt(mlir::Location loc, llvm::APInt intVal,
381 cir::ConstantOp
getConstInt(mlir::Location loc, mlir::Type t, uint64_t
c);
383 cir::ConstantOp
getConstFP(mlir::Location loc, mlir::Type t,
384 llvm::APFloat fpVal);
387 return i == typeCache.uInt8Ty || i == typeCache.sInt8Ty;
390 return i == typeCache.uInt16Ty || i == typeCache.sInt16Ty;
393 return i == typeCache.uInt32Ty || i == typeCache.sInt32Ty;
396 return i == typeCache.uInt64Ty || i == typeCache.sInt64Ty;
398 bool isInt(mlir::Type i) {
return mlir::isa<cir::IntType>(i); }
405 bool packed =
false,
bool padded =
false) {
407 auto kind = cir::RecordType::RecordKind::Struct;
432 if (
auto intTy = mlir::dyn_cast<cir::IntType>(value.getType())) {
434 if (intTy.isUnsigned())
439 llvm_unreachable(
"negation for the given type is NYI");
443 assert(mlir::isa<cir::FPTypeInterface>(value.getType()) &&
444 "Non-fp input type!");
456 mlir::Value
createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
461 return cir::SubOp::create(*
this, loc, lhs, rhs);
464 mlir::Value
createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
469 return cir::AddOp::create(*
this, loc, lhs, rhs);
472 mlir::Value
createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
477 return cir::MulOp::create(*
this, loc, lhs, rhs);
479 mlir::Value
createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
484 return cir::DivOp::create(*
this, loc, lhs, rhs);
496 return cir::CastOp::create(*
this, v.getLoc(), destType,
497 cir::CastKind::floating, v);
501 cir::PointerType destType,
bool isRefCast,
502 cir::DynamicCastInfoAttr info) {
504 isRefCast ? cir::DynamicCastKind::Ref : cir::DynamicCastKind::Ptr;
505 return cir::DynamicCastOp::create(*
this, loc, destType, castKind, src, info,
510 bool vtableUseRelativeLayout) {
514 return cir::DynamicCastOp::create(
515 *
this, loc, destTy, cir::DynamicCastKind::Ptr, src,
516 cir::DynamicCastInfoAttr{}, vtableUseRelativeLayout);
523 mlir::Type destType,
unsigned offset,
524 bool assumeNotNull) {
530 cir::BaseClassAddrOp::create(*
this, loc, ptrTy, addr.
getPointer(),
531 mlir::APInt(64, offset), assumeNotNull);
536 mlir::Type destType,
unsigned offset,
537 bool assumeNotNull) {
543 cir::DerivedClassAddrOp::create(*
this, loc, ptrTy, addr.
getPointer(),
544 mlir::APInt(64, offset), assumeNotNull);
552 mlir::Value addr, uint64_t offset) {
553 return cir::VTTAddrPointOp::create(*
this, loc, retTy,
554 mlir::FlatSymbolRefAttr{}, addr, offset);
558 mlir::FlatSymbolRefAttr sym, uint64_t offset) {
559 return cir::VTTAddrPointOp::create(*
this, loc, retTy, sym, mlir::Value{},
567 cir::FPClassTest flags) {
568 return cir::IsFPClassOp::create(*
this, loc, src, flags);
574 mlir::Type destType) {
584 bool isVolatile =
false) {
586 return cir::LoadOp::create(*
this, loc, addr.
getPointer(),
false,
588 cir::SyncScopeKindAttr{},
589 cir::MemOrderAttr{});
593 mlir::Value ptr, llvm::MaybeAlign align) {
594 if (ty != mlir::cast<cir::PointerType>(ptr.getType()).getPointee())
596 uint64_t alignment = align ? align->value() : 0;
598 return cir::LoadOp::create(*
this, loc, ptr,
false,
600 cir::SyncScopeKindAttr{},
601 cir::MemOrderAttr{});
611 bool isVolatile =
false,
612 mlir::IntegerAttr align = {},
613 cir::SyncScopeKindAttr scope = {},
614 cir::MemOrderAttr order = {}) {
617 return CIRBaseBuilderTy::createStore(loc, val, dst.getPointer(), isVolatile,
618 align, scope, order);
624 auto srcPtrTy = mlir::cast<cir::PointerType>(value.getType());
625 auto srcComplexTy = mlir::cast<cir::ComplexType>(srcPtrTy.getPointee());
626 return cir::ComplexRealPtrOp::create(
627 *
this, loc,
getPointerTo(srcComplexTy.getElementType()), value);
639 auto srcPtrTy = mlir::cast<cir::PointerType>(value.getType());
640 auto srcComplexTy = mlir::cast<cir::ComplexType>(srcPtrTy.getPointee());
641 return cir::ComplexImagPtrOp::create(
642 *
this, loc,
getPointerTo(srcComplexTy.getElementType()), value);
651 mlir::Value objectPtr,
652 mlir::Value memberPtr) {
653 auto memberPtrTy = mlir::cast<cir::DataMemberType>(memberPtr.getType());
657 cir::PointerType resultTy =
getPointerTo(memberPtrTy.getMemberTy());
659 return cir::GetRuntimeMemberOp::create(*
this, loc, resultTy, objectPtr,
667 mlir::Location arrayLocEnd, mlir::Value arrayPtr,
668 mlir::Type eltTy, mlir::Value idx,
692 [[nodiscard]] cir::GlobalOp
694 mlir::StringRef name, mlir::Type
type,
bool isConstant,
695 cir::GlobalLinkageKind linkage,
696 mlir::ptr::MemorySpaceAttrInterface addrSpace = {}) {
698 std::string uniqueName;
699 if (
unsigned version = globalsVersioning[name.str()]++)
700 uniqueName = name.str() +
"." + std::to_string(version);
702 uniqueName = name.str();
709 return cir::StackSaveOp::create(*
this, loc, ty);
713 return cir::StackRestoreOp::create(*
this, loc, v);
717 mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
718 const llvm::APSInt <Res,
const llvm::APSInt &eqRes,
719 const llvm::APSInt >Res, cir::CmpOrdering ordering) {
720 assert(ltRes.getBitWidth() == eqRes.getBitWidth() &&
721 ltRes.getBitWidth() == gtRes.getBitWidth() &&
722 "the three comparison results must have the same bit width");
723 assert((ordering == cir::CmpOrdering::Strong ||
724 ordering == cir::CmpOrdering::Weak) &&
725 "total ordering must be strong or weak");
726 cir::IntType cmpResultTy =
getSIntNTy(ltRes.getBitWidth());
727 auto infoAttr = cir::CmpThreeWayInfoAttr::get(
728 getContext(), ordering, ltRes.getSExtValue(), eqRes.getSExtValue(),
729 gtRes.getSExtValue());
730 return cir::CmpThreeWayOp::create(*
this, loc, cmpResultTy, lhs, rhs,
735 mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
736 const llvm::APSInt <Res,
const llvm::APSInt &eqRes,
737 const llvm::APSInt >Res,
const llvm::APSInt &unorderedRes) {
738 assert(ltRes.getBitWidth() == eqRes.getBitWidth() &&
739 ltRes.getBitWidth() == gtRes.getBitWidth() &&
740 ltRes.getBitWidth() == unorderedRes.getBitWidth() &&
741 "the four comparison results must have the same bit width");
742 cir::IntType cmpResultTy =
getSIntNTy(ltRes.getBitWidth());
743 auto infoAttr = cir::CmpThreeWayInfoAttr::get(
744 getContext(), ltRes.getSExtValue(), eqRes.getSExtValue(),
745 gtRes.getSExtValue(), unorderedRes.getSExtValue());
746 return cir::CmpThreeWayOp::create(*
this, loc, cmpResultTy, lhs, rhs,
751 Address dstAddr, mlir::Type storageType,
753 bool isLvalueVolatile,
bool useVolatile) {
759 useVolatile ? cir::IntType::get(storageType.getContext(),
762 return cir::SetBitfieldOp::create(
763 *
this, loc, resultType, dstAddr.
getPointer(), storageType, src,
769 Address addr, mlir::Type storageType,
771 bool isLvalueVolatile,
bool useVolatile) {
777 useVolatile ? cir::IntType::get(storageType.getContext(),
780 return cir::GetBitfieldOp::create(*
this, loc, resultType, addr.
getPointer(),
781 storageType, info.
name, info.
size, offset,
787 mlir::Value ptr, llvm::Align alignment,
788 mlir::Value mask, mlir::Value passThru) {
789 assert(mlir::isa<cir::VectorType>(ty) &&
"Type should be vector");
790 assert(mask &&
"Mask should not be all-ones (null)");
793 passThru = this->
getConstant(loc, cir::PoisonAttr::get(ty));
796 this->getI64IntegerAttr(
static_cast<int64_t
>(alignment.value()));
798 return cir::VecMaskedLoadOp::create(*
this, loc, ty, ptr, mask, passThru,
805 auto vecType = mlir::cast<cir::VectorType>(vec1.getType());
807 cir::VectorType::get(vecType.getElementType(), maskAttrs.size());
808 return cir::VecShuffleOp::create(*
this, loc, resultTy, vec1, vec2,
809 getArrayAttr(maskAttrs));
815 auto maskAttrs = llvm::to_vector_of<mlir::Attribute>(
816 llvm::map_range(mask, [&](int32_t idx) {
826 cir::ConstantOp poison =
827 getConstant(loc, cir::PoisonAttr::get(vec1.getType()));
831 template <
typename... Operands>
833 const mlir::Type &resTy, Operands &&...op) {
834 return cir::LLVMIntrinsicCallOp::create(*
this, loc,
835 this->getStringAttr(str), resTy,
836 std::forward<Operands>(op)...)
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
__device__ __2f16 float c
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)
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
cir::MemMoveOp createMemMove(mlir::Location loc, mlir::Value dst, mlir::Value src, mlir::Value len)
cir::RecordType getCompleteNamedRecordType(llvm::ArrayRef< mlir::Type > members, bool packed, bool padded, llvm::StringRef name)
Get a CIR named record type.
cir::StackSaveOp createStackSave(mlir::Location loc, mlir::Type ty)
cir::IntType getUInt64Ty()
cir::IntType getUInt8Ty()
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)
cir::RecordType::RecordKind getRecordKind(const clang::TagTypeKind kind)
Get a CIR record kind from a AST declaration tag.
mlir::Value emitIntrinsicCallOp(mlir::Location loc, const llvm::StringRef str, const mlir::Type &resTy, Operands &&...op)
cir::IntType getSIntNTy(int n)
cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type ty={})
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::RecordType getIncompleteRecordTy(llvm::StringRef name, const clang::RecordDecl *rd)
Get an incomplete CIR struct type.
cir::ConstantOp getUInt32(uint32_t c, mlir::Location loc)
void setDefaultConstrainedRounding(llvm::RoundingMode newRounding)
Set the rounding mode handling to be used with constrained floating point.
cir::MemCpyOp createMemCpy(mlir::Location loc, mlir::Value dst, mlir::Value src, mlir::Value len)
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1, mlir::Value vec2, llvm::ArrayRef< mlir::Attribute > maskAttrs)
cir::PointerType getUInt8PtrTy()
std::string getUniqueRecordName(const std::string &baseName)
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
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)
cir::RecordType getAnonRecordTy(llvm::ArrayRef< mlir::Type > members, bool packed=false, bool padded=false)
Get a CIR anonymous record type.
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::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()
mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::SingleType getSingleTy()
Address createDerivedClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)
std::string getUniqueAnonRecordName()
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
cir::GetRuntimeMemberOp createGetIndirectMember(mlir::Location loc, mlir::Value objectPtr, mlir::Value memberPtr)
llvm::RoundingMode getDefaultConstrainedRounding() const
Get the rounding mode handling used with constrained floating point.
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::IntType getSInt8Ty()
void setDefaultConstrainedExcept(llvm::fp::ExceptionBehavior newExcept)
Set the exception handling to be used with constrained floating point.
bool isInt16Ty(mlir::Type i)
bool isInt32Ty(mlir::Type i)
mlir::Value createDynCastToVoid(mlir::Location loc, mlir::Value src, bool vtableUseRelativeLayout)
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1, llvm::ArrayRef< int64_t > mask)
cir::BF16Type getBfloat6Ty()
mlir::Value createFNeg(mlir::Value value)
cir::IntType getUInt16Ty()
mlir::Value createDynCast(mlir::Location loc, mlir::Value src, cir::PointerType destType, bool isRefCast, cir::DynamicCastInfoAttr info)
llvm::fp::ExceptionBehavior getDefaultConstrainedExcept() const
Get the exception handling used with constrained floating point.
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)
mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
bool getIsFPConstrained() const
Query for the use of constrained floating point math.
CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
cir::IsFPClassOp createIsFPClass(mlir::Location loc, mlir::Value src, cir::FPClassTest flags)
cir::RecordType getCompleteRecordType(mlir::ArrayAttr fields, bool packed=false, bool padded=false, llvm::StringRef name="")
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()
void setIsFPConstrained(bool isCon)
Enable/Disable use of constrained floating point math.
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::IntType getUInt32Ty()
mlir::Type getPtrToVPtrType()
cir::IntType getSInt32Ty()
Address createComplexImagPtr(mlir::Location loc, Address addr)
mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const
cir::IntType getSInt16Ty()
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
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)
mlir::Value createNeg(mlir::Value value)
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, clang::CharUnits align=clang::CharUnits::One())
cir::DataMemberAttr getDataMemberAttr(cir::DataMemberType ty, unsigned memberIndex)
cir::DoubleType getDoubleTy()
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
static CharUnits One()
One - Construct a CharUnits quantity of one.
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.
@ Interface
The "__interface" keyword.
@ Struct
The "struct" keyword.
@ Class
The "class" keyword.
@ Union
The "union" keyword.
@ Enum
The "enum" keyword.
static bool metaDataNode()
static bool addressSpace()
static bool fpConstraints()
static bool astRecordDeclAttr()
static bool fastMathFlags()
Record with information about how a bitfield should be accessed.
unsigned offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
unsigned volatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned size
The total size of the bit-field, in bits.
unsigned isSigned
Whether the bit-field is signed.
unsigned volatileOffset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
llvm::StringRef name
The name of a bitfield.
This structure provides a set of types that are commonly used during IR emission.