C++: Refactor isDef and isUse in preparation for iterator flow#11543
Conversation
b953bb0 to
34f2db1
Compare
|
The DCA experiment seems to show quite some slowdown. |
Oops. You're right. Let me take a look at that. Thanks for the heads up 😨. |
34f2db1 to
9f85175
Compare
9f85175 should fix the performance regression. Upon investigating this I realized that #11537 broke the use-use flow branch (we lost 4 taint results in a library test), and this PR will most likely show these as missing results. These will be fixed once:
|
| override Type getBaseType() { result = PointerOrReferenceType.super.getBaseType() } | ||
| } | ||
|
|
||
| predicate isDereference(Instruction deref, Operand address) { |
There was a problem hiding this comment.
Is there a specific reason why we're not modelling LoadInstructions and have a getSourceAddressOperand predicate as a member of Indirection?
There was a problem hiding this comment.
Yeah, there actually is. Since the Indirection class is defined by extending Type it means that every isAdditionalDereference that's implemented must ensure to also bind this to avoid duplicating the work across many Indirection classes. For example, let's suppose we implemented loading from a LoadInstruction by implementing the isAdditionalDereference class in PointerOrReferenceTypeIndirection like:
override predicate isAdditionalDereference(Instruction deref, Operand address) {
deref.(LoadInstruction).getSourceAddressOperand() = address
}this would definitely work, but since this doesn't bind this we'd have a cartesian product between all PointerOrReferenceTypes and the columns in this predicate.
I think we could fix this by implementing the predicate like this instead:
override predicate isAdditionalDereference(Instruction deref, Operand address) {
address.getType() = this and // now we bind this so that every `Indirection` instance contributes a disjoint set of cases.
deref.(LoadInstruction).getSourceAddressOperand() = address
}but since we do actually want all LoadInstruction to be considered dereferences, I figured it was simplest to just implement this case outside the Indirection class.
A third option would be to avoid extending Type, and instead extend an IPA type. This IPA type would then have a branch for each Indirection we care about (the next PR will add an implementation of Indirection for iterators, for example), and we could implement PointerOrReferenceTypeIndirection by extending a unit branch of this IPA type to avoid the cartesian product between PointerOrReferenceType and the columns of isAdditionalDereference.
There was a problem hiding this comment.
I see the problem now.
It seems that the IPA solution would require us to extend the IPA type every time we want to add a type of indirection, right? If so, that makes it more difficult for users to add additional indirection types (in the unlikely case they start digging this deeply), which is not ideal.
So lets leave this as it is.
jketema
left a comment
There was a problem hiding this comment.
Two comments (see above). Otherwise this LGTM.
…actor-isdef-isuse
7c6918d
into
github:mathiasvp/replace-ast-with-ir-use-usedataflow
Note: The first two commits are from #11541 and should not be reviewed as part of this PR.<--- This has been force-pushed away now.This PR performs two refactorings:
LoadInstructionandStoreInstructionto an abstract class. This will be the basis of recognizing iterator reads and writes in a later PR.