Skip to content

Commit

Permalink
Performance updates for MM. New macro nospecialized
Browse files Browse the repository at this point in the history
  • Loading branch information
JKRT committed Oct 3, 2024
1 parent 6f7f39e commit 7c67251
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MetaModelica"
uuid = "9d7f2a79-07b5-5542-8b19-c0100dda6b06"
authors = ["Martin Sjölund <[email protected]>", "John Tinnerholm <[email protected]>"]
version = "0.0.5"
version = "0.0.6"

[deps]
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
Expand All @@ -13,4 +13,4 @@ MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
julia = "1.7"
julia = "1.10"
2 changes: 1 addition & 1 deletion src/MetaModelica.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export @match, @matchcontinue, MatchFailure, ModelicaReal, ModelicaInteger
export @Uniontype, @Record, @UniontypeDecl, @ExtendedFunction, @ExtendedAnonFunction
export List, list, Nil, nil, Cons, cons, =>, Option, SOME, NONE, SourceInfo, SOURCEINFO
export @do_threaded_for, <|, @shouldFail, sourceInfo, _cons, @importDBG
export @assign, @Mutable_Uniontype, @closure
export @assign, @Mutable_Uniontype, @closure, @nospecialized

include("exportmetaRuntime.jl")
include("dangerous.jl")
Expand Down
77 changes: 68 additions & 9 deletions src/matchcontinue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ macro splice(iterator, body)
Expr(:..., :(($(esc(body)) for $(esc(iterator.args[2])) in $(esc(iterator.args[3])))))
end

#=
TODO: make this as a mutable struct and change the msg and value instead
Should have some impact on the exception heavy control flow used in the frontend.
=#
struct MatchFailure <: MetaModelicaException
msg::Any
msg::String
value::Any
end

Expand Down Expand Up @@ -284,7 +288,7 @@ function handle_match_eq(expr)
$(asserts...)
value = $(esc(value))
__omc_match_done = false
$body || throw(MatchFailure("no match", value))
$body || throw(MatchFailure("no match", typeof(value)))
$(@splice variable in bound quote
$(esc(variable)) = $(Symbol("variable_$variable"))
end)
Expand Down Expand Up @@ -317,14 +321,16 @@ function handle_match_case(value, case, tail, asserts, matchcontinue::Bool)
__omc_match_done = true
catch e
#=
We only rethrow for two kinds of exceptions currently.
One for list, and one for generic MetaModelicaExceptions.
We only rethrow for two kinds of exceptions currently.
One for list, and one for generic MetaModelicaExceptions.
(Thinking about it I think this might be a performance sink.
TODO: Removing this? -John March 2024)
=#
#if isa(e, MetaModelicaException) || isa(e, ImmutableListException)
# println(e.msg)
#else
# showerror(stderr, e, catch_backtrace())
#end
# if isa(e, MetaModelicaException) || isa(e, ImmutableListException)
# println(e.msg)
# else
# showerror(stderr, e, catch_backtrace())
# end
if !isa(e, MetaModelicaException) && !isa(e, ImmutableListException)
if isa(e, MatchFailure)
println("MatchFailure:" + e.msg)
Expand Down Expand Up @@ -369,6 +375,59 @@ function handle_match_cases(value, match::Expr; mathcontinue::Bool=false)
error("Unrecognized match syntax: Expected begin block $match")
end
line = nothing

local neverFails = false
cases = Expr[]
asserts = Expr[]
for arg in match.args
if isa(arg, LineNumberNode)
line = arg
continue
elseif isa(arg, Expr)
push!(cases, arg)
end
end
for case in reverse(cases)
tail = handle_match_case(:value, case, tail, asserts, mathcontinue)
if line !== nothing
replaceLineNum(tail, @__FILE__, line)
end
#= If one case contains a _ we know this match never fails. =#
pat = case.args[2]
if pat === :_
neverFails = true
end
end
if neverFails == false || mathcontinue
quote
$(asserts...)
local value = $(esc(value))
local __omc_match_done::Bool = false
local res
$tail
if !__omc_match_done
throw(MatchFailure("unfinished match for type", typeof(value)))
end
res
end
else
quote
$(asserts...)
local value = $(esc(value))
local __omc_match_done::Bool = false
local res
$tail
res
end
end
end

function unsafe_handle_match_cases(value, match::Expr; mathcontinue::Bool=false)
tail = nothing
if match.head != :block
error("Unrecognized match syntax: Expected begin block $match")
end
line = nothing
cases = Expr[]
asserts = Expr[]
for arg in match.args
Expand Down
10 changes: 7 additions & 3 deletions src/metaRuntime.jl
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,10 @@ function stringCharListString(strs::List{String})::String
str
end

const genericFailure = MetaModelicaGeneralException("Runtime defined generic Meta Modelica failure")

function fail()
throw(MetaModelicaGeneralException("Runtime defined generic Meta Modelica failure"))
throw(genericFailure)
end

""" Sets the stack overflow signal to the given value and returns the old one """
Expand All @@ -760,8 +762,10 @@ function referenceDebugString(functionSymbol::A)::String where {A}
name
end

""" TODO: I am far from sure that this will fly.. in Julia.
The code generated from the transpiler is correct however"""
"""
TODO: I am far from sure that this will fly.. in Julia.
The code generated from the transpiler is correct however
"""
function isPresent(ident::T)::Bool where {T}
local b::Bool
b = true
Expand Down
45 changes: 45 additions & 0 deletions src/utilityMacros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,48 @@ See the FastClosure package for more information.
macro closure(expr)
esc(FastClosures.wrap_closure(__module__, expr))
end

function genNoSpecializedFunction(expr)
local newExpr::Expr
try
if expr.head === :function
if expr.args[1].head === :call
funcCall = expr.args[1]
body = expr.args[2]
funcName = funcCall.args[1]
args = funcCall.args[2:end]
# Convert function name and arguments to strings for printing
funcNameStr = string(funcName)
argsStr = join(string.(args), ", ")
println("Function name: ", funcNameStr)
println("Arguments: ", argsStr)
local newArgs = Expr[]
global ARGS = args
for arg in args
push!(newArgs, :(@nospecialize($arg)))
end
newExpr = quote
Base.@nospecializeinfer function $funcName($(newArgs...))
$(body)
end
end
else
throw()
end
end
catch
error("@nospecialized can only be used on functions defined as function <name>(<arguments>).")
end
# Return the original expression unchanged
return esc(newExpr)
end

"""
Takes a function declaration function <name>(<arguments>) and change it to
@nospecializeinfer function <name>(@nospecialize(a), @nospecialize(b), ..., @nospecialize(n))
"""
macro nospecialized(expr)
res = genNoSpecializedFunction(expr)
replaceLineNum(res, @__FILE__, __source__)
res
end

0 comments on commit 7c67251

Please sign in to comment.