Skip to content

Commit

Permalink
compiler: minor improvements for --opt-append optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Jul 26, 2024
1 parent 61e8069 commit ffec721
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 15 deletions.
9 changes: 0 additions & 9 deletions api/slice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,15 +407,6 @@ namespace jule

Slice &operator=(const jule::Slice<Item> &src) noexcept
{
// Assignment to itself.
if (this->data.alloc != nullptr && this->data.alloc == src.data.alloc)
{
this->_len = src._len;
this->_cap = src._cap;
this->_slice = src._slice;
return *this;
}

this->dealloc();
this->__get_copy(src);
return *this;
Expand Down
46 changes: 42 additions & 4 deletions src/julec/obj/cxx/expr.jule
Original file line number Diff line number Diff line change
Expand Up @@ -1194,15 +1194,53 @@ impl exprCoder {

self.oc.write("{ ")
self.oc.write(self.oc.tc.asSlice(m.Elems.ElemKind))
self.oc.write(" &" + destIdent + " = ")
self.possibleRefExpr(m.Dest)
self.oc.write("; " + destIdent + ".alloc_for_append(")

let mut ptr = false
match type m.Dest {
| &UnaryExprModel:
// Use raw pointer directly if exist.
let mut u = (&UnaryExprModel)(m.Dest)
if u.Expr.Kind.Ptr() != nil {
self.oc.write(" *" + destIdent + " = ")
self.possibleRefExpr(u.Expr.Model)
self.oc.write("; ")
ptr = true
break
}
fall
|:
self.oc.write(" &" + destIdent + " = ")
self.possibleRefExpr(m.Dest)
self.oc.write("; ")
}
// Pushed single item.
if len(m.Elems.Elems) == 1 {
if ptr {
self.oc.write(destIdent + "->push(")
} else {
self.oc.write(destIdent + ".push(")
}
self.possibleRefExpr(m.Elems.Elems[0])
self.oc.write("); }")
ret
}
// Pushed more than single item.
// Pre-allocate enough capacity if not exist for appendation.
if ptr {
self.oc.write(destIdent + "->alloc_for_append(")
} else {
self.oc.write(destIdent + ".alloc_for_append(")
}
self.oc.write(conv::Itoa(len(m.Elems.Elems)))
self.oc.write("); ")
for (_, mut e) in m.Elems.Elems {
self.oc.write(destIdent)
// Use the "__push" method to skip allocation boundary checking.
self.oc.write(".__push(")
if ptr {
self.oc.write("->__push(")
} else {
self.oc.write(".__push(")
}
self.possibleRefExpr(e)
self.oc.write("); ")
}
Expand Down
17 changes: 15 additions & 2 deletions src/julec/opt/expr.jule
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ fn checkForBitShiftOpt(&l: &OperandExprModel, &r: &OperandExprModel): (ok: bool,
}

// Reports l and r the same lvalue expression.
fn areSameLvalueExprModel(mut &l: ExprModel, &r: ExprModel): bool {
fn areSameLvalueExprModel(&l: ExprModel, &r: ExprModel): bool {
match type l {
| &Var:
// Compare values directly.
Expand All @@ -499,7 +499,7 @@ fn areSameLvalueExprModel(mut &l: ExprModel, &r: ExprModel): bool {
|:
ret false
}
let mut lsi = (&StructSubIdentExprModel)(l)
let lsi = (&StructSubIdentExprModel)(l)
let rsi = (&StructSubIdentExprModel)(r)
// Compare fields directly.
// If the l and r have same pointers,
Expand All @@ -509,6 +509,19 @@ fn areSameLvalueExprModel(mut &l: ExprModel, &r: ExprModel): bool {
}
// Check head expressions used for field access.
ret areSameLvalueExprModel(lsi.Expr.Model, rsi.Expr.Model)
| &UnaryExprModel:
match type r {
| &UnaryExprModel:
let ul = (&UnaryExprModel)(l)
let ur = (&UnaryExprModel)(r)
// Unary operators should have the same operator.
// The operator does not matter.
if ul.Op.Id != ur.Op.Id || ul.Op.Kind != ur.Op.Kind {
ret false
}
// Check expressions used for unary.
ret areSameLvalueExprModel(ul.Expr.Model, ur.Expr.Model)
}
}
ret false
}

0 comments on commit ffec721

Please sign in to comment.