Skip to content

Commit

Permalink
Merge pull request #121 from UQ-PAC/performance-tests
Browse files Browse the repository at this point in the history
Performance tests
  • Loading branch information
ailrst authored Nov 1, 2023
2 parents a14ddea + e9b5b0a commit 5f02a10
Show file tree
Hide file tree
Showing 12 changed files with 346 additions and 118 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ samples/const_prop_tests/
src/main/antlr4/.antlr
*.bpl
*.dot
*.il
result.txt
examplesold/
src/test/scala/dump/
Expand Down
6 changes: 3 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ updateExpected := {
if (resultPath.exists()) {
val result = IO.read(resultPath)
val verified = result.strip().equals("Boogie program verifier finished with 0 errors")
if (verified == shouldVerify && outPath.exists()) {
if (!expectedPath.exists() || !compareFiles(outPath, expectedPath)) {
if (verified == shouldVerify) {
if (outPath.exists() && !(expectedPath.exists() && filesContentEqual(outPath, expectedPath))) {
IO.copyFile(outPath, expectedPath)
}
}
Expand All @@ -59,7 +59,7 @@ updateExpected := {
}
}

def compareFiles(path1: File, path2: File): Boolean = {
def filesContentEqual(path1: File, path2: File): Boolean = {
val source1 = Source.fromFile(path1)
val source2 = Source.fromFile(path2)
val lines1 = source1.getLines
Expand Down
22 changes: 12 additions & 10 deletions src/main/scala/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ object Main {
@arg(name = "spec", short = 's', doc = "BASIL specification file.")
specFileName: Option[String],
@arg(name = "output", short = 'o', doc = "Boogie output destination file.")
outFileName: String = "boogie_out.bpl",
outFileName: String = "basil-out",
@arg(name = "boogie-use-lambda-stores", doc = "Use lambda representation of store operations.")
lambdaStores: Flag,
@arg(name = "verbose", short = 'v', doc = "Show extra debugging logs.")
verbose: Flag,
@arg(name = "analyse", doc = "Run static analysis pass.")
analyse: Flag,
@arg(name = "interpret", doc = "Run BASIL IL interpreter.")
interpret: Flag,
@arg(name = "dump-il", doc = "Dump the Intermediate Language to text.")
dumpIL: Flag,
dumpIL: Option[String],
@arg(name = "help", short = 'h', doc = "Show this help message.")
help: Flag
)
Expand All @@ -57,15 +59,15 @@ object Main {
Logger.setLevel(LogLevel.DEBUG)
}

val program: BProgram = RunUtils.loadAndTranslate(
conf.adtFileName,
conf.relfFileName,
conf.specFileName,
conf.analyse.value,
conf.interpret.value,
conf.dumpIL.value
val q = BASILConfig(
loading = ILLoadingConfig(conf.adtFileName, conf.relfFileName, conf.specFileName, conf.dumpIL),
runInterpret = conf.interpret.value,
staticAnalysis = if (conf.analyse.value) then Some(StaticAnalysisConfig(conf.dumpIL)) else None,
boogieTranslation = BoogieGeneratorConfig(if (conf.lambdaStores.value) then BoogieMemoryAccessMode.LambdaStoreSelect else BoogieMemoryAccessMode.SuccessiveStoreSelect),
outputPrefix = conf.outFileName
)
RunUtils.writeToFile(program, conf.outFileName)

RunUtils.run(q);
}

}
65 changes: 65 additions & 0 deletions src/main/scala/boogie/BExpr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,15 @@ trait QuantifierExpr(sort: Quantifier, bound: List[BVar], body: BExpr) extends B
enum Quantifier {
case forall
case exists
case lambda
}

case class ForAll(bound: List[BVar], body: BExpr) extends QuantifierExpr(Quantifier.forall, bound, body)

case class Exists(bound: List[BVar], body: BExpr) extends QuantifierExpr(Quantifier.exists, bound, body)

case class Lambda(bound: List[BVar], body: BExpr) extends QuantifierExpr(Quantifier.lambda, bound, body)

case class Old(body: BExpr) extends BExpr {
override def toString: String = s"old($body)"
override def getType: BType = body.getType
Expand Down Expand Up @@ -471,6 +474,68 @@ case class GammaStoreOp(addressSize: Int, bits: Int, accesses: Int) extends Func
}
case class LOp(memoryType: BType, indexType: BType) extends FunctionOp

/**
* Utility to extract a particular byte from a bitvector.
*/
case class ByteExtract(valueSize: Int, offsetSize: Int) extends FunctionOp {
val fnName: String = s"byte_extract${valueSize}_${offsetSize}"
}

case class BByteExtract(value: BExpr, offset: BExpr) extends BExpr {
override def toString: String = s"$fnName($value, $offset)"

val valueSize: Int = value.getType match {
case b: BitVecBType => b.size
case _ => throw new Exception(s"ByteExtract does not have Bitvector type: $this")
}

val offsetSize: Int = offset.getType match {
case b: BitVecBType => b.size
case _ => throw new Exception(s"ByteExtract does not have Bitvector type: $this")
}

val fnName: String = s"byte_extract${valueSize}_${offsetSize}"

override val getType: BType = BitVecBType(8)
override def functionOps: Set[FunctionOp] =
value.functionOps ++ offset.functionOps + ByteExtract(valueSize, offsetSize)
override def locals: Set[BVar] = value.locals ++ offset.locals
override def globals: Set[BVar] = value.globals ++ offset.globals
override def loads: Set[BExpr] = value.loads ++ offset.loads
}

/**
* Utility to test if a particular value i is within the bounds of a base variable
* and some length. Factors in the problem of wrap around, given the base + length
* exceeds the bitvector size.
*
* Assumes all inputs are of the same bitvector width.
*/
case class InBounds(bits: Int, endian: Endian) extends FunctionOp {
val fnName: String = endian match {
case Endian.LittleEndian => s"in_bounds${bits}_le"
case Endian.BigEndian=> s"in_bounds${bits}_be"
}
}

case class BInBounds(base: BExpr, len: BExpr, endian: Endian, i: BExpr) extends BExpr {
override def toString: String = s"$fnName($base, $len, $i)"

val baseSize: Int = base.getType match {
case b: BitVecBType => b.size
case _ => throw new Exception(s"InBounds does not have Bitvector type: $this")
}

val fnName: String = s"in_bounds${baseSize}"

override val getType: BType = BoolBType
override def functionOps: Set[FunctionOp] =
base.functionOps ++ len.functionOps ++ i.functionOps + InBounds(baseSize, endian)
override def locals: Set[BVar] = base.locals ++ len.locals ++ i.locals
override def globals: Set[BVar] = base.globals ++ len.globals ++ i.globals
override def loads: Set[BExpr] = base.loads ++ len.loads ++ i.loads
}

case class BMemoryLoad(memory: BMapVar, index: BExpr, endian: Endian, bits: Int) extends BExpr {
override def toString: String = s"$fnName($memory, $index)"

Expand Down
17 changes: 8 additions & 9 deletions src/main/scala/boogie/BProgram.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ case class BProcedure(
freeRequires: List[BExpr],
modifies: Set[BVar],
body: List[BCmdOrBlock],
override val attributes: List[BAttribute]
) extends BDeclaration()
override val attributes: List[BAttribute] = List()
) extends BDeclaration
with Ordered[BProcedure] {
override def compare(that: BProcedure): Int = name.compare(that.name)
override def toBoogie: List[String] = {
Expand All @@ -43,7 +43,7 @@ case class BProcedure(
val freeRequiresStrs = freeRequires.map(r => s" free requires $r;")
val freeEnsuresStrs = freeEnsures.map(e => s" free ensures $e;")
val locals = body.flatMap(l => l.locals).distinct.sorted
val localDefs = locals.map(l => " " + BVarDecl(l, List.empty).toString)
val localDefs = locals.map(l => " " + BVarDecl(l).toString)
val bodyStr = if (body.nonEmpty) {
List("{") ++ localDefs ++ body.flatMap(x => x.toBoogie).map(s => " " + s) ++ List("}")
} else {
Expand All @@ -62,15 +62,14 @@ case class BProcedure(
def globals: Set[BVar] = body.flatMap(c => c.globals).toSet ++ modifies
}

case class BAxiom(body: BExpr, override val attributes: List[BAttribute]) extends BDeclaration() {
case class BAxiom(body: BExpr, override val attributes: List[BAttribute] = List()) extends BDeclaration {
override def toString: String = s"axiom $attrString$body;"
}

case class BFunction(name: String, in: List[BVar], out: BVar, body: Option[BExpr],
override val attributes: List[BAttribute])
extends BDeclaration()
override val attributes: List[BAttribute] = List())
extends BDeclaration
with Ordered[BFunction] {

override def compare(that: BFunction): Int = name.compare(that.name)
override def toBoogie: List[String] = {
val inString = in.map(_.withType).mkString(", ")
Expand All @@ -87,7 +86,7 @@ case class BFunction(name: String, in: List[BVar], out: BVar, body: Option[BExpr
}
}

case class BVarDecl(variable: BVar, override val attributes: List[BAttribute]) extends BDeclaration() with Ordered[BVarDecl] {
case class BVarDecl(variable: BVar, override val attributes: List[BAttribute] = List()) extends BDeclaration with Ordered[BVarDecl] {
def compare(that: BVarDecl): Int = variable.compare(that.variable)
override def toString: String = if (variable.scope == Scope.Const) {
s"const $attrString$variable: ${variable.getType};"
Expand All @@ -96,7 +95,7 @@ case class BVarDecl(variable: BVar, override val attributes: List[BAttribute]) e
}
}

case class BConstAxiomPair(const: BVarDecl, axiom: BAxiom) extends BDeclaration() with Ordered[BConstAxiomPair] {
case class BConstAxiomPair(const: BVarDecl, axiom: BAxiom) extends BDeclaration with Ordered[BConstAxiomPair] {
override def compare(that: BConstAxiomPair): Int = const.compare(that.const)
override def toString: String = const.toString + "\n" + axiom.toString
}
Loading

0 comments on commit 5f02a10

Please sign in to comment.