Skip to content

Commit

Permalink
compiler: improve --opt-str optimization flag for the binary expressi…
Browse files Browse the repository at this point in the history
…on operands
  • Loading branch information
mertcandav committed Oct 23, 2024
1 parent 4a833a0 commit 5f4e225
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
4 changes: 4 additions & 0 deletions api/str.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ namespace jule
return jule::Str::lit(s, std::strlen(s));
}

static inline jule::Str unsafe_from_bytes(const jule::Slice<jule::U8> &bytes) noexcept {
return jule::Str::lit(reinterpret_cast<const char*>(bytes.begin()), bytes.len());
}

// Returns element by index.
// Includes safety checking.
// Designed for constant strings.
Expand Down
9 changes: 9 additions & 0 deletions src/julec/obj/cxx/expr.jule
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum compExpr: type {
&opt::UnsafeCastingExpr,
&opt::FnCallIgnoreExceptionalExpr,
&opt::StrConcatExpr,
&opt::StrFromBytes,
}

struct exprCoder {
Expand Down Expand Up @@ -1676,6 +1677,12 @@ impl exprCoder {
self.oc.write(typeCoder.Str + " result; result._len = buf._len; result.buffer = std::move(buf.data); result._slice = buf._slice; std::move(result); })")
}

fn strFromBytes(mut &self, mut m: &opt::StrFromBytes) {
self.oc.write(typeCoder.Str + "::unsafe_from_bytes(")
self.possibleRefExpr(m.Expr)
self.oc.write(")")
}

fn model(mut &self, mut m: compExpr) {
match type m {
| str:
Expand Down Expand Up @@ -1774,6 +1781,8 @@ impl exprCoder {
self.funcCall((&opt::FnCallIgnoreExceptionalExpr)(m).Base, true)
| &opt::StrConcatExpr:
self.strConcat((&opt::StrConcatExpr)(m))
| &opt::StrFromBytes:
self.strFromBytes((&opt::StrFromBytes)(m))
|:
self.oc.write("<unimplemented_expression_model>")
}
Expand Down
46 changes: 44 additions & 2 deletions src/julec/opt/expr.jule
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,34 @@ impl exprOptimizer {
ret true
}

// Optimizes string conversions if possible.
// It may apply optimizations with unsafe behaviors.
// So make sure this optimizations are always safe for the scope.
fn strConv(self, mut &m: &sema::OperandExpr) {
p := m.Type.Prim()
if p == nil || !p.IsStr() {
ret
}
match type m.Model {
| &sema::CastingExpr:
// str(?)
mut c := (&sema::CastingExpr)(m.Model)
mut s := c.Expr.Type.Slc()
if s == nil {
break
}
sp := s.Elem.Prim()
if sp == nil {
break
}
if sp.IsU8() {
// str([]byte)
mut model := any(&StrFromBytes{Expr: c.Expr.Model})
m.Model = unsafe { *(*sema::Expr)(&model) }
}
}
}

fn strCond(self, mut &m: &sema::BinaryExpr): bool {
lp := m.Left.Type.Prim()
if lp == nil || !lp.IsStr() {
Expand Down Expand Up @@ -293,8 +321,14 @@ impl exprOptimizer {
// So handle `"foo" + x + "bar"` expression first, then the right operand `+ "baz"`.
// So, recursively handle the left binary expression operands,
// and push the expression models by left-to-right order.
unsafe { _step((&sema::BinaryExpr)(m).Left.Model) }
unsafe { _step((&sema::BinaryExpr)(m).Right.Model) }
mut binary := (&sema::BinaryExpr)(m)
unsafe {
// Apply common optimizations for each binary expression.
self.binaryStrCommon(binary)

_step(binary.Left.Model)
_step(binary.Right.Model)
}
|:
model.Parts = append(model.Parts, m)
}
Expand Down Expand Up @@ -585,8 +619,16 @@ impl exprOptimizer {
ret true
}

// Common string optimizations for binary expressions.
// Always make sure this optimization will not block the following analysis.
fn binaryStrCommon(self, mut &m: &sema::BinaryExpr) {
self.strConv(m.Left)
self.strConv(m.Right)
}

fn binary(self, mut m: &sema::BinaryExpr) {
if Str {
self.binaryStrCommon(m)
match {
| self.strCond(m)
| self.strConcat(m):
Expand Down
4 changes: 4 additions & 0 deletions src/julec/opt/model.jule
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use "std/jule/constant"
use "std/jule/sema"
use "std/jule/token"

struct StrFromBytes {
Expr: sema::Expr
}

struct ExceptionalForwardingExpr {
Expr: &sema::FnCallExpr
}
Expand Down

0 comments on commit 5f4e225

Please sign in to comment.