UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

70 lines 2.76 kB
"use strict"; 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