├── .classpath
├── .project
├── Example
└── dp_1.4.ll
├── README.txt
├── lib
├── commons-io-2.1.jar
└── libSTPJNI.so
└── src
├── cn
└── edu
│ └── sjtu
│ └── jllvm
│ ├── ESP
│ ├── CFGUtils.java
│ ├── ESPChecking.java
│ ├── ESPProperty
│ │ ├── Clause.java
│ │ ├── ESPState.java
│ │ ├── ESPStateFactory.java
│ │ ├── ESPTransitionSystem.java
│ │ ├── ExecutionState.java
│ │ ├── ExecutionState_STP.java
│ │ ├── IExecutionState.java
│ │ ├── ISymbolicState.java
│ │ ├── Literal.java
│ │ └── SymbolicState.java
│ ├── ILocation.java
│ ├── IState.java
│ ├── IStateFactory.java
│ ├── ITransitionSystem.java
│ ├── IWorklist.java
│ ├── Solver.java
│ ├── SolverUtil.java
│ ├── WorkPair.java
│ └── Worklist.java
│ ├── GUI
│ ├── ESP_GUI.java
│ └── UIUtil.java
│ ├── Lockset
│ ├── Edge.java
│ ├── FunctionCache.java
│ ├── Lock.java
│ ├── Lockset.java
│ ├── LocksetPair.java
│ └── LocksetTraverse.java
│ ├── VMCore
│ ├── Argument.java
│ ├── BasicBlock.java
│ ├── Cell.java
│ ├── Constants
│ │ ├── BinaryConstantExpr.java
│ │ ├── CompareConstantExpr.java
│ │ ├── ComplexConstantValue.java
│ │ ├── Constant.java
│ │ ├── ConstantExpr.java
│ │ ├── ConstantPointerNull.java
│ │ ├── ConvertConstantExpr.java
│ │ ├── Function.java
│ │ ├── FunctionDeclare.java
│ │ ├── GetElementPtrConstantExpr.java
│ │ ├── GlobalAlias.java
│ │ ├── GlobalValue.java
│ │ ├── GlobalVariable.java
│ │ ├── LocalVariable.java
│ │ ├── SimpleConstantValue.java
│ │ └── UndefValue.java
│ ├── Instructions
│ │ ├── AllocaInst.java
│ │ ├── BinaryInst.java
│ │ ├── CallInst.java
│ │ ├── CmpInst.java
│ │ ├── GetElePtrInst.java
│ │ ├── InstFactory.java
│ │ ├── Instruction.java
│ │ ├── LoadInst.java
│ │ ├── OperationInst.java
│ │ ├── PHIInst.java
│ │ ├── SelectInst.java
│ │ ├── StoreInst.java
│ │ └── TerminatorInst.java
│ ├── Module.java
│ ├── Operators
│ │ ├── CompareCondition.java
│ │ ├── InstType.java
│ │ └── Operator.java
│ ├── Parser
│ │ ├── LLVM.g
│ │ ├── LLVM.tokens
│ │ ├── LLVMLexer.java
│ │ └── LLVMParser.java
│ ├── Types
│ │ ├── ArrayType.java
│ │ ├── DerivedType.java
│ │ ├── FunctionType.java
│ │ ├── IDType.java
│ │ ├── IntegerType.java
│ │ ├── OpaqueType.java
│ │ ├── PackedStructType.java
│ │ ├── PointerType.java
│ │ ├── StructType.java
│ │ ├── Type.java
│ │ ├── TypeFactory.java
│ │ ├── UnionType.java
│ │ └── VectorType.java
│ ├── User.java
│ ├── Value.java
│ └── ValueFactory.java
│ └── test
│ ├── ESPArguments.java
│ └── TestLocksetTraverse.java
└── stp
├── Expr.java
├── STPJNI.c
├── STPJNI.h
├── STPJNI.java
├── STPObject.java
├── Type.java
├── VC.java
├── WholeCounterExample.java
├── exprkind_t.java
└── type_t.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | JLLVM
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.dltk.core.scriptbuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.pde.ManifestBuilder
20 |
21 |
22 |
23 |
24 | org.eclipse.pde.SchemaBuilder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.jdt.core.javanature
31 | org.deved.antlride.core.nature
32 | org.eclipse.pde.PluginNature
33 |
34 |
35 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | JLLVM is a Java version of LLVM Core. To get more info about JLLVM you should follow the link: http://tcloud.sjtu.edu.cn/wiki/index.php/User:Liuhaots:JLLVM
2 |
3 | To build the code:
4 | (1) import the project to eclipse
5 | (2) Include ANTLR path to lib.(download ANTLR work from:http://www.antlr.org/download.html).Right click on the project->"Build Path"->"Add External Archives"->choose the "antlrworks-1.4.3.jar"
6 |
7 | When you run the project to analysis LLVM IR, you may encounter the out of memory: It is because the source code is too large(such as Apache is 19MB). Some arguments should be added to Configurations, for example I add "-Xms512m -Xmx1024m" to "VM arguments" of "run Configurations" in eclipse.
8 |
9 | Enjoy it. Thanks!
--------------------------------------------------------------------------------
/lib/commons-io-2.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rwl/JLLVM/f5b9501a6f4c8ba6a8e53fc44db516111b7a2b07/lib/commons-io-2.1.jar
--------------------------------------------------------------------------------
/lib/libSTPJNI.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rwl/JLLVM/f5b9501a6f4c8ba6a8e53fc44db516111b7a2b07/lib/libSTPJNI.so
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/ESPChecking.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP;
2 |
3 | import java.util.Date;
4 | import java.util.Hashtable;
5 |
6 | import java.util.List;
7 |
8 | import cn.edu.sjtu.jllvm.ESP.ESPProperty.ESPStateFactory;
9 | import cn.edu.sjtu.jllvm.ESP.ESPProperty.ESPTransitionSystem;
10 |
11 | /**
12 | * using model checking algorithm to solve a worklist
13 | * @author liuhao 2011-12-19
14 | */
15 | public class ESPChecking {
16 | private IStateFactory factory;
17 | private ITransitionSystem system;
18 | private Hashtable reach;
19 |
20 | private int TIME_OUT = ESPTransitionSystem.USE_SOLVER?120000:20000; //20s
21 | private boolean DEBUG = false;
22 |
23 | public ESPChecking(){
24 | factory = new ESPStateFactory();
25 | }
26 |
27 | /**
28 | * solve a system, the system can return several entry node.
29 | * @param system: a system usually is a CFG
30 | * */
31 | public void solve(ITransitionSystem system){
32 | this.system = system;
33 |
34 | system.setAllLocationStateBottom(); //for all location, let reach(l) = BottomState
35 | reach = system.getAllLocationStates();
36 |
37 | IWorklist worklist = factory.createWorklist(); //empty worklist
38 | system.setWorklist(worklist);
39 |
40 | while(system.hasEntry()){
41 | ILocation loc = system.nextEntry();
42 | if(loc==null)
43 | break;
44 |
45 | IState initState = factory.createInitTopState();
46 |
47 | worklist.add(loc, initState); //worklist = {(entryNode, TopState)}
48 |
49 | solve(worklist);
50 | }
51 | }
52 |
53 | /**
54 | * using worklist algorithm to solve a worklist until it is empty
55 | * @param worklist: initially only has one node.
56 | */
57 | public void solve(IWorklist worklist){
58 | Date stateTime = new Date();
59 |
60 | while(!worklist.isEmpty()){
61 | if(!DEBUG){
62 | Date now = new Date();
63 | if(now.getTime() - stateTime.getTime() > TIME_OUT){
64 | worklist.removeAll();
65 | System.out.println("TIME_OUT");
66 | return;
67 | }
68 | }
69 |
70 | WorkPair workNode = worklist.remove(); //worklist.remvoe();
71 | ILocation loc = workNode.getLocation();
72 | IState state = workNode.getState();
73 |
74 | IState reach_state = reach.get(loc); //reach(l)
75 |
76 | boolean isBelongTo = state.belongTo(reach_state);
77 | if(!isBelongTo){ //!(state<=raach_state) that is: state > reach_state
78 | IState temp_state = reach_state.copy();
79 | reach_state.union(state);
80 |
81 | List dsts = system.getSuccessors(loc);
82 | for(ILocation next: dsts){
83 | IState post = system.getPost(loc, next);
84 |
85 | if(post != null){
86 | worklist.add(next, post);
87 | }else{
88 | reach_state = temp_state;
89 | reach.put(loc, reach_state);
90 | worklist.add(loc, state);
91 |
92 | break;
93 | }
94 | }
95 | }
96 | }
97 | }
98 |
99 | /**
100 | * print out debug info
101 | */
102 | public void print(){
103 | system.print();
104 | }
105 |
106 | public String getInfo(){
107 | return system.getInfo();
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/ESPProperty/Clause.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP.ESPProperty;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author liuhao 2011-12-30
8 | * Core of execution state. Handle union and addconstraint.
9 | * A clause is made up of several literals. Literals are intersected.
10 | */
11 | public class Clause {
12 | //if this clause is bottom, the list is null.
13 | //if this clause is top, the list size is 0.
14 | private List literals;
15 |
16 | /**
17 | * Union another clause
18 | * @param in_clause
19 | */
20 | public void union(Clause in_clause){
21 | if(in_clause.isBottom())
22 | return;
23 |
24 | if(isBottom()){
25 | literals = in_clause.copyLiterals();
26 | return;
27 | }
28 |
29 | if(in_clause.isTop() || this.isTop()){
30 | this.setTop();
31 | return;
32 | }
33 |
34 | for(int i = 0; i < literals.size(); i++){
35 | boolean contains = false;
36 | Literal lit = literals.get(i);
37 |
38 | for(Literal in_lit: in_clause.getLiterals()){
39 | if(lit.isIdEquals(in_lit)){
40 | contains = true;
41 | }
42 | }
43 |
44 | if(!contains){
45 | literals.remove(i);
46 | i--;
47 | }
48 | }
49 |
50 | for(Literal in_lit: in_clause.getLiterals()){
51 | union(in_lit);
52 | }
53 | }
54 |
55 | /**
56 | * Union a literal
57 | * @param in
58 | */
59 | public void union(Literal in){
60 | if(isBottom()){
61 | literals = new ArrayList();
62 | literals.add(in);
63 |
64 | return ;
65 | }
66 |
67 | for(Literal lit: literals){
68 | if(in.isIdEquals(lit)){
69 | if(!in.inField(lit)){ //not the same contraint
70 | literals.remove(lit); //!a UNION a = TRUE
71 | return;
72 | }
73 |
74 | return; //the same
75 | }
76 | }
77 |
78 | literals.add(in);
79 | }
80 |
81 | /**
82 | * Add constraint. If this clause is bottom, do nothing.
83 | * If the added constraint is violate current clause, this clause is set to be bottom.
84 | * @param in
85 | */
86 | public void addConstraint(Literal in){
87 | if(isBottom()){
88 | return;
89 | }
90 |
91 | for(Literal lit: literals){
92 | if(in.isIdEquals(lit)){
93 | if(!in.inField(lit)){
94 | setBottom(); //the clause is unsatisfied, set bottom
95 | return;
96 | }
97 |
98 | return; //else, if contains this constraint, return.
99 | }
100 | }
101 |
102 | literals.add(in);
103 | }
104 |
105 | /**
106 | * @param in
107 | * @return: True, if this clause is less equal than the input clause.
108 | */
109 | public boolean belongTo(Clause in) {
110 | if(in.isBottom() || isBottom()){
111 | if(isBottom())
112 | return true;
113 | return false;
114 | }
115 |
116 | List in_literals = in.getLiterals();
117 |
118 | for(Literal in_lit: in_literals){
119 | boolean contains = false;
120 | for(Literal lit: literals){
121 | if(in_lit.isIdEquals(lit)){
122 | if(in_lit.equals(lit)){
123 | contains = true;
124 | break;
125 | }else{
126 | return false;
127 | }
128 | }
129 | }
130 | if(!contains)
131 | return false;
132 | }
133 |
134 | return true;
135 | }
136 |
137 | public List getLiterals() {
138 | return literals;
139 | }
140 |
141 | public void setLiterals(List literals) {
142 | this.literals = literals;
143 | }
144 |
145 | public List copyLiterals(){
146 | if(isBottom())
147 | return null;
148 |
149 | List re_literals = new ArrayList();
150 | for(Literal lit: literals){
151 | re_literals.add(lit.copy());
152 | }
153 |
154 | return re_literals;
155 | }
156 |
157 | public Clause copy(){
158 | Clause re = new Clause();
159 | re.setLiterals(copyLiterals());
160 |
161 | return re;
162 | }
163 |
164 | public void setTop(){
165 | if(literals == null){
166 | literals = new ArrayList();
167 | }else{
168 | literals.clear();
169 | }
170 | }
171 |
172 | public void setBottom(){
173 | literals = null;
174 | }
175 |
176 | public boolean isTop(){
177 | if(literals==null)
178 | return false;
179 | return literals.size()==0;
180 | }
181 |
182 | public boolean isBottom(){
183 | return literals==null;
184 | }
185 |
186 | @Override
187 | public String toString() {
188 | if(isTop())
189 | return "T";
190 | if(isBottom())
191 | return "NULL";
192 |
193 | String buffer = "";
194 | for(Literal lit: literals){
195 | buffer+=lit.toString()+" & ";
196 | }
197 | int endIndex = buffer.length()-3;
198 |
199 | buffer = buffer.substring(0, endIndex);
200 |
201 | return buffer;
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/ESPProperty/ESPState.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP.ESPProperty;
2 |
3 | import java.util.Hashtable;
4 | import java.util.Set;
5 |
6 | import stp.Expr;
7 |
8 | import cn.edu.sjtu.jllvm.ESP.IState;
9 |
10 |
11 | /**
12 | * @author liuhao 2011-12-30
13 | * This class is used to store multi target id's SymbolicState.
14 | * For exmaple, the Symbolicstates of lock1 and lock2 are stored in info.
15 | */
16 | public class ESPState implements IState{
17 | Hashtable info;
18 |
19 | @Override
20 | public boolean belongTo(IState in) {
21 | ISymbolicState ss = getSymbolicState();
22 | ISymbolicState ss_in = ((ESPState)in).getSymbolicState();
23 |
24 | return ss.belongTo(ss_in);
25 | }
26 |
27 | @Override
28 | public void union(IState in) {
29 |
30 | ISymbolicState ss = getSymbolicState();
31 | ISymbolicState ss_in = ((ESPState)in).getSymbolicState();
32 |
33 | ss.union(ss_in);
34 | }
35 |
36 | @Override
37 | public boolean isBottom() {
38 | if(info == null)
39 | return true;
40 |
41 | return getSymbolicState().isBottom();
42 | }
43 |
44 | /**
45 | * add a constraint to current state. if this state is unsatisfied, set it to bottom
46 | * @param constraint:
47 | */
48 | public void addConstraint(String constraint){
49 | ISymbolicState ss = info.get(ESPTransitionSystem.currentStateId);
50 |
51 | ss.addConstraint(constraint);
52 | }
53 |
54 | /**
55 | * add a constraint to current state. if this state is unsatisfied, set it to bottom
56 | * @param constraint:
57 | */
58 | public void addConstraint(Expr constraint){
59 | ISymbolicState ss = info.get(ESPTransitionSystem.currentStateId);
60 |
61 | ss.addConstraint(constraint);
62 | }
63 |
64 | /**
65 | * set info
66 | * @param info
67 | */
68 | public void setInfo(Hashtable info){
69 | this.info = info;
70 | }
71 |
72 | /**
73 | * get current symbolic state.
74 | * if current symbolic state is null, return a bottom symbolic state
75 | * @return
76 | */
77 | public ISymbolicState getSymbolicState(){
78 | String curId = ESPTransitionSystem.currentStateId;
79 | ISymbolicState ss = info.get(curId);
80 |
81 | if(ss==null){
82 | ss = ESPStateFactory.createBottomSymbolicState();
83 | info.put(curId, ss);
84 | }
85 | return ss;
86 | }
87 |
88 | /**
89 | * set current symbolic state
90 | * @param ss
91 | */
92 | public void setSymbolicState(ISymbolicState ss){
93 | info.put(ESPTransitionSystem.currentStateId, ss);
94 | }
95 |
96 | /**
97 | * handle state change
98 | * @param fName: function that is going to change current state
99 | */
100 | public void transit(String fName){
101 | String curId = ESPTransitionSystem.currentStateId;
102 | ISymbolicState ss = info.get(curId);
103 |
104 | ss.transit(fName);
105 | }
106 |
107 | @Override
108 | public IState copy(){
109 | ESPState temp = new ESPState();
110 | Hashtable temp_info = new Hashtable();
111 |
112 | String currentId = ESPTransitionSystem.currentStateId;
113 | ISymbolicState ss = info.get(currentId);
114 | if(ss == null)
115 | return temp;
116 |
117 | ISymbolicState temp_ss= ss.copy();
118 |
119 | temp_info.put(currentId, temp_ss);
120 | temp.setInfo(temp_info);
121 |
122 | return temp;
123 | }
124 |
125 | @Override
126 | public String toString(){
127 | StringBuffer buf = new StringBuffer();
128 | Set keys = info.keySet();
129 | if(keys.size() == 0){
130 | buf.append(" & ");
131 | }
132 |
133 | for(String key: keys){
134 | buf.append(key+" : \n");
135 | buf.append(getStateString(key));
136 | }
137 |
138 | return buf.toString();
139 | }
140 |
141 | public String getStateString(String stateId){
142 | String re = "";
143 | ISymbolicState ss = info.get(stateId);
144 | if(ss==null){
145 | re+=" & ";
146 | }else{
147 | if(ss.isBottom())
148 | re+=" & ";
149 | else
150 | re+=ss.toString();
151 | }
152 | return re;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/ESPProperty/ESPStateFactory.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP.ESPProperty;
2 |
3 | import java.util.Hashtable;
4 |
5 | import cn.edu.sjtu.jllvm.ESP.IStateFactory;
6 | import cn.edu.sjtu.jllvm.ESP.IState;
7 | import cn.edu.sjtu.jllvm.ESP.IWorklist;
8 | import cn.edu.sjtu.jllvm.ESP.Worklist;
9 |
10 |
11 | public class ESPStateFactory implements IStateFactory{
12 |
13 | public static ISymbolicState createBottomSymbolicState(){
14 | return new SymbolicState();
15 | }
16 |
17 | public static ESPState createTopState(){
18 | Hashtable info = new Hashtable();
19 | ISymbolicState ss = new SymbolicState();
20 | ss.getExecutionState(0).setTop();
21 | info.put(ESPTransitionSystem.currentStateId, ss);
22 |
23 | ESPState state=new ESPState();
24 | state.setInfo(info);
25 |
26 | return state;
27 | }
28 |
29 | public static ESPState createBottomState(){
30 | Hashtable info = new Hashtable();
31 | ISymbolicState ss = new SymbolicState();
32 | info.put(ESPTransitionSystem.currentStateId, ss);
33 |
34 | ESPState state=new ESPState();
35 | state.setInfo(info);
36 |
37 | return state;
38 | }
39 |
40 | @Override
41 | public IWorklist createWorklist() {
42 | return new Worklist();
43 | }
44 |
45 | @Override
46 | public IState createInitBottomState() {
47 | return ESPStateFactory.createBottomState();
48 | }
49 |
50 | @Override
51 | public IState createInitTopState() {
52 | return ESPStateFactory.createTopState();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/ESPProperty/ESPTransitionSystem.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP.ESPProperty;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashSet;
5 | import java.util.Hashtable;
6 | import java.util.List;
7 | import java.util.Set;
8 |
9 | import stp.Expr;
10 | import cn.edu.sjtu.jllvm.ESP.CFGUtils;
11 | import cn.edu.sjtu.jllvm.ESP.ILocation;
12 | import cn.edu.sjtu.jllvm.ESP.IState;
13 | import cn.edu.sjtu.jllvm.ESP.ITransitionSystem;
14 | import cn.edu.sjtu.jllvm.ESP.IWorklist;
15 | import cn.edu.sjtu.jllvm.ESP.SolverUtil;
16 | import cn.edu.sjtu.jllvm.ESP.Worklist;
17 | import cn.edu.sjtu.jllvm.VMCore.BasicBlock;
18 | import cn.edu.sjtu.jllvm.VMCore.Module;
19 | import cn.edu.sjtu.jllvm.VMCore.Constants.Function;
20 | import cn.edu.sjtu.jllvm.VMCore.Instructions.Instruction;
21 | import cn.edu.sjtu.jllvm.test.ESPArguments;
22 |
23 | /**
24 | * @author liuhao 2011-12-19
25 | * A system contain a CFG
26 | */
27 | public class ESPTransitionSystem implements ITransitionSystem {
28 | private Hashtable reach;
29 |
30 | private Module prog;
31 |
32 | private List entryList;
33 | private Worklist worklist;
34 |
35 | //control multi stateId(multi mutex situation)
36 | private ILocation lastEntry;
37 | public static String currentStateId = "";
38 | private List toVisitedStateIds;
39 |
40 | //store lock information generated by esp analysis
41 | private String lockStateInfo = "";
42 |
43 | public static boolean USE_SOLVER = false;
44 |
45 | public static final int NOT_EXECUTIONSTATE = 0;
46 | public static final int ALL_INFO = 1;
47 |
48 | public static int DEBUG_INFO = ALL_INFO;
49 |
50 | public static int switch_label = 1;
51 |
52 | //Run all functions
53 | public ESPTransitionSystem(Module prog){
54 | this.prog = prog;
55 |
56 | reach = new Hashtable();
57 |
58 | entryList = new ArrayList();
59 | for(Function f: prog.getFunctions()){
60 | entryList.add(f.getEntry().getFirst());
61 | }
62 |
63 | toVisitedStateIds = new ArrayList();
64 | }
65 |
66 | //Only run the special input functions
67 | public ESPTransitionSystem(Module prog, String[] functionNames){
68 | this.prog = prog;
69 |
70 | reach = new Hashtable();
71 |
72 | entryList = new ArrayList();
73 | for(String fn: functionNames){
74 | Function f = prog.getFunction(fn);
75 | if(f == null)
76 | continue;
77 |
78 | entryList.add(f.getEntry().getFirst());
79 | }
80 |
81 | toVisitedStateIds = new ArrayList();
82 | }
83 |
84 | @Override
85 | public void setWorklist(IWorklist worklist) {
86 | this.worklist = (Worklist)worklist;
87 | }
88 |
89 | @Override
90 | public void setAllLocationStateBottom() {
91 | for(Function f: prog.getFunctions()){
92 | for(BasicBlock bb: f.getBasicBlocks()){
93 | for(Instruction inst: bb.getInstructions()){
94 | reach.put(inst, ESPStateFactory.createBottomState());
95 | }
96 | }
97 | }
98 | }
99 |
100 | @Override
101 | public Hashtable getAllLocationStates() {
102 | return reach;
103 | }
104 |
105 | @Override
106 | public boolean hasEntry() {
107 | return entryList.size()!=0;
108 | }
109 |
110 | @Override
111 | public ILocation nextEntry() {
112 | if(toVisitedStateIds.size()!=0){
113 | ESPTransitionSystem.currentStateId = toVisitedStateIds.remove(0);
114 |
115 | return lastEntry;
116 | }
117 |
118 | if(!hasEntry())
119 | return null;
120 |
121 | ILocation entry = entryList.remove(0);
122 | Function toVisitedFunction = ((Instruction)entry).getFunction();
123 | toVisitedStateIds = parseFunctionForStateIds(toVisitedFunction);
124 |
125 | if(toVisitedStateIds.size()==0){
126 | return nextEntry();
127 | }else{
128 | ESPTransitionSystem.currentStateId = toVisitedStateIds.remove(0);
129 | }
130 |
131 | if(ESPArguments.DEBUG_CURRENT_FUNCTION){
132 | System.out.println("Solving "+toVisitedFunction.getFunctionName()+" ...");
133 | }
134 |
135 | lastEntry = entry;
136 |
137 | lockStateInfo+="#"+((Instruction)lastEntry).getFunction().getFunctionName()+":\n";
138 | return entry;
139 | }
140 |
141 | /* (non-Javadoc)
142 | * @see cn.edu.sjtu.jllvm.ModelChecking.ITransitionSystem#getSuccessors(cn.edu.sjtu.jllvm.ModelChecking.ILocation)
143 | */
144 | @Override
145 | public List getSuccessors(ILocation loc) {
146 | List succs = new ArrayList();
147 |
148 | Instruction inst = (Instruction)loc;
149 | Instruction next = inst.getNextInst();
150 | if(next!=null){ //inst is not TerminatorInstruction
151 | succs.add(next);
152 | }else{ //inst is the terminator of this basic block
153 | List bbs = inst.getParent().getSuccessors();
154 |
155 | for(BasicBlock bb:bbs){
156 | succs.add(bb.getFirst());
157 | }
158 | }
159 |
160 | return succs;
161 | }
162 |
163 | /**
164 | * Separately handling Branch, Merge, Call and other edges
165 | */
166 | @Override
167 | public IState getPost(ILocation src, ILocation dest) {
168 | Instruction src_inst = (Instruction)src;
169 | Instruction dest_inst = (Instruction)dest;
170 |
171 | ESPState src_state = (ESPState)reach.get(src_inst);
172 | ESPState post_state = (ESPState)src_state.copy(); //changed state
173 |
174 | if(src_inst.isMerge()){
175 | if(adjustWorklist()){
176 | post_state = ESPStateFactory.createBottomState();
177 |
178 | return null;
179 | }
180 | }
181 |
182 | if(src_inst.isConditionalBranch()){ //a branch
183 | if(USE_SOLVER){
184 | List exprList = CFGUtils.parseSTPExprs(src_inst);
185 |
186 |
187 | String blockId = dest_inst.getParent().getBlockID();
188 | if(src_inst.getOperand(1).toString().equals(blockId)){ // true branch
189 | Expr stp_expr = null;
190 |
191 | if(exprList.size()>=2){
192 | Expr [] exprArray = new Expr[exprList.size()];
193 | exprList.toArray(exprArray);
194 | stp_expr = SolverUtil.vc.andExprN(exprArray);
195 | }else if (exprList.size()==1) {
196 | stp_expr = exprList.get(0);
197 | }else{
198 | System.out.println("Empty expr list: "+src_inst.toString());
199 | }
200 |
201 | post_state.addConstraint(stp_expr);
202 | }else{ // false branch
203 | Expr stp_expr = null;
204 |
205 | if(exprList.size()>=2){
206 | Expr [] exprArray = new Expr[exprList.size()];
207 | exprList.toArray(exprArray);
208 | stp_expr = SolverUtil.vc.andExprN(exprArray);
209 | }else if (exprList.size()==1) {
210 | stp_expr = exprList.get(0);
211 | }else{
212 | System.out.println("Empty expr list: "+src_inst.toString());
213 | }
214 |
215 | post_state.addConstraint(SolverUtil.vc.notExpr(stp_expr));
216 | }
217 | }else{
218 | String constraint = CFGUtils.parseVariableString(src_inst, 0);
219 |
220 | String blockId = dest_inst.getParent().getBlockID();
221 | if(src_inst.getOperand(1).toString().equals(blockId)){ // true branch
222 | post_state.addConstraint(constraint);
223 |
224 | }else{ // false branch
225 | post_state.addConstraint("!"+constraint);
226 | }
227 | }
228 | }else if(src_inst.isSwitch()){
229 | if(USE_SOLVER){
230 | List exprList = CFGUtils.parseSTPExprs(src_inst);
231 | Expr stp_expr = null;
232 |
233 | if(exprList.size()>=2){
234 | Expr [] exprArray = new Expr[exprList.size()];
235 | exprList.toArray(exprArray);
236 | stp_expr = SolverUtil.vc.andExprN(exprArray);
237 | }else if (exprList.size()==1) {
238 | stp_expr = exprList.get(0);
239 | }else{
240 | //System.out.println("Empty expr list:"+src_inst.toString());
241 | }
242 |
243 | int numOperand = src_inst.getNumOperands();
244 | String blockId = dest_inst.getParent().getBlockID();
245 | if(!blockId.equals(src_inst.getOperand(switch_label).toString())){
246 |
247 | switch_label = 1;
248 | if(!blockId.equals(src_inst.getOperand(switch_label).toString())){
249 | System.out.println("SWITCH_LABEL ERROR!");
250 | }
251 | }
252 |
253 | if(switch_label==1){
254 | Expr swi = CFGUtils.getOperandExpr(src_inst, 0);
255 | for(int j=2; j=numOperand){
280 | switch_label=1;
281 | }
282 | }else{
283 | int numOperand = src_inst.getNumOperands();
284 | String constraint_id = CFGUtils.parseVariableString(src_inst, 0);
285 |
286 | String blockId = dest_inst.getParent().getBlockID();
287 | for(int i = 2; i=numOperand){
318 | switch_label=1;
319 | }
320 |
321 | }
322 | }
323 |
324 | if(src_inst.isCall()){
325 | String fName = src_inst.getOperand(0).toString();
326 | if(isRelatedFunction(fName)){
327 | String mutex = CFGUtils.parseVariableString(src_inst, 1);
328 | String curId = ESPTransitionSystem.currentStateId;
329 |
330 | if(curId.equals(mutex)){
331 | lockStateInfo += src_state.getStateString(mutex);
332 | lockStateInfo += " ";
333 | if(fName.endsWith("unlock")){
334 | lockStateInfo += "UNLOCK ";
335 | }else{
336 | lockStateInfo += "LOCK ";
337 | }
338 | lockStateInfo += mutex+" <- "+src_inst.toString() +"\n";
339 |
340 | src_state.transit(fName); // change state
341 |
342 | lockStateInfo += src_state.getStateString(mutex)+"\n";
343 |
344 | post_state = (ESPState)src_state.copy();
345 | }
346 | }else{ //interprocedural
347 |
348 | }
349 | }
350 |
351 | return post_state;
352 | }
353 |
354 | /**
355 | * adjust worklist ,make all merge nodes in the tail of the worklist.
356 | * If the worklist isn't changed, it means that there are only mearge nodes in the worklist
357 | * else the worklist has node that is not merge node and make it be the first of the list.
358 | * @return true if worklist is changed, false if worklist isn't changed
359 | */
360 | public boolean adjustWorklist(){
361 | List nodes = worklist.getNodes();
362 | List states = worklist.getStates();
363 | boolean tag = false;
364 | for(int i=0; i parseFunctionForStateIds(Function f){
388 | Set set = new HashSet();
389 | for(BasicBlock b: f.getBasicBlocks()){
390 | for(Instruction i: b.getInstructions()){
391 | if(i.isCall() && isRelatedFunction(i.getOperand(0).toString())){
392 | String mutex = CFGUtils.parseVariableString(i, 1);
393 | set.add(mutex);
394 | }
395 | }
396 | }
397 |
398 | return new ArrayList(set);
399 | }
400 |
401 | /**
402 | * print debug info
403 | */
404 | @Override
405 | public void print(){
406 |
407 | if(ESPArguments.DEBUG_ALL_INFO){
408 | for(Function f: prog.getFunctions()){
409 | for(BasicBlock bb: f.getBasicBlocks()){
410 | for(Instruction inst: bb.getInstructions()){
411 | IState istate = reach.get(inst);
412 |
413 | if(ESPArguments.DEBUG_INFO_TO_FILE){
414 | ESPArguments.fileWriter.println(inst.toString()+"\n"+istate.toString());
415 | }else{
416 | System.out.println(inst.toString()+"\n"+istate.toString());
417 | }
418 | }
419 | }
420 | }
421 | }
422 |
423 | if(ESPArguments.DEBUG_LOCK_INFO){
424 | String lockInfos[] = lockStateInfo.split("#");
425 |
426 | for(String info: lockInfos){
427 | if(info.length()>40){
428 | if(ESPArguments.DEBUG_INFO_TO_FILE){
429 | ESPArguments.fileWriter.println("# "+info);
430 | }else{
431 | System.out.println(info+"\n");
432 | }
433 | }
434 | }
435 | }
436 | }
437 |
438 | @Override
439 | public String getInfo(){
440 | return lockStateInfo;
441 | }
442 | }
443 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/ESPProperty/ExecutionState.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP.ESPProperty;
2 |
3 | import stp.Expr;
4 |
5 | public class ExecutionState implements IExecutionState {
6 | Clause constraints;
7 |
8 | public ExecutionState(){
9 | constraints = new Clause();
10 | }
11 |
12 | public void setConstraints(Clause constraints) {
13 | this.constraints = constraints;
14 | }
15 |
16 | public void addConstraint(Literal lit) {
17 | constraints.addConstraint(lit);
18 | }
19 |
20 | @Override
21 | public void addConstraint(String c) {
22 | if(this.isBottom())
23 | return;
24 |
25 | Literal lit = null;
26 | if(c.startsWith("!")){
27 | lit = new Literal(c.substring(1), Literal.NOT);
28 | }else{
29 | lit = new Literal(c, Literal.IS);
30 | }
31 |
32 | addConstraint(lit);
33 | }
34 |
35 | @Override
36 | public Clause getConstraints() {
37 | return constraints;
38 | }
39 |
40 | @Override
41 | public void union(IExecutionState in) {
42 | this.constraints.union(in.getConstraints());
43 | }
44 |
45 | @Override
46 | public boolean belongTo(IExecutionState in){
47 | return this.constraints.belongTo(in.getConstraints());
48 | }
49 |
50 | @Override
51 | public IExecutionState copy() {
52 | ExecutionState re = new ExecutionState();
53 |
54 | re.setConstraints(constraints.copy());
55 |
56 | return re;
57 | }
58 |
59 | public boolean equals(IExecutionState src) {
60 | return constraints.equals(src.getConstraints());
61 | }
62 |
63 | @Override
64 | public String toString() {
65 | String buffer = "[ ";
66 |
67 | buffer+=constraints.toString();
68 | return buffer+" ]";
69 | }
70 |
71 | @Override
72 | public boolean isTop() {
73 | return constraints.isTop();
74 | }
75 |
76 | @Override
77 | public boolean isBottom() {
78 | return constraints.isBottom();
79 | }
80 |
81 | @Override
82 | public void setBottom() {
83 | constraints.setBottom();
84 | }
85 |
86 | @Override
87 | public void setTop() {
88 | constraints.setTop();
89 | }
90 |
91 | @Override
92 | public void addConstraint(Expr constraint) {
93 | // TODO Auto-generated method stub
94 |
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/ESPProperty/ExecutionState_STP.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP.ESPProperty;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import cn.edu.sjtu.jllvm.ESP.SolverUtil;
7 | import stp.Expr;
8 | import stp.VC;
9 |
10 | public class ExecutionState_STP implements IExecutionState {
11 | //OR relationship between each clause, AND relationship in clause.
12 | List clauses;
13 | VC vc = SolverUtil.vc;
14 |
15 | public ExecutionState_STP(){
16 | // clauses = new ArrayList();
17 | // setBottom();
18 | }
19 |
20 | @Override
21 | public void addConstraint(String constraint) {
22 | // TODO Auto-generated method stub
23 |
24 | }
25 |
26 | @Override
27 | public Clause getConstraints() {
28 | // TODO Auto-generated method stub
29 | return null;
30 | }
31 |
32 | @Override
33 | public boolean belongTo(IExecutionState in) {
34 | if(in.isTop())
35 | return true;
36 | if(in.isBottom()){
37 | if(this.isBottom())
38 | return true;
39 | return false;
40 | }
41 | ExecutionState_STP in_stp = (ExecutionState_STP)in;
42 |
43 | vc.push();
44 | vc.assertFormula(getTotalExpr());
45 | int result = vc.query(in_stp.getTotalExpr());
46 | vc.pop();
47 |
48 | return result == 1;
49 | }
50 |
51 | public void setClauses(List clauses){
52 | this.clauses = clauses;
53 | }
54 |
55 | public List getClauses(){
56 | return clauses;
57 | }
58 |
59 | public Expr getTotalExpr(){
60 | if(isTop())
61 | return vc.trueExpr();
62 | if(isBottom())
63 | return vc.falseExpr();
64 |
65 | if(clauses.size()==1){
66 | return clauses.get(0);
67 | }
68 |
69 | Expr[] exprArray = new Expr[clauses.size()];
70 | clauses.toArray(exprArray);
71 | Expr total = vc.andExprN(exprArray);
72 |
73 | return total;
74 | }
75 |
76 | @Override
77 | public void union(IExecutionState src) {
78 | if(src.isBottom()){
79 | return;
80 | }
81 |
82 | if(src.isTop()){
83 | setTop();
84 | return;
85 | }
86 |
87 | if(isBottom()){
88 | setClauses(((ExecutionState_STP)src.copy()).getClauses());
89 | return;
90 | }
91 |
92 | if(isTop()){
93 | return;
94 | }
95 |
96 | ExecutionState_STP src_stp = (ExecutionState_STP)src;
97 | Expr expr1 = getTotalExpr();
98 | Expr expr2 = src_stp.getTotalExpr();
99 |
100 | int compare = SolverUtil.compare(expr1, expr2);
101 | if(compare == SolverUtil.EQUAL){
102 | return;
103 | }else if(compare == SolverUtil.LESSEQUAL){
104 | setClauses(src_stp.getClauses());
105 | }else if(compare == SolverUtil.GREATEQUAL){
106 | return;
107 | }else if(compare == SolverUtil.NOT){
108 | setTop();
109 | }else{
110 | List o_clauses = src_stp.getClauses();
111 | for(int i=0; i clause, List o_clause){
141 | for(int i=0; i cs = new ArrayList();
178 | for(Expr expr: clauses){
179 | cs.add(expr);
180 | }
181 |
182 | re.setClauses(cs);
183 | }
184 |
185 | return re;
186 | }
187 |
188 | public void setConstraints(List clauses){
189 | // THIS.CLAUSES = CLAUSES;
190 | }
191 |
192 | @Override
193 | public boolean isTop() {
194 | if(clauses!=null && clauses.isEmpty())
195 | return true;
196 | return false;
197 | }
198 |
199 | @Override
200 | public boolean isBottom() {
201 | if(clauses == null)
202 | return true;
203 | return false;
204 | }
205 |
206 | @Override
207 | public void setTop() {
208 | clauses = new ArrayList();
209 | }
210 |
211 | @Override
212 | public void setBottom() {
213 | clauses = null;
214 | }
215 |
216 | @Override
217 | public void addConstraint(Expr expr) {
218 | if(expr == null){
219 | return;
220 | }
221 |
222 | if(isBottom())
223 | return;
224 | if(isTop()){
225 | clauses.add(expr);
226 | return;
227 | }
228 |
229 | boolean isbreak = false;
230 | for(int i = 0; i error;
29 |
30 | es[0].setBottom();
31 | es[0].union(es[1]); //locked -> uinit;
32 | es[1].setBottom();
33 | }else{
34 | es[2].union(es[1]); //locked -> error;
35 |
36 | es[1].setBottom();
37 | es[1].union(es[0]); //unit -> locked;
38 | es[0].setBottom();
39 | }
40 | }
41 |
42 | @Override
43 | public ISymbolicState copy() {
44 | SymbolicState copy = new SymbolicState();
45 |
46 | IExecutionState[] temp_es = new IExecutionState[es.length];
47 | for(int i=0; i getAllLocationStates();
31 |
32 | /**
33 | * @return: true if has next entry node, otherwise false.
34 | */
35 | public boolean hasEntry();
36 |
37 | /**
38 | * get an entry node which is to be added in worklist
39 | * @return: next entry node in this system, if no next node, return null
40 | */
41 | public ILocation nextEntry();
42 |
43 | /**
44 | * @param loc
45 | * @return loc's successors. if no successor, return an empty List;
46 | */
47 | public List getSuccessors(ILocation loc);
48 |
49 | /**
50 | * return the changed state need to be added to dest location.
51 | * @param src: the entry node of an edge.
52 | * @param dest: the dest node of an edge.
53 | * @return: the changed state need to be update in dest node.
54 | */
55 | public IState getPost(ILocation src, ILocation dest);
56 |
57 | /**
58 | * print out debug info in console or output file
59 | */
60 | public void print();
61 |
62 | public String getInfo();
63 | }
64 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/IWorklist.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP;
2 |
3 | /**
4 | * @author liuhao 2011-12-19
5 | * A workList is a set of
6 | */
7 | public interface IWorklist {
8 | /**
9 | * @return: true if the list is empty, otherwise return false.
10 | */
11 | public boolean isEmpty();
12 |
13 | /**
14 | * remove a node and return it.
15 | * @return: the node in list. if no next node, return null
16 | */
17 | public WorkPair remove();
18 |
19 | public void removeAll();
20 |
21 | /**
22 | * add a node in list
23 | * @param loc: location
24 | * @param state: changed state of the location
25 | */
26 | public void add(ILocation loc, IState state);
27 | }
28 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/Solver.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP;
2 | import stp.*;
3 |
4 | /**
5 | *
6 | * @author tm
7 | * The interface of STP solver
8 | */
9 | public interface Solver {
10 | //boolean expressions
11 | public Expr andExpr(Expr t1, Expr t2);
12 | public Expr orExpr(Expr t1, Expr t2);
13 | public Expr notExpr(Expr t1);
14 |
15 | //bit vector operations
16 | public Expr plusExpr(Expr t1, Expr t2);
17 | public Expr multExpr(Expr t1, Expr t2);
18 | public Expr subExpr(Expr t1, Expr t2);
19 | public Expr minusExpr(Expr t1, Expr t2);
20 | public Expr divExpr(Expr t1, Expr t2);
21 | public Expr modExpr(Expr t1, Expr t2);
22 |
23 | //equality
24 | public Expr eqExpr(Expr t1);
25 | //less than
26 | public Expr ltExpr(Expr t1);
27 | //greater than
28 | public Expr gtExpr(Expr t1);
29 | //less than or equal to
30 | public Expr leExpr(Expr t1);
31 | //greater than or equal to
32 |
33 | public Expr bvAndExpr(Expr t1, Expr t2);
34 | public Expr bvOrExpr(Expr t1, Expr t2);
35 | public Expr bvNotExpr(Expr t1);
36 | }
37 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/SolverUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP;
2 |
3 |
4 | import java.util.Hashtable;
5 | import java.util.List;
6 |
7 | import cn.edu.sjtu.jllvm.VMCore.Constants.SimpleConstantValue;
8 |
9 | import stp.Expr;
10 | import stp.VC;
11 |
12 | public class SolverUtil {
13 | public static VC vc = new VC();
14 | public static Hashtable exprTable = new Hashtable();
15 | public static Expr NULL = vc.varExpr("null", vc.bv32Type());
16 | public static Expr TRUE = vc.varExpr("true", vc.bv32Type());
17 | public static Expr FALSE = vc.varExpr("false", vc.bv32Type());
18 | public static Expr UNDEF = vc.varExpr("undef", vc.bv32Type());
19 |
20 | public static final int EQUAL = 1, LESSEQUAL = 2, GREATEQUAL = 3, NOT = 4, NOTCONTAIN = 5;
21 |
22 | public SolverUtil(){
23 |
24 | }
25 |
26 | public static Expr getExprOfVariable(String name){
27 | if(name == null){
28 | return UNDEF;
29 | }
30 |
31 | Expr expr = exprTable.get(name);
32 | if(expr == null){
33 | expr = vc.varExpr(name, vc.bv32Type());
34 | exprTable.put(name, expr);
35 | }
36 |
37 | return expr;
38 | }
39 |
40 | public static Expr getExprOfSimpleValue(SimpleConstantValue value){
41 | Expr expr = null;
42 |
43 | if(value.isInt()){
44 | try{
45 | expr = vc.bv32ConstExprFromInt(Integer.parseInt(value.toString()));
46 | }catch (Exception e) {
47 | expr = vc.bv32ConstExprFromInt(Integer.parseInt(value.toString().substring(6)));
48 | }
49 | }else if(value.isNullValue()){
50 | expr = SolverUtil.NULL;
51 | }else if(value.isBoolean()){
52 | if(value.toString().equals("true"))
53 | expr = SolverUtil.TRUE;
54 | else
55 | expr = SolverUtil.FALSE;
56 | }else{
57 | System.out.println("Unhandled constant value");
58 | expr = SolverUtil.UNDEF;
59 | }
60 |
61 | return expr;
62 | }
63 |
64 | public static Expr createExprOfVariable(String name){
65 | Expr expr = vc.varExpr("nresp1", vc.bv32Type());
66 | exprTable.put(name, expr);
67 |
68 | return expr;
69 | }
70 |
71 | public static boolean sameExpr(Expr e1, Expr e2){
72 | if(e1.toString().equals(e2.toString()))
73 | return true;
74 |
75 | int count = 0;
76 | vc.push();
77 | vc.assertFormula(e1);
78 | if(vc.query(e2) == 1){
79 | count++;
80 | }
81 | vc.pop();
82 |
83 | vc.push();
84 | vc.assertFormula(e2);
85 | if(vc.query(e1) == 1){
86 | count++;
87 | }
88 | vc.pop();
89 |
90 | if(count == 2)
91 | return true;
92 | else
93 | return false;
94 | }
95 |
96 | /**
97 | *
98 | * @param e1
99 | * @param e2
100 | * @return 1 e1 == e2; 2 e1 > e2; 3 e1 < e2; 4 other
101 | */
102 | public static int compare(Expr e1, Expr e2){
103 | boolean e1_le_e2 = false;
104 | boolean e2_le_e1 = false;
105 | vc.push();
106 | vc.assertFormula(e1);
107 | if(vc.query(e2)==1){
108 | //e1<=e2
109 | e1_le_e2 = true;
110 | }
111 | vc.pop();
112 |
113 | vc.push();
114 | vc.assertFormula(e2);
115 | if(vc.query(e1)==1){
116 | //e2<=e1
117 | e2_le_e1 = true;
118 | }
119 | vc.pop();
120 |
121 | if(e1_le_e2){
122 | if(e2_le_e1){
123 | return SolverUtil.EQUAL;
124 | }else{
125 | return SolverUtil.LESSEQUAL;
126 | }
127 | }else{
128 | if(e2_le_e1){
129 | return SolverUtil.GREATEQUAL;
130 | }else{
131 | Expr not_e1 = vc.notExpr(e1);
132 | int count = 0;
133 | vc.push();
134 | vc.assertFormula(not_e1);
135 | if(vc.query(e2)==1){
136 | count++;
137 | }
138 | vc.pop();
139 | vc.push();
140 | vc.assertFormula(e2);
141 | if(vc.query(not_e1)==1){
142 | count++;
143 | }
144 | vc.pop();
145 | if(count == 2){ // not_e1 == e2
146 | return SolverUtil.NOT;
147 | }else{
148 | return SolverUtil.NOTCONTAIN;
149 | }
150 | }
151 | }
152 | }
153 |
154 | public static Expr andExprN(List clauses){
155 | return vc.andExprN((Expr[])clauses.toArray());
156 | }
157 |
158 | public static boolean andTrue(Expr e1, Expr e2){
159 | vc.push();
160 | vc.assertFormula(e1);
161 | int result = vc.query(e2);
162 | vc.pop();
163 |
164 | if(result == 1)
165 | return true;
166 |
167 | vc.push();
168 | vc.assertFormula(e2);
169 | result = vc.query(e1);
170 | vc.pop();
171 |
172 | if(result == 1)
173 | return true;
174 |
175 | return false;
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/WorkPair.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP;
2 |
3 | /**
4 | * @author liuhao 2011-12-30
5 | * This class is used to store a node in worklist. It contains a location and a state of that location.
6 | */
7 | public class WorkPair {
8 | private ILocation location;
9 | private IState state;
10 |
11 | public WorkPair(ILocation loc, IState s){
12 | location = loc;
13 | state = s;
14 | }
15 |
16 | public ILocation getLocation(){
17 | return location;
18 | }
19 |
20 | public IState getState(){
21 | return state;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/ESP/Worklist.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.ESP;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import cn.edu.sjtu.jllvm.VMCore.Instructions.Instruction;
7 |
8 | public class Worklist implements IWorklist {
9 | List nodes;
10 | List states;
11 |
12 | public Worklist(){
13 | nodes = new ArrayList();
14 | states = new ArrayList();
15 | }
16 |
17 | @Override
18 | public boolean isEmpty() {
19 | return nodes.size()==0;
20 | }
21 |
22 | @Override
23 | public WorkPair remove() {
24 | if(isEmpty())
25 | return null;
26 | return new WorkPair(nodes.remove(0),states.remove(0));
27 | }
28 |
29 | @Override
30 | public void add(ILocation loc, IState state) {
31 | if(nodes.contains(loc)){
32 | int i = nodes.indexOf(loc);
33 | IState is = states.get(i);
34 |
35 | is.union(state);
36 | }else{
37 | nodes.add((Instruction)loc);
38 | states.add(state);
39 | }
40 | }
41 |
42 | @Override
43 | public void removeAll(){
44 | nodes.clear();
45 | states.clear();
46 | }
47 |
48 | public List getNodes() {
49 | return nodes;
50 | }
51 |
52 | public List getStates() {
53 | return states;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/GUI/ESP_GUI.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.GUI;
2 |
3 | import java.awt.event.ActionEvent;
4 | import java.awt.event.ActionListener;
5 | import java.io.BufferedInputStream;
6 | import java.io.File;
7 | import java.io.FileInputStream;
8 | import java.io.FileWriter;
9 | import java.io.PrintWriter;
10 |
11 | import javax.swing.GroupLayout;
12 | import javax.swing.JCheckBoxMenuItem;
13 | import javax.swing.JComponent;
14 | import javax.swing.JFileChooser;
15 | import javax.swing.JLabel;
16 | import javax.swing.JMenu;
17 | import javax.swing.JMenuBar;
18 | import javax.swing.JMenuItem;
19 | import javax.swing.JScrollPane;
20 | import javax.swing.JTabbedPane;
21 | import javax.swing.JTextArea;
22 |
23 | import javax.swing.WindowConstants;
24 | import javax.swing.event.ChangeEvent;
25 | import javax.swing.event.ChangeListener;
26 | import javax.swing.SwingUtilities;
27 | import javax.swing.filechooser.FileFilter;
28 |
29 | import cn.edu.sjtu.jllvm.ESP.ESPProperty.ESPTransitionSystem;
30 |
31 | /**
32 | * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI
33 | * Builder, which is free for non-commercial use. If Jigloo is being used
34 | * commercially (ie, by a corporation, company or business for any purpose
35 | * whatever) then you should purchase a license for each developer using Jigloo.
36 | * Please visit www.cloudgarden.com for details. Use of Jigloo implies
37 | * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN
38 | * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR
39 | * ANY CORPORATE OR COMMERCIAL PURPOSE.
40 | */
41 | public class ESP_GUI extends javax.swing.JFrame {
42 | private JMenuBar jMenuBar1;
43 | private JScrollPane jScrollPane1;
44 | private JScrollPane jScrollPane2;
45 | private JCheckBoxMenuItem jCheckBoxMenuItem2;
46 | private JLabel statusLabel;
47 | private JTextArea resultTextArea;
48 | private JTabbedPane jTabbedPane1;
49 | private JTextArea sourceFileArea;
50 | private JCheckBoxMenuItem jCheckBoxMenuItem1;
51 | private JMenu jMenu3;
52 | private JMenuItem jMenuItem3;
53 | private JMenu jMenu2;
54 | private JMenuItem jMenuItem2;
55 | private JMenuItem jMenuItem1;
56 | private JMenu jMenu1;
57 |
58 | /**
59 | * Auto-generated main method to display this JFrame
60 | */
61 | public static void main(String[] args) {
62 | SwingUtilities.invokeLater(new Runnable() {
63 | @Override
64 | public void run() {
65 | ESP_GUI inst = new ESP_GUI();
66 | inst.setLocationRelativeTo(null);
67 | inst.setVisible(true);
68 | }
69 | });
70 | }
71 |
72 | public ESP_GUI() {
73 | super();
74 | initGUI();
75 | }
76 |
77 | private void initGUI() {
78 | try {
79 | GroupLayout thisLayout = new GroupLayout(
80 | getContentPane());
81 | getContentPane().setLayout(thisLayout);
82 | setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
83 | {
84 | jTabbedPane1 = new JTabbedPane();
85 | {
86 | jScrollPane1 = new JScrollPane();
87 | jTabbedPane1.addTab("sourceFile", null, jScrollPane1, null);
88 | jScrollPane1.setPreferredSize(new java.awt.Dimension(715,
89 | 299));
90 | jScrollPane1.getHorizontalScrollBar().setEnabled(false);
91 | {
92 | sourceFileArea = new JTextArea();
93 | jScrollPane1.setViewportView(sourceFileArea);
94 | }
95 | }
96 | {
97 | jScrollPane2 = new JScrollPane();
98 | jTabbedPane1.addTab("result", null, jScrollPane2, null);
99 | jScrollPane2.setPreferredSize(new java.awt.Dimension(715,
100 | 299));
101 | jScrollPane2.getHorizontalScrollBar().setEnabled(false);
102 | {
103 | resultTextArea = new JTextArea();
104 | jScrollPane2.setViewportView(resultTextArea);
105 | }
106 | }
107 | }
108 | {
109 | statusLabel = new JLabel();
110 | statusLabel.setText("");
111 | }
112 | thisLayout.setVerticalGroup(thisLayout
113 | .createSequentialGroup()
114 | .addComponent(jTabbedPane1, 0, 311, Short.MAX_VALUE)
115 | .addComponent(statusLabel, GroupLayout.PREFERRED_SIZE, 21,
116 | GroupLayout.PREFERRED_SIZE));
117 | thisLayout.setHorizontalGroup(thisLayout
118 | .createParallelGroup()
119 | .addComponent(jTabbedPane1, GroupLayout.Alignment.LEADING,
120 | 0, 718, Short.MAX_VALUE)
121 | .addComponent(statusLabel, GroupLayout.Alignment.LEADING,
122 | 0, 718, Short.MAX_VALUE));
123 | {
124 | jMenuBar1 = new JMenuBar();
125 | setJMenuBar(jMenuBar1);
126 | {
127 | jMenu1 = new JMenu();
128 | jMenuBar1.add(jMenu1);
129 | jMenu1.setText("File");
130 | jMenu1.setMnemonic('F');
131 | {
132 | jMenuItem1 = new JMenuItem();
133 | jMenu1.add(jMenuItem1);
134 | jMenuItem1.setText("Open");
135 | jMenuItem1.setMnemonic('O');
136 | jMenuItem1.addActionListener(new ActionListener() {
137 | @Override
138 | public void actionPerformed(ActionEvent evt) {
139 | openFile(evt);
140 | }
141 | });
142 | }
143 | {
144 | jMenuItem2 = new JMenuItem();
145 | jMenu1.add(jMenuItem2);
146 | jMenuItem2.setText("Save");
147 | jMenuItem2.setMnemonic('S');
148 | jMenuItem2.addActionListener(new ActionListener() {
149 | @Override
150 | public void actionPerformed(ActionEvent evt) {
151 | saveResult(evt);
152 | }
153 | });
154 | }
155 | }
156 | {
157 | jMenu2 = new JMenu();
158 | jMenuBar1.add(jMenu2);
159 | jMenu2.setText("Run");
160 | jMenu2.setMnemonic('R');
161 | {
162 | jMenuItem3 = new JMenuItem();
163 | jMenu2.add(jMenuItem3);
164 | jMenuItem3.setText("ESP");
165 | jMenuItem3.setMnemonic('E');
166 | jMenuItem3.addActionListener(new ActionListener() {
167 | @Override
168 | public void actionPerformed(ActionEvent evt) {
169 | runESP(evt);
170 | }
171 | });
172 | }
173 | {
174 | jMenu3 = new JMenu();
175 | jMenu2.add(jMenu3);
176 | jMenu3.setText("Configure");
177 | {
178 | jCheckBoxMenuItem1 = new JCheckBoxMenuItem();
179 | jMenu3.add(jCheckBoxMenuItem1);
180 | jCheckBoxMenuItem1.setText("No Details");
181 | jCheckBoxMenuItem1.addChangeListener(new ChangeListener() {
182 | @Override
183 | public void stateChanged(ChangeEvent evt) {
184 | jCheckBoxMenuItem1StateChanged(evt);
185 | }
186 | });
187 | }
188 | // {
189 | // jCheckBoxMenuItem2 = new JCheckBoxMenuItem();
190 | // jMenu3.add(jCheckBoxMenuItem2);
191 | // jCheckBoxMenuItem2.setText("Use STP Solver");
192 | // jCheckBoxMenuItem2.addChangeListener(new ChangeListener() {
193 | // public void stateChanged(ChangeEvent evt) {
194 | // jCheckBoxMenuItem2StateChanged(evt);
195 | // }
196 | // });
197 | // }
198 | }
199 | }
200 | }
201 | pack();
202 | this.setSize(856, 529);
203 | } catch (Exception e) {
204 | // add your error handling code here
205 | e.printStackTrace();
206 | }
207 | }
208 |
209 | private void openFile(ActionEvent evt) {
210 | JFileChooser chooser = new JFileChooser();
211 | chooser.setCurrentDirectory(new File(UIUtil.fileFolder));
212 | FileFilter filter = new ExtensionFileFilter("llvm file",
213 | new String[] { "ll" });
214 | chooser.setFileFilter(filter);
215 | int returnVal = chooser.showOpenDialog(this);
216 | if (returnVal == JFileChooser.APPROVE_OPTION) {
217 | File file = chooser.getSelectedFile();
218 | if (file != null && file.exists()) {
219 | jTabbedPane1.setSelectedIndex(0);
220 | UIUtil.filePath = file.getAbsolutePath();
221 | UIUtil.fileFolder = file.getPath();
222 | statusLabel.setText(file.getAbsolutePath());
223 |
224 | try {
225 | byte[] buffer = new byte[(int) file.length()];
226 | BufferedInputStream f = new BufferedInputStream(
227 | new FileInputStream(file));
228 | f.read(buffer);
229 | sourceFileArea.setText(new String(buffer));
230 | f.close();
231 | } catch (Exception e) {
232 | e.printStackTrace();
233 | }
234 | }
235 | }
236 | }
237 |
238 | private void saveResult(ActionEvent evt) {
239 | jTabbedPane1.setSelectedIndex(1);
240 | JFileChooser chooser = new JFileChooser();
241 | chooser.setCurrentDirectory(new File(UIUtil.fileFolder));
242 | FileFilter filter = new ExtensionFileFilter("text file",
243 | new String[] { "txt" });
244 | chooser.setFileFilter(filter);
245 | int returnVal = chooser.showSaveDialog(this);
246 | if (returnVal == JFileChooser.APPROVE_OPTION) {
247 | File file = chooser.getSelectedFile();
248 | if (file != null) {
249 | if (!file.exists()) {
250 | try {
251 | file.createNewFile();
252 | } catch (Exception e) {
253 | e.printStackTrace();
254 | return;
255 | }
256 | }
257 |
258 | if (file.isDirectory())
259 | return;
260 |
261 | try {
262 | PrintWriter writer = new PrintWriter(new FileWriter(file));
263 | writer.print(resultTextArea.getText());
264 | writer.close();
265 | } catch (Exception e) {
266 | e.printStackTrace();
267 | }
268 | }
269 | }
270 | }
271 |
272 | private void runESP(ActionEvent evt) {
273 | //
274 | jTabbedPane1.setSelectedIndex(1);
275 | UIUtil rmc = new UIUtil();
276 | try {
277 | String result = rmc.run();
278 | String lockInfos[] = result.split("#");
279 |
280 | resultTextArea.setText("");
281 | for (String info : lockInfos) {
282 | if (info.length() > 40) {
283 | resultTextArea.append("# " + info);
284 | }
285 | }
286 | } catch (Exception e) {
287 | e.printStackTrace();
288 | }
289 | }
290 |
291 | private void jCheckBoxMenuItem1StateChanged(ChangeEvent evt) {
292 | //System.out.println("jCheckBoxMenuItem1.stateChanged, event="+evt);
293 | if(ESPTransitionSystem.DEBUG_INFO==ESPTransitionSystem.ALL_INFO){
294 | ESPTransitionSystem.DEBUG_INFO = ESPTransitionSystem.NOT_EXECUTIONSTATE;
295 | }else{
296 | ESPTransitionSystem.DEBUG_INFO = ESPTransitionSystem.ALL_INFO;
297 | }
298 | }
299 |
300 | private void jCheckBoxMenuItem2StateChanged(ChangeEvent evt) {
301 | //System.out.println("jCheckBoxMenuItem2.stateChanged, event="+evt);
302 | if(ESPTransitionSystem.USE_SOLVER){
303 | ESPTransitionSystem.USE_SOLVER = false;
304 | }else {
305 | ESPTransitionSystem.USE_SOLVER = true;
306 | }
307 | }
308 | }
309 |
310 | class ExtensionFileFilter extends FileFilter {
311 | String description;
312 |
313 | String extensions[];
314 |
315 | public ExtensionFileFilter(String description, String extension) {
316 | this(description, new String[] { extension });
317 | }
318 |
319 | public ExtensionFileFilter(String description, String extensions[]) {
320 | if (description == null) {
321 | this.description = extensions[0];
322 | } else {
323 | this.description = description;
324 | }
325 | this.extensions = extensions.clone();
326 | toLower(this.extensions);
327 | }
328 |
329 | private void toLower(String array[]) {
330 | for (int i = 0, n = array.length; i < n; i++) {
331 | array[i] = array[i].toLowerCase();
332 | }
333 | }
334 |
335 | @Override
336 | public String getDescription() {
337 | return description;
338 | }
339 |
340 | @Override
341 | public boolean accept(File file) {
342 | if (file.isDirectory()) {
343 | return true;
344 | } else {
345 | String path = file.getAbsolutePath().toLowerCase();
346 | for (int i = 0, n = extensions.length; i < n; i++) {
347 | String extension = extensions[i];
348 | if ((path.endsWith(extension) && (path.charAt(path.length()
349 | - extension.length() - 1)) == '.')) {
350 | return true;
351 | }
352 | }
353 | }
354 | return false;
355 | }
356 | }
357 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/GUI/UIUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.GUI;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import org.antlr.runtime.ANTLRStringStream;
7 | import org.antlr.runtime.CommonTokenStream;
8 |
9 | import cn.edu.sjtu.jllvm.ESP.ESPChecking;
10 | import cn.edu.sjtu.jllvm.ESP.ESPProperty.ESPTransitionSystem;
11 | import cn.edu.sjtu.jllvm.VMCore.BasicBlock;
12 | import cn.edu.sjtu.jllvm.VMCore.Module;
13 | import cn.edu.sjtu.jllvm.VMCore.Parser.LLVMLexer;
14 | import cn.edu.sjtu.jllvm.VMCore.Parser.LLVMParser;
15 |
16 | public class UIUtil {
17 | public static String filePath = "./Example/httpd_all_modules.ll";
18 | public static String fileFolder = ".";
19 |
20 | public static boolean
21 | DEBUG_ALL_INFO = false,
22 | DEBUG_LOCK_INFO = true,
23 |
24 | DEBUG_SPECIAL_FUNCTION = false;
25 |
26 | public static String SpecialFunctions[] = {"allocator_alloc"};
27 |
28 | public String run() throws Exception {
29 | if(!filePath.endsWith(".ll")){
30 | return "";
31 | }
32 |
33 | File file = new File(filePath);
34 |
35 | if(!file.exists()){
36 | return "";
37 | }
38 | fileFolder = file.getParent();
39 |
40 | byte[] buffer = new byte[(int) file.length()];
41 | BufferedInputStream f = new BufferedInputStream(new FileInputStream(file));
42 | f.read(buffer);
43 | LLVMLexer l = new LLVMLexer(new ANTLRStringStream(new String(buffer)));
44 | CommonTokenStream ct = new CommonTokenStream(l);
45 | LLVMParser p = new LLVMParser(ct);
46 | BasicBlock.CONTACT=false;
47 | Module cfg = p.program();
48 | cfg.syntaxAnalysis();
49 |
50 | //target is a ESP system
51 | ESPTransitionSystem system = null;
52 | if(DEBUG_SPECIAL_FUNCTION){
53 | system = new ESPTransitionSystem(cfg, SpecialFunctions);
54 | }else{
55 | system = new ESPTransitionSystem(cfg);
56 | }
57 | ESPChecking mc = new ESPChecking();
58 |
59 | //solve the ESP system with standard ModelChecking algorithm
60 | mc.solve(system);
61 |
62 | /*if(DEBUG_INFO_TO_FILE){
63 | String dir = file.getParent()+"\\ModelChecking_ESP_output\\";
64 | File out_dir = new File(dir);
65 | if(!out_dir.exists()){
66 | out_dir.mkdir();
67 | }
68 | String fileName = file.getName();
69 | fileName = fileName.substring(0, fileName.length()-3)+"_ESP.txt";
70 | File outputFile = new File(dir+fileName);
71 | if(!outputFile.exists()){
72 | outputFile.createNewFile();
73 | }
74 |
75 | ESPArguments.fileWriter = new PrintWriter(new FileWriter(outputFile));
76 | }*/
77 |
78 | String result = mc.getInfo();
79 |
80 | return result;
81 | /*if(ESPArguments.DEBUG_INFO_TO_FILE){
82 | ESPArguments.fileWriter.close();
83 | }*/
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/Lockset/Edge.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.Lockset;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class Edge {
7 | private Lockset entry_lockset;
8 | private List exit_locksets;
9 |
10 | public Edge(Lockset entry){
11 | entry_lockset = entry;
12 | exit_locksets = new ArrayList();
13 | }
14 |
15 | public Lockset getEntry_lockset() {
16 | return entry_lockset;
17 | }
18 | public void setEntry_lockset(Lockset entry_lockset) {
19 | this.entry_lockset = entry_lockset;
20 | }
21 | public List getExit_locksets() {
22 | return exit_locksets;
23 | }
24 | public void setExit_locksets(List exit_locksets) {
25 | this.exit_locksets = exit_locksets;
26 | }
27 |
28 | @Override
29 | public String toString(){
30 | StringBuffer buf = new StringBuffer();
31 | if(exit_locksets.size()==0)
32 | buf.append(entry_lockset.toString()+"->"+"{}");
33 | else{
34 | for(Lockset ls:exit_locksets){
35 | buf.append(entry_lockset.toString()+"->"+ls.toString()+"\n");
36 | }
37 | }
38 |
39 | return buf.toString();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/Lockset/FunctionCache.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.Lockset;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Hashtable;
5 | import java.util.List;
6 |
7 | public class FunctionCache {
8 | private List edges;
9 | private boolean on_stack_p;
10 | private Hashtable> blockLocksetPairs; //store each block's locksetPair, index by blockID
11 |
12 | private boolean isRelateToLock; //record whecher this function has lock, used in intraprocedural;
13 |
14 | public FunctionCache(){
15 | edges = new ArrayList();
16 | on_stack_p = false;
17 | blockLocksetPairs = new Hashtable>();
18 | isRelateToLock = false;
19 | }
20 |
21 | public boolean isRelateToLock(){
22 | return isRelateToLock;
23 | }
24 |
25 | public void relateToLock(){
26 | isRelateToLock = true;
27 | }
28 |
29 | public void addLocksets(Edge edge){
30 | edges.add(edge);
31 | }
32 |
33 | public List getLockSets(Lockset ls){
34 | for(Edge edge: edges){
35 | if(edge.getEntry_lockset().equals(ls))
36 | return edge.getExit_locksets();
37 | }
38 |
39 | return null;
40 | }
41 |
42 | public boolean containsLocksetPair(String blockID, LocksetPair lp){
43 | List pairs = blockLocksetPairs.get(blockID);
44 | if(pairs==null){
45 | pairs = new ArrayList();
46 | blockLocksetPairs.put(blockID, pairs);
47 | return false;
48 | }
49 | for(LocksetPair pair: pairs){
50 | if(pair.equals(lp))
51 | return true;
52 | }
53 |
54 | return false;
55 | }
56 |
57 | public void addLocksetPair(String blockID, LocksetPair lp){
58 | List pairs = blockLocksetPairs.get(blockID);
59 | if(pairs==null){
60 | pairs = new ArrayList();
61 | blockLocksetPairs.put(blockID, pairs);
62 | }
63 | pairs.add(lp);
64 | }
65 |
66 | public boolean onStack(){
67 | return on_stack_p;
68 | }
69 |
70 | public void setOnStack(){
71 | on_stack_p = true;
72 | }
73 |
74 | public void setOffStack(){
75 | on_stack_p = false;
76 | }
77 |
78 | @Override
79 | public String toString(){
80 | StringBuffer buf = new StringBuffer();
81 | for(Edge edge:edges){
82 | buf.append(edge.toString()+"\n");
83 | }
84 | return buf.toString();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/Lockset/Lock.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.Lockset;
2 |
3 | public class Lock {
4 | private String name;
5 |
6 | /*state: 0 means lockstate is unchanged, also each lock's state is initialized by 0
7 | 1 means lock one time
8 | 2 means lock more than one time and this state will never change
9 | -1 means unlock one time, if the lockstate is -1 and also want to lock it, the state will stay -1.
10 | -2 means unlock more than one time and this state will never change
11 | */
12 | private int state;
13 |
14 | public Lock(String name){
15 | this.name = name;
16 | state = 0;
17 | }
18 |
19 | public String getName() {
20 | return name;
21 | }
22 |
23 | public boolean equals(Lock lock){
24 | return name.equals(lock.name) && state == lock.state;
25 | }
26 |
27 | public void lock(){
28 | if(state == 2 || state < 0){
29 | return;
30 | }else { //0 or 1
31 | state++;
32 | }
33 | }
34 |
35 | public void unlock(){
36 | if(state == 2 || state == -2){
37 | return;
38 | }else {
39 | state--;
40 | }
41 | }
42 |
43 | public Lock copy(){
44 | Lock newLock = new Lock(this.name);
45 | newLock.state = state;
46 | return newLock;
47 | }
48 |
49 | @Override
50 | public String toString(){
51 | return name+" "+state;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/Lockset/Lockset.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.Lockset;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class Lockset {
7 | private List lockList;
8 |
9 | public Lockset(){
10 | lockList = new ArrayList();
11 | }
12 |
13 | public boolean isEmpty(){
14 | return lockList.size()==0;
15 | }
16 |
17 | public boolean equals(Lockset ls){
18 | if(lockList.size() != ls.lockList.size())
19 | return false;
20 | if(lockList.size() == 0)
21 | return true;
22 |
23 | for(Lock lock: lockList){
24 | boolean exist = false;
25 | for(Lock lock2: ls.lockList){
26 | if(lock.equals(lock2)){
27 | exist = true;
28 | break;
29 | }
30 | }
31 | if(!exist)
32 | return false;
33 | }
34 |
35 | return true;
36 | }
37 |
38 | public void addLock(Lock lock){
39 | Lock lo = getLockInSet(lock);
40 | if(lo==null){
41 | lockList.add(lock);
42 | lock.lock();
43 | }else{
44 | lo.lock();
45 | }
46 | }
47 |
48 | public void removeLock(Lock lock){
49 | Lock lo = getLockInSet(lock);
50 | if(lo==null){
51 | lock.unlock();
52 |
53 | lockList.add(lock);
54 | }else{
55 | lo.unlock();
56 | }
57 | }
58 |
59 | public Lock getLockInSet(Lock lock){
60 | for(Lock lo:lockList){
61 | if(lo.getName().equals(lock.getName()))
62 | return lo;
63 | }
64 | return null;
65 | }
66 |
67 | public Lockset copy(){
68 | Lockset newLockset = new Lockset();
69 | List list = new ArrayList();
70 | for(int i = 0; i lockList){
78 | this.lockList = lockList;
79 | }
80 |
81 | @Override
82 | public String toString(){
83 | StringBuffer buf = new StringBuffer();
84 | if(lockList.size()==0){
85 | buf.append("{}");
86 | }else{
87 | boolean first = true;
88 | for(Lock lock:lockList){
89 | if(first){
90 | buf.append("{"+lock.toString());
91 | first = false;
92 | }else{
93 | buf.append(", "+lock.toString());
94 | }
95 | }
96 | buf.append("}");
97 | }
98 |
99 | return buf.toString();
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/Lockset/LocksetPair.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.Lockset;
2 |
3 | public class LocksetPair {
4 | private Lockset entry_ls;
5 | private Lockset out_ls;
6 | public LocksetPair(Lockset en, Lockset out){
7 | entry_ls = en;
8 | out_ls = out;
9 | }
10 |
11 | public boolean equals(LocksetPair lp){
12 | return entry_ls.equals(lp.entry_ls) && out_ls.equals(lp.out_ls);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/Lockset/LocksetTraverse.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.Lockset;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Hashtable;
5 | import java.util.List;
6 |
7 | import cn.edu.sjtu.jllvm.VMCore.BasicBlock;
8 | import cn.edu.sjtu.jllvm.VMCore.Module;
9 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
10 | import cn.edu.sjtu.jllvm.VMCore.Constants.Function;
11 | import cn.edu.sjtu.jllvm.VMCore.Instructions.Instruction;
12 | import cn.edu.sjtu.jllvm.VMCore.Operators.InstType;
13 |
14 | public class LocksetTraverse {
15 | private Hashtable functionCache;
16 | private Module cfg;
17 |
18 | boolean INTERPROCEDURAL = false;
19 |
20 | public Hashtable getFunctionCache(){
21 | return functionCache;
22 | }
23 |
24 | public void traverse_cfg(Module cfg){
25 | this.cfg = cfg;
26 | List functions = cfg.getFunctions();
27 | Function main = cfg.getMain();
28 |
29 | functionCache = new Hashtable();
30 | for(Function fn: functions){
31 | functionCache.put(fn.getFunctionName(), new FunctionCache());
32 | }
33 |
34 | //traverse_fn(main, new Lockset());
35 | for(Function fn: functions){
36 | traverse_fn(fn, new Lockset());
37 | }
38 | /* List keys = new ArrayList(functionCache.keySet());
39 | for(String key:keys){
40 | FunctionCache cache = functionCache.get(key);
41 | System.out.println(key+":\n"+cache.toString());
42 | }*/
43 | }
44 |
45 | public List traverse_fn(Function fn, Lockset ls){
46 | FunctionCache cache = functionCache.get(fn.getFunctionName());
47 | List locksets = cache.getLockSets(ls);
48 | if(locksets != null)
49 | return locksets;
50 |
51 | if(cache.onStack())
52 | return new ArrayList();
53 |
54 | cache.setOnStack();
55 |
56 | Edge edge = new Edge(ls);
57 | List exitSets = traverse_blocks(fn, fn.getEntry(), ls, ls.copy()); //exitSets mustn't be null
58 | edge.setExit_locksets(exitSets);
59 |
60 | cache.setOffStack();
61 |
62 | cache.addLocksets(edge);
63 |
64 | return exitSets;
65 | }
66 |
67 | //Use BasicBlock instead of stmt, this can save cache space.
68 | //And this will not wrong, because BasicBlock is the basic unit of a CFG.
69 | public List traverse_blocks(Function fn, BasicBlock bb, Lockset entry_ls, Lockset ls){
70 | FunctionCache cache = functionCache.get(fn.getFunctionName());
71 | //cache
72 | LocksetPair pair = new LocksetPair(entry_ls, ls);
73 | if(cache.containsLocksetPair(bb.getBlockID(), pair)){
74 | return new ArrayList(); //{}
75 | }
76 | cache.addLocksetPair(bb.getBlockID(), pair);
77 |
78 | List instructions = bb.getInstructions();
79 |
80 | List worklist = new ArrayList();
81 | worklist.add(ls);
82 |
83 | //traverse each instruction
84 | for(Instruction inst: instructions){
85 | switch(inst.getOpcode()){
86 | case InstType.callInst: //lock , unlock, other calls
87 | if(isLock(inst)){ //lock
88 | cache.relateToLock();
89 |
90 | Constant expr = inst.getOperand(1);
91 |
92 | String lockName = null;
93 | if(expr.isGlobalVariable()){
94 | lockName = "@"+expr.toString()+":"+inst.getType(1).toString();
95 | }else if(expr.isLocalVariable()){
96 | int instIndex = instructions.indexOf(inst);
97 | lockName = getLockType(fn, bb, expr.toString(), instIndex-1); //inst.getType(1).toString(); //parese instructions reversely
98 | }
99 |
100 | if(lockName!=null){
101 | Lock lock = new Lock(lockName);
102 | ls.addLock(lock);
103 | }
104 | }else if(isUnlock(inst)){ //unlock
105 | cache.relateToLock();
106 |
107 | Constant expr = inst.getOperand(1);
108 |
109 | String lockName = null;
110 | if(expr.isGlobalVariable()){
111 | lockName = "@"+expr.toString()+":"+inst.getType(1).toString();
112 | }else if(expr.isLocalVariable()){
113 | int instIndex = instructions.indexOf(inst);
114 | lockName = getLockType(fn, bb, expr.toString(), instIndex-1); //+inst.getType(1).toString(); //parese instructions reversely
115 | }
116 |
117 | if(lockName!=null){
118 | Lock lock = new Lock(lockName);
119 | ls.removeLock(lock);
120 | }
121 | }else{ //other calls, if not interprocedural, ignore.
122 | if(INTERPROCEDURAL){
123 | String name = inst.getOperand(0).toString();
124 | Function next_f = cfg.getFunction(name);
125 | if(next_f == null)//this function is unsolved, ignore it.
126 | continue;
127 |
128 | //function pointer is unsolved
129 |
130 | List tempList = new ArrayList();
131 | for(Lockset lockset: worklist){
132 | tempList.addAll(traverse_fn(next_f, lockset.copy()));
133 | }
134 |
135 | mergeLocksetList(worklist, tempList);
136 | }
137 | }
138 | default:
139 | if(inst.isTerminator()){ //end of a BasicBlock: br switch ret...
140 | if(bb.hasSuccessor()){
141 | List successors = bb.getSuccessors();
142 |
143 | List tempList2 = new ArrayList();
144 | for(BasicBlock nextBb: successors){
145 | for(Lockset lockset: worklist){
146 | tempList2.addAll(traverse_blocks(fn, nextBb, lockset, lockset.copy()));
147 | }
148 | }
149 |
150 | mergeLocksetList(worklist, tempList2);
151 | }else{
152 | return worklist;
153 | }
154 | }
155 | }
156 | }
157 |
158 | return worklist;
159 | }
160 |
161 | public void mergeLocksetList(List locklist, List target){
162 | if(target.size()==0)
163 | return;
164 | for(Lockset tar: target){
165 | boolean contains = false;
166 | for(Lockset lockset:locklist){
167 | if(tar.equals(lockset)){
168 | contains = true;
169 | break;
170 | }
171 | }
172 |
173 | if(!contains){
174 | locklist.add(tar);
175 | }
176 | }
177 | }
178 |
179 |
180 | /**
181 | * @param fn function
182 | * @param bb basic block
183 | * @param var id
184 | * @param instIndex block's instruction index
185 | * @return reversely visit block's instructions and find all info about lock id.
186 | */
187 | public static String getLockType(Function fn, BasicBlock bb, String var, int instIndex){
188 | String returnStr = "";
189 |
190 | List instructions = bb.getInstructions();
191 | for(int i=instIndex; i>=0; i--){
192 | Instruction inst = instructions.get(i);
193 | if(inst.isLoad()){
194 | String dest = inst.getDest().toString();
195 | if(dest.equals(var)){
196 | returnStr=inst.getType(0).toString()+"."+returnStr;
197 | Constant expr = inst.getOperand(0);
198 |
199 | if(expr.isGlobalVariable()){ //end and return
200 | returnStr = "@"+expr.toString()+":"+returnStr;
201 | return returnStr;
202 | }else if(expr.isLocalVariable()){
203 | var = expr.toString();
204 | }else{
205 | return returnStr;
206 | }
207 | }
208 | }else if(inst.isGetElePtr()){
209 | String dest = inst.getDest().toString();
210 | if(dest.equals(var)){
211 | returnStr = inst.getType(0).toString()+"."+returnStr;
212 | Constant expr = inst.getOperand(0);
213 |
214 | if(expr.isGlobalVariable()){
215 | returnStr = "@"+expr.toString()+":"+returnStr;
216 | return returnStr;
217 | }else if(expr.isLocalVariable()){
218 | var = expr.toString();
219 | }else{
220 | return returnStr;
221 | }
222 | }
223 | }else if(inst.isBitcast()){
224 | String dest = inst.getDest().toString();
225 | if(dest.equals(var)){
226 | var = inst.getOperand(0).toString();
227 | }
228 | }
229 | }
230 |
231 | BasicBlock nextBb = fn.getPreBasicBlock(bb);
232 | if(nextBb!=null){
233 | returnStr = getLockType(fn, nextBb, var, nextBb.getNumInst()-2) +returnStr; //next basicblock's terminator inst is ignored
234 | }else{ // get function argument info
235 | int argNum = fn.getNumArgument();
236 | for(int i=0; i pAttributes;
11 | private int align;
12 | private Constant expr; //expr will be null in FunctionDeclare.
13 |
14 | private Function parent;
15 |
16 | public Argument(Type type, List pAttributes, int align, Constant expr){
17 | setType(type);
18 | this.pAttributes = pAttributes;
19 | this.align = align;
20 | this.expr = expr;
21 | if(expr!=null){
22 | expr.setType(type);
23 | }
24 | }
25 |
26 | public Constant getExpr() {
27 | return expr;
28 | }
29 |
30 | @Override
31 | public String toString(){
32 | String value;
33 | if(type == null){
34 | return null;
35 | }
36 | value = type.toString();
37 | for(String str:pAttributes){
38 | value+= " " +str;
39 | }
40 | if(align>0){
41 | value+=" align "+align;
42 | }
43 |
44 | if(expr!=null){
45 | value+= " " + expr.toString();
46 | }
47 |
48 | return value;
49 | }
50 |
51 | public Function getParent() {
52 | return parent;
53 | }
54 |
55 | public void setParent(Function parent) {
56 | this.parent = parent;
57 | }
58 |
59 | public static Argument create(Type type, List pAttributes, int align, Constant expr){
60 | return new Argument(type, pAttributes, align, expr);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/BasicBlock.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Hashtable;
5 | import java.util.List;
6 |
7 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
8 | import cn.edu.sjtu.jllvm.VMCore.Constants.Function;
9 | import cn.edu.sjtu.jllvm.VMCore.Instructions.Instruction;
10 | import cn.edu.sjtu.jllvm.VMCore.Operators.InstType;
11 | import cn.edu.sjtu.jllvm.VMCore.Types.TypeFactory;
12 |
13 | /**
14 | * @author liuhao 2011-12-21
15 | * This class represents a single entry single exit section of the code,
16 | * commonly known as a basic block by the compiler community.
17 | * The BasicBlock class maintains a list of Instructions,
18 | * which form the body of the block. Matching the language definition,
19 | * the last element of this list of instructions is always a terminator instruction (a subclass of the TerminatorInst class).
20 | */
21 | public class BasicBlock extends Value{
22 | private String blockID;
23 | private List instructions;
24 | private List successors;
25 | private List predecessors;
26 | private Function parent;
27 |
28 | public static boolean CONTACT = true;
29 |
30 | public BasicBlock(String basicID, List instructions){
31 | this.blockID = basicID;
32 | this.instructions = instructions;
33 | int size = instructions.size();
34 |
35 | Instruction preInst = null, nextInst = null;
36 | for(int i = 0; i();
50 | predecessors = new ArrayList();
51 |
52 | setType(TypeFactory.getLabelType());
53 | }
54 |
55 | public void parse(Hashtable bbBlocks){
56 | if(hasSuccessor())
57 | return;
58 | Instruction terminator = instructions.get(instructions.size()-1);
59 | int numOperands = terminator.getNumOperands();
60 | switch(terminator.getOpcode()){
61 | case InstType.brInst:
62 | // br i1 , label , label
63 | // br label ; Unconditional branch
64 | if(numOperands==1){ //unconditional br
65 | BasicBlock s = bbBlocks.get(terminator.getOperand(0).toString());
66 | successors.add(s);
67 | s.addPredecessor(this);
68 | s.parse(bbBlocks);
69 | }else{ //conditional br
70 | BasicBlock s = bbBlocks.get(terminator.getOperand(1).toString());
71 | BasicBlock s2 = bbBlocks.get(terminator.getOperand(2).toString());
72 | successors.add(s);
73 | s.addPredecessor(this);
74 | successors.add(s2);
75 | s2.addPredecessor(this);
76 | s.parse(bbBlocks);
77 | s2.parse(bbBlocks);
78 | }
79 | break;
80 | case InstType.switchInst:
81 | // switch , label [ , label ... ]
82 |
83 | for(int i=1; i globalVarTable, Hashtable localVarTable,
98 | int index, List localList){
99 |
100 | for(Instruction inst: instructions){
101 | Constant dest = inst.getDest();
102 | if(dest!=null){
103 | inst.setNumeralDest(index);
104 |
105 | localVarTable.put(dest.toString(), index);
106 | Cell destCell = new Cell();
107 | destCell.setSrcInst(inst);
108 | localList.add(destCell); //need to be rewrite; add valueFlow to Cell
109 |
110 | index++;
111 | }else{
112 | inst.setNumeralDest(0); //no dest
113 | }
114 |
115 | List numeralOperands = new ArrayList();
116 |
117 | // for(Constant expr: inst.getOperands()){
118 | // if(expr.isLocalVariable()){
119 | // Integer in = localVarTable.get(expr.toString());
120 | // if(in!=null){
121 | // numeralOperands.add(in);
122 | // }else{
123 | // numeralOperands.add(0);
124 | // }
125 | // }else if(expr.isGlobalVariable()){
126 | // Integer in = globalVarTable.get(expr.toString());
127 | // if(in!=null){
128 | // numeralOperands.add(new Integer(-in));
129 | // }else{
130 | // numeralOperands.add(0);
131 | // }
132 | // }
133 | // }
134 |
135 | List operands = inst.getOperands();
136 | for(int i = 0; i < operands.size(); i++){
137 | Constant expr = operands.get(i);
138 | String exprStr = expr.toString();
139 |
140 | if(expr.isLocalVariable()){
141 | Integer in = localVarTable.get(expr.toString());
142 | if(in!=null){
143 | numeralOperands.add(in);
144 | }else{
145 | numeralOperands.add(0);
146 | }
147 |
148 | if(CONTACT){
149 | Constant c = getParent().getLocalVarTable().get(exprStr);
150 | if(c!=null){
151 | operands.remove(i);
152 | operands.add(i, c);
153 | }
154 | }
155 |
156 | }else if(expr.isGlobalVariable()){
157 | Integer in = globalVarTable.get(expr.toString());
158 | if(in!=null){
159 | numeralOperands.add(new Integer(-in));
160 | }else{
161 | numeralOperands.add(0);
162 | }
163 |
164 | if(CONTACT){
165 | Constant c = getParent().getParent().getGlobalTable().get(exprStr);
166 | if(c!=null){
167 | operands.remove(i);
168 | operands.add(i, c);
169 | }
170 | }
171 |
172 | }
173 | }
174 |
175 | inst.setNumeralOperands(numeralOperands);
176 | }
177 |
178 | return index;
179 | }
180 |
181 | public Function getParent() {
182 | return parent;
183 | }
184 |
185 | public void setParent(Function parent) {
186 | this.parent = parent;
187 | }
188 |
189 | public int getNumPredecessor(){
190 | return predecessors.size();
191 | }
192 |
193 | public void addPredecessor(BasicBlock bb){
194 | if(predecessors.contains(bb))
195 | return;
196 | predecessors.add(bb);
197 | }
198 |
199 | public List getPredecessors() {
200 | return predecessors;
201 | }
202 |
203 | public BasicBlock getPredecessor(int index) {
204 | return predecessors.get(index);
205 | }
206 |
207 | public List getSuccessors() {
208 | return successors;
209 | }
210 |
211 | public int getNumSuccessor(){
212 | return successors.size();
213 | }
214 |
215 | public BasicBlock getSuccessor(int index){
216 | return successors.get(index);
217 | }
218 |
219 | public Instruction getFirst(){
220 | return instructions.get(0);
221 | }
222 |
223 | public Instruction getTerminator(){
224 | return instructions.get(instructions.size()-1);
225 | }
226 |
227 | public Instruction getInstruction(int index){
228 | return instructions.get(index);
229 | }
230 |
231 | public Instruction getPreInstruction(Instruction inst){
232 | int index = instructions.indexOf(inst);
233 | if(index>=0){
234 | return instructions.get(index-1);
235 | }
236 |
237 | return null;
238 | }
239 |
240 | public int getNumInst(){
241 | return instructions.size();
242 | }
243 |
244 | public boolean hasSuccessor(){
245 | return successors.size()!=0;
246 | }
247 |
248 | public List getInstructions() {
249 | return instructions;
250 | }
251 |
252 | public String getBlockID() {
253 | return blockID;
254 | }
255 |
256 | @Override
257 | public String toString(){
258 | String value = "";
259 | value += " "+blockID+":\n";
260 |
261 | value+= " predecessor: ";
262 | for(BasicBlock bb: predecessors){
263 | value+=bb.getBlockID()+", ";
264 | }
265 |
266 | value+= " successor: ";
267 | for(BasicBlock bb: successors){
268 | value+=bb.getBlockID()+", ";
269 | }
270 |
271 | return value;
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Cell.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore;
2 |
3 | import cn.edu.sjtu.jllvm.VMCore.Instructions.Instruction;
4 |
5 |
6 | /**
7 | * @author Administrator
8 | *
9 | * A memory cell to Store local and global variables' info in Function and Module
10 | */
11 | public class Cell {
12 | private String value;
13 |
14 | private Instruction srcInst;
15 |
16 | public Cell(){
17 |
18 | }
19 |
20 | public Cell(String va){
21 | value = va;
22 | }
23 |
24 | public Instruction getSrcInst() {
25 | return srcInst;
26 | }
27 |
28 | public void setSrcInst(Instruction srcInst) {
29 | this.srcInst = srcInst;
30 | }
31 |
32 | public String getValue() {
33 | return value;
34 | }
35 |
36 | public void setValue(String value) {
37 | this.value = value;
38 | }
39 |
40 | @Override
41 | public String toString(){
42 | if(srcInst!=null){
43 | return srcInst.toString();
44 | }else{
45 | return "unKnown_inst";
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/BinaryConstantExpr.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import java.util.ArrayList;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Operators.Operator;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | public class BinaryConstantExpr extends ConstantExpr {
9 | private String nuw, nsw, exact;
10 | private Type type1, type2;
11 |
12 | public BinaryConstantExpr(String op, String nuw, String nsw, String exact, Type type1, Constant expr1, Type type2, Constant expr2){
13 | this.opcode = Operator.getOpcode(op);
14 | this.nuw = nuw;
15 | this.nsw = nsw;
16 | this.exact = exact;
17 | this.type1 = type1;
18 | this.type2 = type2;
19 |
20 | this.operands = new ArrayList();
21 | operands.add(expr1);
22 | operands.add(expr2);
23 | }
24 |
25 | public static BinaryConstantExpr create(String op, String nuw, String nsw, String exact, Type type1, Constant expr1, Type type2, Constant expr2){
26 | return new BinaryConstantExpr(op, nuw, nsw, exact, type1, expr1, type2, expr2);
27 | }
28 |
29 | @Override
30 | public String toString(){
31 | String value = Operator.getOpStr(opcode);
32 | if(nuw!=null){
33 | value += " nuw";
34 | }
35 | if(nsw!=null){
36 | value += " nsw";
37 | }
38 | if(exact!=null){
39 | value += " exact";
40 | }
41 |
42 | value += " "+type1.toString() + " " + getOperand(0).toString() + ", "+type2.toString()+" "+ getOperand(1).toString();
43 |
44 | return value;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/CompareConstantExpr.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import java.util.ArrayList;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Operators.CompareCondition;
6 | import cn.edu.sjtu.jllvm.VMCore.Operators.Operator;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 |
9 | public class CompareConstantExpr extends ConstantExpr {
10 | private int cond;
11 | private Type type1, type2;
12 |
13 | public CompareConstantExpr(boolean isICmp, String cond, Type type1, Constant expr1, Type type2, Constant expr2){
14 | if(isICmp){
15 | this.opcode = Operator.icmp;
16 | }else{
17 | this.opcode = Operator.fcmp;
18 | }
19 |
20 | this.cond = CompareCondition.getCond(cond);
21 | this.type1 = type1;
22 | this.type2 = type2;
23 |
24 | this.operands = new ArrayList();
25 | operands.add(expr1);
26 | operands.add(expr2);
27 | }
28 |
29 | public static CompareConstantExpr create(boolean isICmp, String cond, Type type1, Constant expr1, Type type2, Constant expr2){
30 | return new CompareConstantExpr(isICmp, cond, type1, expr1, type2, expr2);
31 | }
32 |
33 | @Override
34 | public String toString(){
35 | String value = "";
36 | value += Operator.getOpStr(opcode);
37 |
38 | value+= " "+cond+" "+type1.toString()+" "+getOperand(0).toString()+","+type2.toString()+getOperand(1).toString();
39 | return value;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/ComplexConstantValue.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | public class ComplexConstantValue extends Constant{
4 | public final static int
5 | structure = 7,
6 | array = 8,
7 | vector = 10;
8 |
9 | protected int valueID;
10 |
11 | public ComplexConstantValue(int id, String value){
12 | this.valueID = id;
13 |
14 | this.value = value;
15 | //value=value.substring(1,value.length()-2);
16 | }
17 |
18 | public int getValueID() {
19 | return valueID;
20 | }
21 |
22 | @Override
23 | public boolean isNullValue() {
24 | // TODO Auto-generated method stub
25 | return value.length()==2;
26 | }
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/Constant.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import cn.edu.sjtu.jllvm.VMCore.User;
4 |
5 | /**
6 | * @author liuhao 2011-12-21
7 | * a constant that is initialized with an expression using other constants.
8 | */
9 | public class Constant extends User {
10 | public static final int
11 | simpleConstantValue = 1,
12 | getEleExpr = 2,
13 | converExpr = 3,
14 | binaryExpr = 4,
15 | cmpExpr = 5,
16 | globalVar = 6,
17 | localVar = 7,
18 | undef = 8;
19 |
20 | public int constantID;
21 |
22 | public Constant(){
23 | constantID = Constant.undef;
24 | }
25 |
26 | public boolean isGlobalVariable(){
27 | return constantID == globalVar;
28 | }
29 |
30 | public boolean isLocalVariable(){
31 | return constantID == localVar;
32 | }
33 |
34 | public boolean isSimpleConstantValue(){
35 | return constantID == simpleConstantValue;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/ConstantExpr.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | public class ConstantExpr extends Constant {
4 | protected int opcode;
5 |
6 | public int getOpcode() {
7 | return opcode;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/ConstantPointerNull.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | public class ConstantPointerNull extends Constant {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/ConvertConstantExpr.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import java.util.ArrayList;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Operators.Operator;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | public class ConvertConstantExpr extends ConstantExpr {
9 | private Type fType;
10 | private Type tType;
11 |
12 | public ConvertConstantExpr(String op, Type type1, Constant subExpr, Type type2){
13 | this.opcode = Operator.getOpcode(op);
14 | fType = type1;
15 | this.operands = new ArrayList();
16 | operands.add(subExpr);
17 | tType = type2;
18 | }
19 |
20 | public static ConvertConstantExpr create(String op, Type type1, Constant subExpr, Type type2){
21 | return new ConvertConstantExpr(op, type1, subExpr, type2);
22 | }
23 |
24 | @Override
25 | public String toString(){
26 | String value = opcode + " (" + fType.toString() + " " + getOperand(0).toString() + " to "+ tType.toString()+")";
27 | return value;
28 | }
29 |
30 | public Type getfType() {
31 | return fType;
32 | }
33 |
34 | public Type gettType() {
35 | return tType;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/Function.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Hashtable;
5 | import java.util.List;
6 |
7 | import cn.edu.sjtu.jllvm.VMCore.Argument;
8 | import cn.edu.sjtu.jllvm.VMCore.BasicBlock;
9 | import cn.edu.sjtu.jllvm.VMCore.Cell;
10 | import cn.edu.sjtu.jllvm.VMCore.Module;
11 | import cn.edu.sjtu.jllvm.VMCore.Instructions.Instruction;
12 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
13 | import cn.edu.sjtu.jllvm.VMCore.Types.TypeFactory;
14 |
15 | public class Function extends GlobalValue{
16 | private Type returnType;
17 | private String functionName;
18 | private List blockList;
19 | private Hashtable blockTable;
20 |
21 | private Hashtable localVarTable;
22 | private List arguments;
23 | private List argExprs;
24 | private List argTypes;
25 | boolean isVararg;
26 | private Module parent;
27 |
28 | private Cell[] locals;
29 |
30 | public Function(String linkage, String visibility, String cconv,
31 | List pAttributes,
32 | Type returnType, String name,
33 | List arguments,
34 | boolean isVarargFunction,
35 | List fAttributes,
36 | int align,
37 | List basicBlocks
38 | ){
39 | this.returnType = returnType;
40 | this.functionName = name;
41 |
42 | this.blockList = basicBlocks;
43 | blockTable = new Hashtable();
44 | boolean first=true;
45 | BasicBlock entry = null;
46 | for(BasicBlock bb: basicBlocks){
47 | bb.setParent(this);
48 | blockTable.put(bb.getBlockID(), bb);
49 | if(first){
50 | entry = bb;
51 | first =false;
52 | }
53 | }
54 | entry.parse(blockTable);
55 |
56 | localVarTable = new Hashtable();
57 |
58 | argExprs = new ArrayList();
59 | argTypes = new ArrayList();
60 |
61 | this.arguments = arguments;
62 | for(Argument arg: arguments){
63 | arg.setParent(this);
64 | Constant constant = arg.getExpr();
65 | argExprs.add(constant);
66 | argTypes.add(arg.getType());
67 |
68 | localVarTable.put(constant.toString(), constant);
69 | }
70 |
71 | for(BasicBlock bb: basicBlocks){
72 | for(Instruction inst: bb.getInstructions()){
73 | Constant c = inst.getDest();
74 | if(c!=null){
75 | localVarTable.put(c.toString(), c);
76 | }
77 | }
78 | }
79 |
80 | isVararg = isVarargFunction;
81 |
82 | List funList = new ArrayList();
83 | funList.add(returnType);
84 | funList.addAll(argTypes);
85 | setType(TypeFactory.getFunctionType(funList, isVararg));
86 | }
87 |
88 | public void syntaxAnalysis(Hashtable globalVarTable){
89 | Hashtable localVarIntTable = new Hashtable ();
90 |
91 | List localList = new ArrayList();
92 | localList.add(new Cell());
93 |
94 | int index = 1;
95 |
96 | for(Constant arg: argExprs){
97 | localList.add(new Cell());
98 | localVarIntTable.put(arg.toString(), index);
99 | index++;
100 | }
101 |
102 | for(BasicBlock bb: blockList){ //let all local variables be digit
103 | // index = bb.syntaxAnalysis(globalVarTable, localVarIntTable, index, localList);
104 | index = bb.syntaxAnalysis(globalVarTable, localVarIntTable, index, localList);
105 | }
106 |
107 | locals = localList.toArray(new Cell[localList.size()]);
108 |
109 | for(BasicBlock bb: blockList){
110 | for(Instruction inst: bb.getInstructions()){
111 | Constant dest = inst.getDest();
112 | if(dest!=null){
113 | dest.setType(inst.getType());
114 | }
115 | }
116 | }
117 | }
118 |
119 | public List getUseDefChain(Constant c){
120 | List chain = new ArrayList();
121 | boolean global = false;
122 | String varStr = c.toString();
123 |
124 | if(!c.isLocalVariable()){
125 | if(c.isGlobalVariable()) {
126 | global = true;
127 | }
128 | else {
129 | return chain;
130 | }
131 | }
132 |
133 | for(BasicBlock bb: blockList){
134 | for(Instruction inst: bb.getInstructions()){
135 |
136 | if(!global){
137 | Constant dest = inst.getDest();
138 |
139 | if(dest!=null){
140 | if(dest.toString().equals(c.toString())){
141 | chain.add(inst);
142 | continue;
143 | }
144 | }
145 | }
146 |
147 | for(Constant var: inst.getOperands()){
148 | if(var.isGlobalVariable()){
149 | if(global){
150 | if(var.toString().equals(varStr)){
151 | chain.add(inst);
152 | break;
153 | }
154 | }
155 | }else if(var.isLocalVariable()){
156 | if(!global){
157 | if(var.toString().equals(varStr)){
158 | chain.add(inst);
159 | break;
160 | }
161 | }
162 | }
163 | }
164 | }
165 | }
166 |
167 | return chain;
168 | }
169 |
170 | public Cell getLocal(int index){
171 | if(index<0 || index>locals.length-1)
172 | return null;
173 | return locals[index];
174 | }
175 |
176 | public Cell[] getLocals(){
177 | return locals;
178 | }
179 |
180 | public int getNumArgument(){
181 | return argExprs.size();
182 | }
183 |
184 | public List getArguments() {
185 | return arguments;
186 | }
187 |
188 | public Constant getArgumentExpression(int index){
189 | return argExprs.get(index);
190 | }
191 |
192 | public Type getArgumentType(int index){
193 | return argTypes.get(index);
194 | }
195 |
196 | public Type getReturnType() {
197 | return returnType;
198 | }
199 |
200 | public String getFunctionName() {
201 | return functionName;
202 | }
203 |
204 | public BasicBlock getPreBasicBlock(BasicBlock bb){
205 | int index = blockList.indexOf(bb);
206 | if(index>0)
207 | return blockList.get(index - 1);
208 | return null;
209 | }
210 |
211 | public BasicBlock getBasicBlock(int index){
212 | return blockList.get(index);
213 | }
214 |
215 | public List getBasicBlocks() {
216 | return blockList;
217 | }
218 |
219 | public Hashtable getBlockTable() {
220 | return blockTable;
221 | }
222 |
223 | public BasicBlock getEntry() {
224 | return blockList.get(0);
225 | }
226 |
227 | public boolean isVarArg() {
228 | return false;
229 | }
230 | public boolean isDeclaration() {
231 | return blockList.isEmpty();
232 | }
233 |
234 | public Hashtable getLocalVarTable() {
235 | return localVarTable;
236 | }
237 |
238 | public Module getParent() {
239 | return parent;
240 | }
241 |
242 | public void setParent(Module parent) {
243 | this.parent = parent;
244 | }
245 |
246 | @Override
247 | public String toString(){
248 | String value="function:" +functionName+"\n";
249 | for(BasicBlock bb: blockList){
250 | value+=bb.toString()+"\n\n";
251 | }
252 | return value;
253 | }
254 | }
255 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/FunctionDeclare.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import cn.edu.sjtu.jllvm.VMCore.Argument;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 | import cn.edu.sjtu.jllvm.VMCore.Types.TypeFactory;
9 |
10 | public class FunctionDeclare extends GlobalValue{
11 | private String linkage;
12 | private String visibility;
13 | private String cconv;
14 | private List parameterAttributes;
15 | private Type returnType;
16 | private String name;
17 | private List arguments;
18 | boolean isVararg;
19 | private List functionAttributes;
20 |
21 | public FunctionDeclare(String linkage, String visibility, String cconv,
22 | List pAttributes,
23 | boolean isVararg,
24 | Type type, String name,
25 | List arguments,
26 | List fAttributes
27 | ){
28 | this.linkage = linkage;
29 | this.visibility = visibility;
30 | this.cconv = cconv;
31 | this.parameterAttributes = pAttributes;
32 | this.isVararg = isVararg;
33 | this.returnType = type;
34 | this.name = name;
35 | this.arguments = arguments;
36 | this.functionAttributes = fAttributes;
37 |
38 | List tyList = new ArrayList();
39 | tyList.add(returnType);
40 | for(Argument arg: arguments){
41 | tyList.add(arg.getType());
42 | }
43 | setType(TypeFactory.getFunctionType(tyList, isVararg));
44 | }
45 |
46 | public String getLinkage() {
47 | return linkage;
48 | }
49 |
50 | public String getVisibility() {
51 | return visibility;
52 | }
53 |
54 | public String getCconv() {
55 | return cconv;
56 | }
57 |
58 | public List getParameterAttributes() {
59 | return parameterAttributes;
60 | }
61 |
62 | public Type getReturnType() {
63 | return returnType;
64 | }
65 |
66 | public String getName() {
67 | return name;
68 | }
69 |
70 | public List getArguments() {
71 | return arguments;
72 | }
73 |
74 | public boolean isVararg() {
75 | return isVararg;
76 | }
77 |
78 | public List getFunctionAttributes() {
79 | return functionAttributes;
80 | }
81 |
82 | public int getNumArgument() {
83 | return arguments.size();
84 | }
85 | public Type getArgumentType(int num) {
86 | if(num <= getNumArgument())
87 | return arguments.get(num).getType();
88 | else
89 | return null;
90 | }
91 |
92 |
93 | @Override
94 | public String toString(){
95 | String value = "";
96 | if(linkage != null){
97 | value += linkage;
98 | }
99 | if(visibility != null){
100 | value += " " + visibility;
101 | }
102 | if(cconv != null){
103 | value += " " + cconv;
104 | }
105 | for(String pa:parameterAttributes){
106 | value += " " + pa;
107 | }
108 | value += " " + type.toString() + name;
109 | value += "(";
110 | boolean first = true;
111 | for(Argument ar: arguments){
112 | if(first){
113 | value += ar.toString();
114 | first = false;
115 | }else{
116 | value += ", "+ar.toString();
117 | }
118 | }
119 | value += ")";
120 | for(String fa: functionAttributes){
121 | value += " "+fa;
122 | }
123 |
124 | return value;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/GetElementPtrConstantExpr.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import cn.edu.sjtu.jllvm.VMCore.Operators.Operator;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 |
9 | public class GetElementPtrConstantExpr extends ConstantExpr {
10 | private boolean inbounds;
11 | private Type type;
12 | private List indices;
13 |
14 | public GetElementPtrConstantExpr(boolean inbounds, Type type, Constant subExpr, List indices){
15 | this.inbounds = inbounds;
16 | this.type = type;
17 | this.operands = new ArrayList();
18 | this.operands.add(subExpr);
19 | this.indices = indices;
20 | this.opcode = Operator.getElementPtr;
21 | }
22 |
23 | public boolean isInbounds() {
24 | return inbounds;
25 | }
26 |
27 | @Override
28 | public Type getType() {
29 | return type;
30 | }
31 |
32 | public List getIndices() {
33 | return indices;
34 | }
35 |
36 | @Override
37 | public String toString(){
38 | String value = "getelementptr ";
39 | if(inbounds)
40 | value += "inbounds ";
41 |
42 | value += "(" + type.toString()+" "+getOperand(0).toString();
43 |
44 | for(int i:indices){
45 | value += ", " + i;
46 | }
47 | value += ")";
48 |
49 | return value;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/GlobalAlias.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
4 |
5 | public class GlobalAlias extends GlobalValue{
6 | private String name;
7 | private String linkage;
8 | private String visibility;
9 | private String gVarName;
10 | //aliases_variable :
11 | //GLOBAL_VARIABLE '=' 'alias' LINKAGE? VISIBILITY? derived_type {Type type = $derived_type.type; VMUtil.debug("alias_variable:"+type.toString());} GLOBAL_VARIABLE ;
12 | public GlobalAlias(String name, String linkage, String visibility, Type type, String gVarName){
13 | this.name = name;
14 | this.linkage = linkage;
15 | this.visibility = visibility;
16 | this.type = type;
17 | this.gVarName = gVarName;
18 | }
19 |
20 | public String getName() {
21 | return name;
22 | }
23 |
24 | public String getLinkage() {
25 | return linkage;
26 | }
27 |
28 | public String getVisibility() {
29 | return visibility;
30 | }
31 |
32 | @Override
33 | public Type getType() {
34 | return type;
35 | }
36 |
37 | public String getgVarName() {
38 | return gVarName;
39 | }
40 |
41 | @Override
42 | public String toString(){
43 | // String value="@"+name+"=alias ";
44 | // if(linkage!=null){
45 | // value+=linkage+" ";
46 | // }
47 | // if(visibility!=null){
48 | // value+=visibility+" ";
49 | // }
50 | // value+=type.toString() +" @"+gVarName;
51 | //
52 | // return value;
53 | return getName();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/GlobalValue.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | /**
4 | * @author liuhao 2011-12-21
5 | * Global values (GlobalVariables or Functions) are the only LLVM values that are visible in the bodies of all Functions.
6 | * Because they are visible at global scope,
7 | * they are also subject to linking with other globals defined in different translation units.
8 | */
9 | public class GlobalValue extends Constant{
10 | public GlobalValue(){
11 | super();
12 | }
13 |
14 | public GlobalValue(String value){
15 | this.constantID = Constant.globalVar;
16 | this.value = value;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/GlobalVariable.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
4 |
5 | public class GlobalVariable extends GlobalValue {
6 |
7 | private String name = null;
8 | private String linkage = null;
9 | private boolean isThreadLocal = false;
10 | private boolean isConstant = false;
11 | private Constant initializer = null;
12 | private String section = null;
13 | private int align = -1;
14 |
15 | public GlobalVariable(String name, String linkage, boolean isThreadLocal, boolean isConstant, Type type,
16 | Constant initializer, String section, int align){
17 | this.name = name;
18 | this.linkage = linkage;
19 | this.isThreadLocal = isThreadLocal;
20 | this.isConstant = isConstant;
21 | this.type = type;
22 | this.initializer = initializer;
23 | this.section = section;
24 | this.align = align;
25 | }
26 |
27 | public String getName() {
28 | return name;
29 | }
30 |
31 | public String getLinkage() {
32 | return linkage;
33 | }
34 |
35 | public boolean isThreadLocal() {
36 | return isThreadLocal;
37 | }
38 |
39 | public boolean isConstant() {
40 | return isConstant;
41 | }
42 |
43 | @Override
44 | public Type getType() {
45 | return type;
46 | }
47 |
48 | public boolean hasInitializer(){
49 | return initializer != null;
50 | }
51 |
52 | public Constant getInitializer() {
53 | return initializer;
54 | }
55 |
56 | public String getSection() {
57 | return section;
58 | }
59 |
60 | public int getAlign() {
61 | return align;
62 | }
63 |
64 | @Override
65 | public String toString(){
66 | // String value = "@"+name+"=";
67 | // if(linkage != null){
68 | // value += linkage+" ";
69 | // }
70 | // if(isThreadLocal){
71 | // value += "thread_local ";
72 | // }
73 | // if(isConstant){
74 | // value += "constant ";
75 | // }else{
76 | // value += "global ";
77 | // }
78 | // value += type.toString()+" ";
79 | // if(initializer!=null){
80 | // value += initializer;
81 | // if(section!=null){
82 | // value += ", "+section;
83 | // }
84 | // if(align>0){
85 | // value += ", align "+align;
86 | // }
87 | // }
88 | //
89 | // return value;
90 | return getName();
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/LocalVariable.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | public class LocalVariable extends Constant{
4 | public LocalVariable(String value){
5 | this.constantID = Constant.localVar;
6 | this.value = value;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/SimpleConstantValue.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | public class SimpleConstantValue extends Constant{
4 | public static final int
5 | intConst = 1,
6 | hexConst = 2,
7 | boolConst = 3,
8 | floatConst = 4,
9 | stringConst = 5,
10 | nullConst = 6,
11 | voidConst = 7;
12 |
13 | protected int valueID;
14 |
15 | public SimpleConstantValue(int id, String value){
16 | this.valueID = id;
17 | this.value = value;
18 | this.constantID = Constant.simpleConstantValue;
19 | }
20 |
21 | public int getValueID() {
22 | return valueID;
23 | }
24 |
25 | public boolean isInt() {
26 | return valueID == intConst;
27 | }
28 |
29 | public boolean isString() {
30 | return valueID == stringConst;
31 | }
32 |
33 | public boolean isFloat() {
34 | return valueID == floatConst;
35 | }
36 |
37 | public boolean isNull() {
38 | return valueID == nullConst;
39 | }
40 |
41 | public boolean isBoolean(){
42 | return valueID == boolConst;
43 | }
44 |
45 | @Override
46 | public boolean isNullValue() {
47 | return value.equals("0") || this.valueID==SimpleConstantValue.nullConst;
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Constants/UndefValue.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Constants;
2 |
3 | public class UndefValue extends Constant {
4 | public UndefValue(String value){
5 | this.constantID = Constant.undef;
6 | this.value = value;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/AllocaInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.TypeFactory;
8 |
9 | public class AllocaInst extends Instruction {
10 | public AllocaInst(Constant dest, int opcode, List operands, List types){
11 | super(dest, opcode, operands, types);
12 |
13 | setType(TypeFactory.getPointerType(types.get(0)));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/BinaryInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Operators.Operator;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 |
9 | public class BinaryInst extends OperationInst{
10 | private String nuw;
11 | private String nsw;
12 | private String exact;
13 | public BinaryInst(Constant dest, int opcode, List operands, List types,
14 | String opStr, String nuw, String nsw, String exact){
15 | super(dest, opcode, operands, types, opStr);
16 | this.nuw = nuw;
17 | this.nsw = nsw;
18 | this.exact = exact;
19 | }
20 |
21 | public static BinaryInst create(Constant dest, int opcode, List operands, List types,
22 | String op, String nuw, String nsw, String exact){
23 | return new BinaryInst(dest, opcode, operands, types, op, nuw, nsw, exact);
24 | }
25 |
26 | public int getOp() {
27 | return op;
28 | }
29 |
30 | @Override
31 | public String getOpStr() {
32 | return Operator.getOpStr(op);
33 | }
34 |
35 | public String getNuw() {
36 | return nuw;
37 | }
38 |
39 | public String getNsw() {
40 | return nsw;
41 | }
42 |
43 | public String getExact() {
44 | return exact;
45 | }
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/CallInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | public class CallInst extends Instruction {
9 | private boolean tail;
10 | private String cconv;
11 | private List pAttributes;
12 | private List fAttributes;
13 | public CallInst(Constant dest, int opcode, List operands, List types, boolean tail, String cconv, List pAttributes, List fAttributes){
14 | super(dest, opcode, operands, types);
15 | this.tail = tail;
16 | this.cconv = cconv;
17 | this.pAttributes = pAttributes;
18 | this.fAttributes = fAttributes;
19 | }
20 | public boolean isTail() {
21 | return tail;
22 | }
23 | public String getCconv() {
24 | return cconv;
25 | }
26 | public List getpAttributes() {
27 | return pAttributes;
28 | }
29 | public List getfAttributes() {
30 | return fAttributes;
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/CmpInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Operators.CompareCondition;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 | import cn.edu.sjtu.jllvm.VMCore.Types.TypeFactory;
9 |
10 | public class CmpInst extends Instruction{
11 | private int cond;
12 | public CmpInst(Constant dest, int opcode, List operands, List types,
13 | String cond){
14 | super(dest, opcode, operands, types);
15 | this.cond = CompareCondition.getCond(cond);
16 |
17 | setType(TypeFactory.getInt1Type());
18 | }
19 |
20 | public int getCond() {
21 | return cond;
22 | }
23 |
24 | public void setCond(int cond) {
25 | this.cond = cond;
26 | }
27 |
28 | public static CmpInst create(Constant dest, int opcode, List operands, List types,
29 | String cond){
30 | return new CmpInst(dest, opcode, operands, types, cond);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/GetElePtrInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | public class GetElePtrInst extends Instruction {
9 | private boolean inbounds;
10 |
11 | public GetElePtrInst(Constant dest, int opcode, List operands, List types, boolean inbounds){
12 | super(dest, opcode, operands, types);
13 | this.inbounds = inbounds;
14 |
15 | setType(types.get(0));
16 | }
17 |
18 | public static GetElePtrInst create(Constant dest, int opcode, List operands, List types, boolean inbounds){
19 | return new GetElePtrInst(dest, opcode, operands, types, inbounds);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/InstFactory.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Operators.InstType;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 |
9 | public class InstFactory {
10 | public Instruction createSimpleInst(Constant dest, int opcode, List operands, List types){
11 | switch(opcode){
12 | case InstType.selectInst:
13 | return new SelectInst(dest, opcode, operands, types);
14 | case InstType.allocaInst:
15 | return new AllocaInst(dest, opcode, operands, types);
16 | case InstType.phiInst:
17 | return new PHIInst(dest, opcode, operands, types);
18 | case InstType.retInst:
19 | case InstType.unwindInst:
20 | case InstType.brInst:
21 | case InstType.switchInst:
22 | case InstType.invokeInst:
23 | case InstType.indirectBrInst:
24 | case InstType.unreachableInst:
25 | return new TerminatorInst(dest, opcode, operands, types);
26 | default:
27 | return new Instruction(dest, opcode, operands, types);
28 | }
29 | }
30 |
31 | public Instruction createCallInst(Constant dest, int opcode, List operands, List types,
32 | boolean tail, String cconv, List pAttributes, List fAttributes){
33 | return new CallInst(dest, opcode, operands, types, tail, cconv, pAttributes, fAttributes);
34 | }
35 |
36 | public Instruction createCmpInst(Constant dest, int opcode, List operands, List types,
37 | String cond){
38 | return new CmpInst(dest, opcode, operands, types, cond);
39 | }
40 |
41 | public Instruction createLoadStoreInst(Constant dest, int opcode, List operands, List types,
42 | boolean isVolatile){
43 | if(opcode == InstType.loadInst)
44 | return new LoadInst(dest, opcode, operands, types, isVolatile);
45 | else if(opcode == InstType.storeInst)
46 | return new StoreInst(dest, opcode, operands, types, isVolatile);
47 | return null;
48 | }
49 |
50 | public Instruction createOperationInst(Constant dest, int opcode, List operands, List types,
51 | String op){
52 | return new OperationInst(dest, opcode, operands, types, op);
53 | }
54 |
55 | public Instruction createBinaryInst(Constant dest, int opcode, List operands, List types,
56 | String op, String nuw, String nsw, String exact){
57 | return new BinaryInst(dest, opcode, operands, types, op, nuw, nsw, exact);
58 | }
59 |
60 | public Instruction createGetElePtrInst(Constant dest, int opcode, List operands, List types, boolean inbounds){
61 | return new GetElePtrInst(dest, opcode, operands, types, inbounds);
62 | }
63 | }
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/Instruction.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.ESP.ILocation;
6 | import cn.edu.sjtu.jllvm.VMCore.BasicBlock;
7 | import cn.edu.sjtu.jllvm.VMCore.User;
8 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
9 | import cn.edu.sjtu.jllvm.VMCore.Constants.Function;
10 | import cn.edu.sjtu.jllvm.VMCore.Operators.InstType;
11 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
12 |
13 | /**
14 | * @author liuhao 2011-12-21
15 | * The Instruction class is the common base class for all LLVM instructions.
16 | * It provides only a few methods, but is a very commonly used class.
17 | * The primary data tracked by the Instruction class itself is the opcode
18 | * and the parent BasicBlock the Instruction is embedded into.
19 | * To represent a specific type of instruction, one of many subclasses of Instruction are used.
20 | */
21 | public class Instruction extends User implements ILocation{
22 | protected int opcode;
23 | protected Constant dest;
24 | protected List types;
25 |
26 | protected Instruction preInst; //CFG
27 | protected Instruction nextInst; //CFG
28 | protected BasicBlock parent; //CFG
29 |
30 | protected List numeralOperands; //CFG
31 | protected int numeralDest; //CFG
32 |
33 | public Instruction(Constant dest, int opcode, List operands, List types){
34 | this.opcode = opcode;
35 | this.dest = dest;
36 | this.operands = operands;
37 | this.types = types;
38 |
39 | if(dest!=null){
40 | if(types.size()!=0){
41 | setType(types.get(0));
42 | }
43 | }
44 | }
45 |
46 | public boolean isTerminator(){
47 | return opcode>=InstType.retInst && opcode<=InstType.unreachableInst;
48 | }
49 |
50 | public boolean isRet(){
51 | return opcode == InstType.retInst;
52 | }
53 |
54 | public boolean isUnreachable(){
55 | return opcode == InstType.unreachableInst;
56 | }
57 |
58 | public boolean isCall(){
59 | return opcode == InstType.callInst;
60 | }
61 |
62 | public boolean isLoad(){
63 | return opcode == InstType.loadInst;
64 | }
65 |
66 | public boolean isStore(){
67 | return opcode == InstType.storeInst;
68 | }
69 |
70 | public boolean isGetElePtr(){
71 | return opcode == InstType.getElePtrInst;
72 | }
73 |
74 | public boolean isBranch(){
75 | return opcode == InstType.brInst;
76 | }
77 |
78 | public boolean isConditionalBranch(){
79 | if(isBranch()){
80 | if(this.getNumOperands()>1)
81 | return true;
82 | }
83 | return false;
84 | }
85 |
86 | public boolean isSwitch(){
87 | return opcode == InstType.switchInst;
88 | }
89 |
90 | public boolean isIcmp(){
91 | return opcode == InstType.icmpInst;
92 | }
93 |
94 | public boolean isAllocation(){
95 | return opcode == InstType.allocaInst;
96 | }
97 |
98 | public boolean isBitcast(){
99 | //see in OperationInst
100 |
101 | return false;
102 | }
103 |
104 | public boolean isCastInst(){
105 | //see in OperationInst
106 |
107 | return false;
108 | }
109 |
110 | public boolean isPHINode() {
111 | return opcode == InstType.phiInst;
112 | }
113 |
114 | public boolean isConverInst() {
115 | return opcode == InstType.converInst;
116 | }
117 |
118 | public boolean isSelectIns() {
119 | return opcode == InstType.selectInst;
120 | }
121 |
122 | /**
123 | * @param inst
124 | * @return: true, if the inst has more than one predecessors.
125 | */
126 | public boolean isMerge(){
127 | BasicBlock parent = getParent();
128 | if(this==parent.getFirst()){
129 | if(parent.getNumPredecessor()>1) //more than one predecessor
130 | return true;
131 | }
132 |
133 | return false;
134 | }
135 |
136 | public Instruction getPreInst() {
137 | return preInst;
138 | }
139 |
140 | public void setPreInst(Instruction preInst) {
141 | this.preInst = preInst;
142 | }
143 |
144 | public Instruction getNextInst() {
145 | return nextInst;
146 | }
147 |
148 | public void setNextInst(Instruction nextInst) {
149 | this.nextInst = nextInst;
150 | }
151 |
152 | public Function getFunction() {
153 | return parent.getParent();
154 | }
155 |
156 | public BasicBlock getParent() {
157 | return parent;
158 | }
159 |
160 | public void setParent(BasicBlock parent) {
161 | this.parent = parent;
162 | }
163 |
164 | public List getNumeralOperands() {
165 | return numeralOperands;
166 | }
167 |
168 | public int getNumeralOperand(int index){
169 | return numeralOperands.get(index);
170 | }
171 |
172 | public int getNumNumeralOperand(){
173 | return numeralOperands.size();
174 | }
175 |
176 | public void setNumeralOperands(List numeralOperands) {
177 | this.numeralOperands = numeralOperands;
178 | }
179 |
180 | public int getNumeralDest() {
181 | return numeralDest;
182 | }
183 |
184 | public void setNumeralDest(int numeralDest) {
185 | this.numeralDest = numeralDest;
186 | }
187 |
188 | public int getNumTypes(){
189 | if(types==null)
190 | return 0;
191 | return types.size();
192 | }
193 | public Type getType(int index){
194 | if(index>=getNumTypes())
195 | return null;
196 | return types.get(index);
197 | }
198 | public int getOpcode() {
199 | return opcode;
200 | }
201 | public Constant getDest() {
202 | return dest;
203 | }
204 | public List getOperands() {
205 | return operands;
206 | }
207 | public List getTypes() {
208 | return types;
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/LoadInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Operators.InstType;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 |
9 | public class LoadInst extends Instruction {
10 | private boolean isVolatile;
11 | public LoadInst(Constant dest, int opcode, List operands, List types,
12 | boolean isVolatile){
13 | super(dest, opcode, operands, types);
14 | this.isVolatile = isVolatile;
15 |
16 | if(opcode == InstType.loadInst){
17 | setType(types.get(0).getSubType());
18 | }
19 | }
20 | public boolean isVolatile() {
21 | return isVolatile;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/OperationInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 | import java.util.List;
3 |
4 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
5 | import cn.edu.sjtu.jllvm.VMCore.Operators.Operator;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | public class OperationInst extends Instruction{
9 | protected int op;
10 | public OperationInst(Constant dest, int opcode, List operands, List types,
11 | String opStr){
12 | super(dest, opcode, operands, types);
13 | this.op = Operator.getOpcode(opStr);
14 |
15 | if(dest!=null){
16 | if(types.size()>0){
17 | if(Operator.isConvert(op)){
18 | setType(types.get(types.size()-1));
19 | }
20 | }
21 | }
22 | }
23 |
24 | @Override
25 | public boolean isBitcast(){
26 | return op == Operator.bitcast;
27 | }
28 |
29 | @Override
30 | public boolean isCastInst(){
31 | return (op>=Operator.trunc && op<=Operator.bitcast);
32 |
33 | }
34 |
35 | public String getOpStr(){
36 | return Operator.getOpStr(op);
37 | }
38 |
39 | public static OperationInst create(Constant dest, int opcode, List operands, List types,
40 | String op){
41 | return new OperationInst(dest, opcode, operands, types, op);
42 | }
43 | }
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/PHIInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | /**
9 | * @author liuhao 2011-12-21
10 | * phi
11 | */
12 | public class PHIInst extends Instruction {
13 | public PHIInst(Constant dest, int opcode, List operands, List types){
14 | super(dest, opcode, operands, types);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/SelectInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | public class SelectInst extends Instruction{
9 | public SelectInst(Constant dest, int opcode, List operands, List types){
10 | super(dest, opcode, operands, types);
11 |
12 | if(types.size()>1){
13 | setType(types.get(1));
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/StoreInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Operators.InstType;
7 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
8 |
9 | public class StoreInst extends Instruction{
10 | private boolean isVolatile;
11 | public StoreInst(Constant dest, int opcode, List operands, List types,
12 | boolean isVolatile){
13 | super(dest, opcode, operands, types);
14 | this.isVolatile = isVolatile;
15 |
16 | if(opcode == InstType.loadInst){
17 | setType(types.get(0).getSubType());
18 | }
19 | }
20 | public boolean isVolatile() {
21 | return isVolatile;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Instructions/TerminatorInst.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore.Instructions;
2 |
3 | import java.util.List;
4 |
5 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
6 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
7 |
8 | /**
9 | * @author liuhao 2011-12-21
10 | * retInst,unwindInst,brInst,switchInst,indirectBrInst,invokeInst,unreachableInst;
11 | */
12 | public class TerminatorInst extends Instruction {
13 | public TerminatorInst(Constant dest, int opcode, List operands, List types){
14 | super(dest, opcode, operands, types);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/cn/edu/sjtu/jllvm/VMCore/Module.java:
--------------------------------------------------------------------------------
1 | package cn.edu.sjtu.jllvm.VMCore;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Hashtable;
5 | import java.util.List;
6 |
7 | import cn.edu.sjtu.jllvm.VMCore.Constants.Constant;
8 | import cn.edu.sjtu.jllvm.VMCore.Constants.Function;
9 | import cn.edu.sjtu.jllvm.VMCore.Constants.FunctionDeclare;
10 | import cn.edu.sjtu.jllvm.VMCore.Constants.GlobalAlias;
11 | import cn.edu.sjtu.jllvm.VMCore.Constants.GlobalVariable;
12 | import cn.edu.sjtu.jllvm.VMCore.Types.Type;
13 |
14 | /**
15 | * @author liuhao 2011-12-21
16 | * The Module class represents the top level structure present in LLVM programs.
17 | * An LLVM module is effectively either a translation unit of the original program or a combination of several translation units merged by the linker.
18 | * The Module class keeps track of a list of Functions, a list of GlobalVariables, a FunctionTable...
19 | */
20 | public class Module{
21 | private Hashtable globalVarTable;
22 | private Hashtable globalAliasTable;
23 | private Hashtable globalTable;
24 |
25 | private Hashtable namedTypeTable;
26 |
27 | private List functions;
28 | private Hashtable functionTable;
29 |
30 | private List functionDeclares;
31 |
32 | List globalVariables;
33 | List globalAlias;
34 |
35 | private Cell[] globals;
36 |
37 | boolean COMPLEX = true;
38 |
39 | public Module(List globalVariables, List | | |