pascal.taie.analysis.dataflow.inter.InterSolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tai-e Show documentation
Show all versions of tai-e Show documentation
An easy-to-learn/use static analysis framework for Java
The newest version!
/*
* Tai-e: A Static Analysis Framework for Java
*
* Copyright (C) 2022 Tian Tan
* Copyright (C) 2022 Yue Li
*
* This file is part of Tai-e.
*
* Tai-e is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Tai-e is distributed in the hope that it will be useful,but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Tai-e. If not, see .
*/
package pascal.taie.analysis.dataflow.inter;
import pascal.taie.analysis.dataflow.fact.DataflowResult;
import pascal.taie.analysis.graph.icfg.ICFG;
import pascal.taie.util.collection.SetQueue;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Solver for inter-procedural data-flow analysis.
* The workload of inter-procedural analysis is heavy, thus we always
* adopt work-list algorithm for efficiency.
*/
class InterSolver {
private final InterDataflowAnalysis analysis;
private final ICFG icfg;
private DataflowResult result;
private Queue workList;
InterSolver(InterDataflowAnalysis analysis,
ICFG icfg) {
this.analysis = analysis;
this.icfg = icfg;
}
DataflowResult solve() {
result = new DataflowResult<>();
initialize();
doSolve();
return result;
}
private void initialize() {
Set entryNodes = icfg.entryMethods()
.map(icfg::getEntryOf)
.collect(Collectors.toSet());
entryNodes.forEach(entry -> {
result.setInFact(entry, analysis.newBoundaryFact(entry));
result.setOutFact(entry, analysis.newBoundaryFact(entry));
});
icfg.forEach(node -> {
if (entryNodes.contains(node)) {
return;
}
result.setInFact(node, analysis.newInitialFact());
result.setOutFact(node, analysis.newInitialFact());
});
}
private void doSolve() {
workList = new SetQueue<>();
icfg.forEach(workList::add);
while (!workList.isEmpty()) {
Node node = workList.poll();
// meet incoming facts
Fact in = result.getInFact(node);
icfg.getInEdgesOf(node).forEach(inEdge -> {
Fact predOut = result.getOutFact(inEdge.source());
analysis.meetInto(analysis.transferEdge(inEdge, predOut), in);
});
Fact out = result.getOutFact(node);
boolean changed = analysis.transferNode(node, in, out);
if (changed) {
propagate(node);
}
}
}
void propagate(Node node) {
workList.addAll(icfg.getSuccsOf(node));
}
Fact getOutFact(Node node) {
return result.getOutFact(node);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy