|
@@ -4539,26 +4539,16 @@ SpirvEmitter::incDecRWACSBufferCounter(const CXXMemberCallExpr *expr,
|
|
(void)doExpr(object);
|
|
(void)doExpr(object);
|
|
}
|
|
}
|
|
|
|
|
|
- const auto *counterPair = getFinalACSBufferCounter(object);
|
|
|
|
- if (!counterPair) {
|
|
|
|
|
|
+ auto *counter = getFinalACSBufferCounterInstruction(object);
|
|
|
|
+ if (!counter) {
|
|
emitFatalError("cannot find the associated counter variable",
|
|
emitFatalError("cannot find the associated counter variable",
|
|
object->getExprLoc());
|
|
object->getExprLoc());
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
- llvm::SmallVector<SpirvInstruction *, 2> indexes;
|
|
|
|
- if(const auto *arraySubscriptExpr = dyn_cast<ArraySubscriptExpr>(object)) {
|
|
|
|
- // TODO(5440): This codes does not handle multi-dimensional arrays. We need
|
|
|
|
- // to look at specific example to determine the best way to do it.
|
|
|
|
- indexes.push_back(doExpr(arraySubscriptExpr->getIdx()));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
// Add an extra 0 because the counter is wrapped in a struct.
|
|
// Add an extra 0 because the counter is wrapped in a struct.
|
|
- indexes.push_back(zero);
|
|
|
|
-
|
|
|
|
- auto *counterPtr = spvBuilder.createAccessChain(
|
|
|
|
- astContext.IntTy, counterPair->get(spvBuilder, spvContext), indexes,
|
|
|
|
- srcLoc, srcRange);
|
|
|
|
|
|
+ auto *counterPtr = spvBuilder.createAccessChain(astContext.IntTy, counter,
|
|
|
|
+ {zero}, srcLoc, srcRange);
|
|
|
|
|
|
SpirvInstruction *index = nullptr;
|
|
SpirvInstruction *index = nullptr;
|
|
if (isInc) {
|
|
if (isInc) {
|
|
@@ -4596,13 +4586,13 @@ bool SpirvEmitter::tryToAssignCounterVar(const DeclaratorDecl *dstDecl,
|
|
// Handle AssocCounter#1 (see CounterVarFields comment)
|
|
// Handle AssocCounter#1 (see CounterVarFields comment)
|
|
if (const auto *dstPair =
|
|
if (const auto *dstPair =
|
|
declIdMapper.createOrGetCounterIdAliasPair(dstDecl)) {
|
|
declIdMapper.createOrGetCounterIdAliasPair(dstDecl)) {
|
|
- const auto *srcPair = getFinalACSBufferCounter(srcExpr);
|
|
|
|
- if (!srcPair) {
|
|
|
|
|
|
+ auto *srcCounter = getFinalACSBufferCounterInstruction(srcExpr);
|
|
|
|
+ if (!srcCounter) {
|
|
emitFatalError("cannot find the associated counter variable",
|
|
emitFatalError("cannot find the associated counter variable",
|
|
srcExpr->getExprLoc());
|
|
srcExpr->getExprLoc());
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
- dstPair->assign(*srcPair, spvBuilder, spvContext);
|
|
|
|
|
|
+ dstPair->assign(srcCounter, spvBuilder);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4633,18 +4623,18 @@ bool SpirvEmitter::tryToAssignCounterVar(const Expr *dstExpr,
|
|
dstExpr = dstExpr->IgnoreParenCasts();
|
|
dstExpr = dstExpr->IgnoreParenCasts();
|
|
srcExpr = srcExpr->IgnoreParenCasts();
|
|
srcExpr = srcExpr->IgnoreParenCasts();
|
|
|
|
|
|
- const auto *dstPair = getFinalACSBufferCounter(dstExpr);
|
|
|
|
- const auto *srcPair = getFinalACSBufferCounter(srcExpr);
|
|
|
|
|
|
+ auto *dstCounter = getFinalACSBufferCounterAliasAddressInstruction(dstExpr);
|
|
|
|
+ auto *srcCounter = getFinalACSBufferCounterInstruction(srcExpr);
|
|
|
|
|
|
- if ((dstPair == nullptr) != (srcPair == nullptr)) {
|
|
|
|
|
|
+ if ((dstCounter == nullptr) != (srcCounter == nullptr)) {
|
|
emitFatalError("cannot handle associated counter variable assignment",
|
|
emitFatalError("cannot handle associated counter variable assignment",
|
|
srcExpr->getExprLoc());
|
|
srcExpr->getExprLoc());
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// Handle AssocCounter#1 & AssocCounter#2
|
|
// Handle AssocCounter#1 & AssocCounter#2
|
|
- if (dstPair && srcPair) {
|
|
|
|
- dstPair->assign(*srcPair, spvBuilder, spvContext);
|
|
|
|
|
|
+ if (dstCounter && srcCounter) {
|
|
|
|
+ spvBuilder.createStore(dstCounter, srcCounter, /* SourceLocation */ {});
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4662,6 +4652,37 @@ bool SpirvEmitter::tryToAssignCounterVar(const Expr *dstExpr,
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+SpirvInstruction *SpirvEmitter::getFinalACSBufferCounterAliasAddressInstruction(
|
|
|
|
+ const Expr *expr) {
|
|
|
|
+ const CounterIdAliasPair *counter = getFinalACSBufferCounter(expr);
|
|
|
|
+ return (counter ? counter->getAliasAddress() : nullptr);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+SpirvInstruction *
|
|
|
|
+SpirvEmitter::getFinalACSBufferCounterInstruction(const Expr *expr) {
|
|
|
|
+ const CounterIdAliasPair *counterPair = getFinalACSBufferCounter(expr);
|
|
|
|
+ if (!counterPair)
|
|
|
|
+ return nullptr;
|
|
|
|
+
|
|
|
|
+ SpirvInstruction *counter =
|
|
|
|
+ counterPair->getCounterVariable(spvBuilder, spvContext);
|
|
|
|
+ const auto srcLoc = expr->getExprLoc();
|
|
|
|
+
|
|
|
|
+ // TODO(5440): This codes does not handle multi-dimensional arrays. We need
|
|
|
|
+ // to look at specific example to determine the best way to do it. Could a
|
|
|
|
+ // call to collectArrayStructIndices handle that for us?
|
|
|
|
+ llvm::SmallVector<SpirvInstruction *, 2> indexes;
|
|
|
|
+ if (const auto *arraySubscriptExpr = dyn_cast<ArraySubscriptExpr>(expr)) {
|
|
|
|
+ indexes.push_back(doExpr(arraySubscriptExpr->getIdx()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!indexes.empty()) {
|
|
|
|
+ counter = spvBuilder.createAccessChain(spvContext.getACSBufferCounterType(),
|
|
|
|
+ counter, indexes, srcLoc);
|
|
|
|
+ }
|
|
|
|
+ return counter;
|
|
|
|
+}
|
|
|
|
+
|
|
const CounterIdAliasPair *
|
|
const CounterIdAliasPair *
|
|
SpirvEmitter::getFinalACSBufferCounter(const Expr *expr) {
|
|
SpirvEmitter::getFinalACSBufferCounter(const Expr *expr) {
|
|
// AssocCounter#1: referencing some stand-alone variable
|
|
// AssocCounter#1: referencing some stand-alone variable
|