Skip to content

Commit

Permalink
compiler: update optimization algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Mar 16, 2024
1 parent 83d84e7 commit 4342988
Show file tree
Hide file tree
Showing 6 changed files with 595 additions and 181 deletions.
192 changes: 50 additions & 142 deletions src/julec/obj/cxx/expr.jule
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// license that can be found in the LICENSE file.

use env
use optimizing::{
UnsafeBinopExprModel,
UnsafeIndexingExprModel,
}

use conv for std::conv
use std::env::{ARCH}
Expand Down Expand Up @@ -183,86 +187,33 @@ impl ExprCoder {
}

fn div_by_zero_binary(mut self, &op: Token, mut &l: &OperandExprModel, mut &r: &OperandExprModel): str {
let mut opt = false
if env::OPT_MATH {
match type r.model {
| &Const:
opt = true
}
}

let mut op_func = ""
match op.kind {
| TokenKind.Solidus
| TokenKind.SolidusEq:
op_func = if opt { "/" } else { "div" }
op_func = "div"
| TokenKind.Percent
| TokenKind.PercentEq:
op_func = if opt { "%" } else { "mod" }
op_func = "mod"
}

let mut obj = ""
if opt {
obj = "("
obj += self.expr(l.model)
match op.kind {
| TokenKind.Solidus:
let (ok, x) = check_for_bit_shift_opt(l, r)
if ok {
obj += " >> "
obj += utoa(x)
break
}
fall
|:
obj += " "
obj += op_func
obj += " "
obj += self.expr(r.model)
}
obj += ")"
} else {
obj = "jule::"
obj += op_func
obj += "("
if !env::PRODUCTION {
obj += "\""
obj += self.oc.loc_info(op)
obj += "\","
}
obj += self.expr(l.model)
obj += ","
obj += self.expr(r.model)
obj += ")"
let mut obj = "jule::"
obj += op_func
obj += "("
if !env::PRODUCTION {
obj += "\""
obj += self.oc.loc_info(op)
obj += "\","
}
obj += self.expr(l.model)
obj += ","
obj += self.expr(r.model)
obj += ")"
ret obj
}

fn binary(mut self, mut m: &BinopExprModel): str {
match m.op.kind {
| TokenKind.Solidus | TokenKind.Percent:
// Do not check division of structures safety.
if m.left.kind.strct() == nil {
ret self.div_by_zero_binary(m.op, m.left, m.right)
}
}

fn unsafe_binary(mut self, mut m: &BinopExprModel): str {
let mut obj = "("
if env::OPT_MATH {
match m.op.kind {
| TokenKind.Star: // Multiplication
let (ok, x) = check_for_bit_shift_opt(m.left, m.right)
if !ok {
break
}
obj += self.model(m.left.model)
obj += " << "
obj += utoa(x)
obj += ")"
ret obj
}
}

obj += self.model(m.left.model)
obj += " "
obj += m.op.kind
Expand All @@ -272,6 +223,17 @@ impl ExprCoder {
ret obj
}

fn binary(mut self, mut m: &BinopExprModel): str {
match m.op.kind {
| TokenKind.Solidus | TokenKind.Percent:
// Do not check division of structures safety.
if m.left.kind.strct() == nil {
ret self.div_by_zero_binary(m.op, m.left, m.right)
}
}
ret self.unsafe_binary(m)
}

fn var(self, mut m: &Var): str {
if m.cpp_linked {
let d = find_directive(m.directives, Directive.Namespace)
Expand All @@ -294,16 +256,6 @@ impl ExprCoder {
}

fn unary(mut self, mut m: &UnaryExprModel): str {
if env::OPT_PTR && m.op.kind == TokenKind.Star {
match type m.expr.model {
| &UnaryExprModel:
let mut um = (&UnaryExprModel)(m.expr.model)
if um.op.kind == TokenKind.Amper {
ret self.model(um.expr.model)
}
}
}

match m.op.kind {
| TokenKind.Caret:
let mut obj = "(~("
Expand Down Expand Up @@ -595,40 +547,6 @@ impl ExprCoder {

fn indexing(mut self, mut m: &IndexingExprModel): str {
let mut obj = self.model(m.expr.model)

// Try access optimization.
if env::OPT_ACCESS {
let array = m.expr.kind.arr() != nil

// Constants checked by semantic analysis for arrays, safe.
if array && m.index.is_const() {
obj += ".__at("
obj += self.expr(m.index.model)
obj += ")"
ret obj
}

match type m.index.model {
| &Var:
let i = (&Var)(m.index.model)
if i.mutable || i.iter_relation == nil {
break
}
match type m.expr.model {
| &Var:
let r = (&Var)(m.expr.model)

// Iterated variable is indexed variable?
if i.iter_relation.range == r {
obj += ".__at("
obj += self.expr(m.index.model)
obj += ")"
ret obj
}
}
}
}

// Index access with safety measures.
match {
| env::PRODUCTION
Expand All @@ -644,7 +562,24 @@ impl ExprCoder {
obj += self.expr(m.index.model)
obj += ")"
}
ret obj
}

fn unsafe_indexing(mut self, mut m: &UnsafeIndexingExprModel): str {
let mut obj = self.model(m.node.expr.model)
// Index access with safety measures.
match {
| env::PRODUCTION
| m.node.expr.kind.ptr() != nil
| m.node.expr.kind.map() != nil:
obj += "["
obj += self.expr(m.node.index.model)
obj += "]"
|:
obj += ".__at("
obj += self.expr(m.node.index.model)
obj += ")"
}
ret obj
}

Expand Down Expand Up @@ -1023,6 +958,8 @@ impl ExprCoder {
ret self.structure_ins((&StructIns)(m))
| &FnIns:
ret self.func_ins_common((&FnIns)(m))
| &UnsafeBinopExprModel:
ret self.unsafe_binary((&UnsafeBinopExprModel)(m).node)
| &BinopExprModel:
ret self.binary((&BinopExprModel)(m))
| &UnaryExprModel:
Expand All @@ -1039,6 +976,8 @@ impl ExprCoder {
ret self.slice((&SliceExprModel)(m))
| &ArrayExprModel:
ret self.array((&ArrayExprModel)(m))
| &UnsafeIndexingExprModel:
ret self.unsafe_indexing((&UnsafeIndexingExprModel)(m))
| &IndexingExprModel:
ret self.indexing((&IndexingExprModel)(m))
| &AnonFnExprModel:
Expand Down Expand Up @@ -1136,37 +1075,6 @@ fn concat_all_parts(parts: ...Token): str {
ret s
}

// Checks for bit-shifting optimizations.
// Reports true if conditions are:
// - l is integer
// - r is integer
// - r is constant
// - r > 0 && r%2 == 0
// - log2(r) returns integer without fraction
//
// As a result: returns whether bit-shifting is possible and what nth power of 2^r.
fn check_for_bit_shift_opt(&l: &OperandExprModel, &r: &OperandExprModel): (ok: bool, x: u64) {
if !types::is_int(l.kind.to_str()) || !types::is_int(r.kind.to_str()) {
ret false, 0
}
match type r.model {
| &Const:
break
|:
ret false, 0
}
x = (&Const)(r.model).as_u64()
if x == 0 || x%2 != 0 {
ret false, 0
}
let j = math::log2(f64(x))
let z = u64(j)
if f64(z) != j {
ret false, 0
}
ret true, z
}

fn decompose_common_esq(b: byte): str {
match b {
| '\\':
Expand Down
17 changes: 0 additions & 17 deletions src/julec/obj/cxx/scope.jule
Original file line number Diff line number Diff line change
Expand Up @@ -312,23 +312,7 @@ impl ScopeCoder {
ret obj
}

fn div_by_zero_assign(mut self, mut a: &Assign): str {
let mut obj = self.oc.ec.expr(a.l.model)
obj += " = "
obj += self.oc.ec.div_by_zero_binary(a.op, a.l, a.r)
obj += ";"
ret obj
}

fn assign(mut self, mut a: &Assign): str {
match a.op.kind {
| TokenKind.SolidusEq | TokenKind.PercentEq:
// Do not check division of structures safety.
if a.l.kind.strct() == nil {
ret self.div_by_zero_assign(a)
}
}

let mut obj = self.oc.ec.expr(a.l.model)
obj += a.op.kind
if env::OPT_APPEND {
Expand All @@ -340,7 +324,6 @@ impl ScopeCoder {
ret expr
}
obj += expr

|:
obj += self.oc.ec.expr(a.r.model)
}
Expand Down
Loading

0 comments on commit 4342988

Please sign in to comment.