@@ -98,15 +98,13 @@ class CopyingValueRepresentation {
98
98
99
99
class FieldMemcpyizer {
100
100
public:
101
- FieldMemcpyizer (CIRGenFunction &CGF, const CXXRecordDecl *ClassDecl ,
101
+ FieldMemcpyizer (CIRGenFunction &CGF, const CXXMethodDecl *MethodDecl ,
102
102
const VarDecl *SrcRec)
103
- : CGF(CGF), ClassDecl( ClassDecl),
104
- // SrcRec(SrcRec),
103
+ : CGF(CGF), MethodDecl(MethodDecl), ClassDecl(MethodDecl-> getParent () ),
104
+ SrcRec(SrcRec),
105
105
RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
106
106
FirstField(nullptr ), LastField(nullptr ), FirstFieldOffset(0 ),
107
- LastFieldOffset(0 ), LastAddedFieldIndex(0 ) {
108
- (void )SrcRec;
109
- }
107
+ LastFieldOffset(0 ), LastAddedFieldIndex(0 ) {}
110
108
111
109
bool isMemcpyableField (FieldDecl *F) const {
112
110
// Never memcpy fields when we are adding poised paddings.
@@ -115,11 +113,11 @@ class FieldMemcpyizer {
115
113
Qualifiers Qual = F->getType ().getQualifiers ();
116
114
if (Qual.hasVolatile () || Qual.hasObjCLifetime ())
117
115
return false ;
118
-
119
116
return true ;
120
117
}
121
118
122
119
void addMemcpyableField (FieldDecl *F) {
120
+ assert (!cir::MissingFeatures::isEmptyFieldForLayout ());
123
121
if (F->isZeroSize (CGF.getContext ()))
124
122
return ;
125
123
if (!FirstField)
@@ -148,18 +146,54 @@ class FieldMemcpyizer {
148
146
return ;
149
147
}
150
148
151
- llvm_unreachable (" NYI" );
149
+ uint64_t firstByteOffset;
150
+ if (FirstField->isBitField ()) {
151
+ const CIRGenRecordLayout &rl =
152
+ CGF.getTypes ().getCIRGenRecordLayout (FirstField->getParent ());
153
+ const CIRGenBitFieldInfo &bfInfo = rl.getBitFieldInfo (FirstField);
154
+ // FirstFieldOffset is not appropriate for bitfields,
155
+ // we need to use the storage offset instead.
156
+ firstByteOffset = CGF.getContext ().toBits (bfInfo.StorageOffset );
157
+ } else {
158
+ firstByteOffset = FirstFieldOffset;
159
+ }
160
+
161
+ CharUnits memcpySize = getMemcpySize (firstByteOffset);
162
+ QualType recordTy = CGF.getContext ().getTypeDeclType (ClassDecl);
163
+ Address thisPtr = CGF.LoadCXXThisAddress ();
164
+ LValue destLv = CGF.makeAddrLValue (thisPtr, recordTy);
165
+ LValue dest = CGF.emitLValueForFieldInitialization (destLv, FirstField,
166
+ FirstField->getName ());
167
+ cir::LoadOp srcPtr = CGF.getBuilder ().createLoad (
168
+ CGF.getLoc (MethodDecl->getLocation ()), CGF.GetAddrOfLocalVar (SrcRec));
169
+ LValue srcLv = CGF.MakeNaturalAlignAddrLValue (srcPtr, recordTy);
170
+ LValue src = CGF.emitLValueForFieldInitialization (srcLv, FirstField,
171
+ FirstField->getName ());
172
+
173
+ emitMemcpyIR (dest.isBitField () ? dest.getBitFieldAddress ()
174
+ : dest.getAddress (),
175
+ src.isBitField () ? src.getBitFieldAddress () : src.getAddress (),
176
+ memcpySize);
177
+ reset ();
152
178
}
153
179
154
180
void reset () { FirstField = nullptr ; }
155
181
156
182
protected:
157
183
CIRGenFunction &CGF;
184
+ const CXXMethodDecl *MethodDecl;
158
185
const CXXRecordDecl *ClassDecl;
159
186
160
187
private:
161
188
void emitMemcpyIR (Address DestPtr, Address SrcPtr, CharUnits Size ) {
162
- llvm_unreachable (" NYI" );
189
+ mlir::Location loc = CGF.getLoc (MethodDecl->getLocation ());
190
+ cir::ConstantOp sizeOp =
191
+ CGF.getBuilder ().getConstInt (loc, CGF.SizeTy , Size .getQuantity ());
192
+ mlir::Value dest =
193
+ CGF.getBuilder ().createBitcast (DestPtr.getPointer (), CGF.VoidPtrTy );
194
+ mlir::Value src =
195
+ CGF.getBuilder ().createBitcast (SrcPtr.getPointer (), CGF.VoidPtrTy );
196
+ CGF.getBuilder ().createMemCpy (loc, dest, src, sizeOp);
163
197
}
164
198
165
199
void addInitialField (FieldDecl *F) {
@@ -192,7 +226,7 @@ class FieldMemcpyizer {
192
226
}
193
227
}
194
228
195
- // const VarDecl *SrcRec;
229
+ const VarDecl *SrcRec;
196
230
const ASTRecordLayout &RecLayout;
197
231
FieldDecl *FirstField;
198
232
FieldDecl *LastField;
@@ -307,8 +341,7 @@ class ConstructorMemcpyizer : public FieldMemcpyizer {
307
341
public:
308
342
ConstructorMemcpyizer (CIRGenFunction &CGF, const CXXConstructorDecl *CD,
309
343
FunctionArgList &Args)
310
- : FieldMemcpyizer(CGF, CD->getParent (),
311
- getTrivialCopySource(CGF, CD, Args)),
344
+ : FieldMemcpyizer(CGF, CD, getTrivialCopySource(CGF, CD, Args)),
312
345
ConstructorDecl (CD),
313
346
MemcpyableCtor(CD->isDefaulted () && CD->isCopyOrMoveConstructor() &&
314
347
CGF.getLangOpts().getGC() == LangOptions::NonGC),
@@ -446,7 +479,7 @@ class AssignmentMemcpyizer : public FieldMemcpyizer {
446
479
public:
447
480
AssignmentMemcpyizer (CIRGenFunction &CGF, const CXXMethodDecl *AD,
448
481
FunctionArgList &Args)
449
- : FieldMemcpyizer(CGF, AD-> getParent () , Args[Args.size() - 1]),
482
+ : FieldMemcpyizer(CGF, AD, Args[Args.size() - 1 ]),
450
483
AssignmentsMemcpyable (CGF.getLangOpts().getGC() == LangOptions::NonGC) {
451
484
assert (Args.size () == 2 );
452
485
}
0 commit comments