alanphipps marked an inline comment as done.
alanphipps added inline comments.


================
Comment at: clang/lib/CodeGen/CodeGenFunction.h:4359
+  /// condition (i.e. no "&&" or "||").
+  static bool isLeafCondition(const Expr *C);
+
----------------
vsk wrote:
> alanphipps wrote:
> > vsk wrote:
> > > alanphipps wrote:
> > > > vsk wrote:
> > > > > vsk wrote:
> > > > > > It might be helpful to either require that `C` be the RHS of a 
> > > > > > logical binop (e.g. by passing the binop expr in), or to document 
> > > > > > that requirement.
> > > > > Given a logical binop like `E = a && !(b || c)`, 
> > > > > `isLeafCondition(E->getRHS())` is true. That seems a bit 
> > > > > counter-intuitive, because `E->getRHS()` contains another leaf 
> > > > > condition. Would it make sense to rename the condition (perhaps to 
> > > > > something like 'InstrumentedCondition')? Have I misunderstood what a 
> > > > > leaf condition is?
> > > > Background: isLeafCondition() is an auxiliary routine that is used 
> > > > during 1.) counter allocation on binop RHS (CodeGenPGO.cpp), 2.) 
> > > > counter instrumentation (CodeGenFunction.cpp), and 3.) branch region 
> > > > generation (CoverageMappingGen.cpp).  In the #3 case, it isn't always 
> > > > looking at the RHS of a logical binop but can be used to assess whether 
> > > > any condition is instrumented/evaluated.
> > > > 
> > > > Given your example condition:
> > > > 
> > > > E = a && !(b || c)
> > > > 
> > > > You are correct that isLeafCondition(E->getRHS()) will return true, but 
> > > > I think it should actually return false here (and bypass logical-NOT), 
> > > > so I will adapt this. 
> > > > 
> > > > However, given a condition that includes an binary operator (like 
> > > > assign):
> > > > 
> > > > E = a && (x = !(b || c))
> > > > 
> > > > isLeafCondition(E->getRHS()) will also return true, and I think that is 
> > > > the correct behavior.  Given that, then I agree that maybe 
> > > > isLeafCondition() should be renamed to isInstrumentedCondition() since 
> > > > it's not technically just leaves that are tracked in the presence of 
> > > > operators.
> > > What is special about the assignment expression nested within "a && (x = 
> > > !(b || c))" that necessitates an extra counter compared to "a && !(b || 
> > > c)"?
> > I'm exempting the logical NOT operator basically to match the functionality 
> > of other coverage vendors (Bullseye, GCOV).  It's a simplistic operator in 
> > the sense that (as far as I can tell) it only affects the sense of the 
> > generated branch on a condition.
> > 
> > As for the assignment, we're effectively creating a new condition that is 
> > evaluatable (even if a branch may technically not be generated), and so 
> > creating a counter for it is more interesting (and matches other vendor 
> > behavior).
> > 
> > But I'm open to persuasion.  We could just be more conservative and create 
> > counters for logical NOT, but I think there's value in matching some of the 
> > expected behavior of other vendors.  This is also something we could 
> > continue to fine-tune in future patches.
> I agree that there isn't a need to insert a fresh counter to accommodate a 
> logical NOT operator in a condition. But I don't see how an assignment 
> expression effectively creates a new, evaluatable condition. It seems like 
> the count for the assignment expr can be derived by looking up the count for 
> its parent region.
> 
> At this stage I'm more interested in understanding the high-level design. If 
> the question of whether/not to add fresh counters for assignment exprs in a 
> condition is effectively about optimization, then I'm fine with tabling it.
I just realized I didn't make this name change to isInstrumentedCondition(). I 
will do that.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84467/new/

https://reviews.llvm.org/D84467

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to