зеркало из https://github.com/mozilla/pjs.git
Bug 433939: update outparams for latest Treehydra revision
This commit is contained in:
Родитель
bcbd3682b3
Коммит
ca0affce96
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче