Skip to content

Commit 800dd6f

Browse files
authored
Merge pull request #336 from UQ-PAC/simp-pass-dsa
Simplification Pass DSA
2 parents 37bbf3d + e78f229 commit 800dd6f

18 files changed

+1593
-108
lines changed

mill

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,4 @@ unset MILL_REPO_URL
238238

239239
# We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes
240240
# shellcheck disable=SC2086
241-
exec "${MILL}" $MILL_FIRST_ARG -D "mill.main.cli=${MILL_MAIN_CLI}" "$@"
241+
exec "${MILL}" $MILL_FIRST_ARG -D "mill.main.cli=${MILL_MAIN_CLI}" "$@"

src/main/scala/analysis/data_structure_analysis/Constraints.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ sealed trait CallConstraint[T <: Call, V <: Procedure | Variable](call: T) exten
7676
def caller: Procedure = call.parent.parent
7777
def target: V
7878
val inParams: Map[LocalVar, Expr]
79-
val outParmas: Map[LocalVar, LocalVar]
79+
val outParams: Map[LocalVar, LocalVar]
8080
def inConstraints: Set[AssignmentConstraint] =
8181
inParams.map(pair => AssignmentConstraint(call, pair._1, pair._2)).toSet
8282
def outConstraints: Set[AssignmentConstraint] =
83-
outParmas.map(pair => AssignmentConstraint(call, pair._1, pair._2)).toSet
83+
outParams.map(pair => AssignmentConstraint(call, pair._1, pair._2)).toSet
8484
override def source: T = call
8585
override def toString: String = eval()
8686

@@ -94,15 +94,15 @@ case class DirectCallConstraint(call: DirectCall) extends CallConstraint[DirectC
9494
override def target: Procedure = call.target
9595

9696
override val inParams: Map[LocalVar, Expr] = call.actualParams
97-
override val outParmas: Map[LocalVar, LocalVar] = call.outParams.view.mapValues(_.asInstanceOf[LocalVar]).toMap
97+
override val outParams: Map[LocalVar, LocalVar] = call.outParams.view.mapValues(_.asInstanceOf[LocalVar]).toMap
9898
}
9999

100100
case class IndirectCallConstraint(call: IndirectCall) extends CallConstraint[IndirectCall, Variable](call) {
101101

102102
override def target: Variable = call.target
103103

104104
override val inParams: Map[LocalVar, Expr] = Map.empty
105-
override val outParmas: Map[LocalVar, LocalVar] = Map.empty
105+
override val outParams: Map[LocalVar, LocalVar] = Map.empty
106106
}
107107

108108
def generateConstraints(proc: Procedure): Set[Constraint] = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package analysis.data_structure_analysis
2+
3+
import analysis.solvers.{DSAUnionFindSolver, OffsetUnionFindSolver, UnionFindSolver}
4+
import ir.{Expr, Procedure, Program}
5+
import specification.{ExternalFunction, SymbolTableEntry}
6+
import util.{DSALogger, IRContext}
7+
import java.io.File
8+
9+
import scala.collection.{SortedSet, mutable}
10+
11+
trait Counter(val init: Int = 0) {
12+
private var counter = init
13+
def increment(by: Int = 1): Int = {
14+
counter += by
15+
counter
16+
}
17+
18+
def decrement(by: Int = 1): Int = {
19+
counter -= by
20+
counter
21+
}
22+
23+
def get: Int = counter
24+
25+
def reset(): Unit = counter = init
26+
}
27+
28+
enum DSAPhase {
29+
case Pre, Local, BU, TD
30+
}
31+
32+
enum Interval(val start: Option[Int], val end: Option[Int]) {
33+
case Top extends Interval(None, None)
34+
case Value(s: Int, e: Int) extends Interval(Some(s), Some(e))
35+
36+
override def toString: String =
37+
this match
38+
case Interval.Top => "Top"
39+
case Interval.Value(start, end) => s"$start-${end - 1}"
40+
41+
def size: Option[Int] =
42+
this match
43+
case Interval.Top => None
44+
case Interval.Value(start, end) => Some(end - 1 - start)
45+
46+
def move(func: Int => Int): Interval =
47+
this match
48+
case Interval.Top => Interval.Top
49+
case Interval.Value(start, end) => Value(func(start), func(end))
50+
51+
def isEmpty: Boolean = this.size.contains(0)
52+
53+
def growTo(size: Int): Interval =
54+
this match
55+
case Interval.Top => Interval.Top
56+
case Interval.Value(start, end) => Interval(start, math.max(end, start + size))
57+
58+
def contains(offset: Int): Boolean =
59+
this match
60+
case Interval.Top => true
61+
case Interval.Value(start, end) => start <= offset && end > offset
62+
63+
def contains(interval: Interval): Boolean =
64+
(this, interval) match
65+
case (Interval.Top, _) => true
66+
case (_, Interval.Top) => false // this is not top
67+
case (Interval.Value(start1, end1), Interval.Value(start2, end2)) =>
68+
start1 <= start2 && end1 >= end2
69+
70+
def isOverlapping(other: Interval): Boolean =
71+
(this, other) match
72+
case (Interval.Top, _) => true
73+
case (_, Interval.Top) => true
74+
case (Interval.Value(start1, end1), Interval.Value(start2, end2)) =>
75+
!(start1 >= end2 || start2 >= end1)
76+
77+
def join(other: Interval): Interval = {
78+
(this, other) match
79+
case (Interval.Top, _) => Interval.Top
80+
case (_, Interval.Top) => Interval.Top
81+
case (Interval.Value(start1, end1), Interval.Value(start2, end2)) =>
82+
Interval(math.min(start1, start2), math.max(end1, end2))
83+
}
84+
}
85+
86+
object Interval {
87+
def apply(start: Int, end: Int) = Interval.Value(start, end)
88+
def join(interval1: Interval, interval2: Interval): Interval = interval1.join(interval2)
89+
implicit def orderingByTuple[T <: Interval]: Ordering[T] =
90+
Ordering.by { case Interval.Value(start, end) =>
91+
(start, end)
92+
}
93+
}
94+
95+
class DSFlag {
96+
var collapsed = false
97+
var function = false
98+
var stack = false
99+
var heap = false
100+
var global = false
101+
var unknown = false
102+
var read = false
103+
var modified = false
104+
var incomplete = false
105+
var foreign = false
106+
var merged = false
107+
108+
def join(other: DSFlag): Unit =
109+
collapsed = collapsed || other.collapsed
110+
stack = other.stack || stack
111+
heap = other.heap || heap
112+
global = other.global || global
113+
unknown = other.unknown || unknown
114+
read = other.read || read
115+
modified = other.modified || modified
116+
incomplete = other.incomplete || incomplete
117+
foreign = other.foreign && foreign
118+
merged = true
119+
function = function || other.function
120+
}
121+
122+
def computeDSADomain(proc: Procedure, context: IRContext): Set[Procedure] = {
123+
var domain: Set[Procedure] = Set(proc) ++ (context.program.procedures.filter(f =>
124+
context.funcEntries.map(_.name).filter(!_.startsWith("_")).contains(f.procName)
125+
))
126+
127+
val stack: mutable.Stack[Procedure] = mutable.Stack()
128+
stack.pushAll(domain.flatMap(_.calls))
129+
130+
// calculate the procedures used in the program
131+
while (stack.nonEmpty) {
132+
val current = stack.pop()
133+
domain += current
134+
stack.pushAll(current.calls.diff(domain))
135+
}
136+
137+
domain
138+
}
139+
140+
trait DSACell

0 commit comments

Comments
 (0)