================
@@ -346,6 +352,39 @@ class CompoundVal : public NonLoc {
   static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
 };
 
+/// The simplest example of a concrete compound value is nonloc::CompoundVal,
+/// which represents a concrete r-value of an initializer-list or a string.
+/// Internally, it contains an llvm::ImmutableList of SVal's stored inside the
+/// literal.
+///
+/// However, there is another compound value used in the analyzer, which 
appears
+/// much more often during analysis, which is nonloc::LazyCompoundVal. This
+/// value is an r-value that represents a snapshot of any structure "as a 
whole"
+/// at a given moment during the analysis. Such value is already quite far from
+/// being re- ferred to as "concrete", as many fields inside it would be 
unknown
+/// or symbolic. nonloc::LazyCompoundVal operates by storing two things:
+///   * a reference to the TypedValueRegion being snapshotted (yes, it is 
always
+///     typed), and also
+///   * a copy of the whole Store object, obtained from the ProgramState in
----------------
haoNoQ wrote:

> Is it truly a copy of the store object? This seems to contradict the "is a 
> very cheap operation" line in the next paragraph...?

Yes! Congratulations, now you understand functional programming. Because the 
Store is an ImmutableMap, it is uniquely identified by a single pointer to the 
unique, carefully deduplicated instance of that map. The cost of a copy is the 
cost of a single 64-bit assignment. It's literally cheaper to copy the entire 
thing than to copy a portion of it, because a portion would be a different 
object, which we haven't created yet. It's like copy on write, except, the 
write isn't supported in the first place.

Of course the best part is that the "modification" is also cheap. Instead of 
modifying a map (and ruining everyone's "copy"), we just describe the modified 
map as essentially "the same as the other map except this one key has a 
different value". Which is also very quick to describe. Though, we still need 
to organize them into AVL trees for both fast lookup and fast deduplication. So 
it's not as straightforward as immutable lists which all naturally "grow on 
trees". But still, yes, all these operations are cheap, and this is how when 
you print the exploded graph it prints you every state, every store, behind 
every node. Because it doesn't cost anything extra to keep the copies around.

https://github.com/llvm/llvm-project/pull/97407
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to