Skip to content

Commit

Permalink
Merge: Inline binops
Browse files Browse the repository at this point in the history
This PR re-introduces several binary operations implemented as intern to avoid indirection through FFI in some specific cases to improve performance notably in `core/text/native`

Also a style change for `abs` which could easily be inlined and burned by eyes when I saw it, I can remove the commit if someone objects to the modification

Pull-Request: #1881
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
  • Loading branch information
privat committed Dec 9, 2015
2 parents ff48d41 + 5b44ff8 commit b02f326
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 30 deletions.
38 changes: 22 additions & 16 deletions lib/core/kernel.nit
Expand Up @@ -644,17 +644,23 @@ universal Byte
# `i` bits shift fo the left
#
# assert 5u8 << 1 == 10u8
fun <<(i: Int): Byte `{ return self << i; `}
fun <<(i: Int): Byte is intern do return lsh(i)

private fun lsh(i: Int): Byte `{ return self << i; `}

# `i` bits shift fo the right
#
# assert 5u8 >> 1 == 2u8
fun >>(i: Int): Byte `{ return self >> i; `}
fun >>(i: Int): Byte is intern do return rsh(i)

private fun rsh(i: Int): Byte `{ return self >> i; `}

# Returns the character equivalent of `self`
#
# REQUIRE: `self <= 127u8`
fun ascii: Char `{ return (uint32_t)self; `}
fun ascii: Char is intern do return ffi_ascii

private fun ffi_ascii: Char `{ return (uint32_t)self; `}

redef fun to_i is intern
redef fun to_f is intern
Expand Down Expand Up @@ -743,12 +749,16 @@ universal Int
# `i` bits shift fo the left
#
# assert 5 << 1 == 10
fun <<(i: Int): Int `{ return self << i; `}
fun <<(i: Int): Int is intern do return lsh(i)

private fun lsh(i: Int): Int `{ return self << i; `}

# `i` bits shift fo the right
#
# assert 5 >> 1 == 2
fun >>(i: Int): Int `{ return self >> i; `}
fun >>(i: Int): Int is intern do return rsh(i)

private fun rsh(i: Int): Int `{ return self >> i; `}

redef fun to_i do return self
redef fun to_f is intern
Expand Down Expand Up @@ -807,7 +817,9 @@ universal Int
# assert 65.code_point == 'A'
# assert 10.code_point == '\n'
# assert 0x220B.code_point == '∋'
fun code_point: Char `{ return (uint32_t)self; `}
fun code_point: Char is intern do return cp

private fun cp: Char `{ return (uint32_t)self; `}

# Number of digits of an integer in base `b` (plus one if negative)
#
Expand Down Expand Up @@ -878,15 +890,7 @@ universal Int
# assert (-10).abs == 10
# assert 10.abs == 10
# assert 0.abs == 0
fun abs: Int
do
if self >= 0
then
return self
else
return -1 * self
end
end
fun abs: Int do return if self >= 0 then self else -self
end

# Native characters.
Expand Down Expand Up @@ -961,7 +965,9 @@ universal Char
# assert 'A'.code_point == 65
# assert '\n'.code_point == 10
# assert '∋'.code_point == 0x220B
fun code_point: Int `{ return (long)self; `}
fun code_point: Int is intern do return cp

private fun cp: Int `{ return (long)self; `}

# Is `self` an ASCII character ?
#
Expand Down
12 changes: 9 additions & 3 deletions lib/core/math.nit
Expand Up @@ -67,12 +67,16 @@ redef class Int
# Returns the result of a binary AND operation on `self` and `i`
#
# assert 0x10 & 0x01 == 0
fun &(i: Int): Int `{ return self & i; `}
fun &(i: Int): Int is intern do return band(i)

private fun band(i: Int): Int `{ return self & i; `}

# Returns the result of a binary OR operation on `self` and `i`
#
# assert 0x10 | 0x01 == 0x11
fun |(i: Int): Int `{ return self | i; `}
fun |(i: Int): Int is intern do return bor(i)

private fun bor(i: Int): Int `{ return self | i; `}

# Returns the result of a binary XOR operation on `self` and `i`
#
Expand Down Expand Up @@ -175,7 +179,9 @@ redef class Byte
# Returns the result of a binary AND operation on `self` and `i`
#
# assert 0x10u8 & 0x01u8 == 0u8
fun &(i: Byte): Byte `{ return self & i; `}
fun &(i: Byte): Byte is intern do return band(i)

