2121#include " clang/AST/GlobalDecl.h"
2222#include " clang/Basic/Builtins.h"
2323#include " clang/CIR/Dialect/IR/CIRDialect.h"
24- #include " clang/CIR/Dialect/IR/CIROpsEnums.h"
2524#include " clang/CIR/Dialect/IR/CIRTypes.h"
2625#include " llvm/Support/Casting.h"
2726#include " llvm/Support/ErrorHandling.h"
@@ -129,7 +128,6 @@ static Address buildPointerWithAlignment(const Expr *E,
129128 if (PtrTy->getPointeeType ()->isVoidType ())
130129 break ;
131130 assert (!UnimplementedFeature::tbaa ());
132-
133131 LValueBaseInfo InnerBaseInfo;
134132 Address Addr = CGF.buildPointerWithAlignment (
135133 CE->getSubExpr (), &InnerBaseInfo, IsKnownNonNull);
@@ -213,78 +211,13 @@ static Address buildPointerWithAlignment(const Expr *E,
213211 return Address (CGF.buildScalarExpr (E), Align);
214212}
215213
216- // / Helper method to check if the underlying ABI is AAPCS
217- static bool isAAPCS (const TargetInfo &TargetInfo) {
218- return TargetInfo.getABI ().starts_with (" aapcs" );
219- }
220-
221- Address CIRGenFunction::getAddrOfField (LValue base, const FieldDecl *field,
222- unsigned index) {
223- if (index == 0 )
224- return base.getAddress ();
225-
226- auto loc = getLoc (field->getLocation ());
227- auto fieldType = convertType (field->getType ());
228- auto fieldPtr =
229- mlir::cir::PointerType::get (getBuilder ().getContext (), fieldType);
230- auto sea = getBuilder ().createGetMember (
231- loc, fieldPtr, base.getPointer (), field->getName (), index);
232-
233- return Address (sea, CharUnits::One ());
234- }
235-
236- static bool useVolatileForBitField (const CIRGenModule &cgm, LValue base,
237- const CIRGenBitFieldInfo &info,
238- const FieldDecl *field) {
239- return isAAPCS (cgm.getTarget ()) && cgm.getCodeGenOpts ().AAPCSBitfieldWidth &&
240- info.VolatileStorageSize != 0 &&
241- field->getType ()
242- .withCVRQualifiers (base.getVRQualifiers ())
243- .isVolatileQualified ();
244- }
245-
246- LValue CIRGenFunction::buildLValueForBitField (LValue base,
247- const FieldDecl *field) {
248-
249- LValueBaseInfo BaseInfo = base.getBaseInfo ();
250- const RecordDecl *rec = field->getParent ();
251- auto &layout = CGM.getTypes ().getCIRGenRecordLayout (field->getParent ());
252- auto &info = layout.getBitFieldInfo (field);
253- auto useVolatile = useVolatileForBitField (CGM, base, info, field);
254- unsigned Idx = layout.getCIRFieldNo (field);
255-
256- if (useVolatile ||
257- (IsInPreservedAIRegion ||
258- (getDebugInfo () && rec->hasAttr <BPFPreserveAccessIndexAttr>()))) {
259- llvm_unreachable (" NYI" );
260- }
261-
262- Address Addr = getAddrOfField (base, field, Idx);
263-
264- const unsigned SS = useVolatile ? info.VolatileStorageSize : info.StorageSize ;
265-
266- // Get the access type.
267- mlir::Type FieldIntTy = builder.getUIntNTy (SS);
268-
269- auto loc = getLoc (field->getLocation ());
270- if (Addr.getElementType () != FieldIntTy)
271- Addr = builder.createElementBitCast (loc, Addr, FieldIntTy);
272-
273- QualType fieldType =
274- field->getType ().withCVRQualifiers (base.getVRQualifiers ());
275-
276- assert (!UnimplementedFeature::tbaa () && " NYI TBAA for bit fields" );
277- LValueBaseInfo FieldBaseInfo (BaseInfo.getAlignmentSource ());
278- return LValue::MakeBitfield (Addr, info, fieldType, FieldBaseInfo);
279- }
280-
281214LValue CIRGenFunction::buildLValueForField (LValue base,
282215 const FieldDecl *field) {
283-
284216 LValueBaseInfo BaseInfo = base.getBaseInfo ();
285217
286- if (field->isBitField ())
287- return buildLValueForBitField (base, field);
218+ if (field->isBitField ()) {
219+ llvm_unreachable (" NYI" );
220+ }
288221
289222 // Fields of may-alias structures are may-alais themselves.
290223 // FIXME: this hould get propagated down through anonymous structs and unions.
@@ -587,55 +520,12 @@ void CIRGenFunction::buildStoreOfScalar(mlir::Value value, LValue lvalue,
587520// / method emits the address of the lvalue, then loads the result as an rvalue,
588521// / returning the rvalue.
589522RValue CIRGenFunction::buildLoadOfLValue (LValue LV, SourceLocation Loc) {
523+ assert (LV.isSimple () && " not implemented" );
590524 assert (!LV.getType ()->isFunctionType ());
591525 assert (!(LV.getType ()->isConstantMatrixType ()) && " not implemented" );
592526
593- if (LV.isBitField ())
594- return buildLoadOfBitfieldLValue (LV, Loc);
595-
596- if (LV.isSimple ())
597- return RValue::get (buildLoadOfScalar (LV, Loc));
598- llvm_unreachable (" NYI" );
599- }
600-
601- RValue CIRGenFunction::buildLoadOfBitfieldLValue (LValue LV,
602- SourceLocation Loc) {
603- const CIRGenBitFieldInfo &Info = LV.getBitFieldInfo ();
604-
605- // Get the output type.
606- mlir::Type ResLTy = convertType (LV.getType ());
607- Address Ptr = LV.getBitFieldAddress ();
608- mlir::Value Val = builder.createLoad (getLoc (Loc), Ptr);
609- auto ValWidth = Val.getType ().cast <IntType>().getWidth ();
610-
611- bool UseVolatile = LV.isVolatileQualified () &&
612- Info.VolatileStorageSize != 0 && isAAPCS (CGM.getTarget ());
613- const unsigned Offset = UseVolatile ? Info.VolatileOffset : Info.Offset ;
614- const unsigned StorageSize =
615- UseVolatile ? Info.VolatileStorageSize : Info.StorageSize ;
616-
617- if (Info.IsSigned ) {
618- assert (static_cast <unsigned >(Offset + Info.Size ) <= StorageSize);
619-
620- mlir::Type typ = builder.getSIntNTy (ValWidth);
621- Val = builder.createIntCast (Val, typ);
622-
623- unsigned HighBits = StorageSize - Offset - Info.Size ;
624- if (HighBits)
625- Val = builder.createShiftLeft (Val, HighBits);
626- if (Offset + HighBits)
627- Val = builder.createShiftRight (Val, Offset + HighBits);
628- } else {
629- if (Offset)
630- Val = builder.createShiftRight (Val, Offset);
631-
632- if (static_cast <unsigned >(Offset) + Info.Size < StorageSize)
633- Val = builder.createAnd (Val,
634- llvm::APInt::getLowBitsSet (ValWidth, Info.Size ));
635- }
636- Val = builder.createIntCast (Val, ResLTy);
637- assert (!UnimplementedFeature::emitScalarRangeCheck () && " NYI" );
638- return RValue::get (Val);
527+ // Everything needs a load.
528+ return RValue::get (buildLoadOfScalar (LV, Loc));
639529}
640530
641531void CIRGenFunction::buildStoreThroughLValue (RValue Src, LValue Dst) {
@@ -658,81 +548,6 @@ void CIRGenFunction::buildStoreThroughLValue(RValue Src, LValue Dst) {
658548 buildStoreOfScalar (Src.getScalarVal (), Dst);
659549}
660550
661- void CIRGenFunction::buildStoreThroughBitfieldLValue (RValue Src, LValue Dst,
662- mlir::Value &Result) {
663- const CIRGenBitFieldInfo &Info = Dst.getBitFieldInfo ();
664- mlir::Type ResLTy = getTypes ().convertTypeForMem (Dst.getType ());
665- Address Ptr = Dst.getBitFieldAddress ();
666-
667- // Get the source value, truncated to the width of the bit-field.
668- mlir::Value SrcVal = Src.getScalarVal ();
669-
670- // Cast the source to the storage type and shift it into place.
671- SrcVal = builder.createIntCast (SrcVal, Ptr.getElementType ());
672- auto SrcWidth = SrcVal.getType ().cast <IntType>().getWidth ();
673- mlir::Value MaskedVal = SrcVal;
674-
675- const bool UseVolatile =
676- CGM.getCodeGenOpts ().AAPCSBitfieldWidth && Dst.isVolatileQualified () &&
677- Info.VolatileStorageSize != 0 && isAAPCS (CGM.getTarget ());
678- const unsigned StorageSize =
679- UseVolatile ? Info.VolatileStorageSize : Info.StorageSize ;
680- const unsigned Offset = UseVolatile ? Info.VolatileOffset : Info.Offset ;
681- // See if there are other bits in the bitfield's storage we'll need to load
682- // and mask together with source before storing.
683- if (StorageSize != Info.Size ) {
684- assert (StorageSize > Info.Size && " Invalid bitfield size." );
685-
686- mlir::Value Val = buildLoadOfScalar (Dst, Dst.getPointer ().getLoc ());
687-
688- // Mask the source value as needed.
689- if (!hasBooleanRepresentation (Dst.getType ()))
690- SrcVal = builder.createAnd (
691- SrcVal, llvm::APInt::getLowBitsSet (SrcWidth, Info.Size ));
692-
693- MaskedVal = SrcVal;
694- if (Offset)
695- SrcVal = builder.createShiftLeft (SrcVal, Offset);
696-
697- // Mask out the original value.
698- Val = builder.createAnd (
699- Val, ~llvm::APInt::getBitsSet (SrcWidth, Offset, Offset + Info.Size ));
700-
701- // Or together the unchanged values and the source value.
702- SrcVal = builder.createOr (Val, SrcVal);
703-
704- } else {
705- // According to the AACPS:
706- // When a volatile bit-field is written, and its container does not overlap
707- // with any non-bit-field member, its container must be read exactly once
708- // and written exactly once using the access width appropriate to the type
709- // of the container. The two accesses are not atomic.
710- llvm_unreachable (" volatile bit-field is not implemented for the AACPS" );
711- }
712-
713- // Write the new value back out.
714- // TODO: constant matrix type, volatile, no init, non temporal, TBAA
715- buildStoreOfScalar (SrcVal, Ptr, Dst.isVolatileQualified (), Dst.getType (),
716- Dst.getBaseInfo (), false , false );
717-
718- // Return the new value of the bit-field.
719- mlir::Value ResultVal = MaskedVal;
720- ResultVal = builder.createIntCast (ResultVal, ResLTy);
721-
722- // Sign extend the value if needed.
723- if (Info.IsSigned ) {
724- assert (Info.Size <= StorageSize);
725- unsigned HighBits = StorageSize - Info.Size ;
726-
727- if (HighBits) {
728- ResultVal = builder.createShiftLeft (ResultVal, HighBits);
729- ResultVal = builder.createShiftRight (ResultVal, HighBits);
730- }
731- }
732-
733- Result = buildFromMemory (ResultVal, Dst.getType ());
734- }
735-
736551static LValue buildGlobalVarDeclLValue (CIRGenFunction &CGF, const Expr *E,
737552 const VarDecl *VD) {
738553 QualType T = E->getType ();
@@ -956,13 +771,7 @@ LValue CIRGenFunction::buildBinaryOperatorLValue(const BinaryOperator *E) {
956771 LValue LV = buildLValue (E->getLHS ());
957772
958773 SourceLocRAIIObject Loc{*this , getLoc (E->getSourceRange ())};
959- if (LV.isBitField ()) {
960- mlir::Value result;
961- buildStoreThroughBitfieldLValue (RV, LV, result);
962- } else {
963- buildStoreThroughLValue (RV, LV);
964- }
965-
774+ buildStoreThroughLValue (RV, LV);
966775 assert (!getContext ().getLangOpts ().OpenMP &&
967776 " last priv cond not implemented" );
968777 return LV;
@@ -2398,13 +2207,6 @@ mlir::Value CIRGenFunction::buildAlloca(StringRef name, QualType ty,
23982207
23992208mlir::Value CIRGenFunction::buildLoadOfScalar (LValue lvalue,
24002209 SourceLocation Loc) {
2401- return buildLoadOfScalar (lvalue.getAddress (), lvalue.isVolatile (),
2402- lvalue.getType (), getLoc (Loc), lvalue.getBaseInfo (),
2403- lvalue.isNontemporal ());
2404- }
2405-
2406- mlir::Value CIRGenFunction::buildLoadOfScalar (LValue lvalue,
2407- mlir::Location Loc) {
24082210 return buildLoadOfScalar (lvalue.getAddress (), lvalue.isVolatile (),
24092211 lvalue.getType (), Loc, lvalue.getBaseInfo (),
24102212 lvalue.isNontemporal ());
@@ -2422,14 +2224,6 @@ mlir::Value CIRGenFunction::buildLoadOfScalar(Address Addr, bool Volatile,
24222224 QualType Ty, SourceLocation Loc,
24232225 LValueBaseInfo BaseInfo,
24242226 bool isNontemporal) {
2425- return buildLoadOfScalar (Addr, Volatile, Ty, getLoc (Loc), BaseInfo,
2426- isNontemporal);
2427- }
2428-
2429- mlir::Value CIRGenFunction::buildLoadOfScalar (Address Addr, bool Volatile,
2430- QualType Ty, mlir::Location Loc,
2431- LValueBaseInfo BaseInfo,
2432- bool isNontemporal) {
24332227 if (!CGM.getCodeGenOpts ().PreserveVec3Type ) {
24342228 if (Ty->isVectorType ()) {
24352229 llvm_unreachable (" NYI" );
@@ -2443,14 +2237,15 @@ mlir::Value CIRGenFunction::buildLoadOfScalar(Address Addr, bool Volatile,
24432237 }
24442238
24452239 mlir::cir::LoadOp Load = builder.create <mlir::cir::LoadOp>(
2446- Loc, Addr.getElementType (), Addr.getPointer ());
2240+ getLoc ( Loc) , Addr.getElementType (), Addr.getPointer ());
24472241
24482242 if (isNontemporal) {
24492243 llvm_unreachable (" NYI" );
24502244 }
2451-
2452- assert (!UnimplementedFeature::tbaa () && " NYI" );
2453- assert (!UnimplementedFeature::emitScalarRangeCheck () && " NYI" );
2245+
2246+ // TODO: TBAA
2247+
2248+ // TODO: buildScalarRangeCheck
24542249
24552250 return buildFromMemory (Load, Ty);
24562251}
0 commit comments