@@ -6361,62 +6361,87 @@ LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) {
6361
6361
}
6362
6362
6363
6363
void CodeGenFunction::FlattenAccessAndType (
6364
- Address Val, QualType SrcTy, SmallVector<llvm::Value *, 4 > &IdxList,
6365
- SmallVector<std::pair<Address, llvm::Value *>, 16 > &GEPList,
6366
- SmallVector<QualType> &FlatTypes) {
6364
+ Address Addr, QualType AddrType,
6365
+ SmallVectorImpl<std::pair<Address, llvm::Value *>> &AccessList,
6366
+ SmallVectorImpl<QualType> &FlatTypes) {
6367
+ // WorkList is list of type we are processing + the Index List to access
6368
+ // the field of that type in Addr for use in a GEP
6369
+ llvm::SmallVector<std::pair<QualType, llvm::SmallVector<llvm::Value *, 4 >>,
6370
+ 16 >
6371
+ WorkList;
6367
6372
llvm::IntegerType *IdxTy = llvm::IntegerType::get (getLLVMContext (), 32 );
6368
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(SrcTy)) {
6369
- uint64_t Size = CAT->getZExtSize ();
6370
- for (unsigned i = 0 ; i < Size; i++) {
6371
- // flatten each member of the array
6372
- // add index of this element to index list
6373
- llvm::Value *Idx = llvm::ConstantInt::get (IdxTy, i);
6374
- IdxList.push_back (Idx);
6375
- // recur on this object
6376
- FlattenAccessAndType (Val, CAT->getElementType (), IdxList, GEPList,
6377
- FlatTypes);
6378
- // remove index of this element from index list
6379
- IdxList.pop_back ();
6380
- }
6381
- } else if (const RecordType *RT = SrcTy->getAs <RecordType>()) {
6382
- RecordDecl *Record = RT->getDecl ();
6383
- const CGRecordLayout &RL = getTypes ().getCGRecordLayout (Record);
6384
- // do I need to check if its a cxx record decl?
6385
-
6386
- for (auto fieldIter = Record->field_begin (), fieldEnd = Record->field_end ();
6387
- fieldIter != fieldEnd; ++fieldIter) {
6388
- // get the field number
6389
- unsigned FieldNum = RL.getLLVMFieldNo (*fieldIter);
6390
- // can we just do *fieldIter->getFieldIndex();
6391
- // add that index to the index list
6392
- llvm::Value *Idx = llvm::ConstantInt::get (IdxTy, FieldNum);
6393
- IdxList.push_back (Idx);
6394
- // recur on the field
6395
- FlattenAccessAndType (Val, fieldIter->getType (), IdxList, GEPList,
6396
- FlatTypes);
6397
- // remove index of this element from index list
6398
- IdxList.pop_back ();
6399
- }
6400
- } else if (const VectorType *VT = SrcTy->getAs <VectorType>()) {
6401
- llvm::Type *VTy = ConvertTypeForMem (SrcTy);
6402
- CharUnits Align = getContext ().getTypeAlignInChars (SrcTy);
6403
- Address GEP =
6404
- Builder.CreateInBoundsGEP (Val, IdxList, VTy, Align, " vector.gep" );
6405
- for (unsigned i = 0 ; i < VT->getNumElements (); i++) {
6406
- // add index to the list
6407
- llvm::Value *Idx = llvm::ConstantInt::get (IdxTy, i);
6408
- // create gep. no need to recur since its always a scalar
6409
- // gep on vector is not recommended so combine gep with extract/insert
6410
- GEPList.push_back ({GEP, Idx});
6411
- FlatTypes.push_back (VT->getElementType ());
6373
+ WorkList.push_back (
6374
+ {AddrType,
6375
+ {llvm::ConstantInt::get (
6376
+ IdxTy,
6377
+ 0 )}}); // Addr should be a pointer so we need to 'dereference' it
6378
+
6379
+ while (!WorkList.empty ()) {
6380
+ std::pair<QualType, llvm::SmallVector<llvm::Value *, 4 >> P =
6381
+ WorkList.pop_back_val ();
6382
+ QualType T = P.first ;
6383
+ llvm::SmallVector<llvm::Value *, 4 > IdxList = P.second ;
6384
+ T = T.getCanonicalType ().getUnqualifiedType ();
6385
+ assert (!isa<MatrixType>(T) && " Matrix types not yet supported in HLSL" );
6386
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(T)) {
6387
+ uint64_t Size = CAT->getZExtSize ();
6388
+ for (int64_t i = Size - 1 ; i > -1 ; i--) {
6389
+ llvm::SmallVector<llvm::Value *, 4 > IdxListCopy = IdxList;
6390
+ IdxListCopy.push_back (llvm::ConstantInt::get (IdxTy, i));
6391
+ WorkList.insert (WorkList.end (), {CAT->getElementType (), IdxListCopy});
6392
+ }
6393
+ } else if (const auto *RT = dyn_cast<RecordType>(T)) {
6394
+ const RecordDecl *Record = RT->getDecl ();
6395
+ if (Record->isUnion ()) {
6396
+ IdxList.push_back (llvm::ConstantInt::get (IdxTy, 0 ));
6397
+ llvm::Type *LLVMT = ConvertTypeForMem (T);
6398
+ CharUnits Align = getContext ().getTypeAlignInChars (T);
6399
+ Address GEP =
6400
+ Builder.CreateInBoundsGEP (Addr, IdxList, LLVMT, Align, " union.gep" );
6401
+ AccessList.push_back ({GEP, NULL });
6402
+ FlatTypes.push_back (T);
6403
+ continue ;
6404
+ }
6405
+ const CXXRecordDecl *CXXD = dyn_cast<CXXRecordDecl>(Record);
6406
+
6407
+ llvm::SmallVector<QualType, 16 > FieldTypes;
6408
+ if (CXXD && CXXD->isStandardLayout ())
6409
+ Record = CXXD->getStandardLayoutBaseWithFields ();
6410
+
6411
+ // deal with potential base classes
6412
+ if (CXXD && !CXXD->isStandardLayout ()) {
6413
+ for (auto &Base : CXXD->bases ())
6414
+ FieldTypes.push_back (Base.getType ());
6415
+ }
6416
+
6417
+ for (auto *FD : Record->fields ())
6418
+ FieldTypes.push_back (FD->getType ());
6419
+
6420
+ for (int64_t i = FieldTypes.size () - 1 ; i > -1 ; i--) {
6421
+ llvm::SmallVector<llvm::Value *, 4 > IdxListCopy = IdxList;
6422
+ IdxListCopy.push_back (llvm::ConstantInt::get (IdxTy, i));
6423
+ WorkList.insert (WorkList.end (), {FieldTypes[i], IdxListCopy});
6424
+ }
6425
+ } else if (const auto *VT = dyn_cast<VectorType>(T)) {
6426
+ llvm::Type *LLVMT = ConvertTypeForMem (T);
6427
+ CharUnits Align = getContext ().getTypeAlignInChars (T);
6428
+ Address GEP =
6429
+ Builder.CreateInBoundsGEP (Addr, IdxList, LLVMT, Align, " vector.gep" );
6430
+ for (unsigned i = 0 ; i < VT->getNumElements (); i++) {
6431
+ llvm::Value *Idx = llvm::ConstantInt::get (IdxTy, i);
6432
+ // gep on vector fields is not recommended so combine gep with
6433
+ // extract/insert
6434
+ AccessList.push_back ({GEP, Idx});
6435
+ FlatTypes.push_back (VT->getElementType ());
6436
+ }
6437
+ } else {
6438
+ // a scalar/builtin type
6439
+ llvm::Type *LLVMT = ConvertTypeForMem (T);
6440
+ CharUnits Align = getContext ().getTypeAlignInChars (T);
6441
+ Address GEP =
6442
+ Builder.CreateInBoundsGEP (Addr, IdxList, LLVMT, Align, " gep" );
6443
+ AccessList.push_back ({GEP, NULL });
6444
+ FlatTypes.push_back (T);
6412
6445
}
6413
- } else { // should be a scalar should we assert or check?
6414
- // create a gep
6415
- llvm::Type *Ty = ConvertTypeForMem (SrcTy);
6416
- CharUnits Align = getContext ().getTypeAlignInChars (SrcTy);
6417
- Address GEP = Builder.CreateInBoundsGEP (Val, IdxList, Ty, Align, " gep" );
6418
- GEPList.push_back ({GEP, NULL });
6419
- FlatTypes.push_back (SrcTy);
6420
- }
6421
- // target extension types?
6446
+ }
6422
6447
}
0 commit comments