ISLE: remove all uses of argument polarity, and remove it from the language. (#4091)
This PR removes "argument polarity": the feature of ISLE extractors that lets them take inputs aside from the value to be matched. Cases that need this expressivity have been subsumed by #4072 with if-let clauses; we can now finally remove this misfeature of the language, which has caused significant confusion and has always felt like a bit of a hack. This PR (i) removes the feature from the ISLE compiler; (ii) removes it from the reference documentation; and (iii) refactors away all uses of the feature in our three existing backends written in ISLE.
This commit is contained in:
@@ -1290,14 +1290,14 @@
|
||||
(decl move_wide_const_from_negated_u64 (MoveWideConst) u64)
|
||||
(extern extractor move_wide_const_from_negated_u64 move_wide_const_from_negated_u64)
|
||||
|
||||
(decl imm_logic_from_u64 (Type ImmLogic) u64)
|
||||
(extern extractor imm_logic_from_u64 imm_logic_from_u64 (in out))
|
||||
(decl pure imm_logic_from_u64 (Type u64) ImmLogic)
|
||||
(extern constructor imm_logic_from_u64 imm_logic_from_u64)
|
||||
|
||||
(decl imm_logic_from_imm64 (Type ImmLogic) Imm64)
|
||||
(extern extractor imm_logic_from_imm64 imm_logic_from_imm64 (in out))
|
||||
(decl pure imm_logic_from_imm64 (Type Imm64) ImmLogic)
|
||||
(extern constructor imm_logic_from_imm64 imm_logic_from_imm64)
|
||||
|
||||
(decl imm_shift_from_imm64 (Type ImmShift) Imm64)
|
||||
(extern extractor imm_shift_from_imm64 imm_shift_from_imm64 (in out))
|
||||
(decl pure imm_shift_from_imm64 (Type Imm64) ImmShift)
|
||||
(extern constructor imm_shift_from_imm64 imm_shift_from_imm64)
|
||||
|
||||
(decl imm_shift_from_u8 (u8) ImmShift)
|
||||
(extern constructor imm_shift_from_u8 imm_shift_from_u8)
|
||||
@@ -1317,8 +1317,8 @@
|
||||
(decl imm12_from_negated_u64 (Imm12) u64)
|
||||
(extern extractor imm12_from_negated_u64 imm12_from_negated_u64)
|
||||
|
||||
(decl lshl_from_imm64 (Type ShiftOpAndAmt) Imm64)
|
||||
(extern extractor lshl_from_imm64 lshl_from_imm64 (in out))
|
||||
(decl pure lshl_from_imm64 (Type Imm64) ShiftOpAndAmt)
|
||||
(extern constructor lshl_from_imm64 lshl_from_imm64)
|
||||
|
||||
(decl integral_ty (Type) Type)
|
||||
(extern extractor integral_ty integral_ty)
|
||||
@@ -1330,13 +1330,13 @@
|
||||
(decl imm12_from_value (Imm12) Value)
|
||||
(extractor
|
||||
(imm12_from_value n)
|
||||
(def_inst (iconst (u64_from_imm64 (imm12_from_u64 n)))))
|
||||
(iconst (u64_from_imm64 (imm12_from_u64 n))))
|
||||
|
||||
;; Same as `imm12_from_value`, but tries negating the constant value.
|
||||
(decl imm12_from_negated_value (Imm12) Value)
|
||||
(extractor
|
||||
(imm12_from_negated_value n)
|
||||
(def_inst (iconst (u64_from_imm64 (imm12_from_negated_u64 n)))))
|
||||
(iconst (u64_from_imm64 (imm12_from_negated_u64 n))))
|
||||
|
||||
;; Helper type to represent a value and an extend operation fused together.
|
||||
(type ExtendedValue extern (enum))
|
||||
@@ -1877,7 +1877,8 @@
|
||||
(movn n (OperandSize.Size64)))
|
||||
|
||||
;; Weird logical-instruction immediate in ORI using zero register
|
||||
(rule (imm (integral_ty _ty) (imm_logic_from_u64 <$I64 n))
|
||||
(rule (imm (integral_ty _ty) k)
|
||||
(if-let n (imm_logic_from_u64 $I64 k))
|
||||
(orr_imm $I64 (zero_reg) n))
|
||||
|
||||
(decl load_constant64_full (u64) Reg)
|
||||
@@ -1978,29 +1979,35 @@
|
||||
|
||||
;; Base case of operating on registers.
|
||||
(rule (alu_rs_imm_logic_commutative op ty x y)
|
||||
(alu_rrr op ty (put_in_reg x) (put_in_reg y)))
|
||||
(alu_rrr op ty x y))
|
||||
|
||||
;; Special cases for when one operand is a constant.
|
||||
(rule (alu_rs_imm_logic_commutative op ty x (def_inst (iconst (imm_logic_from_imm64 <ty imm))))
|
||||
(alu_rr_imm_logic op ty (put_in_reg x) imm))
|
||||
(rule (alu_rs_imm_logic_commutative op ty (def_inst (iconst (imm_logic_from_imm64 <ty imm))) x)
|
||||
(alu_rr_imm_logic op ty (put_in_reg x) imm))
|
||||
(rule (alu_rs_imm_logic_commutative op ty x (iconst k))
|
||||
(if-let imm (imm_logic_from_imm64 ty k))
|
||||
(alu_rr_imm_logic op ty x imm))
|
||||
(rule (alu_rs_imm_logic_commutative op ty (iconst k) x)
|
||||
(if-let imm (imm_logic_from_imm64 ty k))
|
||||
(alu_rr_imm_logic op ty x imm))
|
||||
|
||||
;; Special cases for when one operand is shifted left by a constant.
|
||||
(rule (alu_rs_imm_logic_commutative op ty x (def_inst (ishl y (def_inst (iconst (lshl_from_imm64 <ty amt))))))
|
||||
(alu_rrr_shift op ty (put_in_reg x) (put_in_reg y) amt))
|
||||
(rule (alu_rs_imm_logic_commutative op ty (def_inst (ishl x (def_inst (iconst (lshl_from_imm64 <ty amt))))) y)
|
||||
(alu_rrr_shift op ty (put_in_reg y) (put_in_reg x) amt))
|
||||
(rule (alu_rs_imm_logic_commutative op ty x (ishl y (iconst k)))
|
||||
(if-let amt (lshl_from_imm64 ty k))
|
||||
(alu_rrr_shift op ty x y amt))
|
||||
(rule (alu_rs_imm_logic_commutative op ty (ishl x (iconst k)) y)
|
||||
(if-let amt (lshl_from_imm64 ty k))
|
||||
(alu_rrr_shift op ty y x amt))
|
||||
|
||||
;; Same as `alu_rs_imm_logic_commutative` above, except that it doesn't require
|
||||
;; that the operation is commutative.
|
||||
(decl alu_rs_imm_logic (ALUOp Type Value Value) Reg)
|
||||
(rule (alu_rs_imm_logic op ty x y)
|
||||
(alu_rrr op ty (put_in_reg x) (put_in_reg y)))
|
||||
(rule (alu_rs_imm_logic op ty x (def_inst (iconst (imm_logic_from_imm64 <ty imm))))
|
||||
(alu_rr_imm_logic op ty (put_in_reg x) imm))
|
||||
(rule (alu_rs_imm_logic op ty x (def_inst (ishl y (def_inst (iconst (lshl_from_imm64 <ty amt))))))
|
||||
(alu_rrr_shift op ty (put_in_reg x) (put_in_reg y) amt))
|
||||
(alu_rrr op ty x y))
|
||||
(rule (alu_rs_imm_logic op ty x (iconst k))
|
||||
(if-let imm (imm_logic_from_imm64 ty k))
|
||||
(alu_rr_imm_logic op ty x imm))
|
||||
(rule (alu_rs_imm_logic op ty x (ishl y (iconst k)))
|
||||
(if-let amt (lshl_from_imm64 ty k))
|
||||
(alu_rrr_shift op ty x y amt))
|
||||
|
||||
;; Helper for generating i128 bitops which simply do the same operation to the
|
||||
;; hi/lo registers.
|
||||
|
||||
@@ -56,11 +56,13 @@
|
||||
;; Special cases for when we're adding the shift of a different
|
||||
;; register by a constant amount and the shift can get folded into the add.
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(iadd x (ishl y (iconst (lshl_from_imm64 <ty amt))))))
|
||||
(iadd x (ishl y (iconst k)))))
|
||||
(if-let amt (lshl_from_imm64 ty k))
|
||||
(add_shift ty x y amt))
|
||||
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(iadd (ishl x (iconst (lshl_from_imm64 <ty amt))) y)))
|
||||
(iadd (ishl x (iconst k)) y)))
|
||||
(if-let amt (lshl_from_imm64 ty k))
|
||||
(add_shift ty y x amt))
|
||||
|
||||
;; Fold an `iadd` and `imul` combination into a `madd` instruction.
|
||||
@@ -122,7 +124,8 @@
|
||||
;; Finally a special case for when we're subtracting the shift of a different
|
||||
;; register by a constant amount and the shift can get folded into the sub.
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(isub x (ishl y (iconst (lshl_from_imm64 <ty amt))))))
|
||||
(isub x (ishl y (iconst k)))))
|
||||
(if-let amt (lshl_from_imm64 ty k))
|
||||
(sub_shift ty x y amt))
|
||||
|
||||
;; vectors
|
||||
@@ -568,7 +571,8 @@
|
||||
;; Special case to use `orr_not_shift` if it's a `bnot` of a const-left-shifted
|
||||
;; value.
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(bnot (ishl x (iconst (lshl_from_imm64 <ty amt))))))
|
||||
(bnot (ishl x (iconst k)))))
|
||||
(if-let amt (lshl_from_imm64 ty k))
|
||||
(orr_not_shift ty (zero_reg) x amt))
|
||||
|
||||
;; Implementation of `bnot` for `i128`.
|
||||
@@ -737,7 +741,8 @@
|
||||
;; Note that this rule explicitly has a higher priority than the others
|
||||
;; to ensure it's attempted first, otherwise the type-based filters on the
|
||||
;; previous rules seem to take priority over this rule.
|
||||
(rule 1 (do_shift op ty x (iconst (imm_shift_from_imm64 <ty shift)))
|
||||
(rule 1 (do_shift op ty x (iconst k))
|
||||
(if-let shift (imm_shift_from_imm64 ty k))
|
||||
(alu_rr_imm_shift op ty x shift))
|
||||
|
||||
;;;; Rules for `ushr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -846,7 +851,8 @@
|
||||
(small_rotr ty (put_in_reg_zext32 x) neg_shift)))
|
||||
|
||||
;; Specialization for the 8/16-bit case when the rotation amount is an immediate.
|
||||
(rule (lower (has_type (fits_in_16 ty) (rotl x (iconst (imm_shift_from_imm64 <ty n)))))
|
||||
(rule (lower (has_type (fits_in_16 ty) (rotl x (iconst k))))
|
||||
(if-let n (imm_shift_from_imm64 ty k))
|
||||
(small_rotr_imm ty (put_in_reg_zext32 x) (negate_imm_shift ty n)))
|
||||
|
||||
;; aarch64 doesn't have a left-rotate instruction, but a left rotation of K
|
||||
@@ -868,11 +874,13 @@
|
||||
(a64_rotr $I64 x neg_shift)))
|
||||
|
||||
;; Specialization for the 32-bit case when the rotation amount is an immediate.
|
||||
(rule (lower (has_type $I32 (rotl x (iconst (imm_shift_from_imm64 <$I32 n)))))
|
||||
(rule (lower (has_type $I32 (rotl x (iconst k))))
|
||||
(if-let n (imm_shift_from_imm64 $I32 k))
|
||||
(a64_rotr_imm $I32 x (negate_imm_shift $I32 n)))
|
||||
|
||||
;; Specialization for the 64-bit case when the rotation amount is an immediate.
|
||||
(rule (lower (has_type $I64 (rotl x (iconst (imm_shift_from_imm64 <$I64 n)))))
|
||||
(rule (lower (has_type $I64 (rotl x (iconst k))))
|
||||
(if-let n (imm_shift_from_imm64 $I64 k))
|
||||
(a64_rotr_imm $I64 x (negate_imm_shift $I64 n)))
|
||||
|
||||
(decl negate_imm_shift (Type ImmShift) ImmShift)
|
||||
@@ -906,15 +914,18 @@
|
||||
(a64_rotr $I64 x y))
|
||||
|
||||
;; Specialization for the 8/16-bit case when the rotation amount is an immediate.
|
||||
(rule (lower (has_type (fits_in_16 ty) (rotr x (iconst (imm_shift_from_imm64 <ty n)))))
|
||||
(rule (lower (has_type (fits_in_16 ty) (rotr x (iconst k))))
|
||||
(if-let n (imm_shift_from_imm64 ty k))
|
||||
(small_rotr_imm ty (put_in_reg_zext32 x) n))
|
||||
|
||||
;; Specialization for the 32-bit case when the rotation amount is an immediate.
|
||||
(rule (lower (has_type $I32 (rotr x (iconst (imm_shift_from_imm64 <$I32 n)))))
|
||||
(rule (lower (has_type $I32 (rotr x (iconst k))))
|
||||
(if-let n (imm_shift_from_imm64 $I32 k))
|
||||
(a64_rotr_imm $I32 x n))
|
||||
|
||||
;; Specialization for the 64-bit case when the rotation amount is an immediate.
|
||||
(rule (lower (has_type $I64 (rotr x (iconst (imm_shift_from_imm64 <$I64 n)))))
|
||||
(rule (lower (has_type $I64 (rotr x (iconst k))))
|
||||
(if-let n (imm_shift_from_imm64 $I64 k))
|
||||
(a64_rotr_imm $I64 x n))
|
||||
|
||||
;; For a < 32-bit rotate-right, we synthesize this as:
|
||||
|
||||
@@ -83,13 +83,13 @@ where
|
||||
MoveWideConst::maybe_from_u64(!n)
|
||||
}
|
||||
|
||||
fn imm_logic_from_u64(&mut self, n: u64, ty: Type) -> Option<ImmLogic> {
|
||||
fn imm_logic_from_u64(&mut self, ty: Type, n: u64) -> Option<ImmLogic> {
|
||||
let ty = if ty.bits() < 32 { I32 } else { ty };
|
||||
ImmLogic::maybe_from_u64(n, ty)
|
||||
}
|
||||
|
||||
fn imm_logic_from_imm64(&mut self, n: Imm64, ty: Type) -> Option<ImmLogic> {
|
||||
self.imm_logic_from_u64(n.bits() as u64, ty)
|
||||
fn imm_logic_from_imm64(&mut self, ty: Type, n: Imm64) -> Option<ImmLogic> {
|
||||
self.imm_logic_from_u64(ty, n.bits() as u64)
|
||||
}
|
||||
|
||||
fn imm12_from_u64(&mut self, n: u64) -> Option<Imm12> {
|
||||
@@ -104,7 +104,7 @@ where
|
||||
ImmShift::maybe_from_u64(n.into()).unwrap()
|
||||
}
|
||||
|
||||
fn lshl_from_imm64(&mut self, n: Imm64, ty: Type) -> Option<ShiftOpAndAmt> {
|
||||
fn lshl_from_imm64(&mut self, ty: Type, n: Imm64) -> Option<ShiftOpAndAmt> {
|
||||
let shiftimm = ShiftOpShiftImm::maybe_from_shift(n.bits() as u64)?;
|
||||
let shiftee_bits = ty_bits(ty);
|
||||
if shiftee_bits <= std::u8::MAX as usize {
|
||||
@@ -292,7 +292,7 @@ where
|
||||
ImmLogic::maybe_from_u64(mask, I32).unwrap()
|
||||
}
|
||||
|
||||
fn imm_shift_from_imm64(&mut self, val: Imm64, ty: Type) -> Option<ImmShift> {
|
||||
fn imm_shift_from_imm64(&mut self, ty: Type, val: Imm64) -> Option<ImmShift> {
|
||||
let imm_value = (val.bits() as u64) & ((ty.bits() - 1) as u64);
|
||||
ImmShift::maybe_from_u64(imm_value)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 443b34b797fc8ace
|
||||
src/prelude.isle a7915a6b88310eb5
|
||||
src/isa/aarch64/inst.isle a2c0ae729bfa24a8
|
||||
src/isa/aarch64/lower.isle 15641ca7f0ac061a
|
||||
src/isa/aarch64/inst.isle 21a43af20be377d2
|
||||
src/isa/aarch64/lower.isle 75ad8450963e3829
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user