Skip to content

Commit 9ed55c6

Browse files
author
1475505
committed
pass CHABuilder.java local test.
1 parent 956df3d commit 9ed55c6

File tree

4 files changed

+256
-15
lines changed

4 files changed

+256
-15
lines changed

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

Lines changed: 149 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package pascal.taie.analysis.dataflow.analysis.constprop;
2424

2525
import pascal.taie.analysis.dataflow.analysis.AbstractDataflowAnalysis;
26+
import pascal.taie.analysis.dataflow.fact.MapFact;
2627
import pascal.taie.analysis.graph.cfg.CFG;
2728
import pascal.taie.config.AnalysisConfig;
2829
import pascal.taie.ir.IR;
@@ -40,6 +41,10 @@
4041
import pascal.taie.language.type.Type;
4142
import pascal.taie.util.AnalysisException;
4243

44+
import java.util.HashMap;
45+
import java.util.HashSet;
46+
import java.util.Map;
47+
4348
public class ConstantPropagation extends
4449
AbstractDataflowAnalysis<Stmt, CPFact> {
4550

@@ -57,32 +62,65 @@ public boolean isForward() {
5762
@Override
5863
public CPFact newBoundaryFact(CFG<Stmt> cfg) {
5964
// TODO - finish me
60-
return null;
65+
CPFact cpFact = new CPFact();
66+
for (Var param : cfg.getIR().getParams() ){
67+
if (canHoldInt(param)){
68+
cpFact.update(param, Value.getNAC());
69+
// Actually, absence means "UNDEF", i.e. TOP.
70+
}
71+
}
72+
return cpFact;
6173
}
6274

6375
@Override
6476
public CPFact newInitialFact() {
6577
// TODO - finish me
66-
return null;
78+
return new CPFact();
6779
}
6880

6981
@Override
7082
public void meetInto(CPFact fact, CPFact target) {
7183
// TODO - finish me
84+
fact.forEach((Var var, Value value) -> {
85+
target.update(var, meetValue(target.get(var), value));
86+
});
7287
}
7388

7489
/**
7590
* Meets two Values.
7691
*/
7792
public Value meetValue(Value v1, Value v2) {
7893
// TODO - finish me
79-
return null;
94+
if (v1.isNAC() || v2.isNAC()){
95+
return Value.getNAC();
96+
}
97+
if (v1.isUndef()) return v2;
98+
if (v2.isUndef()) return v1;
99+
if (v1.getConstant() == v2.getConstant()){
100+
return v1;
101+
} else {
102+
return Value.getNAC();
103+
}
80104
}
81105

82106
@Override
83107
public boolean transferNode(Stmt stmt, CPFact in, CPFact out) {
84108
// TODO - finish me
85-
return false;
109+
var gen = stmt.getDef();
110+
CPFact old_out = out.copy();
111+
out.copyFrom(in);
112+
if (gen.isPresent() && gen.get() instanceof Var def) {
113+
if (!(stmt instanceof DefinitionStmt<?,?> definitionStmt) || !canHoldInt(def)){
114+
return true;
115+
}
116+
var rValue = definitionStmt.getRValue();
117+
if (rValue != null) {
118+
out.update(def, evaluate(rValue, in));
119+
} else {
120+
out.update(def, Value.getNAC());
121+
}
122+
}
123+
return out.equals(old_out);
86124
}
87125

88126
/**
@@ -112,6 +150,112 @@ public static boolean canHoldInt(Var var) {
112150
*/
113151
public static Value evaluate(Exp exp, CPFact in) {
114152
// TODO - finish me
115-
return null;
153+
if (exp instanceof Var){
154+
if (canHoldInt((Var) exp)) {
155+
return in.get((Var) exp);
156+
} else {
157+
return Value.getNAC();
158+
}
159+
} else if (exp instanceof IntLiteral){
160+
return Value.makeConstant(((IntLiteral)exp).getValue());
161+
} else if (exp instanceof BinaryExp){
162+
Value op1 = evaluate(((BinaryExp) exp).getOperand1(), in);
163+
Value op2 = evaluate(((BinaryExp) exp).getOperand2(), in);
164+
// By issue: https://github.com/pascal-lab/Tai-e-assignments/issues/2
165+
// judge '/0' and '%0' at first.
166+
BinaryExp.Op op = ((BinaryExp) exp).getOperator();
167+
if ( op2.isConstant() && op2.getConstant() == 0 && (op == ArithmeticExp.Op.DIV || op == ArithmeticExp.Op.REM) ){
168+
return Value.getUndef();
169+
}
170+
if ( op1.isNAC() || op2.isNAC()){
171+
return Value.getNAC();
172+
}
173+
if ( !op1.isConstant() || !op2.isConstant()){
174+
return Value.getUndef();
175+
}
176+
if (op instanceof ArithmeticExp.Op) {
177+
switch ((ArithmeticExp.Op)op) {
178+
case ADD -> {
179+
return Value.makeConstant(op1.getConstant() + op2.getConstant());
180+
}
181+
case SUB -> {
182+
return Value.makeConstant(op1.getConstant() - op2.getConstant());
183+
}
184+
case MUL -> {
185+
return Value.makeConstant(op1.getConstant() * op2.getConstant());
186+
}
187+
case DIV -> {
188+
if (op2.getConstant() == 0) {
189+
return Value.getUndef();
190+
}
191+
return Value.makeConstant(op1.getConstant() / op2.getConstant());
192+
}
193+
case REM -> {
194+
if (op2.getConstant() == 0) {
195+
return Value.getUndef();
196+
}
197+
return Value.makeConstant(op1.getConstant() % op2.getConstant());
198+
}
199+
}
200+
}
201+
if (op instanceof ConditionExp.Op){
202+
switch ((ConditionExp.Op)op){
203+
case EQ -> {
204+
return Value.makeConstant(op1.getConstant() == op2.getConstant()? 1 : 0);
205+
}
206+
case GE -> {
207+
return Value.makeConstant(op1.getConstant() >= op2.getConstant()? 1 : 0);
208+
}
209+
case GT -> {
210+
return Value.makeConstant(op1.getConstant() > op2.getConstant()? 1 : 0);
211+
}
212+
case LE -> {
213+
return Value.makeConstant(op1.getConstant() <= op2.getConstant()? 1 : 0);
214+
}
215+
case LT -> {
216+
return Value.makeConstant(op1.getConstant() < op2.getConstant()? 1 : 0);
217+
}
218+
case NE -> {
219+
return Value.makeConstant(op1.getConstant() != op2.getConstant()? 1 : 0);
220+
}
221+
}
222+
}
223+
if (op instanceof ShiftExp.Op){
224+
switch ((ShiftExp.Op)op){
225+
case SHL -> {
226+
return Value.makeConstant(op1.getConstant() << op2.getConstant());
227+
}
228+
case SHR -> {
229+
return Value.makeConstant(op1.getConstant() >> op2.getConstant());
230+
}
231+
case USHR -> {
232+
return Value.makeConstant(op1.getConstant() >>> op2.getConstant());
233+
}
234+
}
235+
}
236+
if (op instanceof BitwiseExp.Op) {
237+
// maybe no need to process it? NO!!! logic rather than bitwise.
238+
switch ((BitwiseExp.Op)op){
239+
case OR -> {
240+
return Value.makeConstant(op1.getConstant() | op2.getConstant());
241+
}
242+
case AND -> {
243+
return Value.makeConstant(op1.getConstant() & op2.getConstant());
244+
}
245+
case XOR -> {
246+
return Value.makeConstant(op1.getConstant() ^ op2.getConstant());
247+
}
248+
}
249+
}
250+
return Value.getUndef();
251+
}
252+
/*
253+
f(y,z) =
254+
val(y) op val(z) // if val(y) and val(z) are constants
255+
NAC // if val(y) or val(z) is NAC
256+
UNDEF // otherwise
257+
对于其它情况,该方法会像我们在第 2.1 节提到的那样返回 NAC。
258+
*/
259+
return Value.getNAC();
116260
}
117261
}

A4/tai-e/src/main/java/pascal/taie/analysis/dataflow/inter/InterConstantPropagation.java

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

2525
import pascal.taie.analysis.dataflow.analysis.constprop.CPFact;
2626
import pascal.taie.analysis.dataflow.analysis.constprop.ConstantPropagation;
27+
import pascal.taie.analysis.dataflow.analysis.constprop.Value;
2728
import pascal.taie.analysis.graph.cfg.CFG;
2829
import pascal.taie.analysis.graph.cfg.CFGBuilder;
2930
import pascal.taie.analysis.graph.icfg.CallEdge;
@@ -34,6 +35,7 @@
3435
import pascal.taie.ir.IR;
3536
import pascal.taie.ir.exp.InvokeExp;
3637
import pascal.taie.ir.exp.Var;
38+
import pascal.taie.ir.stmt.DefinitionStmt;
3739
import pascal.taie.ir.stmt.Invoke;
3840
import pascal.taie.ir.stmt.Stmt;
3941
import pascal.taie.language.classes.JMethod;
@@ -77,36 +79,59 @@ public void meetInto(CPFact fact, CPFact target) {
7779
@Override
7880
protected boolean transferCallNode(Stmt stmt, CPFact in, CPFact out) {
7981
// TODO - finish me
80-
return false;
82+
return out.copyFrom(in);
8183
}
8284

8385
@Override
8486
protected boolean transferNonCallNode(Stmt stmt, CPFact in, CPFact out) {
8587
// TODO - finish me
86-
return false;
88+
return cp.transferNode(stmt, in, out);
8789
}
8890

8991
@Override
9092
protected CPFact transferNormalEdge(NormalEdge<Stmt> edge, CPFact out) {
9193
// TODO - finish me
92-
return null;
94+
return out.copy();
9395
}
9496

9597
@Override
9698
protected CPFact transferCallToReturnEdge(CallToReturnEdge<Stmt> edge, CPFact out) {
9799
// TODO - finish me
98-
return null;
100+
CPFact cpFact = out.copy();
101+
if (edge.getSource() instanceof Invoke callSite){
102+
var def = callSite.getResult();
103+
if (def != null)
104+
cpFact.remove(def);
105+
}
106+
return cpFact;
99107
}
100108

101109
@Override
102110
protected CPFact transferCallEdge(CallEdge<Stmt> edge, CPFact callSiteOut) {
103111
// TODO - finish me
104-
return null;
112+
CPFact cpFact = new CPFact();
113+
var method = edge.getCallee();
114+
var params = method.getIR().getParams();
115+
var args = ((Invoke)edge.getSource()).getInvokeExp().getArgs();
116+
for (int i = 0; i < params.size(); i++){
117+
cpFact.update(params.get(i), callSiteOut.get(args.get(i)));
118+
}
119+
return cpFact;
105120
}
106121

107122
@Override
108123
protected CPFact transferReturnEdge(ReturnEdge<Stmt> edge, CPFact returnOut) {
109124
// TODO - finish me
110-
return null;
125+
CPFact cpFact = new CPFact();
126+
var ret = edge.getReturnVars();
127+
var rcv = ((Invoke)edge.getCallSite()).getResult();
128+
if (rcv != null){
129+
Value target = Value.getUndef();
130+
for (Var var : ret){
131+
target = cp.meetValue(target, returnOut.get(var));
132+
}
133+
cpFact.update(rcv, target);
134+
}
135+
return cpFact;
111136
}
112137
}

A4/tai-e/src/main/java/pascal/taie/analysis/dataflow/inter/InterSolver.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import pascal.taie.analysis.graph.icfg.ICFG;
2727
import pascal.taie.util.collection.SetQueue;
2828

29+
import java.util.LinkedList;
2930
import java.util.Queue;
3031
import java.util.Set;
3132
import java.util.stream.Collectors;
@@ -60,9 +61,30 @@ DataflowResult<Node, Fact> solve() {
6061

6162
private void initialize() {
6263
// TODO - finish me
64+
for (Node node : icfg) {
65+
result.setOutFact(node, analysis.newInitialFact());
66+
result.setInFact(node, analysis.newInitialFact());
67+
}
68+
for (Method method : icfg.entryMethods().toList()){
69+
Node node = icfg.getEntryOf(method);
70+
result.setOutFact(node, analysis.newBoundaryFact(node));
71+
}
6372
}
6473

6574
private void doSolve() {
6675
// TODO - finish me
76+
Queue<Node> workList = new LinkedList<>(); // queue
77+
for (Node node : icfg){
78+
workList.add(node);
79+
}
80+
while (!workList.isEmpty()) {
81+
Node node = workList.poll();
82+
for (var edge : icfg.getInEdgesOf(node)) {
83+
analysis.meetInto(analysis.transferEdge(edge, result.getOutFact(edge.getSource())), result.getInFact(node));
84+
}
85+
if (!analysis.transferNode(node, result.getInFact(node), result.getOutFact(node))) {
86+
workList.addAll(icfg.getSuccsOf(node));
87+
}
88+
}
6789
}
6890
}

0 commit comments

Comments
 (0)