@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.
- package/README.md +25 -24
- package/package.json +1 -1
- package/src/aggregate.ts +149 -0
- package/src/backend/c.ts +2 -0
- package/src/backend/cfamily.ts +197 -61
- package/src/backend/cpp.ts +3 -1
- package/src/backend/lines.ts +10 -0
- package/src/backend/pascal.ts +47 -16
- package/src/cdecl/parse.ts +21 -0
- package/src/contracts.ts +246 -36
- package/src/declare.ts +69 -20
- package/src/frontend/arm-body.ts +155 -0
- package/src/frontend/asmdata.ts +9 -2
- package/src/frontend/call-plan.ts +1117 -61
- package/src/frontend/callee-body.ts +370 -0
- package/src/frontend/dead-reads.ts +628 -0
- package/src/frontend/device-pins.ts +33 -4
- package/src/frontend/emit.ts +4 -3
- package/src/frontend/fpu.ts +224 -17
- package/src/frontend/frame-objects.ts +1689 -206
- package/src/frontend/frontend.ts +84 -3
- package/src/frontend/high-half.ts +53 -4
- package/src/frontend/jump-table.ts +545 -0
- package/src/frontend/local-object.ts +158 -32
- package/src/frontend/mips.ts +2296 -217
- package/src/frontend/own-struct-return.ts +500 -0
- package/src/frontend/ppc.ts +2748 -245
- package/src/frontend/register-struct-call.ts +399 -0
- package/src/frontend/reloc-symbol.ts +22 -7
- package/src/frontend/ssa.ts +1721 -43
- package/src/frontend/stackargs.ts +199 -72
- package/src/frontend/thumb-entry.ts +340 -0
- package/src/frontend/thumb.ts +2400 -325
- package/src/ir/alias.ts +65 -2
- package/src/ir/bits.ts +1699 -4
- package/src/ir/core.ts +254 -9
- package/src/ir/discipline.ts +86 -21
- package/src/ir/entry.ts +157 -0
- package/src/{structure → ir}/loops.ts +6 -2
- package/src/ir/opcodes.ts +137 -9
- package/src/ir/parse.ts +1 -0
- package/src/ir/simplify.ts +61 -10
- package/src/ir/types.ts +86 -2
- package/src/ir/verify.ts +96 -11
- package/src/l3/argbase.ts +2 -0
- package/src/l3/ast.ts +582 -18
- package/src/l3/basecse.ts +68 -15
- package/src/l3/caseendgoto.ts +223 -0
- package/src/l3/coalesce.ts +42 -14
- package/src/l3/constinit.ts +410 -0
- package/src/l3/dce.ts +53 -9
- package/src/l3/initfirst.ts +42 -11
- package/src/l3/intcell.ts +2 -1
- package/src/l3/narrowdecl.ts +77 -36
- package/src/l3/pollguard.ts +8 -2
- package/src/l3/ptrcell.ts +33 -34
- package/src/l3/ptrfield.ts +123 -8
- package/src/l3/regspell.ts +11 -4
- package/src/l3/reindex.ts +295 -99
- package/src/l3/scopebase.ts +2 -0
- package/src/l3/storage.ts +98 -1
- package/src/l3/symbol-refs.ts +84 -6
- package/src/l3/tailmerge.ts +6 -2
- package/src/l3/typing.ts +108 -15
- package/src/l3/unreduce.ts +6 -5
- package/src/l3/volatileptr.ts +17 -54
- package/src/mangle.ts +30 -0
- package/src/pattern/engine.ts +361 -73
- package/src/pipeline.ts +1039 -38
- package/src/proto-context.ts +1039 -45
- package/src/proto.ts +555 -40
- package/src/raise/aggmembers.ts +290 -0
- package/src/raise/arrays.ts +5 -1
- package/src/raise/const.ts +25 -0
- package/src/raise/declared-volatile.ts +207 -31
- package/src/raise/divpow2.ts +192 -0
- package/src/raise/floathelpers.ts +254 -33
- package/src/raise/gvn.ts +3 -3
- package/src/raise/latch.ts +162 -6
- package/src/raise/memberarrays.ts +10 -4
- package/src/raise/offsetnames.ts +422 -36
- package/src/raise/pairparams.ts +33 -0
- package/src/raise/paramwidth.ts +196 -6
- package/src/raise/pre-recovery.ts +107 -21
- package/src/raise/pre-structure.ts +73 -0
- package/src/raise/recover.ts +12 -5
- package/src/raise/reroll.ts +674 -0
- package/src/raise/shortcircuit.ts +217 -34
- package/src/raise/softdiv.ts +1 -1
- package/src/raise/storesign.ts +153 -0
- package/src/raise/struct-arrays.ts +30 -11
- package/src/raise/structs.ts +396 -33
- package/src/raise/truncload.ts +4 -3
- package/src/raise/unpre.ts +594 -0
- package/src/raise/unthread.ts +400 -0
- package/src/rank-declare.ts +118 -12
- package/src/rank-variations.ts +186 -35
- package/src/rank.ts +536 -68
- package/src/runtime-helpers.ts +140 -22
- package/src/structure/analysis.ts +217 -8
- package/src/structure/arith-ops.ts +23 -0
- package/src/structure/cross-jumped-tail.ts +216 -0
- package/src/structure/globalaccess.ts +157 -10
- package/src/structure/hazards.ts +16 -64
- package/src/structure/local-statics.ts +145 -9
- package/src/structure/namecoalesce.ts +1 -1
- package/src/structure/pointer-spelling.ts +1106 -0
- package/src/structure/redundant-test.ts +1 -1
- package/src/structure/structure.ts +6192 -1213
- package/src/structure/switch-recover.ts +583 -120
- package/src/structure/unfolded-branch-constant.ts +90 -0
- package/src/symbols.ts +58 -15
- package/src/target.ts +1028 -54
- package/src/trace.ts +49 -17
- package/src/variation-definitions.ts +333 -20
- package/src/variation-gates.ts +4 -0
- 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
|
|
16
|
-
//
|
|
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
|