-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
s390x: Migrate branches and traps to ISLE #3724
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -679,7 +679,6 @@ | |
(type BoxCallInfo (primitive BoxCallInfo)) | ||
(type BoxCallIndInfo (primitive BoxCallIndInfo)) | ||
(type MachLabel (primitive MachLabel)) | ||
(type VecMachLabel (primitive VecMachLabel)) | ||
(type BoxJTSequenceInfo (primitive BoxJTSequenceInfo)) | ||
(type BoxExternalName (primitive BoxExternalName)) | ||
(type ValueLabel (primitive ValueLabel)) | ||
|
@@ -1040,6 +1039,19 @@ | |
(extern extractor unsigned unsigned) | ||
|
||
|
||
;; Helpers for machine label vectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
|
||
;; VecMachLabel needs to be passed by reference, so it cannot be | ||
;; declared as primitive type. Declare as extern enum instead. | ||
(type VecMachLabel extern (enum)) | ||
|
||
(decl vec_length_minus1 (VecMachLabel) u32) | ||
(extern constructor vec_length_minus1 vec_length_minus1) | ||
|
||
(decl vec_element (VecMachLabel u8) MachLabel) | ||
(extern constructor vec_element vec_element) | ||
|
||
|
||
;; Helpers for memory arguments ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
|
||
;; Accessors for `RelocDistance`. | ||
|
@@ -1284,6 +1296,8 @@ | |
;; implementation detail by helpers that preserve the SSA facade themselves. | ||
(decl emit (MInst) Unit) | ||
(extern constructor emit emit) | ||
(decl emit_safepoint (MInst) Unit) | ||
(extern constructor emit_safepoint emit_safepoint) | ||
|
||
;; Helper for emitting `MInst.AluRRR` instructions. | ||
(decl alu_rrr (Type ALUOp Reg Reg) Reg) | ||
|
@@ -1695,6 +1709,26 @@ | |
(_ Unit (emit (MInst.LoadAddr dst mem)))) | ||
(writable_reg_to_reg dst))) | ||
|
||
;; Helper for emitting `MInst.Jump` instructions. | ||
(decl jump_impl (MachLabel) SideEffectNoResult) | ||
(rule (jump_impl target) | ||
(SideEffectNoResult.Inst (MInst.Jump target))) | ||
|
||
;; Helper for emitting `MInst.CondBr` instructions. | ||
(decl cond_br (MachLabel MachLabel Cond) SideEffectNoResult) | ||
(rule (cond_br taken not_taken cond) | ||
(SideEffectNoResult.Inst (MInst.CondBr taken not_taken cond))) | ||
|
||
;; Helper for emitting `MInst.OneWayCondBr` instructions. | ||
(decl oneway_cond_br (MachLabel Cond) SideEffectNoResult) | ||
(rule (oneway_cond_br dest cond) | ||
(SideEffectNoResult.Inst (MInst.OneWayCondBr dest cond))) | ||
|
||
;; Helper for emitting `MInst.JTSequence` instructions. | ||
(decl jt_sequence (Reg VecMachLabel) SideEffectNoResult) | ||
(rule (jt_sequence ridx targets) | ||
(SideEffectNoResult.Inst (MInst.JTSequence ridx targets))) | ||
|
||
;; Emit a `ProducesFlags` instruction when the flags are not actually needed. | ||
(decl drop_flags (ProducesFlags) Reg) | ||
(rule (drop_flags (ProducesFlags.ProducesFlags inst result)) | ||
|
@@ -2149,6 +2183,23 @@ | |
src imm cond trap_code)))) | ||
(invalid_reg))) | ||
|
||
(decl trap_impl (TrapCode) SideEffectNoResult) | ||
(rule (trap_impl trap_code) | ||
(SideEffectNoResult.Inst (MInst.Trap trap_code))) | ||
|
||
(decl trap_if_impl (Cond TrapCode) SideEffectNoResult) | ||
(rule (trap_if_impl cond trap_code) | ||
(SideEffectNoResult.Inst (MInst.TrapIf cond trap_code))) | ||
|
||
(decl debugtrap_impl () SideEffectNoResult) | ||
(rule (debugtrap_impl) | ||
(SideEffectNoResult.Inst (MInst.Debugtrap))) | ||
|
||
(decl safepoint (SideEffectNoResult) ValueRegs) | ||
(rule (safepoint (SideEffectNoResult.Inst inst)) | ||
(let ((_ Unit (emit_safepoint inst))) | ||
(value_regs_invalid))) | ||
Comment on lines
+2198
to
+2201
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should go in the shared prelude, next to |
||
|
||
|
||
;; Helpers for handling boolean conditions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
|
||
|
@@ -2201,6 +2252,24 @@ | |
(rule (lower_bool $B32 cond) (select_bool_imm $B32 cond -1 0)) | ||
(rule (lower_bool $B64 cond) (select_bool_imm $B64 cond -1 0)) | ||
|
||
;; Emit a conditional branch based on a boolean condition. | ||
(decl cond_br_bool (ProducesBool MachLabel MachLabel) SideEffectNoResult) | ||
(rule (cond_br_bool (ProducesBool.ProducesBool producer cond) taken not_taken) | ||
(let ((_ Unit (emit_producer producer))) | ||
(cond_br taken not_taken cond))) | ||
|
||
;; Emit a one-way conditional branch based on a boolean condition. | ||
(decl oneway_cond_br_bool (ProducesBool MachLabel) SideEffectNoResult) | ||
(rule (oneway_cond_br_bool (ProducesBool.ProducesBool producer cond) dest) | ||
(let ((_ Unit (emit_producer producer))) | ||
(oneway_cond_br dest cond))) | ||
|
||
;; Emit a conditional trap based on a boolean condition. | ||
(decl trap_if_bool (ProducesBool TrapCode) SideEffectNoResult) | ||
(rule (trap_if_bool (ProducesBool.ProducesBool producer cond) trap_code) | ||
(let ((_ Unit (emit_producer producer))) | ||
(trap_if_impl cond trap_code))) | ||
|
||
|
||
;; Helpers for generating `clz` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this should be in the prelude as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that
emit
actually isn't in the prelude, but we do use it from the prelude. So we should probably moveemit
to the prelude as well, since in practice it has to be the same declaration across all backends anyways. Happy to have that as part of this updated PR or we can do it in another PR.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's why I didn't put it in the prelude ...
I agree it makes sense to move emit / emit_safepoint there, but then we should also move the implementations to machinst/isle.re, right?
I'd be happy to do that, but I think it would be better to do it in another PR, as it will touch all back-ends.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we wouldn't necessarily have to move the implementations as well, nothing is stopping us from implementing the ISLE context's
emit
trait method once for each backend even when thedecl
is in the prelude.In fact the x86_64 implementation is a little different, in that it calls a
mov_mitosis
method on each inst inemitted_insts
, and if we made this code common then we would need to add such a method to theMachInst
trait or something.So I think we can move just the ISLE
decl
into the prelude without moving the rust trait implementations at all. Happy to have this in a follow up PR.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. But even if we don't move the implementaton, once the
decl
is in the prelude asextern constructor
, every back-end must implement it or it won't compile any more. So we'll still need to touch all back-ends. (In fact, with the x86mov_mitosis
implementation, I'm not sure exactly how the safepoint variant would work. I guess only the last instruction in the list should be the safepoint?)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. (Also, it is already the case that every backend must implement it or the ISLE won't compile because we are calling
emit
and assuming it is declared from inside the prelude already, it just so happens that we have N identical declarations for each backend instead of a single shared declaration in the prelude.)Yeah, I will have to think a bit about how to do this best. I think making only the last instruction a safepoint would work, but we might want to have some debug asserts in there too. Planning on tackling this after I'm done with my newtype wrappers PR by which time this PR will have merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think that's the correct solution -- the expanded list should always have the form of zero or more moves, followed by the original instruction; and the safepoint bit applies to the latter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some instructions that always generate their results into a particular register, and so when our SSA-ified version of that instruction wants the result in a temp, we have to generate a move that follows the "real" instruction, so we can have trailing moves as well after move mitosis. This shouldn't be the case for safepoints I don't think (except maybe ABI/calling convention stuff where results are always in
rax
?) and we should be able to just debug assert this.