Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mypyc/codegen/emitfunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,8 @@ def visit_load_mem(self, op: LoadMem) -> None:
# TODO: we shouldn't dereference to type that are pointer type so far
type = self.ctype(op.type)
self.emit_line(f"{dest} = *({type} *){src};")
if not op.is_borrowed:
self.emit_inc_ref(dest, op.type)

def visit_set_mem(self, op: SetMem) -> None:
dest = self.reg(op.dest)
Expand Down
7 changes: 3 additions & 4 deletions mypyc/ir/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -1558,14 +1558,13 @@ class LoadMem(RegisterOp):

error_kind = ERR_NEVER

def __init__(self, type: RType, src: Value, line: int = -1) -> None:
def __init__(self, type: RType, src: Value, line: int = -1, *, borrow: bool = False) -> None:
super().__init__(line)
self.type = type
# TODO: for now we enforce that the src memory address should be Py_ssize_t
# later we should also support same width unsigned int
# TODO: Support other native integer types
assert is_pointer_rprimitive(src.type)
self.src = src
self.is_borrowed = True
self.is_borrowed = borrow and type.is_refcounted

def sources(self) -> list[Value]:
return [self.src]
Expand Down
4 changes: 3 additions & 1 deletion mypyc/ir/pprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ def visit_float_comparison_op(self, op: FloatComparisonOp) -> str:
return self.format("%r = %r %s %r", op, op.lhs, op.op_str[op.op], op.rhs)

def visit_load_mem(self, op: LoadMem) -> str:
return self.format("%r = load_mem %r :: %t*", op, op.src, op.type)
return self.format(
"%r = %sload_mem %r :: %t*", op, self.borrow_prefix(op), op.src, op.type
)

def visit_set_mem(self, op: SetMem) -> str:
return self.format("set_mem %r, %r :: %t*", op.dest, op.src, op.dest_type)
Expand Down
2 changes: 1 addition & 1 deletion mypyc/irbuild/for_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ def gen_condition(self) -> None:

def except_match() -> Value:
addr = builder.add(LoadAddress(pointer_rprimitive, stop_async_iteration_op.src, line))
return builder.add(LoadMem(stop_async_iteration_op.type, addr))
return builder.add(LoadMem(stop_async_iteration_op.type, addr, borrow=True))

def try_body() -> None:
awaitable = builder.call_c(anext_op, [builder.read(self.iter_target)], line)
Expand Down
7 changes: 5 additions & 2 deletions mypyc/irbuild/ll_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ def goto_and_activate(self, block: BasicBlock) -> None:
def keep_alive(self, values: list[Value], *, steal: bool = False) -> None:
self.add(KeepAlive(values, steal=steal))

def load_mem(self, ptr: Value, value_type: RType, *, borrow: bool = False) -> Value:
return self.add(LoadMem(value_type, ptr, borrow=borrow))

def push_error_handler(self, handler: BasicBlock | None) -> None:
self.error_handlers.append(handler)

Expand Down Expand Up @@ -660,7 +663,7 @@ def other() -> Value:

def get_type_of_obj(self, obj: Value, line: int) -> Value:
ob_type_address = self.add(GetElementPtr(obj, PyObject, "ob_type", line))
ob_type = self.add(LoadMem(object_rprimitive, ob_type_address))
ob_type = self.load_mem(ob_type_address, object_rprimitive, borrow=True)
self.add(KeepAlive([obj]))
return ob_type

Expand Down Expand Up @@ -2261,7 +2264,7 @@ def builtin_len(self, val: Value, line: int, use_pyssize_t: bool = False) -> Val
size_value = self.primitive_op(var_object_size, [val], line)
elif is_set_rprimitive(typ) or is_frozenset_rprimitive(typ):
elem_address = self.add(GetElementPtr(val, PySetObject, "used"))
size_value = self.add(LoadMem(c_pyssize_t_rprimitive, elem_address))
size_value = self.load_mem(elem_address, c_pyssize_t_rprimitive)
self.add(KeepAlive([val]))
elif is_dict_rprimitive(typ):
size_value = self.call_c(dict_ssize_t_size_op, [val], line)
Expand Down
8 changes: 3 additions & 5 deletions mypyc/lower/list_ops.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from mypyc.common import PLATFORM_SIZE
from mypyc.ir.ops import GetElementPtr, IncRef, Integer, IntOp, LoadMem, SetMem, Value
from mypyc.ir.ops import GetElementPtr, Integer, IntOp, SetMem, Value
from mypyc.ir.rtypes import (
PyListObject,
c_pyssize_t_rprimitive,
Expand Down Expand Up @@ -42,7 +42,7 @@ def buf_init_item(builder: LowLevelIRBuilder, args: list[Value], line: int) -> V
@lower_primitive_op("list_items")
def list_items(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
ob_item_ptr = builder.add(GetElementPtr(args[0], PyListObject, "ob_item", line))
return builder.add(LoadMem(pointer_rprimitive, ob_item_ptr, line))
return builder.load_mem(ob_item_ptr, pointer_rprimitive)


def list_item_ptr(builder: LowLevelIRBuilder, obj: Value, index: Value, line: int) -> Value:
Expand All @@ -68,6 +68,4 @@ def list_item_ptr(builder: LowLevelIRBuilder, obj: Value, index: Value, line: in
def list_get_item_unsafe(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
index = builder.coerce(args[1], c_pyssize_t_rprimitive, line)
item_ptr = list_item_ptr(builder, args[0], index, line)
value = builder.add(LoadMem(object_rprimitive, item_ptr, line))
builder.add(IncRef(value))
return value
return builder.load_mem(item_ptr, object_rprimitive)
14 changes: 7 additions & 7 deletions mypyc/test-data/irbuild-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def f(x):
L0:
r0 = __main__.B :: type
r1 = get_element_ptr x ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive x
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand Down Expand Up @@ -402,7 +402,7 @@ def f(x):
L0:
r0 = __main__.A :: type
r1 = get_element_ptr x ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive x
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand All @@ -412,7 +412,7 @@ L1:
L2:
r5 = __main__.B :: type
r6 = get_element_ptr x ob_type :: PyObject
r7 = load_mem r6 :: builtins.object*
r7 = borrow load_mem r6 :: builtins.object*
keep_alive x
r8 = r7 == r5
r4 = r8
Expand Down Expand Up @@ -449,7 +449,7 @@ def f(x):
L0:
r0 = __main__.A :: type
r1 = get_element_ptr x ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive x
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand All @@ -459,7 +459,7 @@ L1:
L2:
r5 = __main__.R :: type
r6 = get_element_ptr x ob_type :: PyObject
r7 = load_mem r6 :: builtins.object*
r7 = borrow load_mem r6 :: builtins.object*
keep_alive x
r8 = r7 == r5
r4 = r8
Expand Down Expand Up @@ -500,7 +500,7 @@ def f(x):
L0:
r0 = __main__.A :: type
r1 = get_element_ptr x ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive x
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand All @@ -510,7 +510,7 @@ L1:
L2:
r5 = __main__.C :: type
r6 = get_element_ptr x ob_type :: PyObject
r7 = load_mem r6 :: builtins.object*
r7 = borrow load_mem r6 :: builtins.object*
keep_alive x
r8 = r7 == r5
r4 = r8
Expand Down
2 changes: 1 addition & 1 deletion mypyc/test-data/irbuild-isinstance.test
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ L0:
x = r0
r1 = __main__.C :: type
r2 = get_element_ptr x ob_type :: PyObject
r3 = load_mem r2 :: builtins.object*
r3 = borrow load_mem r2 :: builtins.object*
keep_alive x
r4 = r3 == r1
if r4 goto L1 else goto L2 :: bool
Expand Down
10 changes: 5 additions & 5 deletions mypyc/test-data/irbuild-optional.test
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def get(o):
L0:
r0 = __main__.A :: type
r1 = get_element_ptr o ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive o
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand Down Expand Up @@ -396,7 +396,7 @@ def g(o):
L0:
r0 = __main__.A :: type
r1 = get_element_ptr o ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive o
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand All @@ -409,7 +409,7 @@ L1:
L2:
r8 = __main__.B :: type
r9 = get_element_ptr o ob_type :: PyObject
r10 = load_mem r9 :: builtins.object*
r10 = borrow load_mem r9 :: builtins.object*
keep_alive o
r11 = r10 == r8
if r11 goto L3 else goto L4 :: bool
Expand Down Expand Up @@ -462,7 +462,7 @@ def f(o):
L0:
r0 = __main__.A :: type
r1 = get_element_ptr o ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive o
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand Down Expand Up @@ -494,7 +494,7 @@ def g(o):
L0:
r0 = __main__.A :: type
r1 = get_element_ptr o ob_type :: PyObject
r2 = load_mem r1 :: builtins.object*
r2 = borrow load_mem r1 :: builtins.object*
keep_alive o
r3 = r2 == r0
if r3 goto L1 else goto L2 :: bool
Expand Down
8 changes: 4 additions & 4 deletions mypyc/test-data/irbuild-singledispatch.test
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def f_obj.__call__(__mypyc_self__, arg):
r27 :: bool
L0:
r0 = get_element_ptr arg ob_type :: PyObject
r1 = load_mem r0 :: builtins.object*
r1 = borrow load_mem r0 :: builtins.object*
keep_alive arg
r2 = __mypyc_self__.dispatch_cache
r3 = CPyDict_GetWithNone(r2, r1)
Expand All @@ -82,7 +82,7 @@ L2:
L3:
r16 = load_address PyLong_Type
r17 = get_element_ptr r6 ob_type :: PyObject
r18 = load_mem r17 :: builtins.object*
r18 = borrow load_mem r17 :: builtins.object*
keep_alive r6
r19 = r18 == r16
if r19 goto L4 else goto L7 :: bool
Expand Down Expand Up @@ -195,7 +195,7 @@ def f_obj.__call__(__mypyc_self__, x):
r24 :: None
L0:
r0 = get_element_ptr x ob_type :: PyObject
r1 = load_mem r0 :: builtins.object*
r1 = borrow load_mem r0 :: builtins.object*
keep_alive x
r2 = __mypyc_self__.dispatch_cache
r3 = CPyDict_GetWithNone(r2, r1)
Expand All @@ -220,7 +220,7 @@ L2:
L3:
r16 = load_address PyLong_Type
r17 = get_element_ptr r6 ob_type :: PyObject
r18 = load_mem r17 :: builtins.object*
r18 = borrow load_mem r17 :: builtins.object*
keep_alive r6
r19 = r18 == r16
if r19 goto L4 else goto L5 :: bool
Expand Down
1 change: 0 additions & 1 deletion mypyc/test-data/lowering-int.test
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,6 @@ L2:
r6 = r0 * 8
r7 = r5 + r6
r8 = load_mem r7 :: builtins.object*
inc_ref r8
r9 = unbox(int, r8)
dec_ref r8
if is_error(r9) goto L6 (error at f:4) else goto L3
Expand Down
2 changes: 1 addition & 1 deletion mypyc/test-data/refcount.test
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ L0:
r0 = borrow x.a
r1 = __main__.D :: type
r2 = get_element_ptr r0 ob_type :: PyObject
r3 = load_mem r2 :: builtins.object*
r3 = borrow load_mem r2 :: builtins.object*
r4 = r3 == r1
if r4 goto L1 else goto L2 :: bool
L1:
Expand Down