Skip to content

Commit a8c31c6

Browse files
committed
Split Intrinsic.Copy on MemoryAccess.Default with IP enabled.
1 parent 617d245 commit a8c31c6

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

shared/src/main/scala/org/sireum/anvil/Anvil.scala

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,11 @@ import Anvil._
506506

507507
config.memoryAccess match {
508508
case Anvil.Config.MemoryAccess.Default =>
509+
if (config.useIP) {
510+
p = anvil.transformCopyDefaultIp(fresh, p, maxTemps)
511+
output.add(F, irProcedurePath(p.id, p.tipe, stage, pass, "copy"), p.prettyST(anvil.printer))
512+
pass = pass + 1
513+
}
509514
case Anvil.Config.MemoryAccess.Subroutine =>
510515

511516
p = anvil.transformTempLoadSubroutine(fresh, p, maxTemps)
@@ -1285,6 +1290,58 @@ import Anvil._
12851290
return p(body = body(blocks = blocks))
12861291
}
12871292

1293+
def transformCopyDefaultIp(fresh: lang.IRTranslator.Fresh, p: AST.IR.Procedure, maxTemps: TempVector): AST.IR.Procedure = {
1294+
val spt: AST.Typed = if (config.splitTempSizes) spType else AST.Typed.u64
1295+
fresh.setTemp(maxTemps.typeCount(this, spt))
1296+
val lhsOffsetParam = fresh.temp()
1297+
val rhsOffsetParam = fresh.temp()
1298+
val rhsElementSizeParam = fresh.temp()
1299+
1300+
val body = p.body.asInstanceOf[AST.IR.Body.Basic]
1301+
var blocks = ISZ[AST.IR.BasicBlock]()
1302+
for (b <- body.blocks) {
1303+
b.grounds match {
1304+
case ISZ(AST.IR.Stmt.Intrinsic(in: Intrinsic.Copy)) if !in.rhsBytes.isInstanceOf[AST.IR.Exp.Int] =>
1305+
val copyLabel = fresh.label()
1306+
val t = in.rhsTipe
1307+
val pos = in.pos
1308+
var grounds = ISZ[AST.IR.Stmt.Ground]()
1309+
grounds = grounds :+ AST.IR.Stmt.Assign.Temp(lhsOffsetParam, in.lhsOffset, pos)
1310+
grounds = grounds :+ AST.IR.Stmt.Assign.Temp(rhsOffsetParam, in.rhs, pos)
1311+
val sizeInfoOpt = classSizeFieldOffsets(t.asInstanceOf[AST.Typed.Name])._2.get("size")
1312+
if (config.erase || sizeInfoOpt.isEmpty) {
1313+
grounds = grounds :+ AST.IR.Stmt.Assign.Temp(rhsElementSizeParam, in.rhsBytes, pos)
1314+
} else {
1315+
val (sizeType, sizeOffset) = sizeInfoOpt.get
1316+
val elementByteSize: Z = if (t == AST.Typed.string) 1 else typeByteSize(t.asInstanceOf[AST.Typed.Name].args(1))
1317+
var elementSize: AST.IR.Exp = AST.IR.Exp.Type(F,
1318+
AST.IR.Exp.Intrinsic(Intrinsic.Load(
1319+
AST.IR.Exp.Binary(spType, in.rhs, AST.IR.Exp.Binary.Op.Add, AST.IR.Exp.Int(spType, sizeOffset, pos), pos),
1320+
isSigned(sizeType), typeByteSize(sizeType), st"", sizeType, pos)),
1321+
spType, pos)
1322+
if (elementByteSize != 1) {
1323+
elementSize = AST.IR.Exp.Binary(spType, elementSize, AST.IR.Exp.Binary.Op.Mul,
1324+
AST.IR.Exp.Int(spType, elementByteSize, pos), pos)
1325+
}
1326+
grounds = grounds :+ AST.IR.Stmt.Assign.Temp(rhsElementSizeParam, elementSize, pos)
1327+
}
1328+
blocks = blocks :+ AST.IR.BasicBlock(b.label, grounds, AST.IR.Jump.Goto(copyLabel, pos))
1329+
blocks = blocks :+ AST.IR.BasicBlock(copyLabel, ISZ(
1330+
AST.IR.Stmt.Intrinsic(in(
1331+
lhsOffset = AST.IR.Exp.Temp(lhsOffsetParam, spType, pos),
1332+
rhs = AST.IR.Exp.Temp(rhsOffsetParam, spType, pos),
1333+
rhsBytes =
1334+
if (config.erase) AST.IR.Exp.Temp(rhsElementSizeParam, spType, pos)
1335+
else AST.IR.Exp.Binary(spType,
1336+
AST.IR.Exp.Temp(rhsElementSizeParam, spType, pos), AST.IR.Exp.Binary.Op.Add,
1337+
AST.IR.Exp.Int(spType, typeShaSize + typeByteSize(AST.Typed.z), pos), pos)))
1338+
), b.jump)
1339+
case _ => blocks = blocks :+ b
1340+
}
1341+
}
1342+
return p(body = body(blocks = blocks))
1343+
}
1344+
12881345
def transformCopySubroutine(fresh: lang.IRTranslator.Fresh, p: AST.IR.Procedure, maxTemps: TempVector): AST.IR.Procedure = {
12891346
val copyLabel = fresh.label()
12901347
val cpt: AST.Typed = if (config.splitTempSizes) cpType else AST.Typed.u64

0 commit comments

Comments
 (0)