Skip to content

Commit 2695e95

Browse files
authored
[mypyc] Cleanup old style primitive code (#9699)
We have moved all the existing ops into the new IR, so this PR removes the old PrimitiveOp and related code. Relates to mypyc/mypyc#709, closes mypyc/mypyc#753
1 parent 613c0ce commit 2695e95

File tree

7 files changed

+9
-275
lines changed

7 files changed

+9
-275
lines changed

mypyc/analysis/dataflow.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Value, ControlOp,
99
BasicBlock, OpVisitor, Assign, LoadInt, LoadErrorValue, RegisterOp, Goto, Branch, Return, Call,
1010
Environment, Box, Unbox, Cast, Op, Unreachable, TupleGet, TupleSet, GetAttr, SetAttr,
11-
LoadStatic, InitStatic, PrimitiveOp, MethodCall, RaiseStandardError, CallC, LoadGlobal,
11+
LoadStatic, InitStatic, MethodCall, RaiseStandardError, CallC, LoadGlobal,
1212
Truncate, BinaryIntOp, LoadMem, GetElementPtr, LoadAddress, ComparisonOp, SetMem
1313
)
1414

@@ -161,9 +161,6 @@ def visit_call(self, op: Call) -> GenAndKill:
161161
def visit_method_call(self, op: MethodCall) -> GenAndKill:
162162
return self.visit_register_op(op)
163163

164-
def visit_primitive_op(self, op: PrimitiveOp) -> GenAndKill:
165-
return self.visit_register_op(op)
166-
167164
def visit_load_int(self, op: LoadInt) -> GenAndKill:
168165
return self.visit_register_op(op)
169166

mypyc/codegen/emitfunc.py

+1-12
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from mypyc.ir.ops import (
1111
OpVisitor, Goto, Branch, Return, Assign, LoadInt, LoadErrorValue, GetAttr, SetAttr,
1212
LoadStatic, InitStatic, TupleGet, TupleSet, Call, IncRef, DecRef, Box, Cast, Unbox,
13-
BasicBlock, Value, MethodCall, PrimitiveOp, EmitterInterface, Unreachable, NAMESPACE_STATIC,
13+
BasicBlock, Value, MethodCall, EmitterInterface, Unreachable, NAMESPACE_STATIC,
1414
NAMESPACE_TYPE, NAMESPACE_MODULE, RaiseStandardError, CallC, LoadGlobal, Truncate,
1515
BinaryIntOp, LoadMem, GetElementPtr, LoadAddress, ComparisonOp, SetMem, Register
1616
)
@@ -152,17 +152,6 @@ def visit_return(self, op: Return) -> None:
152152
regstr = self.reg(op.reg)
153153
self.emit_line('return %s;' % regstr)
154154

155-
def visit_primitive_op(self, op: PrimitiveOp) -> None:
156-
args = [self.reg(arg) for arg in op.args]
157-
if not op.is_void:
158-
dest = self.reg(op)
159-
else:
160-
# This will generate a C compile error if used. The reason for this
161-
# is that we don't want to insert "assert dest is not None" checks
162-
# everywhere.
163-
dest = '<undefined dest>'
164-
op.desc.emit(self, args, dest)
165-
166155
def visit_tuple_set(self, op: TupleSet) -> None:
167156
dest = self.reg(op)
168157
tuple_type = op.tuple_type

mypyc/ir/ops.py

+1-80
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from abc import abstractmethod
1414
from typing import (
15-
List, Sequence, Dict, Generic, TypeVar, Optional, Any, NamedTuple, Tuple, Callable,
15+
List, Sequence, Dict, Generic, TypeVar, Optional, Any, NamedTuple, Tuple,
1616
Union, Iterable, Set
1717
)
1818
from mypy.ordered_dict import OrderedDict
@@ -693,84 +693,9 @@ def emit_declaration(self, line: str) -> None:
693693
raise NotImplementedError
694694

695695

696-
EmitCallback = Callable[[EmitterInterface, List[str], str], None]
697-
698696
# True steals all arguments, False steals none, a list steals those in matching positions
699697
StealsDescription = Union[bool, List[bool]]
700698

