Stream: t-compiler

Topic: dataflow


oli (Dec 14 2019 at 19:27, on Zulip):

Hi @ecstatic-morse I have a question about dataflow.
If I understand normal dataflow correctly, if you have a BOTTOM_VALUE = false and you gen a value, this spreads and marks all following blocks as also being true for that value. Is there a way to set it up so the a block's value is only true if all incoming blocks are true for that value?

ecstatic-morse (Dec 14 2019 at 19:31, on Zulip):

Besides initializing all entry sets to true, BOTTOM_VALUE = true will use intersection instead of union as the default join operator. I believe "gen"-ing bits still sets them to true, regardless of BOTTOM_VALUE.

oli (Dec 14 2019 at 19:35, on Zulip):

Oh... so if I override the start_block_effect to be the opposite of BOTTOM_VALUE, this may just work out

oli (Dec 14 2019 at 19:36, on Zulip):

hmm no :frown:

ecstatic-morse (Dec 14 2019 at 19:36, on Zulip):

if you want to the initial value of the block entry sets to be false, BOTTOM_VALUE should be false, and you should override the join operator instead.

ecstatic-morse (Dec 14 2019 at 19:38, on Zulip):

You could explain the analysis you're trying to do if you want more help.

oli (Dec 14 2019 at 19:40, on Zulip):

ok, so I have a ZST Idx so every block just has one bit. I set this bit when I encounter a TerminatorKind::Call to a specific function. I want to be able to ask at each location whether the function has been called if we got to this place in the MIR

oli (Dec 14 2019 at 19:40, on Zulip):

this means if some_cond { specific_function(); /* here it's true */ } /* here it's false */

ecstatic-morse (Dec 14 2019 at 19:43, on Zulip):

It seems like you want BOTTOM_VALUE to be false (function not called before this point) and the join operator to be union (if the function could have been called in one predecessor but not another, it could have been called in this basic block).

ecstatic-morse (Dec 14 2019 at 19:44, on Zulip):

Oh, there's no else in your example. You mean function has definitely been called, not maybe been called?

oli (Dec 14 2019 at 19:45, on Zulip):

yes

oli (Dec 14 2019 at 19:45, on Zulip):

that's my problem. maybe is easy I got that working quickly

oli (Dec 14 2019 at 19:45, on Zulip):

but I don't think dataflow supports my use case

ecstatic-morse (Dec 14 2019 at 19:45, on Zulip):

In that case yeah, BOTTOM_VALUE is false (function not definitely called) and the join operator is intersection (if the function was definitely called in one predecessor but not definitely called in another, it has not definitely been called in this basic block.

oli (Dec 14 2019 at 19:57, on Zulip):

So.. that's what I tried earlier. I reran and dumped all the state changes. What's happening right now is that specific_function(); foo(); says that at foo the bit is false. I dumped all joins and what I'm seeing is two intersects: [] & [MyBit] and [] & []. So I'm guessing that the initial state is also joined with the newly set bits?

ecstatic-morse (Dec 14 2019 at 19:58, on Zulip):

Ugh, sorry. Yes you're right.

oli (Dec 14 2019 at 20:02, on Zulip):

So, I mean this is fairly easy to write without duplicating too much dataflow (I'm just looking at basic blocks after all), I was just hoping I could make it work with dataflow so I don't have to write the dirty_set logic :D

ecstatic-morse (Dec 14 2019 at 20:04, on Zulip):

One last try. how about setting BOTTOM_VALUE to true with the same gen/kill semantics (FnDefinitelyCalled), then setting everything to false in initalize_start_block.

ecstatic-morse (Dec 14 2019 at 20:04, on Zulip):

You mentioned this above

ecstatic-morse (Dec 14 2019 at 20:07, on Zulip):

and indeed this is what DefinitelyInitalizedPlaces does, which has similar semantics

oli (Dec 14 2019 at 20:17, on Zulip):

Hmm... I thought I tried this, but may have screwed up, I'll see what that does tomorrow morning.

oli (Dec 15 2019 at 08:14, on Zulip):

It works!! Thanks

oli (Dec 15 2019 at 08:14, on Zulip):

/me goes write some docs

Last update: May 26 2020 at 11:10UTC