aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64
diff options
context:
space:
mode:
authorAndrew Carlotti <andrew.carlotti@arm.com>2024-10-15 17:31:28 +0100
committerAndrew Carlotti <andrew.carlotti@arm.com>2025-01-10 14:12:11 +0000
commite7f98d9603808b1c17106d3d9f2000bc34f2c50c (patch)
tree6c7940546897e86b9054da880352abd09535d1ab /gcc/config/aarch64
parent21212f08d8258fa6d4cfdd21a35d0ee7c44ccbea (diff)
downloadgcc-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.h4
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 */