intrinsics.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import jit
  2. import tree_ir
  3. BINARY_INTRINSICS = {
  4. 'value_eq' : '==',
  5. 'value_neq' : '!=',
  6. 'bool_and' : 'and',
  7. 'bool_or' : 'or',
  8. 'integer_addition' : '+',
  9. 'integer_subtraction' : '-',
  10. 'integer_multiplication' : '*',
  11. 'integer_division' : '/',
  12. 'integer_gt' : '>',
  13. 'integer_gte' : '>=',
  14. 'integer_lt' : '<',
  15. 'integer_lte' : '<=',
  16. 'float_addition' : '+',
  17. 'float_subtraction' : '-',
  18. 'float_multiplication' : '*',
  19. 'float_division' : '/',
  20. 'float_gt' : '>',
  21. 'float_gte' : '>=',
  22. 'float_lt' : '<',
  23. 'float_lte' : '<='
  24. }
  25. UNARY_INTRINSICS = {
  26. 'bool_not' : 'not',
  27. 'integer_neg' : '-',
  28. 'float_neg' : '-'
  29. }
  30. # Don't compain about the variable names, pylint. It's important that we
  31. # get them right.
  32. # pylint: disable=I0011,C0103
  33. def __set_add(a, b):
  34. tmp = tree_ir.StoreLocalInstruction(None, a)
  35. return tree_ir.create_block(
  36. tmp,
  37. tree_ir.CreateEdgeInstruction(tmp.create_load(), b),
  38. tmp.create_load())
  39. def __dict_add(a, b, c):
  40. a_tmp = tree_ir.StoreLocalInstruction(None, a)
  41. b_tmp = tree_ir.StoreLocalInstruction(None, b)
  42. return tree_ir.create_block(
  43. a_tmp,
  44. b_tmp,
  45. tree_ir.CreateEdgeInstruction(
  46. tree_ir.CreateEdgeInstruction(a_tmp.create_load(), c),
  47. b_tmp.create_load()),
  48. a_tmp.create_load())
  49. MISC_INTRINSICS = {
  50. # Reference equality
  51. 'element_eq' :
  52. lambda a, b:
  53. tree_ir.CreateNodeWithValueInstruction(
  54. tree_ir.BinaryInstruction(a, '==', b)),
  55. 'element_neq' :
  56. lambda a, b:
  57. tree_ir.CreateNodeWithValueInstruction(
  58. tree_ir.BinaryInstruction(a, '!=', b)),
  59. # Strings
  60. 'string_get' :
  61. lambda a, b:
  62. tree_ir.CreateNodeWithValueInstruction(
  63. tree_ir.LoadIndexInstruction(
  64. tree_ir.ReadValueInstruction(a),
  65. tree_ir.ReadValueInstruction(b))),
  66. 'string_len' :
  67. lambda a:
  68. tree_ir.CreateNodeWithValueInstruction(
  69. tree_ir.CallInstruction(
  70. tree_ir.LoadGlobalInstruction('len'),
  71. [tree_ir.ReadValueInstruction(a)])),
  72. 'string_join' :
  73. lambda a, b:
  74. tree_ir.CreateNodeWithValueInstruction(
  75. tree_ir.BinaryInstruction(
  76. tree_ir.CallInstruction(
  77. tree_ir.LoadGlobalInstruction('str'),
  78. [tree_ir.ReadValueInstruction(a)]),
  79. '+',
  80. tree_ir.CallInstruction(
  81. tree_ir.LoadGlobalInstruction('str'),
  82. [tree_ir.ReadValueInstruction(b)]))),
  83. 'string_startswith' :
  84. lambda a, b:
  85. tree_ir.CreateNodeWithValueInstruction(
  86. tree_ir.CallInstruction(
  87. tree_ir.LoadMemberInstruction(
  88. tree_ir.ReadValueInstruction(a),
  89. 'startswith'),
  90. [tree_ir.ReadValueInstruction(b)])),
  91. # State creation
  92. 'create_node' : tree_ir.CreateNodeInstruction,
  93. 'create_edge' :
  94. # Lambda is totally necessary here, pylint.
  95. # You totally dropped the ball on this one.
  96. # pylint: disable=I0011,W0108
  97. lambda a, b:
  98. tree_ir.CreateEdgeInstruction(a, b),
  99. 'create_value' :
  100. lambda a:
  101. tree_ir.CreateNodeWithValueInstruction(
  102. tree_ir.ReadValueInstruction(a)),
  103. # State reads
  104. 'read_edge_src' :
  105. lambda a:
  106. tree_ir.LoadIndexInstruction(
  107. tree_ir.ReadEdgeInstruction(a),
  108. tree_ir.LiteralInstruction(0)),
  109. 'read_edge_dst' :
  110. lambda a:
  111. tree_ir.LoadIndexInstruction(
  112. tree_ir.ReadEdgeInstruction(a),
  113. tree_ir.LiteralInstruction(1)),
  114. 'is_edge' :
  115. lambda a:
  116. tree_ir.CreateNodeWithValueInstruction(
  117. tree_ir.BinaryInstruction(
  118. tree_ir.LoadIndexInstruction(
  119. tree_ir.ReadEdgeInstruction(a),
  120. tree_ir.LiteralInstruction(0)),
  121. 'is not',
  122. tree_ir.LiteralInstruction(None))),
  123. # read_root
  124. 'read_root' :
  125. lambda:
  126. tree_ir.LoadIndexInstruction(
  127. tree_ir.LoadLocalInstruction(jit.KWARGS_PARAMETER_NAME),
  128. tree_ir.LiteralInstruction('root')),
  129. # Dictionary operations
  130. 'dict_read' :
  131. lambda a, b:
  132. tree_ir.ReadDictionaryValueInstruction(
  133. a, tree_ir.ReadValueInstruction(b)),
  134. 'dict_read_edge' :
  135. lambda a, b:
  136. tree_ir.ReadDictionaryEdgeInstruction(
  137. a, tree_ir.ReadValueInstruction(b)),
  138. 'dict_add' : __dict_add,
  139. # Set operations
  140. 'set_add' : __set_add
  141. }
  142. def register_intrinsics(target_jit):
  143. """Registers all intrinsics in the module with the given JIT."""
  144. for (key, value) in BINARY_INTRINSICS.items():
  145. target_jit.register_binary_intrinsic(key, value)
  146. for (key, value) in UNARY_INTRINSICS.items():
  147. target_jit.register_unary_intrinsic(key, value)
  148. for (key, value) in MISC_INTRINSICS.items():
  149. target_jit.register_intrinsic(key, value)