@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
68 lines • 2.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultCfgSimplificationOrder = exports.CfgSimplificationPasses = void 0;
exports.simplifyControlFlowInformation = simplifyControlFlowInformation;
exports.cfgFindAllReachable = cfgFindAllReachable;
const cfg_to_basic_blocks_1 = require("./cfg-to-basic-blocks");
const simple_visitor_1 = require("./simple-visitor");
const cfg_dead_code_1 = require("./cfg-dead-code");
exports.CfgSimplificationPasses = {
'unique-cf-sets': uniqueControlFlowSets,
'analyze-dead-code': cfg_dead_code_1.cfgAnalyzeDeadCode,
'remove-dead-code': cfgRemoveDeadCode,
'to-basic-blocks': toBasicBlocks
};
exports.DefaultCfgSimplificationOrder = [
'unique-cf-sets',
// 'remove-dead-code' // way too expensive for conventional use!
// basic blocks must be requested
];
/**
* Simplify the control flow information by applying the given passes.
* This may reduce the vertex count, in- and outgoing edges, entry and exit points, etc.
*/
function simplifyControlFlowInformation(cfg, info, passes = exports.DefaultCfgSimplificationOrder) {
for (const pass of passes) {
const passFn = exports.CfgSimplificationPasses[pass];
cfg = passFn(cfg, info);
}
return cfg;
}
/**
* removes dead vertices and edges from the control flow graph.
*/
function cfgRemoveDeadCode(cfg, _info) {
// remove every root level node and accompanying vertices that can not be reached from the entry points
const reachable = cfgFindAllReachable(cfg);
for (const id of cfg.graph.rootIds()) {
if (!reachable.has(id)) {
cfg.graph.removeVertex(id);
}
}
return cfg;
}
function uniqueControlFlowSets(cfg, _info) {
return {
returns: Array.from(new Set(cfg.returns)),
entryPoints: Array.from(new Set(cfg.entryPoints)),
exitPoints: Array.from(new Set(cfg.exitPoints)),
breaks: Array.from(new Set(cfg.breaks)),
nexts: Array.from(new Set(cfg.nexts)),
graph: cfg.graph
};
}
function toBasicBlocks(cfg, _info) {
return (0, cfg_to_basic_blocks_1.convertCfgToBasicBlocks)(cfg);
}
/**
* Uses {@link visitCfgInOrder} to find all nodes that are reachable from the control flow graph's {@link ControlFlowInformation.entryPoints} and returns them as a set.
* @param cfg - The control flow graph whose reachable nodes to find.
*/
function cfgFindAllReachable(cfg) {
const reachable = new Set();
(0, simple_visitor_1.visitCfgInOrder)(cfg.graph, cfg.entryPoints, node => {
reachable.add(node);
});
return reachable;
}
//# sourceMappingURL=cfg-simplification.js.map