mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v: add compiler support for _unlikely_(x) too
This commit is contained in:
parent
c7d4360931
commit
4fc41c4bc4
@ -1700,6 +1700,9 @@ boolean expression is very likely to be true, so it can generate assembly
|
|||||||
code, with less chance of branch misprediction. In the JS backend,
|
code, with less chance of branch misprediction. In the JS backend,
|
||||||
that does nothing.
|
that does nothing.
|
||||||
|
|
||||||
|
`if _unlikely_(bool expression) {` similar to `_likely_(x)`, but it hints that
|
||||||
|
the boolean expression is highly improbable. In the JS backend, that does nothing.
|
||||||
|
|
||||||
## Reflection via codegen
|
## Reflection via codegen
|
||||||
|
|
||||||
Having built-in JSON support is nice, but V also allows you to create efficient
|
Having built-in JSON support is nice, but V also allows you to create efficient
|
||||||
|
@ -759,6 +759,7 @@ pub struct Likely {
|
|||||||
pub:
|
pub:
|
||||||
expr Expr
|
expr Expr
|
||||||
pos token.Position
|
pos token.Position
|
||||||
|
is_likely bool // false for _unlikely_
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TypeOf {
|
pub struct TypeOf {
|
||||||
|
@ -1948,7 +1948,8 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
|||||||
ltype := c.expr(it.expr)
|
ltype := c.expr(it.expr)
|
||||||
if !c.check_types(ltype, table.bool_type) {
|
if !c.check_types(ltype, table.bool_type) {
|
||||||
ltype_sym := c.table.get_type_symbol(ltype)
|
ltype_sym := c.table.get_type_symbol(ltype)
|
||||||
c.error('`_likely_()` expects a boolean expression, instead it got `${ltype_sym.name}`', it.pos)
|
lname := if it.is_likely { '_likely_' } else { '_unlikely_' }
|
||||||
|
c.error('`${lname}()` expects a boolean expression, instead it got `${ltype_sym.name}`', it.pos)
|
||||||
}
|
}
|
||||||
return table.bool_type
|
return table.bool_type
|
||||||
}
|
}
|
||||||
|
@ -735,7 +735,12 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
|||||||
f.write(')')
|
f.write(')')
|
||||||
}
|
}
|
||||||
ast.Likely {
|
ast.Likely {
|
||||||
f.write('_likely_(')
|
if it.is_likely {
|
||||||
|
f.write('_likely_')
|
||||||
|
} else {
|
||||||
|
f.write('_unlikely_')
|
||||||
|
}
|
||||||
|
f.write('(')
|
||||||
f.expr(it.expr)
|
f.expr(it.expr)
|
||||||
f.write(')')
|
f.write(')')
|
||||||
}
|
}
|
||||||
|
@ -1587,7 +1587,12 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||||||
g.typeof_expr(it)
|
g.typeof_expr(it)
|
||||||
}
|
}
|
||||||
ast.Likely {
|
ast.Likely {
|
||||||
g.write('_likely_(')
|
if it.is_likely {
|
||||||
|
g.write('_likely_')
|
||||||
|
} else {
|
||||||
|
g.write('_unlikely_')
|
||||||
|
}
|
||||||
|
g.write('(')
|
||||||
g.expr(it.expr)
|
g.expr(it.expr)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,10 @@ void _vcleanup();
|
|||||||
|
|
||||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) || defined(__TINYC__)
|
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) || defined(__TINYC__)
|
||||||
#define _likely_(x) __builtin_expect(x, 1)
|
#define _likely_(x) __builtin_expect(x, 1)
|
||||||
|
#define _unlikely_(x) __builtin_expect((x), 0)
|
||||||
#else
|
#else
|
||||||
#define _likely_(x) (x)
|
#define _likely_(x) (x)
|
||||||
|
#define _unlikely_(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TARGET_ORDER_IS_LITTLE)
|
#if defined(TARGET_ORDER_IS_LITTLE)
|
||||||
|
@ -103,7 +103,8 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||||||
expr: expr
|
expr: expr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_likely {
|
.key_likely, .key_unlikely {
|
||||||
|
is_likely := p.tok.kind == .key_likely
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.lpar)
|
p.check(.lpar)
|
||||||
lpos := p.tok.position()
|
lpos := p.tok.position()
|
||||||
@ -112,6 +113,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||||||
node = ast.Likely{
|
node = ast.Likely{
|
||||||
expr: expr
|
expr: expr
|
||||||
pos: lpos
|
pos: lpos
|
||||||
|
is_likely: is_likely
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.lcbr {
|
.lcbr {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// _likely_(expr) should be compilable, and it should return the expr
|
// _likely_(expr) should be compilable, and it should return the expr
|
||||||
|
|
||||||
fn test_likely_type() {
|
fn test_likely_type() {
|
||||||
assert typeof(_likely_(false)) == 'bool'
|
assert typeof(_likely_(false)) == 'bool'
|
||||||
|
assert _likely_(false) == false
|
||||||
|
assert _likely_(true) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_likely() {
|
fn test_likely() {
|
||||||
@ -22,3 +23,10 @@ fn test_likely_returns_the_value_of_its_bool_argument(){
|
|||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _unlikely_ is the same as _likely_ from the V point of view:
|
||||||
|
fn test_unlikely_type() {
|
||||||
|
assert typeof(_unlikely_(false)) == 'bool'
|
||||||
|
assert _unlikely_(false) == false
|
||||||
|
assert _unlikely_(true) == true
|
||||||
|
}
|
||||||
|
@ -113,6 +113,7 @@ pub enum Kind {
|
|||||||
key_select
|
key_select
|
||||||
key_sizeof
|
key_sizeof
|
||||||
key_likely
|
key_likely
|
||||||
|
key_unlikely
|
||||||
key_offsetof
|
key_offsetof
|
||||||
key_struct
|
key_struct
|
||||||
key_switch
|
key_switch
|
||||||
@ -220,6 +221,7 @@ fn build_token_str() []string {
|
|||||||
s[Kind.key_module] = 'module'
|
s[Kind.key_module] = 'module'
|
||||||
s[Kind.key_sizeof] = 'sizeof'
|
s[Kind.key_sizeof] = 'sizeof'
|
||||||
s[Kind.key_likely] = '_likely_'
|
s[Kind.key_likely] = '_likely_'
|
||||||
|
s[Kind.key_unlikely] = '_unlikely_'
|
||||||
s[Kind.key_go] = 'go'
|
s[Kind.key_go] = 'go'
|
||||||
s[Kind.key_goto] = 'goto'
|
s[Kind.key_goto] = 'goto'
|
||||||
s[Kind.key_const] = 'const'
|
s[Kind.key_const] = 'const'
|
||||||
|
Loading…
Reference in New Issue
Block a user