Skip to content

Commit

Permalink
[clang][Interp] Cleaning up FIXMEs added during ArrayInitLoopExpr
Browse files Browse the repository at this point in the history
… implementation. (#70053)

This patch removes the two `FIXME`s that were added with patches related
to the expression mentioned in the title.
  • Loading branch information
isuckatcs committed Jan 26, 2024
1 parent f13aac6 commit c177507
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
20 changes: 8 additions & 12 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1056,21 +1056,17 @@ bool ByteCodeExprGen<Emitter>::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
assert(Initializing);
assert(!DiscardResult);

// We visit the common opaque expression here once so we have its value
// cached.
if (!this->discard(E->getCommonExpr()))
return false;

// TODO: This compiles to quite a lot of bytecode if the array is larger.
// Investigate compiling this to a loop.

const Expr *SubExpr = E->getSubExpr();
const Expr *CommonExpr = E->getCommonExpr();
size_t Size = E->getArraySize().getZExtValue();

// If the common expression is an opaque expression, we visit it
// here once so we have its value cached.
// FIXME: This might be necessary (or useful) for all expressions.
if (isa<OpaqueValueExpr>(CommonExpr)) {
if (!this->discard(CommonExpr))
return false;
}

// So, every iteration, we execute an assignment here
// where the LHS is on the stack (the target array)
// and the RHS is our SubExpr.
Expand Down Expand Up @@ -1107,13 +1103,13 @@ bool ByteCodeExprGen<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
return false;

// Here the local variable is created but the value is removed from the stack,
// so we put it back, because the caller might need it.
// so we put it back if the caller needs it.
if (!DiscardResult) {
if (!this->emitGetLocal(SubExprT, *LocalIndex, E))
return false;
}

// FIXME: Ideally the cached value should be cleaned up later.
// This is cleaned up when the local variable is destroyed.
OpaqueExprs.insert({E, *LocalIndex});

return true;
Expand Down
21 changes: 21 additions & 0 deletions clang/lib/AST/Interp/ByteCodeExprGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
if (!Idx)
return;
this->Ctx->emitDestroy(*Idx, SourceInfo{});
removeStoredOpaqueValues();
}

/// Overriden to support explicit destruction.
Expand All @@ -382,6 +383,7 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
return;
this->emitDestructors();
this->Ctx->emitDestroy(*Idx, SourceInfo{});
removeStoredOpaqueValues();
this->Idx = std::nullopt;
}

Expand All @@ -403,10 +405,29 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
this->Ctx->emitGetPtrLocal(Local.Offset, SourceInfo{});
this->Ctx->emitRecordDestruction(Local.Desc);
removeIfStoredOpaqueValue(Local);
}
}
}

void removeStoredOpaqueValues() {
if (!Idx)
return;

for (const Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
removeIfStoredOpaqueValue(Local);
}
}

void removeIfStoredOpaqueValue(const Scope::Local &Local) {
if (const auto *OVE =
llvm::dyn_cast_if_present<OpaqueValueExpr>(Local.Desc->asExpr())) {
if (auto It = this->Ctx->OpaqueExprs.find(OVE);
It != this->Ctx->OpaqueExprs.end())
this->Ctx->OpaqueExprs.erase(It);
};
}

/// Index of the scope in the chain.
std::optional<unsigned> Idx;
};
Expand Down

0 comments on commit c177507

Please sign in to comment.