diff options
author | Andrew Carlotti <andrew.carlotti@arm.com> | 2024-10-15 17:31:28 +0100 |
---|---|---|
committer | Andrew Carlotti <andrew.carlotti@arm.com> | 2025-01-10 14:12:11 +0000 |
commit | e7f98d9603808b1c17106d3d9f2000bc34f2c50c (patch) | |
tree | 6c7940546897e86b9054da880352abd09535d1ab /gcc/config/aarch64 | |
parent | 21212f08d8258fa6d4cfdd21a35d0ee7c44ccbea (diff) | |
download | gcc-e7f98d9603808b1c17106d3d9f2000bc34f2c50c.zip gcc-e7f98d9603808b1c17106d3d9f2000bc34f2c50c.tar.gz gcc-e7f98d9603808b1c17106d3d9f2000bc34f2c50c.tar.bz2 |
Add new hardreg PRE pass
This pass is used to optimise assignments to the FPMR register in
aarch64. I chose to implement this as a middle-end pass because it
mostly reuses the existing RTL PRE code within gcse.cc.
Compared to RTL PRE, the key difference in this new pass is that we
insert new writes directly to the destination hardreg, instead of
writing to a new pseudo-register and copying the result later. This
requires changes to the analysis portion of the pass, because sets
cannot be moved before existing instructions that set, use or clobber
the hardreg, and the value becomes unavailable after any uses of
clobbers of the hardreg.
Any uses of the hardreg in debug insns will be deleted. We could do
better than this, but for the aarch64 fpmr I don't think we emit useful
debuginfo for deleted fp8 instructions anyway (and I don't even know if
it's possible to have a debug fpmr use when entering hardreg PRE).
gcc/ChangeLog:
* config/aarch64/aarch64.h (HARDREG_PRE_REGNOS): New macro.
* gcse.cc (doing_hardreg_pre_p): New global variable.
(do_load_motion): New boolean check.
(current_hardreg_regno): New global variable.
(compute_local_properties): Unset transp for hardreg clobbers.
(prune_hardreg_uses): New function.
(want_to_gcse_p): Use different checks for hardreg PRE.
(oprs_unchanged_p): Disable load motion for hardreg PRE pass.
(hash_scan_set): For hardreg PRE, skip non-hardreg sets and
check for hardreg clobbers.
(record_last_mem_set_info): Skip for hardreg PRE.
(compute_pre_data): Prune hardreg uses from transp bitmap.
(pre_expr_reaches_here_p_work): Add sentence to comment.
(insert_insn_start_basic_block): New functions.
(pre_edge_insert): Don't add hardreg sets to predecessor block.
(pre_delete): Use hardreg for the reaching reg.
(reset_hardreg_debug_uses): New function.
(pre_gcse): For hardreg PRE, reset debug uses and don't insert
copies.
(one_pre_gcse_pass): Disable load motion for hardreg PRE.
(execute_hardreg_pre): New.
(class pass_hardreg_pre): New.
(pass_hardreg_pre::gate): New.
(make_pass_hardreg_pre): New.
* passes.def (pass_hardreg_pre): New pass.
* tree-pass.h (make_pass_hardreg_pre): New.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/acle/fpmr-1.c: New test.
* gcc.target/aarch64/acle/fpmr-2.c: New test.
* gcc.target/aarch64/acle/fpmr-3.c: New test.
* gcc.target/aarch64/acle/fpmr-4.c: New test.
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r-- | gcc/config/aarch64/aarch64.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 3f3a475..1ab49e2 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -1652,6 +1652,10 @@ enum class aarch64_tristate_mode : int { NO, YES, MAYBE }; { int (aarch64_tristate_mode::MAYBE), \ int (aarch64_local_sme_state::ANY) } +/* Zero terminated list of regnos for which hardreg PRE should be + applied. */ +#define HARDREG_PRE_REGNOS { FPM_REGNUM, 0 } + #endif #endif /* GCC_AARCH64_H */ |