From f6ad93e7cbbb3e43b045ae3313e556ea70e54c8f Mon Sep 17 00:00:00 2001 From: Alasdair Armstrong Date: Fri, 3 May 2019 17:28:30 +0100 Subject: Jib: Fix optimizations for SMT IR changes Fixes C backend optimizations that were disabled due to changes in the IR while working on the SMT generation. Also add a -Oaarch64_fast option that optimizes any integer within a struct to be an int64_t, which is safe for the ARM v8.5 spec and improves performance significantly (reduces Linux boot times by 4-5 minutes). Eventually this should probably be a directive that can be attached to any arbitrary struct/type. Fixes the -c_specialize option for ARM v8.5. However this only gives a very small performance improvment for a very large increase in compilation time however. --- lib/sail.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- lib/sail.h | 5 +++++ 2 files changed, 49 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/sail.c b/lib/sail.c index 2d47939e..cc4466bb 100644 --- a/lib/sail.c +++ b/lib/sail.c @@ -1017,15 +1017,11 @@ void slice(lbits *rop, const lbits op, const sail_int start_mpz, const sail_int } } -inline +__attribute__((target ("bmi2"))) sbits sslice(const fbits op, const mach_int start, const mach_int len) { sbits rop; -#ifdef INTRINSICS rop.bits = _bzhi_u64(op >> start, len); -#else - rop.bits = (op >> start) & safe_rshift(UINT64_MAX, 64 - len); -#endif rop.len = len; return rop; } @@ -1126,18 +1122,25 @@ void reverse_endianness(lbits *rop, const lbits op) } } -inline bool eq_sbits(const sbits op1, const sbits op2) { return op1.bits == op2.bits; } -inline bool neq_sbits(const sbits op1, const sbits op2) { return op1.bits != op2.bits; } +__attribute__((target ("bmi2"))) +sbits not_sbits(const sbits op) +{ + sbits rop; + rop.bits = (~op.bits) & _bzhi_u64(UINT64_MAX, op.len); + rop.len = op.len; + return rop; +} + sbits xor_sbits(const sbits op1, const sbits op2) { sbits rop; @@ -1146,6 +1149,40 @@ sbits xor_sbits(const sbits op1, const sbits op2) return rop; } +sbits or_sbits(const sbits op1, const sbits op2) +{ + sbits rop; + rop.bits = op1.bits | op2.bits; + rop.len = op1.len; + return rop; +} + +sbits and_sbits(const sbits op1, const sbits op2) +{ + sbits rop; + rop.bits = op1.bits & op2.bits; + rop.len = op1.len; + return rop; +} + +__attribute__((target ("bmi2"))) +sbits add_sbits(const sbits op1, const sbits op2) +{ + sbits rop; + rop.bits = (op1.bits + op2.bits) & _bzhi_u64(UINT64_MAX, op1.len); + rop.len = op1.len; + return rop; +} + +__attribute__((target ("bmi2"))) +sbits sub_sbits(const sbits op1, const sbits op2) +{ + sbits rop; + rop.bits = (op1.bits - op2.bits) & _bzhi_u64(UINT64_MAX, op1.len); + rop.len = op1.len; + return rop; +} + /* ***** Sail Reals ***** */ void CREATE(real)(real *rop) diff --git a/lib/sail.h b/lib/sail.h index 05c65027..258b7a91 100644 --- a/lib/sail.h +++ b/lib/sail.h @@ -333,7 +333,12 @@ void reverse_endianness(lbits*, lbits); bool eq_sbits(const sbits op1, const sbits op2); bool neq_sbits(const sbits op1, const sbits op2); +sbits not_sbits(const sbits op); sbits xor_sbits(const sbits op1, const sbits op2); +sbits or_sbits(const sbits op1, const sbits op2); +sbits and_sbits(const sbits op1, const sbits op2); +sbits add_sbits(const sbits op1, const sbits op2); +sbits sub_sbits(const sbits op1, const sbits op2); /* ***** Sail reals ***** */ -- cgit v1.2.3