@asmlift/core 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +25 -24
  2. package/package.json +1 -1
  3. package/src/aggregate.ts +149 -0
  4. package/src/backend/c.ts +2 -0
  5. package/src/backend/cfamily.ts +197 -61
  6. package/src/backend/cpp.ts +3 -1
  7. package/src/backend/lines.ts +10 -0
  8. package/src/backend/pascal.ts +47 -16
  9. package/src/cdecl/parse.ts +21 -0
  10. package/src/contracts.ts +246 -36
  11. package/src/declare.ts +69 -20
  12. package/src/frontend/arm-body.ts +155 -0
  13. package/src/frontend/asmdata.ts +9 -2
  14. package/src/frontend/call-plan.ts +1117 -61
  15. package/src/frontend/callee-body.ts +370 -0
  16. package/src/frontend/dead-reads.ts +628 -0
  17. package/src/frontend/device-pins.ts +33 -4
  18. package/src/frontend/emit.ts +4 -3
  19. package/src/frontend/fpu.ts +224 -17
  20. package/src/frontend/frame-objects.ts +1689 -206
  21. package/src/frontend/frontend.ts +84 -3
  22. package/src/frontend/high-half.ts +53 -4
  23. package/src/frontend/jump-table.ts +545 -0
  24. package/src/frontend/local-object.ts +158 -32
  25. package/src/frontend/mips.ts +2296 -217
  26. package/src/frontend/own-struct-return.ts +500 -0
  27. package/src/frontend/ppc.ts +2748 -245
  28. package/src/frontend/register-struct-call.ts +399 -0
  29. package/src/frontend/reloc-symbol.ts +22 -7
  30. package/src/frontend/ssa.ts +1721 -43
  31. package/src/frontend/stackargs.ts +199 -72
  32. package/src/frontend/thumb-entry.ts +340 -0
  33. package/src/frontend/thumb.ts +2400 -325
  34. package/src/ir/alias.ts +65 -2
  35. package/src/ir/bits.ts +1699 -4
  36. package/src/ir/core.ts +254 -9
  37. package/src/ir/discipline.ts +86 -21
  38. package/src/ir/entry.ts +157 -0
  39. package/src/{structure → ir}/loops.ts +6 -2
  40. package/src/ir/opcodes.ts +137 -9
  41. package/src/ir/parse.ts +1 -0
  42. package/src/ir/simplify.ts +61 -10
  43. package/src/ir/types.ts +86 -2
  44. package/src/ir/verify.ts +96 -11
  45. package/src/l3/argbase.ts +2 -0
  46. package/src/l3/ast.ts +582 -18
  47. package/src/l3/basecse.ts +68 -15
  48. package/src/l3/caseendgoto.ts +223 -0
  49. package/src/l3/coalesce.ts +42 -14
  50. package/src/l3/constinit.ts +410 -0
  51. package/src/l3/dce.ts +53 -9
  52. package/src/l3/initfirst.ts +42 -11
  53. package/src/l3/intcell.ts +2 -1
  54. package/src/l3/narrowdecl.ts +77 -36
  55. package/src/l3/pollguard.ts +8 -2
  56. package/src/l3/ptrcell.ts +33 -34
  57. package/src/l3/ptrfield.ts +123 -8
  58. package/src/l3/regspell.ts +11 -4
  59. package/src/l3/reindex.ts +295 -99
  60. package/src/l3/scopebase.ts +2 -0
  61. package/src/l3/storage.ts +98 -1
  62. package/src/l3/symbol-refs.ts +84 -6
  63. package/src/l3/tailmerge.ts +6 -2
  64. package/src/l3/typing.ts +108 -15
  65. package/src/l3/unreduce.ts +6 -5
  66. package/src/l3/volatileptr.ts +17 -54
  67. package/src/mangle.ts +30 -0
  68. package/src/pattern/engine.ts +361 -73
  69. package/src/pipeline.ts +1039 -38
  70. package/src/proto-context.ts +1039 -45
  71. package/src/proto.ts +555 -40
  72. package/src/raise/aggmembers.ts +290 -0
  73. package/src/raise/arrays.ts +5 -1
  74. package/src/raise/const.ts +25 -0
  75. package/src/raise/declared-volatile.ts +207 -31
  76. package/src/raise/divpow2.ts +192 -0
  77. package/src/raise/floathelpers.ts +254 -33
  78. package/src/raise/gvn.ts +3 -3
  79. package/src/raise/latch.ts +162 -6
  80. package/src/raise/memberarrays.ts +10 -4
  81. package/src/raise/offsetnames.ts +422 -36
  82. package/src/raise/pairparams.ts +33 -0
  83. package/src/raise/paramwidth.ts +196 -6
  84. package/src/raise/pre-recovery.ts +107 -21
  85. package/src/raise/pre-structure.ts +73 -0
  86. package/src/raise/recover.ts +12 -5
  87. package/src/raise/reroll.ts +674 -0
  88. package/src/raise/shortcircuit.ts +217 -34
  89. package/src/raise/softdiv.ts +1 -1
  90. package/src/raise/storesign.ts +153 -0
  91. package/src/raise/struct-arrays.ts +30 -11
  92. package/src/raise/structs.ts +396 -33
  93. package/src/raise/truncload.ts +4 -3
  94. package/src/raise/unpre.ts +594 -0
  95. package/src/raise/unthread.ts +400 -0
  96. package/src/rank-declare.ts +118 -12
  97. package/src/rank-variations.ts +186 -35
  98. package/src/rank.ts +536 -68
  99. package/src/runtime-helpers.ts +140 -22
  100. package/src/structure/analysis.ts +217 -8
  101. package/src/structure/arith-ops.ts +23 -0
  102. package/src/structure/cross-jumped-tail.ts +216 -0
  103. package/src/structure/globalaccess.ts +157 -10
  104. package/src/structure/hazards.ts +16 -64
  105. package/src/structure/local-statics.ts +145 -9
  106. package/src/structure/namecoalesce.ts +1 -1
  107. package/src/structure/pointer-spelling.ts +1106 -0
  108. package/src/structure/redundant-test.ts +1 -1
  109. package/src/structure/structure.ts +6192 -1213
  110. package/src/structure/switch-recover.ts +583 -120
  111. package/src/structure/unfolded-branch-constant.ts +90 -0
  112. package/src/symbols.ts +58 -15
  113. package/src/target.ts +1028 -54
  114. package/src/trace.ts +49 -17
  115. package/src/variation-definitions.ts +333 -20
  116. package/src/variation-gates.ts +4 -0
  117. package/src/variation-tokens.ts +68 -3
