-
Notifications
You must be signed in to change notification settings - Fork 52
Chaining Conditionals and SCCP #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Collect callee and caller save masks (inverts of each other, except for spills). Reorg layout to be closer to each other; remove dead mask definitions; add final keyword
Callee-save registers and masks and inserting LRGs for same and spilling and picking good spills. Insert CalleeSaveNodes and edges to RetXXXs and RegMasks for those edges. Iterators for regmask. Better printing post-allocation
All regs available arm, risc. MergeSort compiles & runs
No flags on risc5. Branch takes 2 inputs (one can be imm12). Float compare only sets a GPR to 0/1. Bool has a isFloat Common risc5 imm-form handling
Missing lots of stuff still
Function sigs to calls allow wide ints
A series of minor fixes, generally making transfer functions monotonic, or p[reserving sanity for error test cases.
Most tests pass, a few failures remain. Split Opto code into a seperate file. Improve `compute` precision in several places showing up during opto. bugfix: "split-thru-phis" on Parms changes calling conventions. Not ready for that yet.
Handle non-default main. Simplify trivial inlining cutout test. ParmNode excludes most Phi opts Region idom excludes dead paths RPC now interns
Float math handles high types monotonically Minus node does not reset int widen. Phi widen handles non-int mintype Dead returns do not error complain. Better handling default vs dead main
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Introduces chained relational/conditional parsing and an interprocedural SCCP (Sparse Conditional Constant Propagation) optimization pass, along with supporting type‑system widening and loop-phi widening mechanics. Key changes also refactor float arithmetic nodes into a shared base and add infrastructure for interprocedural call graph linking during SCCP.
- Added parsing and tests for chained relational/equality expressions.
- Implemented interprocedural SCCP (new Opto phase) with type widening (integers, floats, loop phis) and call graph linking.
- Refactored float arithmetic nodes and expanded type lattice capabilities (widening, high forms, memory/struct helpers).
Reviewed Changes
Copilot reviewed 52 out of 52 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| stacked_r_12x.c / stacked_r_13x.c | Added small C harnesses for new stacked relational tests. |
| Eval2.java | Graceful handling of previously unimplemented constant pointer cases. |
| Chapter24Test.java | Added tests for chained conditionals and SCCP (one naming/spelling issue). |
| Chapter19/18 Tests | Adjusted expected outputs after SCCP/type changes. |
| BrainFuckTest.java | Simplified program initialization; updated register references. |
| TypeStruct/TypeMemPtr/TypeInteger/... | Added high/widening helpers and integer widen tracking. |
| TypeRPC.java | Added freelist allocation; made fields mutable (pooling support). |
| Multiple type classes | Minor correctness / equality / lattice adjustments. |
| Arithmetic float nodes (AddF/MulF/SubF/DivF) | Unified via new ArithFNode. |
| Parser.java | Added chained comparison parsing & SCCP-related casting/widening tweaks. |
| Opto.java | New interprocedural SCCP driver and call graph linking/unlinking. |
| CodeGen / IterPeeps / Node / FunNode / PhiNode | Infrastructure to support optimistic analysis and widening. |
| README.md / TypeAnalysis.md | New chapter documentation; some documentation issues introduced. |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| }; | ||
|
|
||
| @Test | ||
| public void testSSCP() { |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Method name testSSCP likely intends to reference SCCP (Sparse Conditional Constant Propagation); consider renaming to testSCCP for correctness and consistency with terminology.
| public void testSSCP() { | |
| public void testSCCP() { |
| Parser.ParseException err = super.err(); | ||
| if( err != null ) return err; | ||
| if( ptr()._type == Type.TOP ) | ||
| return null; // This means we have an error input, report elsewher |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in comment: "elsewher" should be "elsewhere".
| return null; // This means we have an error input, report elsewher | |
| return null; // This means we have an error input, report elsewhere |
chapter24/README.md
Outdated
| Expressions that mix opposite directions of comparison, like using both | ||
| `<=` and `=`, are not allowed, because they create ambiguous logic. |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple documentation issues: (1) Line 40 likely meant >= instead of = when describing opposite directions; (2) Line 48 missing the word "valid" ("are only valid if..."); (3) Line 55 should use == instead of assignment =; suggest correcting to avoid reader confusion.
chapter24/README.md
Outdated
| ### Operator direction rules | ||
| Stacked comparisons are *only* if all the comparison operators |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple documentation issues: (1) Line 40 likely meant >= instead of = when describing opposite directions; (2) Line 48 missing the word "valid" ("are only valid if..."); (3) Line 55 should use == instead of assignment =; suggest correcting to avoid reader confusion.
chapter24/README.md
Outdated
| - `>` with `>` | ||
| - `>` with `>=` | ||
|
|
||
| All operators above can be combined with `=` and `!=`. |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple documentation issues: (1) Line 40 likely meant >= instead of = when describing opposite directions; (2) Line 48 missing the word "valid" ("are only valid if..."); (3) Line 55 should use == instead of assignment =; suggest correcting to avoid reader confusion.
| public void insertDef(int idx, Node new_def) { | ||
| _inputs.insert(null,idx); | ||
| setDef(idx,new_def); |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] insertDef formerly returned the Node but now returns void; if any existing internal or external callers relied on method chaining or the return value, this is a silent breaking API change—consider either restoring the return value or auditing all usages to ensure no regressions.
| public void insertDef(int idx, Node new_def) { | |
| _inputs.insert(null,idx); | |
| setDef(idx,new_def); | |
| public Node insertDef(int idx, Node new_def) { | |
| _inputs.insert(null,idx); | |
| return setDef(idx,new_def); |
|
|
||
| @Override public boolean isHigh() { return this==TOP; } | ||
| @Override boolean _isConstant() { return true; } | ||
| Type _glb(boolean mem) { return this; } |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chapter24/README.md
Outdated
| - `>` with `>` | ||
| - `>` with `>=` | ||
|
|
||
| All operators above can be combined with `=` and `!=`. |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single equals = is assignment in most languages; for equality the text should use ==. Recommend: "All operators above can be combined with == and !=."
| All operators above can be combined with `=` and `!=`. | |
| All operators above can be combined with `==` and `!=`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 53 out of 53 changed files in this pull request and generated 4 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| int subs = arm.imm_inst(arm.OP_SUBS, 0, reg1, self); | ||
| enc.add4(subs); | ||
| int cset = arm.cond_set(arm.OP_CSET, 31, arm.COND.EQ, 63, reg1); | ||
| int cset = arm.cond_set(arm.OP_CSET, 31, arm.COND.EQ, 31, reg1); |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fourth parameter should be 63 (xzr register) instead of 31. ARM64 uses register 31 as the zero register (wzr/xzr) and the instruction expects the destination register in the fourth parameter, not the condition register.
| int cset = arm.cond_set(arm.OP_CSET, 31, arm.COND.EQ, 31, reg1); | |
| int cset = arm.cond_set(arm.OP_CSET, 31, arm.COND.EQ, self, reg1); |
| @Override public boolean eq(Node n) { | ||
| ConFldOffNode off = (ConFldOffNode)n; // Invariant | ||
| return _name==off._name && _fname==off._fname && super.eq(n); | ||
| return _name.equals(off._name) && _fname.equals(off._fname) && super.eq(n); |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String comparison using == was changed to equals(), but this could cause NullPointerException if _name or _fname is null. Consider using Objects.equals() for null-safe comparison.
| public void insertDef(int idx, Node new_def) { | ||
| _inputs.insert(null,idx); | ||
| setDef(idx,new_def); |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method signature changed from returning Node to void, but callers might expect the fluent interface pattern. Consider returning 'this' to maintain chainability.
| public void insertDef(int idx, Node new_def) { | |
| _inputs.insert(null,idx); | |
| setDef(idx,new_def); | |
| public Node insertDef(int idx, Node new_def) { | |
| _inputs.insert(null,idx); | |
| setDef(idx,new_def); | |
| return this; |
| public static TypeInteger make(long lo, long hi) { | ||
| TypeInteger i = malloc(lo,hi); | ||
| private TypeInteger(long min, long max, byte widen) { super(TINT); init(min,max,widen); } | ||
| private TypeInteger init(long min, long max, byte widen) { |
Copilot
AI
Sep 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The assertion assumes constants always have zero widen, but this constraint isn't clearly documented. Consider adding a comment explaining why constants can't be widened.
| private TypeInteger init(long min, long max, byte widen) { | |
| private TypeInteger init(long min, long max, byte widen) { | |
| // If min == max, this TypeInteger represents a constant value. | |
| // Constants must always have a widen value of zero, because widening is only meaningful | |
| // for ranges of values, not for single, fixed values. Allowing a widened constant would | |
| // break assumptions elsewhere in the type system, where wideness is used to represent | |
| // uncertainty or generalization over a range, not a specific value. |
|
Approved in discord by @Hels15 |
cliffclick
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor typos
Add chained conditional/relational tests.
Add SCCP.
This is an extension of
#229
and is co-authored with @Hels15