private fun band(i: Byte): Byte `{ return self & i; `}

# Returns the result of a binary OR operation on `self` and `i`
#
Expand Down
30 changes: 30 additions & 0 deletions src/compiler/abstract_compiler.nit
Expand Up @@ -2249,6 +2249,21 @@ redef class AMethPropdef
else if pname == "to_b" then
v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
return true
else if pname == "code_point" then
v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
return true
else if pname == "&" then
v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
return true
else if pname == "|" then
v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
return true
else if pname == ">>" then
v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
return true
else if pname == "<<" then
v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
return true
end
else if cname == "Char" then
if pname == "object_id" then
Expand Down Expand Up @@ -2282,6 +2297,9 @@ redef class AMethPropdef
else if pname == "to_i" then
v.ret(v.new_expr("{arguments[0]}-'0'", ret.as(not null)))
return true
else if pname == "code_point" then
v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
return true
end
else if cname == "Byte" then
if pname == "output" then
Expand Down Expand Up @@ -2330,6 +2348,15 @@ redef class AMethPropdef
else if pname == ">=" then
v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
return true
else if pname == ">>" then
v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
return true
else if pname == "<<" then
v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
return true
else if pname == "&" then
v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
return true
else if pname == "to_i" then
v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
return true
Expand All @@ -2351,6 +2378,9 @@ redef class AMethPropdef
else if pname == "to_u32" then
v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
return true
else if pname == "ascii" then
v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
return true
end
else if cname == "Bool" then
if pname == "output" then
Expand Down
10 changes: 5 additions & 5 deletions tests/sav/error_class_glob.res
Expand Up @@ -6,8 +6,8 @@
../lib/core/kernel.nit:431,1--486,3: Error: `kernel#Numeric` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:492,1--515,3: Error: `kernel#Bool` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:517,1--599,3: Error: `kernel#Float` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:601,1--702,3: Error: `kernel#Byte` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:704,1--890,3: Error: `kernel#Int` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:892,1--1060,3: Error: `kernel#Char` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:1062,1--1069,3: Error: `kernel#Pointer` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:1071,1--1080,3: Error: `kernel#Task` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:601,1--708,3: Error: `kernel#Byte` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:710,1--894,3: Error: `kernel#Int` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:896,1--1066,3: Error: `kernel#Char` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:1068,1--1075,3: Error: `kernel#Pointer` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:1077,1--1086,3: Error: `kernel#Task` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
2 changes: 1 addition & 1 deletion tests/sav/nitce/fixme/base_gen_reassign_alt4.res
@@ -1,4 +1,4 @@
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:731)
11
21
31
Expand Down
2 changes: 1 addition & 1 deletion tests/sav/nitce/fixme/base_gen_reassign_alt5.res
@@ -1,4 +1,4 @@
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:731)
11
21
31
Expand Down
2 changes: 1 addition & 1 deletion tests/sav/nitce/fixme/base_gen_reassign_alt6.res
@@ -1,4 +1,4 @@
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:731)
11
21
31
Expand Down
6 changes: 3 additions & 3 deletions tests/sav/nituml_args3.res
Expand Up @@ -51,19 +51,19 @@ Float [
Numeric -> Float [dir=back arrowtail=open style=dashed];

Byte [
label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ ascii(): Char\l}"
label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l- lsh(i: Int): Byte\l+ \>\>(i: Int): Byte\l- rsh(i: Int): Byte\l+ ascii(): Char\l- ffi_ascii(): Char\l}"
]
Discrete -> Byte [dir=back arrowtail=open style=dashed];
Numeric -> Byte [dir=back arrowtail=open style=dashed];

Int [
label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l+ \>\>(i: Int): Int\l+ code_point(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l- lsh(i: Int): Int\l+ \>\>(i: Int): Int\l- rsh(i: Int): Int\l+ code_point(): Char\l- cp(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
]
Discrete -> Int [dir=back arrowtail=open style=dashed];
Numeric -> Int [dir=back arrowtail=open style=dashed];

Char [
label = "{Char||+ to_i(): Int\l+ ascii(): Byte\l+ code_point(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
label = "{Char||+ to_i(): Int\l+ ascii(): Byte\l+ code_point(): Int\l- cp(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
]
Discrete -> Char [dir=back arrowtail=open style=dashed];

Expand Down

0 comments on commit b02f326

Please sign in to comment.