package/src/ir/alias.ts CHANGED
@@ -12,8 +12,23 @@
12
12
  // • two DIFFERENT named globals are different objects, so a store through one can never change
13
13
  // what a read of the other sees. That is a C guarantee about distinct declared objects, not a
14
14
  // heuristic about what the compiler happened to do.
15
- // • name comparison suffices because the pool promotion picks ONE canonical name per address,
16
- // so a single cell cannot appear under two names within one function (frontend/thumb.ts).
15
+ // • name comparison suffices where a cell has ONE spelling per function and a name ONE cell, and
16
+ // that is enforced for every access whose address a symbol map places, through defs and
17
+ // joins alike and with constant arithmetic folded as the C compiler will fold it (an index or
18
+ // displacement built in several steps): raise/offsetnames.ts `cellSpelledTwice` declines a
19
+ // lift that reaches one byte under two names, or under a name and a numeric address, with a
20
+ // store among them, and one that reads a name the map places at several addresses at two of
21
+ // them. The pool promotion's one canonical name per address does not give it alone: an
22
+ // interior attribution into an object sized over its neighbour, a walk the offset-name gates
23
+ // leave as `base + K` past the base's end, a raw constant beside an unsized name, and any of
24
+ // them carried across a join each reach a named cell a second way. On a compiler that reloads
25
+ // across two spellings (`reloadsAcrossSpellings`, IDO 7.1) a pair in one block outside any
26
+ // loop with the store first is exempt, whoever chose them, because the C reads the cell back
27
+ // after the store as the asm did; IDO sinks a read placed before the store past it, so that
28
+ // order declines there too. agbcc and gcc 2.7.2 forward.
29
+ // KNOWN GAP: with no map (or a name the map does not hold) nothing is placed, so a relocation
30
+ // and a literal for one cell lift unchecked — faithful on IDO, wrong C on agbcc and gcc 2.7.2
31
+ // where the asm reloaded.
17
32
  // • anything that does not resolve to a name — a materialized base, a variable index, a pointer
