This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Untangle instruction properties from VSETVLIInfo [NFC]
ClosedPublic

Authored by reames on Jun 2 2022, 2:10 PM.

Details

Summary

The abstract state used in the data flow should not know anything about the instructions which produced the abstract states. Instead, when comparing two states, we can simply use information about the machine instr at that time.

In the old design, basically any use of the instruction flags on the current (as opposed to a "Require" - aka upcoming state) would be a bug. We don't seem to actually have any such bugs, but we can make this much more obvious with code structure.

Diff Detail

Event Timeline

reames created this revision.Jun 2 2022, 2:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 2 2022, 2:10 PM
reames requested review of this revision.Jun 2 2022, 2:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 2 2022, 2:10 PM
reames updated this revision to Diff 433892.Jun 2 2022, 2:44 PM

I agree that instruction properties shouldn't be part of the abstract state, so I agree with the principle behind this patch.

I worry that this change is throwing another free variable into the mix when checking compatibility, which causes confusion and potentially leads to another sort of subtle bug - or people worrying about another sort of bug - about what happens if MI and Require are out of sync somehow.

As far as I can tell, MI and Require have to be in sync for correctness, is that right? We only ever call needVSETVLI when the Require has been computed from MI, anyway. So one idea I had was: may we have a tighter implementation if we removed the Require parameter from needVSETVLI and computed it fresh inside that function from MI? That way its API is obvious: "does this MI need a VSETVLI given the current VSETVLI state?". Now, we do need Require in other places outside of needVSETVLI so I dunno if it would just be moving things around as we'd be computing it twice - inside and out - rather than just the once.

Another option - could we assert that the Require is equivalent to that of a freshly-computed VSETVLIInfo?

Or we just document it in needVSETVLI and other APIs somehow. I see you've done that in isCompatible but I still worry about bugs if we're simply documenting rather than ensuring/checking/asserting.

kito-cheng added a comment.EditedJun 8 2022, 2:35 AM

I think the real problem is we didn't extract the abstract info from MI for those case, so what do you think if we turn those info into more abstraction level info and still keep in Require?

e.g.
MaskRegOp: Require same ratio (VLMAX) but no matter LMUL and SEW.
StoreOp: No need tail/mask policy, (Handled by canSkipVSETVLIForLoadStore for now) Require same ratio (VLMAX) but no matter LMUL and SEW, because EEW.
ScalarMovOp: Require same SEW but no matter the LMUL, and always tail-agnostic regardless VTYPE setting
LoadOp: (Handled by canSkipVSETVLIForLoadStore for now) Require same ratio (VLMAX) but no matter LMUL and SEW, because EEW.
Any operation with mask destination: tail elements are always treated as tail-agnostic, regardless of the setting of vta.

So the abstract info is:

  • No matter LMUL?
  • Require same ratio - no matter LMUL and SEW.
  • Regardless tail policy of the setting of VTYPE?
  • Regardless mask policy of the setting of VTYPE?

And then we can get rid of MI once we gather those info into Require.

reames added a comment.EditedJun 8 2022, 7:39 AM

@frasercrmck Let's not let perfection be the enemy of the good here. I see the point you're raising, and I'm willing to explore it in a follow up patch, but can we get this one in first? I see it as a significant improvement in the current code.

Edit: To clarify, the reason this is tricky is that we call needVSETVLI *after mutating MI* in phase3 - specifically, we clear VLOpReg. As a result, the trivially assert fails because the newly computed info disagrees with the info before mutation. Introducing even the assert thus requires a larger code reorg than it seems like it should.

@kito-cheng No, I will not do as you propose. These are properties of the instruction, trying to abstract them into an otherwise unrelated structure just makes the code confusing and hard to follow. For clarity, I'm not objecting to maybe abstracting the policy bits (if we find other examples which share the same policies), I'm objecting to them being in the abstract state used in the forward dataflow. These are *backwards* (e.g. demanded) facts. If we had a bidirectional dataflow here, maybe merging them would make sense, but we don't.

@reames Fair enough, but I still think I'd like to see a comment on needVSETVLI to say MI and Require must be in sync.

reames updated this revision to Diff 435165.Jun 8 2022, 8:04 AM

Comment updated per request.

p.s. @frasercrmck, you commented at about the same time I edited my previous comment for clarity. If you haven't seen that, might want to read the part starting with Edit:

frasercrmck accepted this revision.Jun 8 2022, 8:06 AM

LGTM, thanks! About your edit, yeah, I was wondering/worrying if that mutation was going to affect things. Drat...

This revision is now accepted and ready to land.Jun 8 2022, 8:06 AM
This revision was landed with ongoing or failed builds.Jun 8 2022, 8:10 AM
This revision was automatically updated to reflect the committed changes.