Digital Larry
Active member
This falls into the "may-never-finish-it-but-who-knows" category. I was working on something for work and complaining about the need for a small utility that would take me half a day to try to write because I don't do that sort of thing all the time. My boss says "see if you can get ChatGPT to write it" and it took two tries. It was the first time I'd ever done that and it sort of blew my mind in spite of me being aware this is what people do nowadays so they can have a nice big layoff of software engineers.
So then I started asking about the problem of the Spin optimizer. I have long been able to describe the optimizations, but it's a programming exercise whose level of complexity means it won't get done for leisure.
This was pretty interesting. First of all ChatGPT is eager to please but makes a LOT of mistakes. I gave it the entire Spin ASM manual to read for reference, but I don't think it gets it. Also, it doesn't have a way to enter a line break AFAICT which means you hit "ENTER" before your question is really done and then it starts trying to answer. I had to tell it "wait until I say "cheese"" which it said it would but I think its eagerness still got the best of it a couple times. It also forgets what you told it earlier and can jump to the wrong conclusion easily. So I messedd with it interactively but then also built up my query in a text editor so it would take it all at once.
I know some of you are programmers or in IT so might find this interesting. Right now I had it implement it in Python assuming I would read a file. If I can get that all working then I'll tell it to write it in Java assuming the ASM listing is in whatever structure SpinCAD uses for it.
Here's what I told it:
; full optimizer example
; individual rules are separated by a small letter followed by close parenthesis.
RDAX and WRAX statements are of the form:
RDAX reg, gain
"reg" in the following examples is any integer between 32 and 64, as well as strings in the pattern "REGx" or "regx", where x is an integer between 1 and 32.
a)
rule description:
if RDAX reg, 1.0 follows WRAX reg, 0 (ignoring comments) and there is no further reference to reg
then comment out both statements. Only modify these lines. Do not change any other lines.
example:
; ------- Smoother
RDAX 37, 1.0
RDFX 40, 0.0700
WRAX 40, 0.0
; ------- Scale/Offset
RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
should produce:
RDAX 37, 1.0
RDFX 40, 0.0700
; optimized WRAX 40, 0.0
; ------- Scale/Offset
; optimized RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
---
b)
rule description:
if RDAX reg, 1.0 follows WRAX reg, 0 (ignoring comments) however there is a further reference to reg:
1) Insert a comment above the WRAX statement: "; optimized - changed gain to 1.0"
2) insert the WRAX statement, changing the gain to 1.0.
3) Comment out the RDAX statement as shown below
Only modify these lines. Do not change any other lines.
example:
; ------- Smoother
RDAX 37, 1.0
RDFX 40, 0.0700
WRAX 40, 0.0
; ------- Scale/Offset
RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 40, 0.0
should produce:
RDAX 37, 1.0
RDFX 40, 0.0700
; optimized - changed gain to 1.0
WRAX 40, 1.0
; ------- Scale/Offset
; optimized - RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 40, 0.0
====================
Here's the Python 3.9 code it created (which you should be able to use if you like).
Before code sample:
; test case A
; RDAX ref, 1.0 following WRAX reg, 0 and there is no further use of reg
; remove both WRAX and RDAX
RDAX 37, 1.0
RDFX 40, 0.0700
; next instruction should optimize out
WRAX 40, 0.0
; ------- Scale/Offset
; next instruction should optimize out
RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
; test case B
; RDAX ref, 1.0 following WRAX reg, 0 and there is further use of reg
RDAX 38, 1.0
RDFX 42, 0.0700
; change gain in following instruction to 1.0
WRAX 42, 0.0
; ------- Scale/Offset
; next instruction should optimize out
RDAX 42, 1.0
SOF 0.2700, 0.7300
WRAX 42, 0.0
====
after (optimized) code sample
; test case A
; RDAX ref, 1.0 following WRAX reg, 0 and there is no further use of reg
; remove both WRAX and RDAX
RDAX 37, 1.0
RDFX 40, 0.0700
; next instruction should optimize out
; optimized WRAX 40, 0.0
; optimized RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
; test case B
; RDAX ref, 1.0 following WRAX reg, 0 and there is further use of reg
RDAX 38, 1.0
RDFX 42, 0.0700
; change gain in following instruction to 1.0
; optimized - changed gain to 1.0
WRAX 42, 1.0
; optimized RDAX 42, 1.0
SOF 0.2700, 0.7300
WRAX 42, 0.0
====================
So then I started asking about the problem of the Spin optimizer. I have long been able to describe the optimizations, but it's a programming exercise whose level of complexity means it won't get done for leisure.
This was pretty interesting. First of all ChatGPT is eager to please but makes a LOT of mistakes. I gave it the entire Spin ASM manual to read for reference, but I don't think it gets it. Also, it doesn't have a way to enter a line break AFAICT which means you hit "ENTER" before your question is really done and then it starts trying to answer. I had to tell it "wait until I say "cheese"" which it said it would but I think its eagerness still got the best of it a couple times. It also forgets what you told it earlier and can jump to the wrong conclusion easily. So I messedd with it interactively but then also built up my query in a text editor so it would take it all at once.
I know some of you are programmers or in IT so might find this interesting. Right now I had it implement it in Python assuming I would read a file. If I can get that all working then I'll tell it to write it in Java assuming the ASM listing is in whatever structure SpinCAD uses for it.
Here's what I told it:
; full optimizer example
; individual rules are separated by a small letter followed by close parenthesis.
RDAX and WRAX statements are of the form:
RDAX reg, gain
"reg" in the following examples is any integer between 32 and 64, as well as strings in the pattern "REGx" or "regx", where x is an integer between 1 and 32.
a)
rule description:
if RDAX reg, 1.0 follows WRAX reg, 0 (ignoring comments) and there is no further reference to reg
then comment out both statements. Only modify these lines. Do not change any other lines.
example:
; ------- Smoother
RDAX 37, 1.0
RDFX 40, 0.0700
WRAX 40, 0.0
; ------- Scale/Offset
RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
should produce:
RDAX 37, 1.0
RDFX 40, 0.0700
; optimized WRAX 40, 0.0
; ------- Scale/Offset
; optimized RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
---
b)
rule description:
if RDAX reg, 1.0 follows WRAX reg, 0 (ignoring comments) however there is a further reference to reg:
1) Insert a comment above the WRAX statement: "; optimized - changed gain to 1.0"
2) insert the WRAX statement, changing the gain to 1.0.
3) Comment out the RDAX statement as shown below
Only modify these lines. Do not change any other lines.
example:
; ------- Smoother
RDAX 37, 1.0
RDFX 40, 0.0700
WRAX 40, 0.0
; ------- Scale/Offset
RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 40, 0.0
should produce:
RDAX 37, 1.0
RDFX 40, 0.0700
; optimized - changed gain to 1.0
WRAX 40, 1.0
; ------- Scale/Offset
; optimized - RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 40, 0.0
====================
Here's the Python 3.9 code it created (which you should be able to use if you like).
==============import re
import sys
import os
def optimize_fv1_code(assembly_code):
lines = assembly_code.split('\n')
optimized_lines = []
skip_next = False
i = 0
while i < len(lines):
if skip_next:
skip_next = False
i += 1
continue
stripped = lines.strip()
# Skip processing comment lines
if stripped.startswith(';'):
optimized_lines.append(stripped)
i += 1
continue
# Find the next non-comment instruction
j = i + 1
while j < len(lines) and lines[j].strip().startswith(';'):
j += 1
# Detect WRAX reg, 0 followed by RDAX reg, 1.0
match_wrax = re.match(r'WRAX\s+(\S+),\s*0(?:\.0+)?', stripped)
match_rdax = re.match(r'RDAX\s+(\S+),\s*1.0+', lines[j].strip()) if j < len(lines) else None
if match_wrax and match_rdax and match_wrax.group(1) == match_rdax.group(1):
reg = match_wrax.group(1)
# Check if reg is used between current instruction and the last instruction
used_later = any(
re.search(r'\b' + re.escape(reg) + r'\b', lines[k]) and not lines[k].strip().startswith(';')
for k in range(j + 1, len(lines))
)
if not used_later:
# Rule (a): No further reference, comment out only WRAX and RDAX, keep following instructions
optimized_lines.append(f"; optimized {stripped}")
optimized_lines.append(f"; optimized {lines[j].strip()}")
i = j + 1 # Skip to the next instruction after RDAX
continue
else:
# Rule (b): Further reference exists, change WRAX and comment out RDAX, keep following instructions
optimized_lines.append("; optimized - changed gain to 1.0")
optimized_lines.append(f"WRAX {reg}, 1.0")
optimized_lines.append(f"; optimized {lines[j].strip()}")
i = j + 1 # Skip to the next instruction after RDAX
continue
optimized_lines.append(stripped)
i += 1
return '\n'.join(optimized_lines)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python optimizer.py <input_file>")
sys.exit(1)
input_file = sys.argv[1]
file_root, file_ext = os.path.splitext(input_file)
output_file = f"{file_root}-optimized{file_ext}"
with open(input_file, "r") as file:
input_code = file.read()
optimized_code = optimize_fv1_code(input_code)
with open(output_file, "w") as file:
file.write(optimized_code)
print(f"Optimized file created: {output_file}")
Before code sample:
; test case A
; RDAX ref, 1.0 following WRAX reg, 0 and there is no further use of reg
; remove both WRAX and RDAX
RDAX 37, 1.0
RDFX 40, 0.0700
; next instruction should optimize out
WRAX 40, 0.0
; ------- Scale/Offset
; next instruction should optimize out
RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
; test case B
; RDAX ref, 1.0 following WRAX reg, 0 and there is further use of reg
RDAX 38, 1.0
RDFX 42, 0.0700
; change gain in following instruction to 1.0
WRAX 42, 0.0
; ------- Scale/Offset
; next instruction should optimize out
RDAX 42, 1.0
SOF 0.2700, 0.7300
WRAX 42, 0.0
====
after (optimized) code sample
; test case A
; RDAX ref, 1.0 following WRAX reg, 0 and there is no further use of reg
; remove both WRAX and RDAX
RDAX 37, 1.0
RDFX 40, 0.0700
; next instruction should optimize out
; optimized WRAX 40, 0.0
; optimized RDAX 40, 1.0
SOF 0.2700, 0.7300
WRAX 41, 0.0
; test case B
; RDAX ref, 1.0 following WRAX reg, 0 and there is further use of reg
RDAX 38, 1.0
RDFX 42, 0.0700
; change gain in following instruction to 1.0
; optimized - changed gain to 1.0
WRAX 42, 1.0
; optimized RDAX 42, 1.0
SOF 0.2700, 0.7300
WRAX 42, 0.0
====================
Last edited: