Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New cfg config option to keep temporary statements + Update to C API test 'CfgApi' #129

Merged
merged 3 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ class ControlFlowGraph extends Graph {
*
* @param {joinpoint} $jp
* @param {boolean} [deterministicIds = false] If true, uses deterministic ids for the graph ids (e.g. id_0, id_1...). Otherwise, uses $jp.astId whenever possible
* @param {Object} [options = {}] An object containing configuration options for the cfg
* @param {Object} [options = {}] An object containing configuration options for the cfg
* @param {boolean} [options.splitInstList = false] If true, statements of each instruction list must be split
* @param {boolean} [options.removeGotoNodes = false] If true, the nodes that correspond to goto statements will be excluded from the resulting graph
* @param {boolean} [options.removeLabelNodes = false] If true, the nodes that correspond to label statements will be excluded from the resulting graph
*
* @param {boolean} [options.keepTemporaryScopeStmts = false] If true, the temporary scope statements will be kept in the resulting graph
* @returns {ControlFlowGraph} a new instance of the ControlFlowGraph class
*/
static build($jp, deterministicIds = false, options = {}) {
Expand Down
26 changes: 19 additions & 7 deletions ClavaLaraApi/src-lara-clava/clava/clava/graphs/cfg/CfgBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,28 @@ class CfgBuilder {
*/
#removeLabelNodes;

/**
* {boolean} If true, the temporary scope statements should not be removed from the graph
*/
#keepTemporaryScopeStmts;

/**
* Creates a new instance of the CfgBuilder class
* @param {joinpoint} $jp
* @param {boolean} [deterministicIds = false] If true, uses deterministic ids for the graph ids (e.g. id_0, id_1...). Otherwise, uses $jp.astId whenever possible
* @param {Object} [options = {}] An object containing configuration options for the cfg
* @param {Object} [options = {}] An object containing configuration options for the cfg
* @param {boolean} [options.splitInstList = false] If true, statements of each instruction list must be split
* @param {boolean} [options.removeGotoNodes = false] If true, the nodes that correspond to goto statements will be excluded from the resulting graph
* @param {boolean} [options.removeLabelNodes = false] If true, the nodes that correspond to label statements will be excluded from the resulting graph
* @param {boolean} [options.keepTemporaryScopeStmts = false] If true, the temporary scope statements will be kept in the resulting graph
*/
constructor($jp, deterministicIds = false, options = {}) {
this.#jp = $jp;
this.#deterministicIds = deterministicIds;
this.#splitInstList = options.splitInstList || false;
this.#removeGotoNodes = options.removeGotoNodes || false;
this.#removeLabelNodes = options.removeLabelNodes || false;
this.#splitInstList = options.splitInstList ?? false;
this.#removeGotoNodes = options.removeGotoNodes ?? false;
this.#removeLabelNodes = options.removeLabelNodes ?? false;
this.#keepTemporaryScopeStmts = options.keepTemporaryScopeStmts ?? false;
this.#currentId = 0;
this.#dataFactory = new DataFactory(this.#jp);
this.#graph = Graphs.newGraph();
Expand Down Expand Up @@ -558,10 +565,12 @@ class CfgBuilder {

_cleanCfg() {
// Remove temporary instructions from the code
for (const stmtId in this.#temporaryStmts) {
this.#temporaryStmts[stmtId].detach();
if (!this.#keepTemporaryScopeStmts) {
for (const stmtId in this.#temporaryStmts) {
this.#temporaryStmts[stmtId].detach();
}
}

// Remove temporary instructions from the instList nodes and this.#nodes
for (const node of this.#nodes.values()) {
// Only inst lists need to be cleaned
Expand All @@ -581,6 +590,9 @@ class CfgBuilder {

// Filter stmts that are temporary statements

if (this.#keepTemporaryScopeStmts)
continue;

const filteredStmts = [];
for (const $stmt of node.data().stmts) {
// If not a temporary stmt, add to filtered list
Expand Down
30 changes: 24 additions & 6 deletions ClavaWeaver/resources/clava/test/api/CfgApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ laraImport("clava.graphs.cfg.CfgUtils");
laraImport("clava.graphs.cfg.CfgEdgeType");
laraImport("weaver.Query");

const $fooFunction = Query.search("function", "foo").first();
const cfg = ControlFlowGraph.build($fooFunction, true);
println("Graph for foo:");
println(Graphs.toDot(cfg.graph));
verifyGraph(cfg)
println("Verification done")
const $functions = Query.search("function");
for (const $function of $functions) {
buildAndVerifyCfg($function);
}

const $gotoLabelFunction = Query.search("function", "gotoAndLabelExample").first();
const cfgOptions = {splitInstList: true,
removeLabelNodes: true,
removeGotoNodes: true,
keepTemporaryScopeStmts: true};
buildAndVerifyCfg($gotoLabelFunction, cfgOptions);

// Stress test
for(const $stmt of Query.search("function", "foo").search("statement")) {
Expand All @@ -18,7 +23,20 @@ for(const $stmt of Query.search("function", "foo").search("statement")) {
// println(Graphs.toDot(smallCfg.graph));
}

function buildAndVerifyCfg($function, options) {
const cfg = ControlFlowGraph.build($function, true, options);

if (options !== undefined) {
println(`Options used and Graph for ${$function.name}:`)
println(`${JSON.stringify(options, null, 2)}`);
}
else
println(`Graph for ${$function.name}:`)

println(Graphs.toDot(cfg.graph));
verifyGraph(cfg)
println(`Verification completed for ${$function.name}\n`)
}

function verifyGraph(cfg) {
for(const node of cfg.graph.nodes()) {
Expand Down
Loading