[cfe-dev] Next step
Aaron Ballman
aaron at aaronballman.com
Thu May 15 07:16:07 PDT 2014
On Wed, May 14, 2014 at 11:50 AM, Delesley Hutchins <delesley at google.com> wrote:
> [Ongoing discussion on thread safety analysis, moved to list in case
> anyone cares. :-)]
>
>> * change getMutexIDs so that it creates an LExpr instead of a set of
>> SExprs. Instead of returning a MutexIDList, it should return the LExpr
>> created.
>
> Yes.
>
>> * addLock should be changed to take an LExpr instead of a MutexIDList
>> (same for removeLock)
>
> Yes.
>
>> * FactSet needs to be updated to handle LExprs for findLock, addLock
>> and removeLock
>
> Yes, but there's more to it. (See below.)
>
>> * FactManager needs to create a FactID from an LExpr for newLock
>
> Not quite. (See below.)
>
>> * FactEntry needs to be updated to hold (a union including SExpr and?) an LExpr
>
> Not quite. (See below.)
>
> A few notes on implementation: MutexIDList is just a short list of
> SExprs, and it's used when extracting SExprs from attributes, because
> an attribute (e.g. exclusive_locks_required) can hold a list of
> SExprs, rather than a single one.
Good, that matches my understanding.
> FactSet holds a set of SExprs that are known to be held. It's not
> just a list for two reasons. (1) A FactSet keeps track of some
> additional information about each SExpr, e.g. where the SExprs were
> acquired, whether they are exclusive or shared, and the weirdness
> associated with scoped_lockable. (2) FactSets are optimized for small
> size and merging.
This also matches my understanding.
>
> You will need to change FactSet so that it holds a single LExpr.
> Instead of the set {A, B, C}, you will store the LExpr (A & B & C).
> What this means is that the operations to add locks, remove locks, and
> merge locksets will now apply to LExprs.
Okay, so the FactSet basically becomes our computed environment for
capabilities, and is simply a single LExpr that we constantly update?
> For example:
>
> Current context: (A & B & !C). Call C.lock(). New context:
> (A & B & C).
> Current context: (A & B & C). Call B.unlock(). New context:
> (A & C & !B).
> Context1: (A & B & C). Context2: (A & B & D). Merge on join
> point: (A & B & (C | D))
>
> [Joint points]. At every join point in the CFG, the analysis will
> have to merge the two LExprs.
So this would mean modifying ThreadSafetyAnalyzer::intersectAndWarn?
Or are there other places requiring modification?
> Merging is conceptually simple: if we
> can arrive at a given basic block from either block 1, with context
> E1, or from block 2, with context E2, then the context for that block
> is (E1 | E2). However, you will get an exponential blowup in
> expression size unless you *simplify* (E1 | E2) afterward, as shown
> above.
Do you have a particular algorithm in mind for performing the simplification?
>
> [Adding and removing locks.] In order to add or remove a mutex A from
> an LExpr E, you must first remove all prior occurrences of A from E.
> (We're chan do not know ging what we know about A.) Unfortunately,
> that's not just a simple matter of traversing E, and deleting the
> references. You need to derive a new expression E' which does not
> mention A, where E is satisfiable only if E' is satisfiable. More
> formally, you must factor out A, by refactoring E into the form (A &
> E1) | (!A & E2), where E1 and E2 do not refer to A; E' is then (E1 |
> E2). There are algorithms to do this for BDDs; the operation is known
> as boolean existential quantification. See:
> http://gauss.ececs.uc.edu/Courses/c626/lectures/BDD/bdd-desc.pdf
Thank you for the link!
>
> Unfortunately, I do not know how to do this for the simple LExprs that
> you have constructed. One option is to require the LExpr to be in the
> format (E1 & E2 ... En & A) to start with (so no refactoring
> necessary), and simply fail otherwise. That will work for locks,
> because it matches the way FactSet is implemented now, and it will
> thus allow you to make forward progress. But it largely defeats the
> point of implementing LExprs, since analysis will fail if it
> encounters anything more complicated than what we already have. The
> other option is to ditch LExprs, and implement BDDs. Talk to Dean; he
> knows more about this than I do.
It sounds a lot more like we really want a BDD than an LExpr. I will
talk to Dean, but do you have any feelings on whether a BDD is a
better approach than the LExpr we have? If you think BDDs are the
correct approach long-term, do you know of any BDD libraries that
would be compatible with our licensing requirements, or whether there
would be issues with bringing in a 3rd party library for this?
> My task list, in order of priority, would be:
>
> (1) Add the ability to merge (logical or) and simplify LExprs.
> (convert to conjuctive normal form?)
> (2) Add the existential quantification operation to LExprs (or
> possibly implement BDDs?).
> (3) Augment LExprs so that they keep track of exclusive vs. shared,
> where locks were acquired, and scoped_lockable.
I think the highest priority would be to determine whether we are
going to use LExrs, BDDs, or a combination of the two. The work is
likely to be roughly the same in terms of hooking things up, but the
tools are different.
> That's quite a lot of work already, and it will take you some time.
> Once it's done, *then* we can do a single patch to swap FactSet over
> to the new LExpr stuff. The patch sequence is the same as my strategy
> for the TIL/SExpr stuff; build the new functionality in parallel with
> the old, make sure the new functionality works, and then flip the
> switch from old to new. Notice that I haven't flipped the switch for
> SExpr yet. :-)
>
> We can set up a video chat if you want to talk about this further.
I think a video chat would be a great idea. We can discuss offlist.
Thanks!
~Aaron
More information about the cfe-dev
mailing list