Skip to content

Commit 3a28b87

Browse files
authored
BE-253: HashQL: Optimize away special casing for logical operators in MIR (#8199)
1 parent fd6d8b5 commit 3a28b87

File tree

4 files changed

+111
-20
lines changed

4 files changed

+111
-20
lines changed

libs/@local/hashql/mir/src/body/rvalue/binary.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,101 @@
44
//! produce a single result value. They are fundamental building blocks for
55
//! arithmetic, logical, and comparison operations in the MIR.
66
7-
use hashql_hir::node::operation::BinOp;
7+
use hashql_core::symbol::{Symbol, sym};
88

99
use crate::body::operand::Operand;
1010

11+
/// The kinds of binary operators available in HashQL.
12+
///
13+
/// Represents the various operations that can be performed with two operands,
14+
/// including arithmetic, comparison, logical, and bitwise operations.
15+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
16+
pub enum BinOp {
17+
/// The `+` operator (addition).
18+
Add(!),
19+
/// The `-` operator (subtraction).
20+
Sub(!),
21+
/// The `*` operator (multiplication).
22+
Mul(!),
23+
/// The `/` operator (division).
24+
Div(!),
25+
/// The `%` operator (remainder).
26+
Rem(!),
27+
/// The `%%`/`⟲` operator (modulo).
28+
Mod(!),
29+
/// The `**`/`↑` operator (exponentiation).
30+
Pow(!),
31+
/// The `^` operator (bitwise xor).
32+
BitXor(!),
33+
/// The `&` operator (bitwise and).
34+
BitAnd,
35+
/// The `|` operator (bitwise or).
36+
BitOr,
37+
/// The `<<` operator (shift left).
38+
BitShl(!),
39+
/// The `>>` operator (shift right).
40+
BitShr(!),
41+
/// The `==` operator (equality).
42+
Eq,
43+
/// The `!=` operator (not equal to).
44+
Ne,
45+
/// The `<` operator (less than).
46+
Lt,
47+
/// The `<=` operator (less than or equal to).
48+
Lte,
49+
/// The `>` operator (greater than).
50+
Gt,
51+
/// The `>=` operator (greater than or equal to).
52+
Gte,
53+
}
54+
55+
impl BinOp {
56+
#[must_use]
57+
pub const fn as_str(self) -> &'static str {
58+
match self {
59+
Self::BitAnd => "&",
60+
Self::BitOr => "|",
61+
Self::Eq => "==",
62+
Self::Lt => "<",
63+
Self::Lte => "<=",
64+
Self::Ne => "!=",
65+
Self::Gte => ">=",
66+
Self::Gt => ">",
67+
}
68+
}
69+
70+
#[must_use]
71+
pub const fn as_symbol(self) -> Symbol<'static> {
72+
match self {
73+
Self::BitAnd => sym::symbol::ampersand,
74+
Self::BitOr => sym::symbol::pipe,
75+
Self::Eq => sym::symbol::eq,
76+
Self::Lt => sym::symbol::lt,
77+
Self::Lte => sym::symbol::lte,
78+
Self::Ne => sym::symbol::ne,
79+
Self::Gte => sym::symbol::gte,
80+
Self::Gt => sym::symbol::gt,
81+
}
82+
}
83+
}
84+
85+
impl From<hashql_hir::node::operation::BinOp> for BinOp {
86+
fn from(value: hashql_hir::node::operation::BinOp) -> Self {
87+
// `And` on bools (what the HIR enforces) is the same as a bitwise `And` and `Or`
88+
// respectively
89+
match value {
90+
hashql_hir::node::operation::BinOp::And => Self::BitAnd,
91+
hashql_hir::node::operation::BinOp::Or => Self::BitOr,
92+
hashql_hir::node::operation::BinOp::Eq => Self::Eq,
93+
hashql_hir::node::operation::BinOp::Ne => Self::Ne,
94+
hashql_hir::node::operation::BinOp::Lt => Self::Lt,
95+
hashql_hir::node::operation::BinOp::Lte => Self::Lte,
96+
hashql_hir::node::operation::BinOp::Gt => Self::Gt,
97+
hashql_hir::node::operation::BinOp::Gte => Self::Gte,
98+
}
99+
}
100+
}
101+
11102
/// A binary operation in the HashQL MIR.
12103
///
13104
/// Binary operations represent computations that take two input operands and

libs/@local/hashql/mir/src/body/rvalue/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod unary;
1313
pub use self::{
1414
aggregate::{Aggregate, AggregateKind},
1515
apply::{Apply, ArgIndex},
16-
binary::Binary,
16+
binary::{BinOp, Binary},
1717
input::Input,
1818
unary::Unary,
1919
};

libs/@local/hashql/mir/src/builder.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use hashql_core::{
4646
r#type::{TypeId, builder::IntoSymbol},
4747
value::{Float, Primitive},
4848
};
49-
use hashql_hir::node::operation::{BinOp, InputOp, UnOp};
49+
use hashql_hir::node::operation::{InputOp, UnOp};
5050

5151
use crate::{
5252
body::{
@@ -57,7 +57,7 @@ use crate::{
5757
local::{Local, LocalDecl, LocalVec},
5858
operand::Operand,
5959
place::{FieldIndex, Place, Projection, ProjectionKind},
60-
rvalue::{Aggregate, AggregateKind, Apply, Binary, Input, RValue, Unary},
60+
rvalue::{Aggregate, AggregateKind, Apply, BinOp, Binary, Input, RValue, Unary},
6161
statement::{Assign, Statement, StatementKind},
6262
terminator::{Goto, Return, SwitchInt, SwitchTargets, Target, Terminator, TerminatorKind},
6363
},
@@ -102,7 +102,7 @@ macro_rules! scaffold {
102102
/// Comparison and logical operators are supported:
103103
///
104104
/// ```
105-
/// use hashql_hir::node::operation::BinOp;
105+
/// use hashql_mir::body::rvalue::BinOp;
106106
/// use hashql_mir::op;
107107
///
108108
/// // Comparison
@@ -114,8 +114,8 @@ macro_rules! scaffold {
114114
/// assert!(matches!(op![>=], BinOp::Gte));
115115
///
116116
/// // Logical
117-
/// assert!(matches!(op![&&], BinOp::And));
118-
/// assert!(matches!(op![||], BinOp::Or));
117+
/// assert!(matches!(op![&], BinOp::BitAnd));
118+
/// assert!(matches!(op![|], BinOp::BitOr));
119119
/// ```
120120
///
121121
/// Arithmetic operators are also available (`op![+]`, `op![-]`, `op![*]`, `op![/]`),
@@ -133,18 +133,18 @@ macro_rules! scaffold {
133133
#[macro_export]
134134
macro_rules! op {
135135
// Binary operators
136-
[+] => { hashql_hir::node::operation::BinOp::Add };
137-
[-] => { hashql_hir::node::operation::BinOp::Sub };
138-
[*] => { hashql_hir::node::operation::BinOp::Mul };
139-
[/] => { hashql_hir::node::operation::BinOp::Div };
140-
[==] => { hashql_hir::node::operation::BinOp::Eq };
141-
[!=] => { hashql_hir::node::operation::BinOp::Ne };
142-
[<] => { hashql_hir::node::operation::BinOp::Lt };
143-
[<=] => { hashql_hir::node::operation::BinOp::Lte };
144-
[>] => { hashql_hir::node::operation::BinOp::Gt };
145-
[>=] => { hashql_hir::node::operation::BinOp::Gte };
146-
[&&] => { hashql_hir::node::operation::BinOp::And };
147-
[||] => { hashql_hir::node::operation::BinOp::Or };
136+
[+] => { $crate::body::rvalue::BinOp::Add };
137+
[-] => { $crate::body::rvalue::BinOp::Sub };
138+
[*] => { $crate::body::rvalue::BinOp::Mul };
139+
[/] => { $crate::body::rvalue::BinOp::Div };
140+
[==] => { $crate::body::rvalue::BinOp::Eq };
141+
[!=] => { $crate::body::rvalue::BinOp::Ne };
142+
[<] => { $crate::body::rvalue::BinOp::Lt };
143+
[<=] => { $crate::body::rvalue::BinOp::Lte };
144+
[>] => { $crate::body::rvalue::BinOp::Gt };
145+
[>=] => { $crate::body::rvalue::BinOp::Gte };
146+
[&] => { $crate::body::rvalue::BinOp::BitAnd };
147+
[|] => { $crate::body::rvalue::BinOp::BitOr };
148148

149149
// Unary operators
150150
[!] => { hashql_hir::node::operation::UnOp::Not };

libs/@local/hashql/mir/src/reify/rvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ impl<'mir, 'heap> Reifier<'_, 'mir, '_, '_, 'heap> {
136136
let right = self.operand(right);
137137

138138
RValue::Binary(Binary {
139-
op: op.value,
139+
op: op.value.into(),
140140
left,
141141
right,
142142
})

0 commit comments

Comments
 (0)