@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
70 lines • 2.76 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");
/**
* All available control flow graph simplification passes.
*/
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.
* Please note that this will not visit the grouping delimiters of expression list!
* @param cfg - The control flow graph whose reachable nodes to find.
*/
function cfgFindAllReachable(cfg) {
return (0, simple_visitor_1.visitCfgInOrder)(cfg.graph, cfg.entryPoints, () => {
/* do nothing */
});
}
//# sourceMappingURL=cfg-simplification.js.map