diff --git a/src/julec/compile.jule b/src/julec/compile.jule index 7a6e066fc..5027f0980 100644 --- a/src/julec/compile.jule +++ b/src/julec/compile.jule @@ -312,6 +312,7 @@ fn checkFlags(&args: []str): []str { fs.AddVar[bool](unsafe { (&bool)(&opt::Array) }, "opt-array", 0, "Array optimizations") fs.AddVar[bool](unsafe { (&bool)(&opt::Len) }, "opt-len", 0, "Len optimizations") fs.AddVar[bool](unsafe { (&bool)(&opt::StdStrings) }, "opt-std-strings", 0, "Special optimizations for the std/strings package") + fs.AddVar[bool](unsafe { (&bool)(&opt::StdMathCmplx) }, "opt-std-math-cmplx", 0, "Special optimizations for the std/math/cmplx package") mut content := fs.Parse(args) else { handle::Throw(str(error)) diff --git a/src/julec/obj/meta.jule b/src/julec/obj/meta.jule index d580117a1..4a237a455 100644 --- a/src/julec/obj/meta.jule +++ b/src/julec/obj/meta.jule @@ -8,6 +8,7 @@ use "std/jule/sema" // Linkpath of common packages. const linkpathRuntime = "std/runtime" const linkpathStrings = "std/strings" +const linkpathMathCmplx = "std/math/cmplx" // Program metadata for the main IR. // All required packages use this metada collection instead of @@ -42,10 +43,26 @@ struct MetaRuntime { MapIterator: &sema::Struct } +// Metadata for the std/math/cmplx package. +struct MetaMathCmplx { + Cmplx: &sema::StructIns // Cmplx + + CmplxAdd: &sema::FnIns // Cmplx.Add + CmplxSub: &sema::FnIns // Cmplx.Sub + CmplxMul: &sema::FnIns // Cmplx.Mul + CmplxDiv: &sema::FnIns // Cmplx.Div + CmplxAddZ: &sema::FnIns // Cmplx.add + CmplxSubZ: &sema::FnIns // Cmplx.sub + CmplxMulZ: &sema::FnIns // Cmplx.mul + CmplxDivZ: &sema::FnIns // Cmplx.div +} + // Metadata for common objects. struct Meta { Runtime: &MetaRuntime StrBuilder: &MetaStrBuilder + MathCmplx: &MetaMathCmplx + EntryPoint: &sema::Fn } @@ -55,6 +72,7 @@ impl Meta { mut meta := new(Meta) meta.Runtime = Meta.CollectRuntime(ir) meta.StrBuilder = Meta.CollectStrBuilder(ir) + meta.MathCmplx = Meta.CollectMathCmplx(ir) ret meta } @@ -100,4 +118,26 @@ impl Meta { } ret meta } + + // Collects MetaMathCmplx from IR if possible. + static fn CollectMathCmplx(mut &ir: &IR): &MetaMathCmplx { + mut p := SelectImport(ir.Used, linkpathMathCmplx) + if p == nil { + ret nil + } + mut meta := new(MetaMathCmplx) + + const Static = false + meta.Cmplx = RuntimeFindStruct(p, "Cmplx").Instances[0] + meta.CmplxAdd = meta.Cmplx.FindMethod("Add", Static).Instances[0] + meta.CmplxSub = meta.Cmplx.FindMethod("Sub", Static).Instances[0] + meta.CmplxMul = meta.Cmplx.FindMethod("Mul", Static).Instances[0] + meta.CmplxDiv = meta.Cmplx.FindMethod("Div", Static).Instances[0] + meta.CmplxAddZ = meta.Cmplx.FindMethod("add", Static).Instances[0] + meta.CmplxSubZ = meta.Cmplx.FindMethod("sub", Static).Instances[0] + meta.CmplxMulZ = meta.Cmplx.FindMethod("mul", Static).Instances[0] + meta.CmplxDivZ = meta.Cmplx.FindMethod("div", Static).Instances[0] + + ret meta + } } \ No newline at end of file diff --git a/src/julec/opt/flag.jule b/src/julec/opt/flag.jule index eafa63bc4..56c5cd82b 100644 --- a/src/julec/opt/flag.jule +++ b/src/julec/opt/flag.jule @@ -14,7 +14,7 @@ enum OptLevel { // Passed flags: // All flags of the L0, L1 and additionally: - // StdStrings + // StdStrings, StdMathCmplx L2, } @@ -35,6 +35,7 @@ static mut Dynamic = false static mut Array = false static mut Len = false static mut StdStrings = false +static mut StdMathCmplx = false // Pushes optimization flags related with optimization level. fn PushOptLevel(level: OptLevel) { @@ -59,4 +60,5 @@ fn PushOptLevel(level: OptLevel) { Len = l1 StdStrings = l2 + StdMathCmplx = l2 } \ No newline at end of file diff --git a/src/julec/opt/optimizer.jule b/src/julec/opt/optimizer.jule index e8b5af4b6..ded1411f3 100644 --- a/src/julec/opt/optimizer.jule +++ b/src/julec/opt/optimizer.jule @@ -119,5 +119,5 @@ fn detectEnabled() { exprEnabled = StdStrings || Ptr || Math || Access || Cond || Array || Str || Dynamic || Len scopeEnabled = Cond || Append || Copy || Str || Slice || Assign || Exceptional || - Iter || Dynamic + Iter || Dynamic || StdMathCmplx } \ No newline at end of file diff --git a/src/julec/opt/scope.jule b/src/julec/opt/scope.jule index cb34f0069..347fb87aa 100644 --- a/src/julec/opt/scope.jule +++ b/src/julec/opt/scope.jule @@ -409,6 +409,48 @@ impl scopeOptimizer { exprOptimizer.optimizeData(postfix.Expr, self.data) } + fn cmplxAssign(mut &self, mut &assign: &sema::Assign): bool { + if !StdMathCmplx || assign.Op.Id != token::Id.Eq || obj::ProgramMeta.MathCmplx == nil { + ret false + } + mut s := assign.Left.Type.Struct() + if s == nil || s != obj::ProgramMeta.MathCmplx.Cmplx { + ret false + } + match type assign.Right.Model { + | &sema::FnCallExprModel: + break + |: + ret false + } + mut fc := (&sema::FnCallExprModel)(assign.Right.Model) + match type fc.Expr { + | &sema::StructSubIdentExprModel: + break + |: + ret false + } + mut siem := (&sema::StructSubIdentExprModel)(fc.Expr) + if !equalModels(assign.Left.Model, siem.Expr.Model) { + ret false + } + match fc.Func { + | obj::ProgramMeta.MathCmplx.CmplxAdd: + fc.Func = obj::ProgramMeta.MathCmplx.CmplxAddZ + | obj::ProgramMeta.MathCmplx.CmplxSub: + fc.Func = obj::ProgramMeta.MathCmplx.CmplxSubZ + | obj::ProgramMeta.MathCmplx.CmplxMul: + fc.Func = obj::ProgramMeta.MathCmplx.CmplxMulZ + | obj::ProgramMeta.MathCmplx.CmplxDiv: + fc.Func = obj::ProgramMeta.MathCmplx.CmplxDivZ + |: + ret false + } + siem.Method = fc.Func + self.setCurrentStmt(&sema::Data{Model: fc}) + ret true + } + fn optimizeAssign(mut &self, mut assign: &sema::Assign) { if assign.Op.Id == token::Id.Eq && equalModels(assign.Left.Model, assign.Right.Model) { @@ -446,7 +488,8 @@ impl scopeOptimizer { match { | self.strAssign(assign) - | self.sliceAssign(assign): + | self.sliceAssign(assign) + | self.cmplxAssign(assign): ret }