701-
# Description of a primitive operation
702-
OpDescription = NamedTuple(
703-
'OpDescription', [('name', str),
704-
('arg_types', List[RType]),
705-
('result_type', Optional[RType]),
706-
('is_var_arg', bool),
707-
('error_kind', int),
708-
('format_str', str),
709-
('emit', EmitCallback),
710-
('steals', StealsDescription),
711-
('is_borrowed', bool),
712-
('priority', int)]) # To resolve ambiguities, highest priority wins
713-
714-
715-
class PrimitiveOp(RegisterOp):
716-
"""reg = op(reg, ...)
717-
718-
These are register-based primitive operations that work on specific
719-
operand types.
720-
721-
The details of the operation are defined by the 'desc'
722-
attribute. The modules under mypyc.primitives define the supported
723-
operations. mypyc.irbuild uses the descriptions to look for suitable
724-
primitive ops.
725-
"""
726-
727-
def __init__(self,
728-
args: List[Value],
729-
desc: OpDescription,
730-
line: int) -> None:
731-
if not desc.is_var_arg:
732-
assert len(args) == len(desc.arg_types)
733-
self.error_kind = desc.error_kind
734-
super().__init__(line)
735-
self.args = args
736-
self.desc = desc
737-
if desc.result_type is None:
738-
assert desc.error_kind == ERR_FALSE # TODO: No-value ops not supported yet
739-
self.type = bool_rprimitive
740-
else:
741-
self.type = desc.result_type
742-
743-
self.is_borrowed = desc.is_borrowed
744-
745-
def sources(self) -> List[Value]:
746-
return list(self.args)
747-
748-
def stolen(self) -> List[Value]:
749-
if isinstance(self.desc.steals, list):
750-
assert len(self.desc.steals) == len(self.args)
751-
return [arg for arg, steal in zip(self.args, self.desc.steals) if steal]
752-
else:
753-
return [] if not self.desc.steals else self.sources()
754-
755-
def __repr__(self) -> str:
756-
return '<PrimitiveOp name=%r args=%s>' % (self.desc.name,
757-
self.args)
758-
759-
def to_str(self, env: Environment) -> str:
760-
params = {} # type: Dict[str, Any]
761-
if not self.is_void:
762-
params['dest'] = env.format('%r', self)
763-
args = [env.format('%r', arg) for arg in self.args]
764-
params['args'] = args
765-
params['comma_args'] = ', '.join(args)
766-
params['colon_args'] = ', '.join(
767-
'{}: {}'.format(k, v) for k, v in zip(args[::2], args[1::2])
768-
)
769-
return self.desc.format_str.format(**params).strip()
770-
771-
def accept(self, visitor: 'OpVisitor[T]') -> T:
772-
return visitor.visit_primitive_op(self)
773-
774699

775700
class Assign(Op):
776701
"""Assign a value to a register (dest = int)."""
@@ -1555,10 +1480,6 @@ def visit_return(self, op: Return) -> T:
15551480
def visit_unreachable(self, op: Unreachable) -> T:
15561481
raise NotImplementedError
15571482

1558-
@abstractmethod
1559-
def visit_primitive_op(self, op: PrimitiveOp) -> T:
1560-
raise NotImplementedError
1561-
15621483
@abstractmethod
15631484
def visit_assign(self, op: Assign) -> T:
15641485
raise NotImplementedError

mypyc/irbuild/builder.py

+2-11
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
BasicBlock, AssignmentTarget, AssignmentTargetRegister, AssignmentTargetIndex,
3535
AssignmentTargetAttr, AssignmentTargetTuple, Environment, LoadInt, Value,
3636
Register, Op, Assign, Branch, Unreachable, TupleGet, GetAttr, SetAttr, LoadStatic,
37-
InitStatic, OpDescription, NAMESPACE_MODULE, RaiseStandardError,
37+
InitStatic, NAMESPACE_MODULE, RaiseStandardError,
3838
)
3939
from mypyc.ir.rtypes import (
4040
RType, RTuple, RInstance, int_rprimitive, dict_rprimitive,
@@ -43,7 +43,7 @@
4343
)
4444
from mypyc.ir.func_ir import FuncIR, INVALID_FUNC_DEF
4545
from mypyc.ir.class_ir import ClassIR, NonExtClassInfo
46-
from mypyc.primitives.registry import func_ops, CFunctionDescription, c_function_ops
46+
from mypyc.primitives.registry import CFunctionDescription, c_function_ops
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
@@ -188,9 +188,6 @@ def load_static_unicode(self, value: str) -> Value:
188188
def load_static_int(self, value: int) -> Value:
189189
return self.builder.load_static_int(value)
190190

191-
def primitive_op(self, desc: OpDescription, args: List[Value], line: int) -> Value:
192-
return self.builder.primitive_op(desc, args, line)
193-
194191
def unary_op(self, lreg: Value, expr_op: str, line: int) -> Value:
195192
return self.builder.unary_op(lreg, expr_op, line)
196193

@@ -763,12 +760,6 @@ def call_refexpr_with_args(
763760
expr.line, self.node_type(expr))
764761
if target:
765762
return target
766-
ops = func_ops.get(callee.fullname, [])
767-
target = self.builder.matching_primitive_op(
768-
ops, arg_values, expr.line, self.node_type(expr)
769-
)
770-
if target:
771-
return target
772763

773764
# Standard native call if signature and fullname are good and all arguments are positional
774765
# or named.

mypyc/irbuild/ll_builder.py

