Skip to content

Commit

Permalink
Add some support for std::vector (and likely other single member/firs…
Browse files Browse the repository at this point in the history
…t member data containers)
  • Loading branch information
agozillon committed Dec 18, 2023
1 parent 259921b commit 82d1a16
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5359,6 +5359,9 @@ APValue *FindSubobjectAPVal(APValue &APV, EvalInfo &Info) {
if (APV.isNullPointer())
return &APV;

if (APV.isStruct())
APV = APV.getStructField(0);

QualType Type = getType(APV.getLValueBase());
ArrayRef<APValue::LValuePathEntry> Path = APV.getLValuePath();

Expand Down Expand Up @@ -6088,21 +6091,43 @@ class LoopWrapperGatherer : public ConstStmtVisitor<LoopWrapperGatherer, bool> {
llvm::Any ArgOrTemp;
int64_t TySz;

const Expr *ExprArgZero = E->getArg(0);
if (auto CE = dyn_cast<CXXConstructExpr>(E->getArg(0)))
ExprArgZero = CE->getArg(0);

// Parameter: T Var
// FIXME/TODO: Make this a function, so we can reuse it in the other
// 2 calls and more in the future, its a common idiom at this point
if (auto ICE = dyn_cast<ImplicitCastExpr>(E->getArg(0)))
if (auto ICE = dyn_cast<ImplicitCastExpr>(ExprArgZero))
if (auto DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
if (auto PVD = dyn_cast<const ParmVarDecl>(DRE->getDecl())) {
ArgOrTemp = PVD;
QualType QTy = PVD->getType();

// NOTE: This will only work for std::vector, or containers with a
// single member (or the first member of the container) that happens
// to be the data we are working on
if (QTy->isRecordType()) {
auto RD= QTy->getAsRecordDecl();
QTy = RD->field_begin()->getType();
}

TySz = QTy->isPointerType() || QTy->isReferenceType()
? Info.Ctx.getTypeSizeInChars(QTy->getPointeeType())
.getQuantity()
: Info.Ctx.getTypeSizeInChars(QTy).getQuantity();
} else if (auto VD = dyn_cast<VarDecl>(DRE->getDecl())) {
ArgOrTemp = static_cast<const void *>(VD);
QualType QTy = VD->getType();

// NOTE: This will only work for std::vector, or containers with a
// single member (or the first member of the container) that happens
// to be the data we are working on
if (QTy->isRecordType()) {
auto RD= QTy->getAsRecordDecl();
QTy = RD->field_begin()->getType();
}

TySz = QTy->isPointerType() || QTy->isReferenceType()
? Info.Ctx.getTypeSizeInChars(QTy->getPointeeType())
.getQuantity()
Expand All @@ -6122,7 +6147,7 @@ class LoopWrapperGatherer : public ConstStmtVisitor<LoopWrapperGatherer, bool> {

if (OpInt < 0 || AccumInt < 0)
return false;

// A reduction should be excluded from the normal copy back interaction
// as it's a special case handling of copying back some data from
// threads
Expand All @@ -6131,7 +6156,6 @@ class LoopWrapperGatherer : public ConstStmtVisitor<LoopWrapperGatherer, bool> {

RedList.push_back(std::tuple<int, int, llvm::Any, int64_t, APValue>(
AccumInt, OpInt, ArgOrTemp, TySz, CopyAPValue(ArgOrTemp)));

return true;
}

Expand Down Expand Up @@ -6698,7 +6722,7 @@ void OrderedAssign(EvalInfo &Info, std::vector<EvalInfo> &ThreadInfo,
// the below code wont work for everything
APValue *SubObjAPVal = GetArgOrTemp(ArgOrTemp, Info);
APValue *CompleteObjAPV = FindSubobjectAPVal(*SubObjAPVal, Info);

if (CompleteObjAPV->isArray()) {
// NOTE: In certain cases (like std::array) you can use
// getTypeSizeInChars on the ParentQt QualType to get the correct
Expand Down Expand Up @@ -6744,6 +6768,7 @@ void OrderedAssign(EvalInfo &Info, std::vector<EvalInfo> &ThreadInfo,
}
} else {
int64_t PrevEndIndex = 0;

for (int i = 0; i < Lwg.GetThreadUtilisation(); ++i) {
APValue *ThreadSubObjAPVal =
GetArgOrTemp(ArgOrTemp, ThreadInfo[i]);
Expand All @@ -6753,11 +6778,13 @@ void OrderedAssign(EvalInfo &Info, std::vector<EvalInfo> &ThreadInfo,
// In byte offset, not an index
int64_t IteratorEndPoint =
ThreadSubObjAPVal->getLValueOffset().getQuantity();

int64_t ThreadEndIndex = IteratorEndPoint / TySz;

// TODO/FIXME: This has to take into account overflow still
// int64_t ThreadStartIndex = (ThreadPartitionSize * i) / TySz;
int64_t ThreadStartIndex = (Partitioned) ? PrevEndIndex : 0;

for (int j = ThreadStartIndex; j < ThreadEndIndex; ++j) {
CompleteObjAPV->getArrayInitializedElt(ArrStartIndex)
.swap(ThreadObjAPV->getArrayInitializedElt(j));
Expand Down

0 comments on commit 82d1a16

Please sign in to comment.