summaryrefslogtreecommitdiff
path: root/chapter20/src/main/java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-09-19 10:30:13 -0700
committerCliff Click <cliffc@acm.org>2026-09-19 10:30:13 -0700
commitbf3e5632ddf21c109f7ef0f61bcc62e2ed0f9d49 (patch)
treebe2972819600b0a9790fceb882b5464c7c12857a /chapter20/src/main/java
parent200162345900136663027b6deae21d72cf30818c (diff)
downloadSimple-bf3e5632ddf21c109f7ef0f61bcc62e2ed0f9d49.tar.gz
Simple-bf3e5632ddf21c109f7ef0f61bcc62e2ed0f9d49.zip
Handle double-negation preserving not-null knowledge
Diffstat (limited to 'chapter20/src/main/java')
-rw-r--r--chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java17
1 files changed, 15 insertions, 2 deletions
diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
index f193e55a..3411756d 100644
--- a/chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
+++ b/chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
@@ -346,10 +346,23 @@ public class ScopeNode extends MemMergeNode {
// E.g. "if( ptr ) ptr.field;" is legal because ptr is known not-null.
public void addGuards( Node ctrl, Node pred, boolean invert ) {
assert ctrl instanceof CFGNode;
- _guards.add(ctrl); // Marker to distinguish 0,1,2 guards
+ _guards.add(ctrl); // Marker between guard sets
// add pred & its cast to the normal input list, with special Vars
if( pred==null || pred.isDead() )
return; // Dead, do not add any guards
+ _addGuards(ctrl,pred,invert);
+ }
+
+ private void _addGuards( Node ctrl, Node pred, boolean invert ) {
+ if( pred==null || pred.isDead() )
+ return;
+ // A single negation is handled below. For !!p (including p != null),
+ // also refine the underlying p without changing the Boolean result.
+ if( pred instanceof NotNode not && not.in(1) instanceof NotNode ) {
+ pred.keep(); // Recursive peepholes may rediscover this Not.
+ _addGuards(ctrl,not.in(1),!invert);
+ pred.unkeep();
+ }
// Invert the If conditional
if( invert )
pred = pred instanceof NotNode not ? not.in(1) : CodeGen.CODE.add(new NotNode(pred).peephole());
@@ -381,7 +394,7 @@ public class ScopeNode extends MemMergeNode {
// Remove matching pred/cast pairs from this guarded region.
public ScopeNode removeGuards( Node ctrl ) {
assert ctrl instanceof CFGNode;
- // 0,1 or 2 guards
+ // Pop the guards up to this region's marker.
while( true ) {
Node g = _guards.pop();
if( g == ctrl ) break;