6
Last Updated: 12th April 2014
8
This file provides the semantics of CCDFG. It specifies what it
9
means to execute a CCDFG. This can be viewed as providing an
10
interpreter semantics to a parse tree.
12
The syntax and semantics together provide a way to write a program in
13
terms of a graph and allow classical logic to manipulate and reason
14
about that graph-based program.
19
(include-book "functions")
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23
;; Section 1: Execute a statement in a CCDFG
24
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26
;; execute-store statement
27
(defun append-pos (val pos heap)
28
(if (or (not (integerp val))
32
(if (equal pos 0) (append (list val) (cdr heap))
33
(append (list (car heap))
34
(append-pos val (1- pos) (cdr heap))))))
36
;; stmt is store value address v
37
(defun execute-store (stmt init-state)
38
(let* ((val (evaluate-val (second stmt) (car init-state)))
39
(addr (evaluate-val (third stmt) (car init-state)))
40
(heap (evaluate-val (fourth stmt) (third init-state))))
41
(if (or (not (integerp addr))
46
(list (car init-state) (second init-state)
47
(replace-var (fourth stmt)
48
(append-pos val addr heap)
49
(third init-state))))))
51
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
52
;; Now execution of assignment statement.
53
;; This really is in two parts. First we will need to evaluate the
54
;; expression and then we will do an assignment of the appropriate
55
;; variable to extend the mapping.
57
(defun evaluate-load (expr mem bindings)
58
(let* ((addr (evaluate-val (second expr) bindings)))
59
(if (or (not (integerp addr))
61
(>= addr (- (len mem) 2))) nil
62
(nth addr (cdr mem)))))
64
(defun evaluate-load2 (expr mem bindings)
65
(let* ((addr (evaluate-val (second expr) bindings)))
66
(if (or (not (integerp addr))
68
(>= addr (- (len mem) 2))) nil
69
(nth addr (cdr mem)))))
71
(defun evaluate-add (expr bindings)
72
(let ((op1 (evaluate-val (second expr) bindings))
73
(op2 (evaluate-val (third expr) bindings)))
74
(if (and (acl2-numberp op1)
79
(defun evaluate-xor (expr bindings)
80
(let* ((op1 (evaluate-val (second expr) bindings))
81
(op2 (evaluate-val (third expr) bindings)))
82
(let ((res (xor (if (equal op1 0) nil t)
83
(if (equal op2 0) nil t))))
84
(if (equal (or op1 op2) nil) nil
87
(defun evaluate-lshr (expr bindings)
88
(let ((op1 (evaluate-val (second expr) bindings))
89
(op2 (evaluate-val (third expr) bindings)))
90
(if (and (integerp op1)
95
(defun evaluate-shl (expr bindings)
96
(let* ((op1 (evaluate-val (second expr) bindings))
97
(op2 (evaluate-val (third expr) bindings)))
98
(if (and (integerp op1)
103
(defun evaluate-symbol (expr bindings)
104
(let ((op (evaluate-val (first expr) bindings)))
107
(defun evaluate-eq (expr bindings)
108
(let ((op1 (evaluate-val (second expr) bindings))
109
(op2 (evaluate-val (third expr) bindings)))
110
(if (equal op1 op2) 1
113
(defun evaluate-ptr (expr ptrs)
114
(let ((op (nth 0 (evaluate-val (second expr) ptrs))))
117
(defun execute-assignment (stmt init-state)
119
((expr (second stmt))
123
((load-expression-p expr) (evaluate-load expr (second init-state) (car init-state)))
124
((load2-expression-p expr) (evaluate-load2 expr (second init-state) (car init-state)))
125
((add-expression-p expr) (evaluate-add expr (car init-state)))
126
((xor-expression-p expr) (evaluate-xor expr (car init-state)))
127
((shl-expression-p expr) (evaluate-shl expr (car init-state)))
128
((lshr-expression-p expr) (evaluate-lshr expr (car init-state)))
129
((eq-expression-p expr) (evaluate-eq expr (car init-state)))
130
((getelementptr-expression-p expr) (evaluate-ptr expr (third init-state)))
131
((symbol-expression-p expr) (evaluate-symbol expr (car init-state)))
132
(t (er hard 'evaluate-assignment "wrong expression ~p0~%" expr)))))
133
(list (replace-var var val (car init-state)) (second init-state) (third init-state))))
135
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
139
(defun choose (choices prev-bb)
140
(if (or (equal (nth 1 (first choices)) prev-bb)
141
(equal (symbol-name (nth 1 (first choices))) prev-bb))
142
(nth 0 (first choices))
143
(nth 0 (second choices))))
145
;;one stmt is (|%v0_1| (phi (|%v0_2| bb) (|%v0| entry)))
146
(defun execute-phi (stmt init-state prev-bb)
152
((phi-expression-p expr) (evaluate-val (choose (cdr (car expr)) prev-bb) (car init-state)))
153
(t (er hard 'evaluate-phi "wrong expression ~p0~%" expr)))))
154
(list (replace-var var val (car init-state)) (second init-state) (third init-state))))
156
(defun execute-phi-s (stmts init-state prev-bb)
158
(not (consp stmts))) init-state
159
(execute-phi-s (cdr stmts)
160
(execute-phi (car stmts)
165
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
167
;; while executing a CCDFG, we give special treatement to phi and branch statements,
168
;; for others we do execute-statement
169
;; so we have branch, assignment and store
170
;; we keep phi separate as it is not used once phi-construct is removed
171
;; we keep branch separate as it changes the control flow
172
(defun execute-statement (stmt init-state)
173
(cond ((branch-statement-p stmt) init-state)
174
((store-statement-p stmt) (execute-store (car stmt) init-state))
175
((assignment-statement-p stmt) (execute-assignment (car stmt) init-state))
178
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
180
;; br bb1 [from entry]
181
(defun get-next-block-uncond (stmt init-state)
182
(declare (ignore init-state))
185
;; A conditional branch statement has a condition label and two
186
;; targets (based on the value of the source).
187
;; condition is either true or false
188
(defun get-next-block-cond (stmt init-state)
189
(let* ((condition (evaluate-val (second stmt) (car init-state)))
192
(if (equal condition 1)
196
;; gives the name of the next basic block by evaluating the branch statement
197
(defun get-next-bb (stmt init-state)
198
(if (unconditional-branch-statement-p stmt)
199
(get-next-block-uncond stmt init-state)
200
(get-next-block-cond stmt init-state)))
202
;; finds the next steps in same list of msteps from where to start executing if encounter a branch
203
(defun next-to-execute (msteps bb)
204
(if (endp msteps) nil
205
(if (equal (prefix (car msteps))
208
(next-to-execute (cdr msteps) bb))))
210
;; if there is no branch statement in the block, next block is the one in order
211
;; if there is a branch which has been used within the block, then too
212
;; else next block is found by get-next-bb
213
(defun get-next-lists (l init-state)
215
(if (not (branch-statement-p (cdr (car l))))
216
(get-next-lists (cdr l) init-state)
217
(if (equal (next-to-execute (cdr l) (get-next-bb (cadr (car l)) init-state)) nil)
218
(get-next-bb (cadr (car l)) init-state)
221
(defun get-next-block (block init-state)
223
(if (equal (get-next-block (cdr block) (get-next-lists (car block) init-state)) nil)
224
(get-next-lists (car block) init-state)
227
;; if branch-statement, go to next stmt with the next bb if in the same block
228
;; for everything else, execute-statement and go to next one
229
;; when you run a block, we go in order unless there is a branch
230
;; a block is a list of msteps
233
(defun run-lists (msteps init-state next prev)
234
(if (endp msteps) init-state
235
(if (or (equal next nil)
236
(equal next (prefix (car msteps))))
237
(if (branch-statement-p (cdr (car msteps)))
238
(run-lists (next-to-execute (cdr msteps) (get-next-bb (cadr (car msteps)) init-state))
242
(if (phi-statements-p (cdar msteps))
243
(run-lists (cdr msteps) (execute-phi-s (cdar msteps) init-state prev) nil prev)
244
(run-lists (cdr msteps) (execute-statement (cdar msteps) init-state) nil prev)))
245
(run-lists (cdr msteps) init-state next prev))))
248
(defun run-block (b init-state next prev)
249
(if (endp b) init-state
250
(run-block (cdr b) (run-lists (car b) init-state next
252
(get-next-block b init-state)
255
;; run a set of blocks, c here is equivalent to a list of basic blocks
256
;; (cadar c) = ((a) (b) (c))
257
;; first statement is (caar (cadar c))
258
;; if next is nil or next is equal to prefix of first statement, then execute the first statement
259
(defun run-block-set (c init-state next-bb prev)
260
(if (endp c) init-state
261
(run-block-set (cdr c) (run-block (cadar c) init-state next-bb prev)
262
(get-next-block (cadar c) init-state)
265
;; run the entire loop block set for certian number of iterations
266
;; c = ((name1 ((a)(b)(c))) (name2 (()()())))
267
(defun run-blocks-iters (c init-state iter prev)
268
(if (zp iter) init-state
269
(run-blocks-iters c (run-block-set c init-state nil prev) (- iter 1) prev)))
271
;; Because we want loop to be iterated a certain number of types,
272
;; I have divided run a ccdfg into run-pre, run-loop and run-post
273
;; run-ccdfg-k means run-pre, then run-loop for k iterations
274
(defun run-ccdfg-k (pre loop iterations init-state prev)
275
(let* ((state1 (run-block-set pre init-state nil prev))
276
(state2 (run-blocks-iters loop state1 iterations
277
(prefix (car (last (cadar (last loop))))))))
280
;; run-pre, then run-loop for k iterations, then run-post
281
(defun run-ccdfg (pre loop post iterations init-state prev)
282
(let* ((state1 (run-block-set pre init-state nil prev))
283
(state2 (run-blocks-iters loop state1 iterations
284
(prefix (car (last (cadar (last loop)))))))
285
(state3 (run-block-set post state2 nil
286
(prefix (car (last (cadar (last post))))))))