Instead of creating a new shape guard op with extra information,
this just creates a new LoadObject and corresponding Constant op
with extra information, relying on the existing shape guard
elimination pass to clean up the shape guards which are now all
relying on commoned up ConstantObjectProtos.
This breaks without a change to congruentIfOperandsEqual, though,
as the ConstantObjectProtos will each have a different GuardShape
dependency, and thus won't look the same. It looks to me to be
safe to just eliminate object guards in congruentIfOperandsEqual,
though? I don't expect this to be particularly expensive either,
so it seems like a good idea to just go ahead and do it so we're
not killing optimization opportunities with slot stores whose
shape guards aren't cleaned up until the eliminate redundant
shapeguards pass well after GVN.
One last thing to note here is I didn't add a separate NurseryObject
op for cases where the object has a nursery index. I actually am
not entirely sure how common that is or what reproduces that - I
kind of expected that in my simple test case the object would only
live in the nursery, as I just loop creating objects with a
constructori, so I'm confused why I don't hit this case. Clearly
I'm misunderstanding something here, so I just left the bit that I
didn't know enough about out of my patch for now.