Skip to content

Commit 77529dd

Browse files
author
blacktree
committed
A6
1 parent 397f8b0 commit 77529dd

File tree

13 files changed

+515
-156
lines changed

13 files changed

+515
-156
lines changed

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

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public boolean transferNode(Stmt stmt, CPFact in, CPFact out) {
9494
if (stmt instanceof DefinitionStmt<?,?>) {
9595
var lv = ((DefinitionStmt<?, ?>) stmt).getLValue();
9696
var rv = ((DefinitionStmt<?, ?>) stmt).getRValue();
97-
if (lv == null || !canHoldInt((Var) lv)) return false;
97+
if (!(lv instanceof Var) || !canHoldInt((Var) lv)) return false;
9898
out.remove((Var) lv);
9999
out.update((Var) lv, evaluate(rv, in));
100100
}
@@ -137,74 +137,75 @@ public static Value evaluate(Exp exp, CPFact in) {
137137
var o1 = evaluate(((BinaryExp) exp).getOperand1(), in);
138138
var o2 = evaluate(((BinaryExp) exp).getOperand2(), in);
139139
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());
140+
else if (o1.isConstant() && o2.isConstant()) {
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+
}
152153
}
153154
}
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());
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+
}
174175
}
175176
}
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);
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+
}
194195
}
195196
}
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());
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+
}
208209
}
209210
}
210211
}

A3/tai-e/src/main/java/pascal/taie/analysis/dataflow/analysis/DeadCodeDetection.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public Set<Stmt> analyze(IR ir) {
8181
var fact = constants.getResult(stmt);
8282
if (fact.get(condition.getOperand1()).isConstant()
8383
&& fact.get(condition.getOperand2()).isConstant()) {
84+
var operator = condition.getOperator();
8485

8586
}
8687
}

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

Lines changed: 133 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,13 @@
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;
33+
34+
import java.util.concurrent.atomic.AtomicBoolean;
4235

