Skip to content

[SandboxIR] Implement UnaryInstruction class #101541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 2, 2024
Merged

[SandboxIR] Implement UnaryInstruction class #101541

merged 1 commit into from
Aug 2, 2024

Conversation

vporpo
Copy link
Contributor

@vporpo vporpo commented Aug 1, 2024

This patch implements sandboxir::UnaryInstruction class and updates sandboxir::LoadInst and sandboxir::CastInst to inherit from it instead of sandboxir::Instruction.

Copy link
Contributor

@aeubanks aeubanks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is useful. UnaryInstruction doesn't expose any new common methods for people to use, and passes aren't going to check for UnaryInstruction. At least the LLVM IR UnaryInstruction has some allocation size logic.

return I->getOpcode() == Instruction::Opcode::Load || isa<CastInst>(I);
}
static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
Copy link

@tschuett tschuett Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isa + cast again?

if (Instruction *I = dyn_cast<Instruction>(V))
  return classof(I);
return false;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a bit too verbose? Three lines instead of one. And btw this is exactly how it's implemented in InstrTypes.h.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had this discussion before. The manual asks for dyn_cast.

Copy link
Contributor Author

@vporpo vporpo Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you may be misinterpreting the manual. This pattern is very common throughout LLVM. It can't be that no one noticed that all this code does not conform to the coding style. include/llvm/IR/ in particular contains this exact pattern 119 times across a couple of header files.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Widely use is a bad argument.
"Note that you should not use an isa<> test followed by a cast<>, for that use the dyn_cast<> operator."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

although I like the less redundant dyn_cast version, there is merit to keeping code short. I would bring this up on discourse if you feel strongly about this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Widely use is a bad argument.

True, but if it's widely used then it probably means that either:
(i) we are not conflicting with what the manual says and we are misinterpreting it, or
(ii) using isa<> + cast<> in this particular case is preferable despite what the manual says, because it is much less verbose.

In any case, I don't think we should be spending too much time arguing about this, it's just a style issue and both isa<> + cast<> and dyn_cast<> versions exist in the LLVM codebase.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, it was a common pattern to use isa + cast. Then the manual was updated: please use dyn_cast, but not all occurrences of isa +cast were converted to dyn_cast. That is why you find this pattern in many places.

I contribute to:
https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
We try to model LLVM-IR, but we are forced to deviations. There is also some freedom, i.e., ExtOrTrunc.
My point is : we use switches.

@vporpo
Copy link
Contributor Author

vporpo commented Aug 1, 2024

I'm not sure this is useful. UnaryInstruction doesn't expose any new common methods for people to use,

Yeah it's not super useful, but it is another way to check if an instruction has a single operand. I don't feel too strongly about keeping though. On the other hand it's not a huge burden to add it in either. There are just a handful of instructions that inherit from it.

@tschuett
Copy link

tschuett commented Aug 1, 2024

It makes SandboxIR closer to LLVM-IR.

@aeubanks
Copy link
Contributor

aeubanks commented Aug 1, 2024

I'm not sure this is useful. UnaryInstruction doesn't expose any new common methods for people to use,

Yeah it's not super useful, but it is another way to check if an instruction has a single operand. I don't feel too strongly about keeping though. On the other hand it's not a huge burden to add it in either. There are just a handful of instructions that inherit from it.

Having multiple ways of checking if an instruction has a single operand is worse than just having one way, and checking if an instruction has exactly one operand doesn't seem super useful/generic. Any code we can avoid adding is good.

It makes SandboxIR closer to LLVM-IR.

Sure but it's really just used as an internal implementation detail to share some allocation code. There are some places throughout LLVM that check for UnaryInstruction, but there are better ways to do what they want to do.

@aeubanks
Copy link
Contributor

aeubanks commented Aug 1, 2024

in general I'm a big advocate of only adding what you actually need and use; you can always add missing functionality later if it comes up

@vporpo
Copy link
Contributor Author

vporpo commented Aug 1, 2024

Having multiple ways of checking if an instruction has a single operand is worse than just having one way

But this is very much the llvm-way of checking things, which is by casting to the appropriate class with isa<>, and dyn_cast<>.

in general I'm a big advocate of only adding what you actually need and use; you can always add missing functionality later if it comes up

I agree with this, but in this case there the UnaryInstruction class is actually used as a parent class, it's not dead code. Yes, we aren't actually using isa<UnaryInstruction>(), but this is true for all of SandboxIR at this point.

I think that we should not try to diverge from LLVM IR unless there is some technical issue or something, which I don't feel this is the case. In the docs we are claiming that Sandbox IR feels-like LLVM, so we should try to stick to this as much as possible.

Copy link
Contributor

@aeubanks aeubanks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not thrilled about adding this, but sure we can mirror the LLVM hierarchy


public:
static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Opcode::Load || isa<CastInst>(I);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird that the load and cast check use different methods (opcode vs isa)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. There is no CastInst opcode, so we need isa<CastInst>(I). The alternative is a large switch case with the opcodes of the sub-classes of CastInst.
I guess we could use isa<LoadInst>(I) || isa<CastInst>(I).

This patch implements sandboxir::UnaryInstruction class and updates
sandboxir::LoadInst and sandboxir::CastInst to inherit from it instead of
sandboxir::Instruction.
@vporpo vporpo merged commit f9392fc into llvm:main Aug 2, 2024
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants