Skip to content

Commit d98ba8e

Browse files
authored
[mypyc] Introduce low level integer type (#8955)
closes mypyc/mypyc#735 This PR introduces a c_int_rprimitive RType which represents a low level, plain integer (corresponds to C's Py_ssize_t). It also allows LoadInt to select its rtype to generate tagged/plain integer code accordingly.
1 parent 3adb2e9 commit d98ba8e

File tree

4 files changed

+19
-6
lines changed

4 files changed

+19
-6
lines changed

mypyc/codegen/emitfunc.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
BasicBlock, Value, MethodCall, PrimitiveOp, EmitterInterface, Unreachable, NAMESPACE_STATIC,
1414
NAMESPACE_TYPE, NAMESPACE_MODULE, RaiseStandardError, CallC
1515
)
16-
from mypyc.ir.rtypes import RType, RTuple
16+
from mypyc.ir.rtypes import RType, RTuple, is_c_int_rprimitive
1717
from mypyc.ir.func_ir import FuncIR, FuncDecl, FUNC_STATICMETHOD, FUNC_CLASSMETHOD
1818
from mypyc.ir.class_ir import ClassIR
1919

@@ -179,7 +179,10 @@ def visit_assign(self, op: Assign) -> None:
179179

180180
def visit_load_int(self, op: LoadInt) -> None:
181181
dest = self.reg(op)
182-
self.emit_line('%s = %d;' % (dest, op.value * 2))
182+
if is_c_int_rprimitive(op.type):
183+
self.emit_line('%s = %d;' % (dest, op.value))
184+
else:
185+
self.emit_line('%s = %d;' % (dest, op.value * 2))
183186

184187
def visit_load_error_value(self, op: LoadErrorValue) -> None:
185188
if isinstance(op.type, RTuple):

mypyc/ir/ops.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -783,10 +783,10 @@ class LoadInt(RegisterOp):
783783

784784
error_kind = ERR_NEVER
785785

786-
def __init__(self, value: int, line: int = -1) -> None:
786+
def __init__(self, value: int, line: int = -1, rtype: RType = short_int_rprimitive) -> None:
787787
super().__init__(line)
788788
self.value = value
789-
self.type = short_int_rprimitive
789+
self.type = rtype
790790

791791
def sources(self) -> List[Value]:
792792
return []

mypyc/ir/rtypes.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def __init__(self,
174174
self.is_unboxed = is_unboxed
175175
self._ctype = ctype
176176
self.is_refcounted = is_refcounted
177-
if ctype == 'CPyTagged':
177+
if ctype in ('CPyTagged', 'Py_ssize_t'):
178178
self.c_undefined = 'CPY_INT_TAG'
179179
elif ctype == 'PyObject *':
180180
# Boxed types use the null pointer as the error value.
@@ -234,6 +234,10 @@ def __repr__(self) -> str:
234234
short_int_rprimitive = RPrimitive('short_int', is_unboxed=True, is_refcounted=False,
235235
ctype='CPyTagged') # type: Final
236236

237+
# low level integer (corresponds to C's 'int').
238+
c_int_rprimitive = RPrimitive('c_int', is_unboxed=True, is_refcounted=False,
239+
ctype='Py_ssize_t') # type: Final
240+
237241
# Floats are represent as 'float' PyObject * values. (In the future
238242
# we'll likely switch to a more efficient, unboxed representation.)
239243
float_rprimitive = RPrimitive('builtins.float', is_unboxed=False,
@@ -275,6 +279,10 @@ def is_short_int_rprimitive(rtype: RType) -> bool:
275279
return rtype is short_int_rprimitive
276280

277281

282+
def is_c_int_rprimitive(rtype: RType) -> bool:
283+
return rtype is c_int_rprimitive
284+
285+
278286
def is_float_rprimitive(rtype: RType) -> bool:
279287
return isinstance(rtype, RPrimitive) and rtype.name == 'builtins.float'
280288

mypyc/test/test_emitfunc.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
)
1313
from mypyc.ir.rtypes import (
1414
RTuple, RInstance, int_rprimitive, bool_rprimitive, list_rprimitive,
15-
dict_rprimitive, object_rprimitive
15+
dict_rprimitive, object_rprimitive, c_int_rprimitive
1616
)
1717
from mypyc.ir.func_ir import FuncIR, FuncDecl, RuntimeArg, FuncSignature
1818
from mypyc.ir.class_ir import ClassIR
@@ -70,6 +70,8 @@ def test_return(self) -> None:
7070
def test_load_int(self) -> None:
7171
self.assert_emit(LoadInt(5),
7272
"cpy_r_r0 = 10;")
73+
self.assert_emit(LoadInt(5, -1, c_int_rprimitive),
74+
"cpy_r_r00 = 5;")
7375

7476
def test_tuple_get(self) -> None:
7577
self.assert_emit(TupleGet(self.t, 1, 0), 'cpy_r_r0 = cpy_r_t.f1;')

0 commit comments

Comments
 (0)