/whalesong/js-assembler/collect-jump-targets.rkt

https://github.com/dyoo/whalesong · Racket · 348 lines · 303 code · 41 blank · 4 comment · 17 complexity · a162268698066c70b0919714f9d1a4bc MD5 · raw file

  1. #lang typed/racket/base
  2. (require "../compiler/expression-structs.rkt"
  3. "../compiler/il-structs.rkt"
  4. "../compiler/lexical-structs.rkt"
  5. "../helpers.rkt"
  6. "../parameters.rkt"
  7. racket/list)
  8. (provide collect-general-jump-targets
  9. collect-entry-points)
  10. (: collect-general-jump-targets ((Listof Statement) -> (Listof Symbol)))
  11. ;; collects all the labels that are potential targets for GOTOs or branches.
  12. (define (collect-general-jump-targets stmts)
  13. (: collect-statement (Statement -> (Listof Symbol)))
  14. (define (collect-statement stmt)
  15. (cond
  16. [(symbol? stmt)
  17. empty]
  18. [(LinkedLabel? stmt)
  19. (list (LinkedLabel-label stmt)
  20. (LinkedLabel-linked-to stmt))]
  21. [(DebugPrint? stmt)
  22. empty]
  23. [(MarkEntryPoint? stmt)
  24. (list (MarkEntryPoint-label stmt))]
  25. [(AssignImmediate? stmt)
  26. (let: ([v : OpArg (AssignImmediate-value stmt)])
  27. (collect-input v))]
  28. [(AssignPrimOp? stmt)
  29. (collect-primitive-operator (AssignPrimOp-op stmt))]
  30. [(Perform? stmt)
  31. (collect-primitive-command (Perform-op stmt))]
  32. [(TestAndJump? stmt)
  33. (list (TestAndJump-label stmt))]
  34. [(Goto? stmt)
  35. (collect-input (Goto-target stmt))]
  36. [(PushEnvironment? stmt)
  37. empty]
  38. [(PopEnvironment? stmt)
  39. empty]
  40. [(PushImmediateOntoEnvironment? stmt)
  41. (collect-input (PushImmediateOntoEnvironment-value stmt))]
  42. [(PushControlFrame/Generic? stmt)
  43. empty]
  44. [(PushControlFrame/Call? stmt)
  45. (label->labels (PushControlFrame/Call-label stmt))]
  46. [(PushControlFrame/Prompt? stmt)
  47. (label->labels (PushControlFrame/Prompt-label stmt))]
  48. [(PopControlFrame? stmt)
  49. empty]
  50. [(Comment? stmt)
  51. empty]))
  52. (: collect-input (OpArg -> (Listof Symbol)))
  53. (define (collect-input an-input)
  54. (cond
  55. [(Reg? an-input)
  56. empty]
  57. [(Const? an-input)
  58. empty]
  59. [(Label? an-input)
  60. (list (Label-name an-input))]
  61. [(EnvLexicalReference? an-input)
  62. empty]
  63. [(EnvPrefixReference? an-input)
  64. empty]
  65. [(EnvWholePrefixReference? an-input)
  66. empty]
  67. [(SubtractArg? an-input)
  68. (append (collect-input (SubtractArg-lhs an-input))
  69. (collect-input (SubtractArg-rhs an-input)))]
  70. [(ControlStackLabel? an-input)
  71. empty]
  72. [(ControlStackLabel/MultipleValueReturn? an-input)
  73. empty]
  74. [(ControlFrameTemporary? an-input)
  75. empty]
  76. [(CompiledProcedureEntry? an-input)
  77. (collect-input (CompiledProcedureEntry-proc an-input))]
  78. [(CompiledProcedureClosureReference? an-input)
  79. (collect-input (CompiledProcedureClosureReference-proc an-input))]
  80. [(PrimitiveKernelValue? an-input)
  81. empty]
  82. [(ModuleEntry? an-input)
  83. empty]
  84. [(ModulePredicate? an-input)
  85. empty]
  86. [(VariableReference? an-input)
  87. empty]))
  88. (: collect-location ((U Reg Label) -> (Listof Symbol)))
  89. (define (collect-location a-location)
  90. (cond
  91. [(Reg? a-location)
  92. empty]
  93. [(Label? a-location)
  94. (list (Label-name a-location))]))
  95. (: collect-primitive-operator (PrimitiveOperator -> (Listof Symbol)))
  96. (define (collect-primitive-operator op)
  97. (cond
  98. [(GetCompiledProcedureEntry? op)
  99. empty]
  100. [(MakeCompiledProcedure? op)
  101. (list (MakeCompiledProcedure-label op))]
  102. [(MakeCompiledProcedureShell? op)
  103. (list (MakeCompiledProcedureShell-label op))]
  104. [(ApplyPrimitiveProcedure? op)
  105. empty]
  106. [(CaptureEnvironment? op)
  107. empty]
  108. [(CaptureControl? op)
  109. empty]
  110. [(MakeBoxedEnvironmentValue? op)
  111. empty]
  112. [(CallKernelPrimitiveProcedure? op)
  113. empty]
  114. [(ModuleVariable? op)
  115. empty]
  116. [(PrimitivesReference? op)
  117. empty]
  118. [(GlobalsReference? op)
  119. empty]))
  120. (: collect-primitive-command (PrimitiveCommand -> (Listof Symbol)))
  121. (define (collect-primitive-command op)
  122. (cond
  123. [(InstallModuleEntry!? op)
  124. (list (InstallModuleEntry!-entry-point op))]
  125. [else
  126. empty]))
  127. (: start-time Real)
  128. (define start-time (current-inexact-milliseconds))
  129. (: result (Listof Symbol))
  130. (define result
  131. (unique/eq?
  132. (let: loop : (Listof Symbol) ([stmts : (Listof Statement) stmts])
  133. (cond [(empty? stmts)
  134. empty]
  135. [else
  136. (let: ([stmt : Statement (first stmts)])
  137. (append (collect-statement stmt)
  138. (loop (rest stmts))))]))))
  139. (: end-time Real)
  140. (define end-time (current-inexact-milliseconds))
  141. (fprintf (current-timing-port) " collect-general-jump-targets: ~a milliseconds\n" (- end-time start-time))
  142. result)
  143. (: collect-entry-points ((Listof Statement) -> (Listof Symbol)))
  144. ;; collects all the labels that are general entry points. The entry points are
  145. ;; from the starting basic block, from functions headers, and finally return points.
  146. (define (collect-entry-points stmts)
  147. (: collect-statement (Statement -> (Listof Symbol)))
  148. (define (collect-statement stmt)
  149. (cond
  150. [(symbol? stmt)
  151. empty]
  152. [(LinkedLabel? stmt)
  153. (list (LinkedLabel-label stmt)
  154. (LinkedLabel-linked-to stmt))]
  155. [(MarkEntryPoint? stmt)
  156. (list (MarkEntryPoint-label stmt))]
  157. [(DebugPrint? stmt)
  158. empty]
  159. [(AssignImmediate? stmt)
  160. (let: ([v : OpArg (AssignImmediate-value stmt)])
  161. (collect-input v))]
  162. [(AssignPrimOp? stmt)
  163. (collect-primitive-operator (AssignPrimOp-op stmt))]
  164. [(Perform? stmt)
  165. (collect-primitive-command (Perform-op stmt))]
  166. [(TestAndJump? stmt)
  167. empty]
  168. [(Goto? stmt)
  169. empty]
  170. [(PushEnvironment? stmt)
  171. empty]
  172. [(PopEnvironment? stmt)
  173. empty]
  174. [(PushImmediateOntoEnvironment? stmt)
  175. (collect-input (PushImmediateOntoEnvironment-value stmt))]
  176. [(PushControlFrame/Generic? stmt)
  177. empty]
  178. [(PushControlFrame/Call? stmt)
  179. (label->labels (PushControlFrame/Call-label stmt))]
  180. [(PushControlFrame/Prompt? stmt)
  181. (label->labels (PushControlFrame/Prompt-label stmt))]
  182. [(PopControlFrame? stmt)
  183. empty]
  184. [(Comment? stmt)
  185. empty]))
  186. (: collect-input (OpArg -> (Listof Symbol)))
  187. (define (collect-input an-input)
  188. (cond
  189. [(Reg? an-input)
  190. empty]
  191. [(Const? an-input)
  192. empty]
  193. [(Label? an-input)
  194. (list (Label-name an-input))]
  195. [(EnvLexicalReference? an-input)
  196. empty]
  197. [(EnvPrefixReference? an-input)
  198. empty]
  199. [(EnvWholePrefixReference? an-input)
  200. empty]
  201. [(SubtractArg? an-input)
  202. (append (collect-input (SubtractArg-lhs an-input))
  203. (collect-input (SubtractArg-rhs an-input)))]
  204. [(ControlStackLabel? an-input)
  205. empty]
  206. [(ControlStackLabel/MultipleValueReturn? an-input)
  207. empty]
  208. [(ControlFrameTemporary? an-input)
  209. empty]
  210. [(CompiledProcedureEntry? an-input)
  211. (collect-input (CompiledProcedureEntry-proc an-input))]
  212. [(CompiledProcedureClosureReference? an-input)
  213. (collect-input (CompiledProcedureClosureReference-proc an-input))]
  214. [(PrimitiveKernelValue? an-input)
  215. empty]
  216. [(ModuleEntry? an-input)
  217. empty]
  218. [(ModulePredicate? an-input)
  219. empty]
  220. [(VariableReference? an-input)
  221. empty]))
  222. (: collect-location ((U Reg Label) -> (Listof Symbol)))
  223. (define (collect-location a-location)
  224. (cond
  225. [(Reg? a-location)
  226. empty]
  227. [(Label? a-location)
  228. (list (Label-name a-location))]))
  229. (: collect-primitive-operator (PrimitiveOperator -> (Listof Symbol)))
  230. (define (collect-primitive-operator op)
  231. (cond
  232. [(GetCompiledProcedureEntry? op)
  233. empty]
  234. [(MakeCompiledProcedure? op)
  235. (list (MakeCompiledProcedure-label op))]
  236. [(MakeCompiledProcedureShell? op)
  237. (list (MakeCompiledProcedureShell-label op))]
  238. [(ApplyPrimitiveProcedure? op)
  239. empty]
  240. [(CaptureEnvironment? op)
  241. empty]
  242. [(CaptureControl? op)
  243. empty]
  244. [(MakeBoxedEnvironmentValue? op)
  245. empty]
  246. [(CallKernelPrimitiveProcedure? op)
  247. empty]
  248. [(ModuleVariable? op)
  249. empty]
  250. [(PrimitivesReference? op)
  251. empty]
  252. [(GlobalsReference? op)
  253. empty]))
  254. (: collect-primitive-command (PrimitiveCommand -> (Listof Symbol)))
  255. (define (collect-primitive-command op)
  256. (cond
  257. [(InstallModuleEntry!? op)
  258. (list (InstallModuleEntry!-entry-point op))]
  259. [else
  260. empty]
  261. ;; currently written this way because I'm hitting some bad type-checking behavior.
  262. #;([(CheckToplevelBound!? op)
  263. empty]
  264. [(CheckClosureAndArity!? op)
  265. empty]
  266. [(CheckPrimitiveArity!? op)
  267. empty]
  268. [(ExtendEnvironment/Prefix!? op)
  269. empty]
  270. [(InstallClosureValues!? op)
  271. empty]
  272. [(RestoreEnvironment!? op)
  273. empty]
  274. [(RestoreControl!? op)
  275. empty]
  276. [(SetFrameCallee!? op)
  277. empty]
  278. [(SpliceListIntoStack!? op)
  279. empty]
  280. [(UnspliceRestFromStack!? op)
  281. empty]
  282. [(FixClosureShellMap!? op)
  283. empty]
  284. [(InstallContinuationMarkEntry!? op)
  285. empty]
  286. [(RaiseContextExpectedValuesError!? op)
  287. empty]
  288. [(RaiseArityMismatchError!? op)
  289. empty]
  290. [(RaiseOperatorApplicationError!? op)
  291. empty])))
  292. (unique/eq?
  293. (let: loop : (Listof Symbol) ([stmts : (Listof Statement) stmts])
  294. (cond [(empty? stmts)
  295. empty]
  296. [else
  297. (let: ([stmt : Statement (first stmts)])
  298. (append (collect-statement stmt)
  299. (loop (rest stmts))))]))))
  300. (: label->labels ((U Symbol LinkedLabel) -> (Listof Symbol)))
  301. (define (label->labels label)
  302. (cond
  303. [(symbol? label)
  304. (list label)]
  305. [(LinkedLabel? label)
  306. (list (LinkedLabel-label label)
  307. (LinkedLabel-linked-to label))]))