18
33
  // parameter — is unknown, and unknown BARS. A call or an `opaque` bars unconditionally: it may
19
34
  // write anything.
@@ -139,6 +154,54 @@ export function constAddressOf(defs: Map<Value, Op>, addr: Value, off: number):
139
154
  return null;
140
155
  }
141
156
 
157
+ /**
158
+ * A constant DISPLACEMENT off a root, read through defs alone: `add(p, K)`, `add(K, p)`, `sub(p, K)`,
159
+ * or a chain of them, as the root `p`, the summed `K`, and the chain's values from `addr` toward
160
+ * `p`. Null when `addr` is not such a link. `sub` is not commutative, so `K - p` stops the walk; a
161
+ * link whose two operands are both constants stops it too (that is a literal address,
162
+ * {@link constAddressOf}'s question). The one reading of address arithmetic that raise/structs.ts
163
+ * (which accesses share a base), raise/offsetnames.ts (which named global an address stands on) and
164
+ * raise/shortcircuit.ts (which root a shared address the fold hoists stands on) all ask, so they
165
+ * cannot disagree about where a chain ends.
166
+ *
167
+ * `constOf` is what counts as a constant operand: a `const` def by default, which is where those
168
+ * two readers want a chain to end. raise/offsetnames.ts `cellSpelledTwice`, which must place an
169
+ * address the way the C compiler will once it folds the emitted arithmetic, passes a reader that
170
+ * folds constant subtrees too.
171
+ */
172
+ export function constDisplacementOf(
173
+ defs: ReadonlyMap<Value, Op>,
174
+ addr: Value,
175
+ constOf: (x: Value) => number | null = (x) => {
176
+ const d = defs.get(x);
177
+ return d?.opcode === 'const' && typeof d.attrs.value === 'number' ? d.attrs.value : null;
178
+ },
179
+ ): { root: Value; k: number; chain: Value[] } | null {
180
+ let k = 0;
181
+ const chain: Value[] = [];
182
+ let cur = addr;
183
+ for (;;) {
184
+ const d = defs.get(cur);
185
+ if (!d || (d.opcode !== 'add' && d.opcode !== 'sub') || d.operands.length !== 2) {
186
+ break;
187
+ }
188
+ const [x, y] = d.operands;
189
+ const ky = constOf(y);
190
+ const kx = d.opcode === 'add' ? constOf(x) : null;
191
+ if (ky !== null && kx === null) {
192
+ k += d.opcode === 'add' ? ky : -ky;
193
+ cur = x;
194
+ } else if (kx !== null && ky === null) {
195
+ k += kx;
196
+ cur = y;
197
+ } else {
198
+ break;
199
+ }
200
+ chain.push(d.results[0]);
201
+ }
202
+ return chain.length === 0 ? null : { root: cur, k, chain };
203
+ }
204
+
142
205
  /**
143
206
  * Are these two accesses through ONE base provably different byte cells — same base value, both at
144
207
  * a constant offset and width, ranges non-overlapping? The everyday struct interleave