@@ -341,31 +341,65 @@ class CounterExpr {
341341 // / Returns true if this is a Zero node.
342342 bool isZero () const { return K == Kind::Zero; }
343343
344+ // / Returns true if the counter is semantically a Zero node. This considers
345+ // / the simplified version of the counter that has eliminated redundant
346+ // / operations.
347+ bool isSemanticallyZero () const {
348+ // Run the counter through the counter builder to simplify it, using a dummy
349+ // mapping of unique counter indices for each node reference. The value of
350+ // the indices doesn't matter, but we need to ensure that e.g subtraction
351+ // of a node from itself cancels out.
352+ llvm::coverage::CounterExpressionBuilder Builder;
353+ llvm::DenseMap<ASTNode, unsigned > DummyIndices;
354+ unsigned LastIdx = 0 ;
355+ auto Counter = expand (Builder, [&](auto Node) {
356+ if (!DummyIndices.count (Node)) {
357+ DummyIndices[Node] = LastIdx;
358+ LastIdx += 1 ;
359+ }
360+ return DummyIndices[Node];
361+ });
362+ return Counter.isZero ();
363+ }
364+
344365 // / Expand this node into an llvm::coverage::Counter.
345366 // /
346367 // / Updates \c Builder with any expressions that are needed to represent this
347368 // / counter.
348369 llvm::coverage::Counter
349370 expand (llvm::coverage::CounterExpressionBuilder &Builder,
350- llvm::DenseMap<ASTNode, unsigned > &Counters ) const {
371+ llvm::function_ref< unsigned (ASTNode)> GetCounterIdx ) const {
351372 switch (K) {
352373 case Kind::Zero:
353374 return llvm::coverage::Counter::getZero ();
354375 case Kind::Node:
355- return llvm::coverage::Counter::getCounter (Counters[ Node] );
376+ return llvm::coverage::Counter::getCounter (GetCounterIdx ( Node) );
356377 case Kind::Add:
357- return Builder.add (LHS->expand (Builder, Counters ),
358- RHS->expand (Builder, Counters ));
378+ return Builder.add (LHS->expand (Builder, GetCounterIdx ),
379+ RHS->expand (Builder, GetCounterIdx ));
359380 case Kind::Sub:
360- return Builder.subtract (LHS->expand (Builder, Counters ),
361- RHS->expand (Builder, Counters ));
381+ return Builder.subtract (LHS->expand (Builder, GetCounterIdx ),
382+ RHS->expand (Builder, GetCounterIdx ));
362383 case Kind::Ref:
363- return LHS->expand (Builder, Counters );
384+ return LHS->expand (Builder, GetCounterIdx );
364385 }
365386
366387 llvm_unreachable (" Unhandled Kind in switch." );
367388 }
368389
390+ // / Expand this node into an llvm::coverage::Counter.
391+ // /
392+ // / Updates \c Builder with any expressions that are needed to represent this
393+ // / counter.
394+ llvm::coverage::Counter
395+ expand (llvm::coverage::CounterExpressionBuilder &Builder,
396+ const llvm::DenseMap<ASTNode, unsigned > &Counters) const {
397+ return expand (Builder, [&](auto Node) {
398+ // FIXME: We ought to assert that the node is present.
399+ return Counters.lookup (Node);
400+ });
401+ }
402+
369403 void print (raw_ostream &OS) const {
370404 switch (K) {
371405 case Kind::Zero:
0 commit comments