From 3ca355ea77319a818bda29fbe7423b40ad09adaf Mon Sep 17 00:00:00 2001
From: David Mandelin <dmandelin@mozilla.com>
Date: Tue, 20 May 2008 11:28:00 -0700
Subject: [PATCH] Bug 433939: update outparams for latest Treehydra revision

---
 xpcom/analysis/liveness.js  | 42 -----------------------------
 xpcom/analysis/outparams.js | 54 ++++++++++++++++++++++++++++++++++---
 2 files changed, 50 insertions(+), 46 deletions(-)
 delete mode 100644 xpcom/analysis/liveness.js

diff --git a/xpcom/analysis/liveness.js b/xpcom/analysis/liveness.js
deleted file mode 100644
index 414663f12517c..0000000000000
--- a/xpcom/analysis/liveness.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/** Liveness analysis.. */
-
-function LivenessAnalysis() {
-  BackwardAnalysis.apply(this, arguments);
-}
-
-LivenessAnalysis.prototype = new BackwardAnalysis;
-
-LivenessAnalysis.prototype.flowState = function(isn, state) {
-  switch (TREE_CODE(isn)) {
-  case RETURN_EXPR:
-    let gms = TREE_OPERAND(isn, 0);
-    if (gms) {
-      // gms is usually a GIMPLE_MODIFY_STMT but can be a RESULT_DECL
-      if (TREE_CODE(gms) == GIMPLE_MODIFY_STMT) {
-        let v = GIMPLE_STMT_OPERAND(gms, 1);
-        state.add(v);
-      } else if (TREE_CODE(gms) == RESULT_DECL) {
-        // TODO figure out what really happens here
-        // Presumably we already saw the assignment to it.
-      }
-    }
-    break;
-  case GIMPLE_MODIFY_STMT:
-  case COND_EXPR:
-  case SWITCH_EXPR:
-  case CALL_EXPR:
-    for (let e in isn_defs(isn, 'strong')) {
-      if (DECL_P(e)) {
-        state.remove(e);
-      }
-    }
-    for (let e in isn_uses(isn)) {
-      if (DECL_P(e)) {
-        state.add(e);
-      }
-    }
-    break;
-  default:
-    break;
-  }
-};
diff --git a/xpcom/analysis/outparams.js b/xpcom/analysis/outparams.js
index 9a1738bc4a00a..366cdd3fe8237 100644
--- a/xpcom/analysis/outparams.js
+++ b/xpcom/analysis/outparams.js
@@ -9,8 +9,8 @@ include('gcc_print.js');
 include('unstable/adts.js');
 include('unstable/analysis.js');
 include('unstable/esp.js');
+include('unstable/liveness.js');
 
-include('liveness.js');
 include('mayreturn.js');
 
 MapFactory.use_injective = true;
@@ -83,8 +83,7 @@ function process_tree(func_decl) {
     let b = new LivenessAnalysis(cfg, trace);
     b.run();
     for (let bb in cfg_bb_iterator(cfg)) {
-      bb.liveVarsIn = bb.stateIn;
-      bb.liveVarsOut = bb.stateOut;
+      bb.keepVars = bb.stateIn;
     }
   }
   
@@ -96,6 +95,14 @@ function process_tree(func_decl) {
   }();
   if (retvar == undefined && decl.resultType != 'void') throw new Error("assert");
 
+  // Make sure return value and outparams are never dropped from state.
+  for (let bb in cfg_bb_iterator(cfg)) {
+    bb.keepVars.add(retvar);
+    for each (let v in outparam_list) {
+      bb.keepVars.add(v);
+    }
+  }
+
   {
     let trace = TRACE_ESP;
     let fts = link_switches(cfg);
@@ -134,7 +141,7 @@ function OutparamCheck(cfg, psem_list, outparam_list, retvar, retvar_set, finall
       print("    " + expr_display(v));
     }
   }
-  ESP.Analysis.call(this, cfg, this.psvar_list, av.BOTTOM, trace);
+  ESP.Analysis.call(this, cfg, this.psvar_list, av.BOTTOM, av.meet, trace);
 }
 
 // Abstract values for outparam check
@@ -207,6 +214,41 @@ function makeOutparamAV(v) {
   return ans;
 }
 
+/** Return the integer value if this is an integer av, otherwise undefined. */
+av.intVal = function(v) {
+  if (v.hasOwnProperty('int_val'))
+    return v.int_val;
+  return undefined;
+}
+
+/** Meet function for our abstract values. */
+av.meet = function(v1, v2) {
+  // Important for following cases -- as output, undefined means top here.
+  if (v1 == undefined) v1 = av.BOTTOM;
+  if (v2 == undefined) v2 = av.BOTTOM;
+
+  // These cases apply for any lattice.
+  if (v1 == av.BOTTOM) return v2;
+  if (v2 == av.BOTTOM) return v1;
+  if (v1 == v2) return v1;
+
+  // At this point we know v1 != v2.
+  switch (v1) {
+  case av.LOCKED:
+  case av.UNLOCKED:
+    return undefined;
+  case av.ZERO:
+    return av.intVal(v2) == 0 ? v2 : undefined;
+  case av.NONZERO:
+    return av.intVal(v2) != 0 ? v2 : undefined;
+  default:
+    let iv = av.intVal(v1);
+    if (iv == 0) return v2 == av.ZERO ? v1 : undefined;
+    if (iv != undefined) return v2 == av.NONZERO ? v1 : undefined;
+    return undefined;
+  }
+}     
+
 // Outparam check analysis
 OutparamCheck.prototype = new ESP.Analysis;
 
@@ -218,6 +260,10 @@ OutparamCheck.prototype.startValues = function() {
   return ans;
 }
 
+OutparamCheck.prototype.updateEdgeState = function(e) {
+  e.state.keepOnly(e.dest.keepVars);
+}
+
 OutparamCheck.prototype.flowState = function(isn, state) {
   switch (TREE_CODE(isn)) {
   case GIMPLE_MODIFY_STMT:
-- 
GitLab