+2-54
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from mypyc.ir.ops import (
2020
BasicBlock, Environment, Op, LoadInt, Value, Register,
2121
Assign, Branch, Goto, Call, Box, Unbox, Cast, GetAttr,
22-
LoadStatic, MethodCall, PrimitiveOp, OpDescription, RegisterOp, CallC, Truncate,
22+
LoadStatic, MethodCall, RegisterOp, CallC, Truncate,
2323
RaiseStandardError, Unreachable, LoadErrorValue, LoadGlobal,
2424
NAMESPACE_TYPE, NAMESPACE_MODULE, NAMESPACE_STATIC, BinaryIntOp, GetElementPtr,
2525
LoadMem, ComparisonOp, LoadAddress, TupleGet, SetMem, ERR_NEVER, ERR_FALSE
@@ -39,7 +39,7 @@
3939
STATIC_PREFIX, PLATFORM_SIZE
4040
)
4141
from mypyc.primitives.registry import (
42-
func_ops, c_method_call_ops, CFunctionDescription, c_function_ops,
42+
c_method_call_ops, CFunctionDescription, c_function_ops,
4343
c_binary_ops, c_unary_ops, ERR_NEG_INT
4444
)
4545
from mypyc.primitives.list_ops import (
@@ -513,48 +513,6 @@ def load_native_type_object(self, fullname: str) -> Value:
513513
return self.add(LoadStatic(object_rprimitive, name, module, NAMESPACE_TYPE))
514514

515515
# Other primitive operations
516-
517-
def primitive_op(self, desc: OpDescription, args: List[Value], line: int) -> Value:
518-
assert desc.result_type is not None
519-
coerced = []
520-
for i, arg in enumerate(args):
521-
formal_type = self.op_arg_type(desc, i)
522-
arg = self.coerce(arg, formal_type, line)
523-
coerced.append(arg)
524-
target = self.add(PrimitiveOp(coerced, desc, line))
525-
return target
526-
527-
def matching_primitive_op(self,
528-
candidates: List[OpDescription],
529-
args: List[Value],
530-
line: int,
531-
result_type: Optional[RType] = None) -> Optional[Value]:
532-
# Find the highest-priority primitive op that matches.
533-
matching = None # type: Optional[OpDescription]
534-
for desc in candidates:
535-
if len(desc.arg_types) != len(args):
536-
continue
537-
if all(is_subtype(actual.type, formal)
538-
for actual, formal in zip(args, desc.arg_types)):
539-
if matching:
540-
assert matching.priority != desc.priority, 'Ambiguous:\n1) %s\n2) %s' % (
541-
matching, desc)
542-
if desc.priority > matching.priority:
543-
matching = desc
544-
else:
545-
matching = desc
546-
if matching:
547-
target = self.primitive_op(matching, args, line)
548-
if result_type and not is_runtime_subtype(target.type, result_type):
549-
if is_none_rprimitive(result_type):
550-
# Special case None return. The actual result may actually be a bool
551-
# and so we can't just coerce it.
552-
target = self.none()
553-
else:
554-
target = self.coerce(target, result_type, line)
555-
return target
556-
return None
557-
558516
def binary_op(self,
559517
lreg: Value,
560518
rreg: Value,
@@ -857,10 +815,6 @@ def builtin_call(self,
857815
line: int) -> Value:
858816
call_c_ops_candidates = c_function_ops.get(fn_op, [])
859817
target = self.matching_call_c(call_c_ops_candidates, args, line)
860-
if target:
861-
return target
862-
ops = func_ops.get(fn_op, [])
863-
target = self.matching_primitive_op(ops, args, line)
864818
assert target, 'Unsupported builtin function: %s' % fn_op
865819
return target
866820

@@ -1113,12 +1067,6 @@ def decompose_union_helper(self,
11131067
self.activate_block(exit_block)
11141068
return result
11151069

1116-
def op_arg_type(self, desc: OpDescription, n: int) -> RType:
1117-
if n >= len(desc.arg_types):
1118-
assert desc.is_var_arg
1119-
return desc.arg_types[-1]
1120-
return desc.arg_types[n]
1121-
11221070
def translate_special_method_call(self,
11231071
base_reg: Value,
11241072
name: str,

mypyc/primitives/list_ops.py

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
"""List primitive ops."""
22

3-
from typing import List
4-
5-
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER, ERR_FALSE, EmitterInterface
3+
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER, ERR_FALSE
64
from mypyc.ir.rtypes import (
75
int_rprimitive, short_int_rprimitive, list_rprimitive, object_rprimitive, c_int_rprimitive,
86
c_pyssize_t_rprimitive, bit_rprimitive
@@ -122,14 +120,6 @@
122120
c_function_name='CPySequence_RMultiply',
123121
error_kind=ERR_MAGIC)
124122

125-
126-
def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None:
127-
temp = emitter.temp_name()
128-
emitter.emit_declaration('Py_ssize_t %s;' % temp)
129-
emitter.emit_line('%s = PyList_GET_SIZE(%s);' % (temp, args[0]))
130-
emitter.emit_line('%s = CPyTagged_ShortFromSsize_t(%s);' % (dest, temp))
131-
132-
133123
# list[begin:end]
134124
list_slice_op = c_custom_op(
135125
arg_types=[list_rprimitive, int_rprimitive, int_rprimitive],

0 commit comments

Comments
 (0)