Skip to content

Commit

Permalink
Merge pull request #122 from slothy-optimizer/refine-selftest
Browse files Browse the repository at this point in the history
Refine selftest for Armv7-M
  • Loading branch information
hanno-becker authored Dec 15, 2024
2 parents 097fde4 + 549bc31 commit d74078c
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 69 deletions.
16 changes: 8 additions & 8 deletions examples/naive/armv7m/armv7m_simple0.s
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@

start:
ldr r1, [r0, #4]
ldr r1, [r0, #4] // @slothy:reads=a
add r1, r2,r1
eor.w r1,r1, r3
smlabt r3,r2, r2, r1
asrs r3, r3,#1
str r3, [r0,#4]
str r3, [r0,#4] // @slothy:writes=a

ldm r0, {r1-r2,r14}
ldm r0, {r1-r2,r14} // @slothy:reads=a
add r1, r2,r1
eor.w r1,r1, r14
smlabt r3,r2, r2, r1
asrs r3, r3,#1
str r3, [r0,#4]
str r3, [r0,#4] // @slothy:writes=a


ldm r0, {r1-r3}
ldm r0, {r1-r3} // @slothy:reads=a
add r1, r2,r1
eor.w r1,r1, r3
smlabt r3,r2, r2, r1
asrs r3, r3,#1
str r3, [r0,#4]
str r3, [r0,#4] // @slothy:writes=a

ldm r0, {r1,r2,r3}
ldm r0, {r1,r2,r3} // @slothy:reads=a
add r1, r2,r1
eor.w r1,r1, r3
smlabt r3,r2, r2, r1
asrs r3, r3,#1
str r3, [r0,#4]
str r3, [r0,#4] // @slothy:writes=a

end:
112 changes: 56 additions & 56 deletions examples/opt/armv7m/armv7m_simple0_opt_m7.s
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@

start:
// Instructions: 24
// Expected cycles: 14
// Expected IPC: 1.71
//
// Cycle bound: 14.0
// IPC bound: 1.71
//
// Wall time: 0.40s
// User time: 0.40s
//
// ----- cycle (expected) ------>
// 0 25
// |------------------------|----
ldr r10, [r0, #4] // *.............................
ldm r0, {r1,r7,r14} // .*............................
add r10, r2, r10 // .*............................
eor.w r10, r10, r3 // ..*...........................
smlabt r2, r2, r2, r10 // ..*...........................
ldm r0, {r10,r11,r12} // ....*.........................
add r1, r7, r1 // ....*.........................
eor.w r1, r1, r14 // .....*........................
smlabt r6, r7, r7, r1 // .....*........................
asrs r1, r2, #1 // ......*.......................
str r1, [r0, #4] // ......*.......................
add r4, r11, r10 // .......*......................
ldm r0, {r1,r2,r14} // .......*......................
asrs r10, r6, #1 // ........*.....................
eor.w r6, r4, r12 // ........*.....................
smlabt r11, r11, r11, r6 // .........*....................
add r1, r2, r1 // ..........*...................
str r10, [r0, #4] // ..........*...................
eor.w r1, r1, r14 // ...........*..................
smlabt r7, r2, r2, r1 // ...........*..................
asrs r1, r11, #1 // ............*.................
str r1, [r0, #4] // ............*.................
asrs r3, r7, #1 // .............*................
str r3, [r0, #4] // .............*................
// Instructions: 24
// Expected cycles: 26
// Expected IPC: 0.92
//
// Cycle bound: 26.0
// IPC bound: 0.92
//
// Wall time: 0.14s
// User time: 0.14s
//
// ----- cycle (expected) ------>
// 0 25
// |------------------------|----
ldr r1, [r0, #4] // *............................. // @slothy:reads=a
add r11, r2, r1 // .*............................
eor.w r12, r11, r3 // ..*...........................
smlabt r4, r2, r2, r12 // ..*...........................
asrs r9, r4, #1 // ....*.........................
str r9, [r0, #4] // ....*......................... // @slothy:writes=a
ldm r0, {r2,r6,r14} // .....*........................ // @slothy:reads=a
add r3, r6, r2 // ........*.....................
eor.w r1, r3, r14 // .........*....................
smlabt r6, r6, r6, r1 // .........*....................
asrs r3, r6, #1 // ...........*..................
str r3, [r0, #4] // ...........*.................. // @slothy:writes=a
ldm r0, {r5,r7,r8} // ............*................. // @slothy:reads=a
add r1, r7, r5 // ...............*..............
eor.w r9, r1, r8 // ................*.............
smlabt r5, r7, r7, r9 // ................*.............
asrs r5, r5, #1 // ..................*...........
str r5, [r0, #4] // ..................*........... // @slothy:writes=a
ldm r0, {r1,r2,r10} // ...................*.......... // @slothy:reads=a
add r4, r2, r1 // ......................*.......
eor.w r11, r4, r10 // .......................*......
smlabt r3, r2, r2, r11 // .......................*......
asrs r3, r3, #1 // .........................*....
str r3, [r0, #4] // .........................*.... // @slothy:writes=a

// ------ cycle (expected) ------>
// 0 25
Expand All @@ -45,25 +45,25 @@
// add r1, r2,r1 // .*.............................
// eor.w r1,r1, r3 // ..*............................
// smlabt r3,r2, r2, r1 // ..*............................
// asrs r3, r3,#1 // ......*........................
// str r3, [r0,#4] // ......*........................
// ldm r0, {r1-r2,r14} // ....*..........................
// add r1, r2,r1 // .......*.......................
// eor.w r1,r1, r14 // ........*......................
// asrs r3, r3,#1 // ....*..........................
// str r3, [r0,#4] // ....*..........................
// ldm r0, {r1-r2,r14} // .....*.........................
// add r1, r2,r1 // ........*......................
// eor.w r1,r1, r14 // .........*.....................
// smlabt r3,r2, r2, r1 // .........*.....................
// asrs r3, r3,#1 // ............*..................
// str r3, [r0,#4] // ............*..................
// ldm r0, {r1-r3} // .*.............................
// add r1, r2,r1 // ....*..........................
// eor.w r1,r1, r3 // .....*.........................
// smlabt r3,r2, r2, r1 // .....*.........................
// asrs r3, r3,#1 // ........*......................
// str r3, [r0,#4] // ..........*....................
// ldm r0, {r1,r2,r3} // .......*.......................
// add r1, r2,r1 // ..........*....................
// eor.w r1,r1, r3 // ...........*...................
// smlabt r3,r2, r2, r1 // ...........*...................
// asrs r3, r3,#1 // .............*.................
// str r3, [r0,#4] // .............*.................
// asrs r3, r3,#1 // ...........*...................
// str r3, [r0,#4] // ...........*...................
// ldm r0, {r1-r3} // ............*..................
// add r1, r2,r1 // ...............*...............
// eor.w r1,r1, r3 // ................*..............
// smlabt r3,r2, r2, r1 // ................*..............
// asrs r3, r3,#1 // ..................*............
// str r3, [r0,#4] // ..................*............
// ldm r0, {r1,r2,r3} // ...................*...........
// add r1, r2,r1 // ......................*........
// eor.w r1,r1, r3 // .......................*.......
// smlabt r3,r2, r2, r1 // .......................*.......
// asrs r3, r3,#1 // .........................*.....
// str r3, [r0,#4] // .........................*.....

end:
2 changes: 0 additions & 2 deletions slothy/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1303,8 +1303,6 @@ def variable_size(self,val):
self._variable_size = val
@selftest.setter
def selftest(self,val):
if hasattr(self.arch, "Checker") is False:
raise InvalidConfig("Trying to enable checker, but architecture model does not seem to support it")
self._selftest = val
@selftest_iterations.setter
def selftest_iterations(self,val):
Expand Down
8 changes: 6 additions & 2 deletions slothy/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,13 +838,17 @@ def selftest(self, log):
log.warning("Selftest not supported on target architecture")
return

tree = DFG(self._orig_code, log, DFGConfig(self.config, outputs=self.outputs))

if tree.has_symbolic_registers():
log.info("Skipping selftest as input contains symbolic registers.")
return

log.info(f"Running selftest ({self._config.selftest_iterations} iterations)...")

address_gprs = self._config.selftest_address_gprs
if address_gprs is None:
# Try to infer which registes need to be pointers
log_addresses = log.getChild("infer_address_gprs")
tree = DFG(self._orig_code, log_addresses, DFGConfig(self.config, outputs=self.outputs))
# Look for load/store instructions and remember addresses
addresses = set()
for t in tree.nodes:
Expand Down
12 changes: 12 additions & 0 deletions slothy/core/dataflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,18 @@ def update_inputs(self):
for i,v in enumerate(t.src_in_out):
t.inst.args_in_out[i] = v.reduce().name()

def has_symbolic_registers(self):
rt = self.config._arch.RegisterType
for i in self.nodes:
instr = i.inst
for out, ty in zip(instr.args_out, instr.arg_types_out):
if out not in rt.list_registers(ty):
return True
for inout, ty in zip(instr.args_in_out, instr.arg_types_in_out):
if inout not in rt.list_registers(ty):
return True
return False

def ssa(self, filter_func=None):
"""Transform data flow graph into single static assignment (SSA) form."""
# Go through non-virtual instruction nodes and assign unique names to
Expand Down
5 changes: 4 additions & 1 deletion slothy/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1337,7 +1337,7 @@ def run_code(code, txt=None):
except:
log.error("Failed to emulate code using unicorn engine")
log.error("Code")
log.error(SouceLine.write_multiline(code))
log.error(SourceLine.write_multiline(code))

final_register_contents = {}
for r in regs:
Expand Down Expand Up @@ -1371,6 +1371,9 @@ def run_code(code, txt=None):

# Check that callee-saved registers are the same
for r in output_registers:
# skip over hints
if r.startswith("hint_"):
continue
if final_regs_old[r] != final_regs_new[r]:
raise SelfTestException(f"Selftest failed: Register mismatch for {r}: {hex(final_regs_old[r])} != {hex(final_regs_new[r])}")

Expand Down

0 comments on commit d74078c

Please sign in to comment.