Skip to content

Commit 0dfac58

Browse files
authored
[mypyc] Build True, False and None op in irbuild (python#9294)
This PR builds three specialized op directly in irbuild, instead of using name_ref_ops.
1 parent b34f4c6 commit 0dfac58

23 files changed

+516
-874
lines changed

mypyc/irbuild/builder.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
from mypyc.primitives.list_ops import to_list, list_pop_last
4848
from mypyc.primitives.dict_ops import dict_get_item_op, dict_set_item_op
4949
from mypyc.primitives.generic_ops import py_setattr_op, iter_op, next_op
50-
from mypyc.primitives.misc_ops import true_op, false_op, import_op
50+
from mypyc.primitives.misc_ops import import_op
5151
from mypyc.crash import catch_errors
5252
from mypyc.options import CompilerOptions
5353
from mypyc.errors import Errors
@@ -200,6 +200,15 @@ def coerce(self, src: Value, target_type: RType, line: int, force: bool = False)
200200
def none_object(self) -> Value:
201201
return self.builder.none_object()
202202

203+
def none(self) -> Value:
204+
return self.builder.none()
205+
206+
def true(self) -> Value:
207+
return self.builder.true()
208+
209+
def false(self) -> Value:
210+
return self.builder.false()
211+
203212
def py_call(self,
204213
function: Value,
205214
arg_values: List[Value],
@@ -339,9 +348,9 @@ def load_final_literal_value(self, val: Union[int, str, bytes, float, bool],
339348
"""Load value of a final name or class-level attribute."""
340349
if isinstance(val, bool):
341350
if val:
342-
return self.primitive_op(true_op, [], line)
351+
return self.true()
343352
else:
344-
return self.primitive_op(false_op, [], line)
353+
return self.false()
345354
elif isinstance(val, int):
346355
# TODO: take care of negative integer initializers
347356
# (probably easier to fix this in mypy itself).

mypyc/irbuild/classdef.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from mypyc.primitives.generic_ops import py_setattr_op, py_hasattr_op
2020
from mypyc.primitives.misc_ops import (
2121
dataclass_sleight_of_hand, pytype_from_template_op, py_calc_meta_op, type_object_op,
22-
not_implemented_op, true_op
22+
not_implemented_op
2323
)
2424
from mypyc.primitives.dict_ops import dict_set_item_op, dict_new_op
2525
from mypyc.primitives.tuple_ops import new_tuple_op
@@ -350,7 +350,7 @@ def generate_attr_defaults(builder: IRBuilder, cdef: ClassDef) -> None:
350350
val = builder.coerce(builder.accept(stmt.rvalue), attr_type, stmt.line)
351351
builder.add(SetAttr(self_var, lvalue.name, val, -1))
352352

353-
builder.add(Return(builder.primitive_op(true_op, [], -1)))
353+
builder.add(Return(builder.true()))
354354

355355
blocks, env, ret_type, _ = builder.leave()
356356
ir = FuncIR(

mypyc/irbuild/expression.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value:
4242
if fullname in builtin_names:
4343
typ, src = builtin_names[fullname]
4444
return builder.add(LoadAddress(typ, src, expr.line))
45+
# special cases
46+
if fullname == 'builtins.None':
47+
return builder.none()
48+
if fullname == 'builtins.True':
49+
return builder.true()
50+
if fullname == 'builtins.False':
51+
return builder.false()
4552
if fullname in name_ref_ops:
4653
# Use special access op for this particular name.
4754
desc = name_ref_ops[fullname]

mypyc/irbuild/ll_builder.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
RType, RUnion, RInstance, optional_value_type, int_rprimitive, float_rprimitive,
2929
bool_rprimitive, list_rprimitive, str_rprimitive, is_none_rprimitive, object_rprimitive,
3030
c_pyssize_t_rprimitive, is_short_int_rprimitive, is_tagged, PyVarObject, short_int_rprimitive,
31-
is_list_rprimitive, is_tuple_rprimitive, is_dict_rprimitive, is_set_rprimitive, PySetObject
31+
is_list_rprimitive, is_tuple_rprimitive, is_dict_rprimitive, is_set_rprimitive, PySetObject,
32+
none_rprimitive
3233
)
3334
from mypyc.ir.func_ir import FuncDecl, FuncSignature
3435
from mypyc.ir.class_ir import ClassIR, all_concrete_classes
@@ -52,7 +53,7 @@
5253
py_getattr_op, py_call_op, py_call_with_kwargs_op, py_method_call_op, generic_len_op
5354
)
5455
from mypyc.primitives.misc_ops import (
55-
none_op, none_object_op, false_op, fast_isinstance_op, bool_op, type_is_op
56+
none_object_op, fast_isinstance_op, bool_op, type_is_op
5657
)
5758
from mypyc.primitives.int_ops import int_logical_op_mapping
5859
from mypyc.rt_subtype import is_runtime_subtype
@@ -195,7 +196,7 @@ def py_get_attr(self, obj: Value, attr: str, line: int) -> Value:
195196
def isinstance_helper(self, obj: Value, class_irs: List[ClassIR], line: int) -> Value:
196197
"""Fast path for isinstance() that checks against a list of native classes."""
197198
if not class_irs:
198-
return self.primitive_op(false_op, [], line)
199+
return self.false()
199200
ret = self.isinstance_native(obj, class_irs[0], line)
200201
for class_ir in class_irs[1:]:
201202
def other() -> Value:
@@ -217,7 +218,7 @@ def isinstance_native(self, obj: Value, class_ir: ClassIR, line: int) -> Value:
217218
line)
218219
if not concrete:
219220
# There can't be any concrete instance that matches this.
220-
return self.primitive_op(false_op, [], line)
221+
return self.false()
221222
type_obj = self.get_native_type(concrete[0])
222223
ret = self.primitive_op(type_is_op, [obj, type_obj], line)
223224
for c in concrete[1:]:
@@ -424,7 +425,15 @@ def call_union_item(value: Value) -> Value:
424425

425426
def none(self) -> Value:
426427
"""Load unboxed None value (type: none_rprimitive)."""
427-
return self.add(PrimitiveOp([], none_op, line=-1))
428+
return self.add(LoadInt(1, -1, none_rprimitive))
429+
430+
def true(self) -> Value:
431+
"""Load unboxed True value (type: bool_rprimitive)."""
432+
return self.add(LoadInt(1, -1, bool_rprimitive))
433+
434+
def false(self) -> Value:
435+
"""Load unboxed False value (type: bool_rprimitive)."""
436+
return self.add(LoadInt(0, -1, bool_rprimitive))
428437

429438
def none_object(self) -> Value:
430439
"""Load Python None value (type: object_rprimitive)."""

mypyc/irbuild/specialize.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@
1818
from mypy.types import AnyType, TypeOfAny
1919

2020
from mypyc.ir.ops import (
21-
Value, BasicBlock, LoadInt, RaiseStandardError, Unreachable, OpDescription,
21+
Value, BasicBlock, LoadInt, RaiseStandardError, Unreachable
2222
)
2323
from mypyc.ir.rtypes import (
2424
RType, RTuple, str_rprimitive, list_rprimitive, dict_rprimitive, set_rprimitive,
2525
bool_rprimitive, is_dict_rprimitive
2626
)
2727
from mypyc.primitives.dict_ops import dict_keys_op, dict_values_op, dict_items_op
28-
from mypyc.primitives.misc_ops import true_op, false_op
2928
from mypyc.irbuild.builder import IRBuilder
3029
from mypyc.irbuild.for_helpers import translate_list_comprehension, comprehension_helper
3130

@@ -147,7 +146,7 @@ def translate_any_call(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> O
147146
if (len(expr.args) == 1
148147
and expr.arg_kinds == [ARG_POS]
149148
and isinstance(expr.args[0], GeneratorExpr)):
150-
return any_all_helper(builder, expr.args[0], false_op, lambda x: x, true_op)
149+
return any_all_helper(builder, expr.args[0], builder.false, lambda x: x, builder.true)
151150
return None
152151

153152

@@ -158,28 +157,28 @@ def translate_all_call(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> O
158157
and isinstance(expr.args[0], GeneratorExpr)):
159158
return any_all_helper(
160159
builder, expr.args[0],
161-
true_op,
160+
builder.true,
162161
lambda x: builder.unary_op(x, 'not', expr.line),
163-
false_op
162+
builder.false
164163
)
165164
return None
166165

167166

168167
def any_all_helper(builder: IRBuilder,
169168
gen: GeneratorExpr,
170-
initial_value_op: OpDescription,
169+
initial_value: Callable[[], Value],
171170
modify: Callable[[Value], Value],
172-
new_value_op: OpDescription) -> Value:
171+
new_value: Callable[[], Value]) -> Value:
173172
retval = builder.alloc_temp(bool_rprimitive)
174-
builder.assign(retval, builder.primitive_op(initial_value_op, [], -1), -1)
173+
builder.assign(retval, initial_value(), -1)
175174
loop_params = list(zip(gen.indices, gen.sequences, gen.condlists))
176175
true_block, false_block, exit_block = BasicBlock(), BasicBlock(), BasicBlock()
177176

178177
def gen_inner_stmts() -> None:
179178
comparison = modify(builder.accept(gen.left_expr))
180179
builder.add_bool_branch(comparison, true_block, false_block)
181180
builder.activate_block(true_block)
182-
builder.assign(retval, builder.primitive_op(new_value_op, [], -1), -1)
181+
builder.assign(retval, new_value(), -1)
183182
builder.goto(exit_block)
184183
builder.activate_block(false_block)
185184

mypyc/irbuild/statement.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
)
2323
from mypyc.ir.rtypes import exc_rtuple
2424
from mypyc.primitives.generic_ops import py_delattr_op
25-
from mypyc.primitives.misc_ops import true_op, false_op, type_op, get_module_dict_op
25+
from mypyc.primitives.misc_ops import type_op, get_module_dict_op
2626
from mypyc.primitives.dict_ops import dict_get_item_op
2727
from mypyc.primitives.exc_ops import (
2828
raise_exception_op, reraise_exception_op, error_catch_op, exc_matches_op, restore_exc_info_op,
@@ -540,15 +540,15 @@ def transform_with(builder: IRBuilder,
540540
builder.py_get_attr(typ, '__enter__', line), [mgr_v], line
541541
)
542542
mgr = builder.maybe_spill(mgr_v)
543-
exc = builder.maybe_spill_assignable(builder.primitive_op(true_op, [], -1))
543+
exc = builder.maybe_spill_assignable(builder.true())
544544

545545
def try_body() -> None:
546546
if target:
547547
builder.assign(builder.get_assignment_target(target), value, line)
548548
body()
549549

550550
def except_body() -> None:
551-
builder.assign(exc, builder.primitive_op(false_op, [], -1), line)
551+
builder.assign(exc, builder.false(), line)
552552
out_block, reraise_block = BasicBlock(), BasicBlock()
553553
builder.add_bool_branch(
554554
builder.py_call(builder.read(exit_),

mypyc/primitives/misc_ops.py

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
from mypyc.ir.ops import ERR_NEVER, ERR_MAGIC, ERR_FALSE, ERR_NEG_INT
44
from mypyc.ir.rtypes import (
5-
RTuple, none_rprimitive, bool_rprimitive, object_rprimitive, str_rprimitive,
5+
RTuple, bool_rprimitive, object_rprimitive, str_rprimitive,
66
int_rprimitive, dict_rprimitive, c_int_rprimitive
77
)
88
from mypyc.primitives.registry import (
9-
name_ref_op, simple_emit, unary_op, func_op, custom_op, call_emit, name_emit,
9+
simple_emit, unary_op, func_op, custom_op, call_emit, name_emit,
1010
call_negative_magic_emit, c_function_op, c_custom_op, load_address_op
1111
)
1212

@@ -19,23 +19,6 @@
1919
emit=name_emit('Py_None'),
2020
is_borrowed=True)
2121

22-
# Get an unboxed None value
23-
none_op = name_ref_op('builtins.None',
24-
result_type=none_rprimitive,
25-
error_kind=ERR_NEVER,
26-
emit=simple_emit('{dest} = 1; /* None */'))
27-
28-
# Get an unboxed True value
29-
true_op = name_ref_op('builtins.True',
30-
result_type=bool_rprimitive,
31-
error_kind=ERR_NEVER,
32-
emit=simple_emit('{dest} = 1;'))
33-
34-
# Get an unboxed False value
35-
false_op = name_ref_op('builtins.False',
36-
result_type=bool_rprimitive,
37-
error_kind=ERR_NEVER,
38-
emit=simple_emit('{dest} = 0;'))
3922

4023
# Get the boxed object '...'
4124
ellipsis_op = custom_op(name='...',

mypyc/test-data/analysis.test

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ def f(a):
1616
r2, r3, r4 :: bool
1717
y :: int
1818
z :: int
19-
r5 :: None
2019
L0:
2120
x = 2
2221
r1 = x & 1
@@ -37,8 +36,7 @@ L4:
3736
L5:
3837
z = 2
3938
L6:
40-
r5 = None
41-
return r5
39+
return 1
4240
(0, 0) {a} {a}
4341
(0, 1) {a} {a, x}
4442
(0, 2) {a, x} {a, x}
@@ -175,7 +173,6 @@ def f(a):
175173
r2, r3, r4 :: bool
176174
y :: int
177175
x :: int
178-
r5 :: None
179176
L0:
180177
r1 = a & 1
181178
r2 = r1 == 0
@@ -196,8 +193,7 @@ L4:
196193
L5:
197194
x = 4
198195
L6:
199-
r5 = None
200-
return r5
196+
return 1
201197
(0, 0) {a} {a}
202198
(0, 1) {a} {a}
203199
(0, 2) {a} {a}
@@ -246,7 +242,6 @@ def f(n):
246242
r3 :: native_int
247243
r4, r5, r6, r7 :: bool
248244
r8, m :: int
249-
r9 :: None
250245
L0:
251246
L1:
252247
r1 = n & 1
@@ -270,8 +265,7 @@ L5:
270265
m = n
271266
goto L1
272267
L6:
273-
r9 = None
274-
return r9
268+
return 1
275269
(0, 0) {n} {n}
276270
(1, 0) {n} {n}
277271
(1, 1) {n} {n}
@@ -323,7 +317,6 @@ def f(n):
323317
r10 :: bool
324318
r11 :: native_int
325319
r12, r13, r14, r15 :: bool
326-
r16 :: None
327320
L0:
328321
x = 2
329322
y = 2
@@ -368,8 +361,7 @@ L10:
368361
L11:
369362
goto L1
370363
L12:
371-
r16 = None
372-
return r16
364+
return 1
373365
(0, 0) {n} {i0, n}
374366
(0, 1) {i0, n} {n, x}
375367
(0, 2) {n, x} {i1, n, x}
@@ -418,8 +410,8 @@ L12:
418410
(10, 2) {x, y} {n, x, y}
419411
(10, 3) {n, x, y} {n, x, y}
420412
(11, 0) {n, x, y} {n, x, y}
421-
(12, 0) {} {r16}
422-
(12, 1) {r16} {}
413+
(12, 0) {} {i13}
414+
(12, 1) {i13} {}
423415

424416
[case testCall_Liveness]
425417
def f(x: int) -> int:
@@ -472,7 +464,6 @@ def f(a):
472464
r11 :: native_int
473465
r12, r13, r14, r15 :: bool
474466
y, x :: int
475-
r16 :: None
476467
L0:
477468
L1:
478469
r1 = a & 1
@@ -514,8 +505,7 @@ L11:
514505
x = a
515506
goto L1
516507
L12:
517-
r16 = None
518-
return r16
508+
return 1
519509
(0, 0) {a} {a}
520510
(1, 0) {a, r0, r8, x, y} {a, r0, r8, x, y}
521511
(1, 1) {a, r0, r8, x, y} {a, r0, r8, x, y}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy