Skip to content

Commit 114061f

Browse files
committed
assignment 2 with bugs
1 parent 438c7c4 commit 114061f

File tree

7 files changed

+180
-19
lines changed

7 files changed

+180
-19
lines changed

A1/tai-e/src/main/java/pascal/taie/analysis/dataflow/analysis/LiveVariableAnalysis.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import pascal.taie.analysis.dataflow.fact.SetFact;
2626
import pascal.taie.analysis.graph.cfg.CFG;
2727
import pascal.taie.config.AnalysisConfig;
28+
import pascal.taie.ir.exp.LValue;
29+
import pascal.taie.ir.exp.RValue;
2830
import pascal.taie.ir.exp.Var;
2931
import pascal.taie.ir.stmt.Stmt;
3032

@@ -48,23 +50,37 @@ public boolean isForward() {
4850
@Override
4951
public SetFact<Var> newBoundaryFact(CFG<Stmt> cfg) {
5052
// TODO - finish me
51-
return null;
53+
return new SetFact<>();
5254
}
5355

5456
@Override
5557
public SetFact<Var> newInitialFact() {
5658
// TODO - finish me
57-
return null;
59+
return new SetFact<>();
5860
}
5961

6062
@Override
6163
public void meetInto(SetFact<Var> fact, SetFact<Var> target) {
6264
// TODO - finish me
65+
target.union(fact);
6366
}
6467

6568
@Override
6669
public boolean transferNode(Stmt stmt, SetFact<Var> in, SetFact<Var> out) {
6770
// TODO - finish me
68-
return false;
71+
var oldIn = in.copy();
72+
in.clear();
73+
in.union(out);
74+
stmt.getDef().ifPresent(lValue -> {
75+
if (lValue instanceof Var) {
76+
in.remove((Var)lValue);
77+
}
78+
});
79+
for (var use : stmt.getUses()) {
80+
if (use instanceof Var) {
81+
in.add((Var) use);
82+
}
83+
}
84+
return !in.equals(oldIn);
6985
}
7086
}

A1/tai-e/src/main/java/pascal/taie/analysis/dataflow/solver/IterativeSolver.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import pascal.taie.analysis.dataflow.analysis.DataflowAnalysis;
2626
import pascal.taie.analysis.dataflow.fact.DataflowResult;
27+
import pascal.taie.analysis.dataflow.fact.SetFact;
2728
import pascal.taie.analysis.graph.cfg.CFG;
2829

2930
class IterativeSolver<Node, Fact> extends Solver<Node, Fact> {
@@ -40,5 +41,22 @@ protected void doSolveForward(CFG<Node> cfg, DataflowResult<Node, Fact> result)
4041
@Override
4142
protected void doSolveBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
4243
// TODO - finish me
44+
boolean change = true;
45+
while (change) {
46+
change = false;
47+
for (Node node : cfg) {
48+
if (cfg.isExit(node)) continue;
49+
for (var suc : cfg.getSuccsOf(node)) {
50+
if (result.getOutFact(node) == null) {
51+
result.setOutFact(node, analysis.newInitialFact());
52+
}
53+
analysis.meetInto(result.getInFact(suc), result.getOutFact(node));
54+
}
55+
if (analysis.transferNode(node, result.getInFact(node), result.getOutFact(node))) {
56+
change = true;
57+
}
58+
59+
}
60+
}
4361
}
4462
}

A1/tai-e/src/main/java/pascal/taie/analysis/dataflow/solver/Solver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ protected void initializeForward(CFG<Node> cfg, DataflowResult<Node, Fact> resul
8282

8383
protected void initializeBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
8484
// TODO - finish me
85+
result.setInFact(cfg.getExit(), analysis.newBoundaryFact(cfg));
86+
for (var node : cfg) {
87+
if (!cfg.isExit(node)) {
88+
result.setInFact(node, analysis.newInitialFact());
89+
}
90+
}
8591
}
8692

8793
/**

A2/tai-e/src/main/java/pascal/taie/analysis/dataflow/analysis/constprop/ConstantPropagation.java

Lines changed: 112 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* of the License, or (at your option) any later version.
1313
*
1414
* Tai-e is distributed in the hope that it will be useful,but WITHOUT
15-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15+
* ANY WARRANTY; without even the implied warrant of MERCHANTABILITY
1616
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
1717
* Public License for more details.
1818
*
@@ -25,20 +25,11 @@
2525
import pascal.taie.analysis.dataflow.analysis.AbstractDataflowAnalysis;
2626
import pascal.taie.analysis.graph.cfg.CFG;
2727
import pascal.taie.config.AnalysisConfig;
28-
import pascal.taie.ir.IR;
29-
import pascal.taie.ir.exp.ArithmeticExp;
30-
import pascal.taie.ir.exp.BinaryExp;
31-
import pascal.taie.ir.exp.BitwiseExp;
32-
import pascal.taie.ir.exp.ConditionExp;
33-
import pascal.taie.ir.exp.Exp;
34-
import pascal.taie.ir.exp.IntLiteral;
35-
import pascal.taie.ir.exp.ShiftExp;
36-
import pascal.taie.ir.exp.Var;
28+
import pascal.taie.ir.exp.*;
3729
import pascal.taie.ir.stmt.DefinitionStmt;
3830
import pascal.taie.ir.stmt.Stmt;
3931
import pascal.taie.language.type.PrimitiveType;
4032
import pascal.taie.language.type.Type;
41-
import pascal.taie.util.AnalysisException;
4233

4334
public class ConstantPropagation extends
4435
AbstractDataflowAnalysis<Stmt, CPFact> {
@@ -57,32 +48,57 @@ public boolean isForward() {
5748
@Override
5849
public CPFact newBoundaryFact(CFG<Stmt> cfg) {
5950
// TODO - finish me
60-
return null;
51+
var fact = new CPFact();
52+
cfg.getIR().getParams().forEach(param -> {
53+
if (canHoldInt(param))
54+
fact.update(param, Value.getNAC());
55+
});
56+
return fact;
6157
}
6258

6359
@Override
6460
public CPFact newInitialFact() {
6561
// TODO - finish me
66-
return null;
62+
return new CPFact();
6763
}
6864

6965
@Override
7066
public void meetInto(CPFact fact, CPFact target) {
7167
// TODO - finish me
68+
for (var key : fact.keySet()) {
69+
var value1 = fact.get(key);
70+
var value2 = target.get(key);
71+
target.update(key, meetValue(value1, value2));
72+
}
7273
}
7374

7475
/**
7576
* Meets two Values.
7677
*/
7778
public Value meetValue(Value v1, Value v2) {
7879
// TODO - finish me
79-
return null;
80+
if (v1.isNAC() || v2.isNAC()) return Value.getNAC();
81+
if (v1.isUndef() && v2.isUndef()) return Value.getUndef();
82+
if (v1.isUndef() || v2.isUndef()) return v1.isConstant() ?
83+
Value.makeConstant(v1.getConstant()) : Value.makeConstant(v2.getConstant());
84+
return v1.getConstant() == v2.getConstant() ?
85+
Value.makeConstant(v1.getConstant()) : Value.getNAC();
8086
}
8187

8288
@Override
8389
public boolean transferNode(Stmt stmt, CPFact in, CPFact out) {
8490
// TODO - finish me
85-
return false;
91+
// make sure def can hold int
92+
var oldOut = out.copy();
93+
out.clear(); out.copyFrom(in);
94+
if (stmt instanceof DefinitionStmt<?,?>) {
95+
var lv = ((DefinitionStmt<?, ?>) stmt).getLValue();
96+
var rv = ((DefinitionStmt<?, ?>) stmt).getRValue();
97+
if (lv == null || !canHoldInt((Var) lv)) return false;
98+
out.remove((Var) lv);
99+
out.update((Var) lv, evaluate(rv, in));
100+
}
101+
return !oldOut.equals(out);
86102
}
87103

88104
/**
@@ -112,6 +128,86 @@ public static boolean canHoldInt(Var var) {
112128
*/
113129
public static Value evaluate(Exp exp, CPFact in) {
114130
// TODO - finish me
115-
return null;
131+
if (exp instanceof Var) {
132+
return in.get((Var) exp).isConstant() ?
133+
Value.makeConstant(in.get((Var)exp).getConstant()) : in.get((Var)exp);
134+
}
135+
if (exp instanceof IntLiteral) return Value.makeConstant(((IntLiteral) exp).getValue());
136+
if (!(exp instanceof BinaryExp)) return Value.getNAC();
137+
var o1 = evaluate(((BinaryExp) exp).getOperand1(), in);
138+
var o2 = evaluate(((BinaryExp) exp).getOperand2(), in);
139+
if (o1.isNAC() || o2.isNAC()) return Value.getNAC();
140+
if (o1.isUndef() || o2.isUndef()) return Value.getUndef();
141+
if (exp instanceof BitwiseExp) {
142+
var op = ((BitwiseExp) exp).getOperator();
143+
switch (op) {
144+
case OR -> {
145+
return Value.makeConstant(o1.getConstant() | o2.getConstant());
146+
}
147+
case XOR -> {
148+
return Value.makeConstant(o1.getConstant() ^ o2.getConstant());
149+
}
150+
case AND -> {
151+
return Value.makeConstant(o1.getConstant() & o2.getConstant());
152+
}
153+
}
154+
}
155+
if (exp instanceof ArithmeticExp) {
156+
var op = ((ArithmeticExp) exp).getOperator();
157+
switch (op) {
158+
case ADD -> {
159+
return Value.makeConstant(o1.getConstant() + o2.getConstant());
160+
}
161+
case SUB -> {
162+
return Value.makeConstant(o1.getConstant() - o2.getConstant());
163+
}
164+
case MUL -> {
165+
return Value.makeConstant(o1.getConstant() * o2.getConstant());
166+
}
167+
case DIV -> {
168+
if (o2.getConstant() == 0) return Value.getUndef();
169+
return Value.makeConstant(o1.getConstant() / o2.getConstant());
170+
}
171+
case REM -> {
172+
if (o2.getConstant() == 0) return Value.getUndef();
173+
return Value.makeConstant(o1.getConstant() % o2.getConstant());
174+
}
175+
}
176+
}
177+
if (exp instanceof ConditionExp) {
178+
var op = ((ConditionExp) exp).getOperator();
179+
switch (op) {
180+
case EQ -> {
181+
return Value.makeConstant(o1.getConstant() == o2.getConstant() ? 1 : 0);
182+
}
183+
case GE -> {
184+
return Value.makeConstant(o1.getConstant() >= o2.getConstant() ? 1 : 0);
185+
}
186+
case GT -> {
187+
return Value.makeConstant(o1.getConstant() > o2.getConstant() ? 1 : 0);
188+
}
189+
case LE -> {
190+
return Value.makeConstant(o1.getConstant() <= o2.getConstant() ? 1 : 0);
191+
}
192+
case LT -> {
193+
return Value.makeConstant(o1.getConstant() < o2.getConstant() ? 1 : 0);
194+
}
195+
}
196+
}
197+
if (exp instanceof ShiftExp) {
198+
var op = ((ShiftExp) exp).getOperator();
199+
switch (op) {
200+
case SHL -> {
201+
return Value.makeConstant(o1.getConstant() << o2.getConstant());
202+
}
203+
case SHR -> {
204+
return Value.makeConstant(o1.getConstant() >> o2.getConstant());
205+
}
206+
case USHR -> {
207+
return Value.makeConstant(o1.getConstant() >>> o2.getConstant());
208+
}
209+
}
210+
}
211+
return Value.getUndef();
116212
}
117213
}

A2/tai-e/src/main/java/pascal/taie/analysis/dataflow/solver/Solver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ private DataflowResult<Node, Fact> initialize(CFG<Node> cfg) {
7878

7979
protected void initializeForward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
8080
// TODO - finish me
81+
result.setOutFact(cfg.getEntry(), analysis.newBoundaryFact(cfg));
82+
for (var node : cfg) {
83+
if (cfg.isEntry(node)) continue;
84+
result.setOutFact(node, analysis.newInitialFact());
85+
result.setInFact(node, analysis.newInitialFact());
86+
}
8187
}
8288

8389
protected void initializeBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {

A2/tai-e/src/main/java/pascal/taie/analysis/dataflow/solver/WorkListSolver.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
import pascal.taie.analysis.dataflow.fact.DataflowResult;
2727
import pascal.taie.analysis.graph.cfg.CFG;
2828

29+
import java.util.LinkedList;
30+
import java.util.Queue;
31+
2932
class WorkListSolver<Node, Fact> extends Solver<Node, Fact> {
3033

3134
WorkListSolver(DataflowAnalysis<Node, Fact> analysis) {
@@ -35,6 +38,17 @@ class WorkListSolver<Node, Fact> extends Solver<Node, Fact> {
3538
@Override
3639
protected void doSolveForward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
3740
// TODO - finish me
41+
Queue<Node> queue = new LinkedList<>(cfg.getNodes());
42+
while (!queue.isEmpty()) {
43+
Node node = queue.poll();
44+
if (cfg.isEntry(node)) continue;
45+
for (var pre : cfg.getPredsOf(node)) {
46+
analysis.meetInto(result.getOutFact(pre), result.getInFact(node));
47+
}
48+
if (analysis.transferNode(node, result.getInFact(node), result.getOutFact(node))) {
49+
queue.addAll(cfg.getSuccsOf(node));
50+
}
51+
}
3852
}
3953

4054
@Override

A2/tai-e/src/test/java/pascal/taie/analysis/dataflow/analysis/constprop/CPTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,9 @@ public void testBranchConstant() {
6666
public void testInterprocedural() {
6767
testCP("Interprocedural");
6868
}
69+
70+
@Test
71+
public void testSwitch() {
72+
testCP("Switch");
73+
}
6974
}

0 commit comments

Comments
 (0)