4336
public class ConstantPropagation extends
4437
AbstractDataflowAnalysis<Stmt, CPFact> {
@@ -56,33 +49,66 @@ public boolean isForward() {
5649

5750
@Override
5851
public CPFact newBoundaryFact(CFG<Stmt> cfg) {
59-
// TODO - finish me
60-
return null;
52+
CPFact fact = new CPFact();
53+
cfg.getIR().getParams().forEach(var -> {
54+
if(canHoldInt(var)) {
55+
fact.update(var, Value.getNAC());
56+
}
57+
});
58+
return fact;
6159
}
6260

6361
@Override
6462
public CPFact newInitialFact() {
65-
// TODO - finish me
66-
return null;
63+
return new CPFact();
6764
}
6865

6966
@Override
7067
public void meetInto(CPFact fact, CPFact target) {
71-
// TODO - finish me
68+
fact.forEach(((var, value) -> {
69+
target.update(var, meetValue(value, target.get(var)));
70+
}));
7271
}
7372

7473
/**
7574
* Meets two Values.
7675
*/
7776
public Value meetValue(Value v1, Value v2) {
78-
// TODO - finish me
79-
return null;
77+
if(v1.isConstant() && v2.isConstant()){
78+
if(v1.equals(v2)){
79+
return Value.makeConstant(v1.getConstant());
80+
}else{
81+
return Value.getNAC();
82+
}
83+
}else if(v1.isNAC() || v2.isNAC()){
84+
return Value.getNAC();
85+
}else if(v1.isConstant() && v2.isUndef()){
86+
return Value.makeConstant(v1.getConstant());
87+
}else if(v2.isConstant() && v1.isUndef()){
88+
return Value.makeConstant(v2.getConstant());
89+
}
90+
return Value.getUndef();
8091
}
8192

8293
@Override
8394
public boolean transferNode(Stmt stmt, CPFact in, CPFact out) {
84-
// TODO - finish me
85-
return false;
95+
AtomicBoolean changed = new AtomicBoolean(false);
96+
in.forEach(((var, value) -> {
97+
if(out.update(var, value)){
98+
changed.set(true);
99+
}
100+
}));
101+
if(stmt instanceof DefinitionStmt<?, ?> s){
102+
if(s.getLValue() instanceof Var var && canHoldInt(var)) {
103+
CPFact inCopy = in.copy();
104+
Value removedVal = inCopy.get(var);
105+
inCopy.remove(var);
106+
Value newVal = evaluate(s.getRValue(), in);
107+
out.update(var, newVal);
108+
return !removedVal.equals(newVal) || changed.get();
109+
}
110+
}
111+
return changed.get();
86112
}
87113

88114
/**
@@ -111,7 +137,93 @@ public static boolean canHoldInt(Var var) {
111137
* @return the resulting {@link Value}
112138
*/
113139
public static Value evaluate(Exp exp, CPFact in) {
114-
// TODO - finish me
115-
return null;
140+
if(exp instanceof IntLiteral e){
141+
return Value.makeConstant(e.getValue());
142+
}else if(exp instanceof Var var){
143+
if(in.get(var).isConstant()){
144+
return Value.makeConstant(in.get(var).getConstant());
145+
}
146+
return in.get(var);
147+
}else if(exp instanceof BinaryExp b){
148+
Value v1 = evaluate(b.getOperand1(), in);
149+
Value v2 = evaluate(b.getOperand2(), in);
150+
if(v2.isConstant() && v2.getConstant() == 0
151+
&& b.getOperator() instanceof ArithmeticExp.Op op){
152+
if(op == ArithmeticExp.Op.DIV || op == ArithmeticExp.Op.REM){
153+
return Value.getUndef();
154+
}
155+
}
156+
if(v1.isConstant() && v2.isConstant()){
157+
int c1 = v1.getConstant(), c2 = v2.getConstant();
158+
if(b.getOperator() instanceof ArithmeticExp.Op op){
159+
switch (op){
160+
case ADD -> {
161+
return Value.makeConstant(c1 + c2);
162+
}
163+
case SUB -> {
164+
return Value.makeConstant(c1 - c2);
165+
}
166+
case MUL -> {
167+
return Value.makeConstant(c1 * c2);
168+
}
169+
case DIV -> {
170+
return Value.makeConstant(c1 / c2);
171+
}
172+
case REM -> {
173+
return Value.makeConstant(c1 % c2);
174+
}
175+
}
176+
}else if(b.getOperator() instanceof ShiftExp.Op op){
177+
switch (op){
178+
case SHL -> {
179+
return Value.makeConstant(c1 << c2);
180+
}
181+
case SHR -> {
182+
return Value.makeConstant(c1 >> c2);
183+
}
184+
case USHR -> {
185+
return Value.makeConstant(c1 >>> c2);
186+
}
187+
}
188+
}else if(b.getOperator() instanceof BitwiseExp.Op op){
189+
switch (op){
190+
case OR -> {
191+
return Value.makeConstant(c1 | c2);
192+
}
193+
case AND -> {
194+
return Value.makeConstant(c1 & c2);
195+
}
196+
case XOR -> {
197+
return Value.makeConstant(c1 ^ c2);
198+
}
199+
}
200+
}else if(b.getOperator() instanceof ConditionExp.Op op){
201+
switch (op){
202+
case EQ -> {
203+
return Value.makeConstant(c1 == c2 ? 1 : 0);
204+
}
205+
case NE -> {
206+
return Value.makeConstant(c1 != c2 ? 1 : 0);
207+
}
208+
case LT -> {
209+
return Value.makeConstant(c1 < c2 ? 1 : 0);
210+
}
211+
case GT -> {
212+
return Value.makeConstant(c1 > c2 ? 1 : 0);
213+
}
214+
case LE -> {
215+
return Value.makeConstant(c1 <= c2 ? 1 : 0);
216+
}
217+
case GE -> {
218+
return Value.makeConstant(c1 >= c2 ? 1 : 0);
219+
}
220+
}
221+
}
222+
}else if(v1.isNAC() || v2.isNAC()){
223+
return Value.getNAC();
224+
}
225+
return Value.getUndef();
226+
}
227+
return Value.getNAC();
116228
}
117229
}

0 commit comments

Comments
 (0)