Skip to content

Commit

Permalink
Further optimize pointer movement to reduce instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
terminationshock committed Feb 18, 2023
1 parent 6f3a2a7 commit 3882f89
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 16 deletions.
28 changes: 22 additions & 6 deletions src/assembly.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,34 @@ func Assembly(code []*Command, file string, stackSize int) (string, error) {
program += fmt.Sprintf("addq $%d, %%r12", 8 * c.Count) + br
break
case "+":
program += fmt.Sprintf("addq $%d, (%%r12)", c.Count) + br
if c.Offset != 0 {
program += fmt.Sprintf("addq $%d, %d(%%r12)", c.Count, -8 * c.Offset) + br
} else {
program += fmt.Sprintf("addq $%d, (%%r12)", c.Count) + br
}
break
case "-":
program += fmt.Sprintf("subq $%d, (%%r12)", c.Count) + br
if c.Offset != 0 {
program += fmt.Sprintf("subq $%d, %d(%%r12)", c.Count, -8 * c.Offset) + br
} else {
program += fmt.Sprintf("subq $%d, (%%r12)", c.Count) + br
}
break
case ".":
program += "movq (%r12), %rdi" + br
if c.Offset != 0 {
program += fmt.Sprintf("movq %d(%%r12), %%rdi", -8 * c.Offset) + br
} else {
program += "movq (%r12), %rdi" + br
}
program += "call putchar" + br
break
case ",":
program += "call getchar" + br
program += "movq %rax, (%r12)" + br
if c.Offset != 0 {
program += fmt.Sprintf("movq %%rax, %d(%%r12)", -8 * c.Offset) + br
} else {
program += "movq %rax, (%r12)" + br
}
break
case "[":
loopId++
Expand Down Expand Up @@ -107,9 +123,9 @@ func Assembly(code []*Command, file string, stackSize int) (string, error) {
program += "movq (%r12), %rax" + br
}
if m.Factor > 0 {
program += fmt.Sprintf("addq %%rax, %d(%%r12)", -8 * m.CopyTo) + br
program += fmt.Sprintf("addq %%rax, %d(%%r12)", -8 * m.Offset) + br
} else {
program += fmt.Sprintf("subq %%rax, %d(%%r12)", -8 * m.CopyTo) + br
program += fmt.Sprintf("subq %%rax, %d(%%r12)", -8 * m.Offset) + br
}
}
program += "movq $0, (%r12)" + br
Expand Down
95 changes: 89 additions & 6 deletions src/optimize.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func Optimize(commands []*Command, verbose bool) []*Command {
optimized = optimizeDuplicatedCommands(optimized, "><+-", verbose)
optimized = optimizeMultiplyLoops(optimized, verbose)
optimized = optimizeDuplicatedCommands(optimized, "]", verbose)
optimized = optimizePointerMovement(optimized, verbose)

return optimized
}
Expand Down Expand Up @@ -89,8 +90,8 @@ func optimizeMultiplyLoops(commands []*Command, verbose bool) []*Command {
if isMultiplyLoop(currentLoop) {
cnt = currentLoopBegin
optimized = optimized[:cnt+1]
optimized[cnt].String = getLoopPattern(currentLoop)
optimized[cnt].MultiplyLoop = newMultiplyLoop(currentLoop)
optimized[cnt].String = getBlockPattern(currentLoop)
optimized[cnt].MultiplyLoop = getMultiplyLoop(currentLoop)
report(verbose, currentLoop[0], "Optimizing loop", optimized[cnt].String)
}
currentLoop = []*Command{}
Expand All @@ -101,7 +102,41 @@ func optimizeMultiplyLoops(commands []*Command, verbose bool) []*Command {
return optimized
}

func getLoopPattern(commands []*Command) string {
func optimizePointerMovement(commands []*Command, verbose bool) []*Command {
optimized := []*Command{}
i := 0
block := []*Command{}
for i < len(commands) {
if strings.Contains("><+-,.", commands[i].String) && i < len(commands) - 1 {
block = append(block, commands[i])
} else {
if len(block) > 0 {
if isUnoptimizedPointerMovement(block) {
report(verbose, block[0], "Optimizing pointer movement", getBlockPattern(block))
optimized = append(optimized, getRemoteCommands(block)...)
pointer, str := getNetPointerMovement(block)
if pointer != 0 {
optimized = append(optimized, &Command {
String: str,
Count: pointer,
Offset: 0,
Row: block[0].Row,
Col: block[0].Col,
})
}
} else {
optimized = append(optimized, block...)
}
}
block = []*Command{}
optimized = append(optimized, commands[i])
}
i++
}
return optimized
}

func getBlockPattern(commands []*Command) string {
pattern := ""
for _, c := range commands {
pattern += getPattern(c)
Expand Down Expand Up @@ -139,7 +174,55 @@ func isMultiplyLoop(commands []*Command) bool {
return found && pointer == 0
}

func newMultiplyLoop(commands []*Command) []*Multiply {
func isUnoptimizedPointerMovement(commands []*Command) bool {
numMove := 0
for _, c := range commands {
if c.String == ">" || c.String == "<" {
numMove++
}
}
return numMove > 1
}

func getNetPointerMovement(commands []*Command) (int, string) {
pointer := 0
for _, c := range commands {
if c.String == ">" {
pointer += c.Count
} else if c.String == "<" {
pointer -= c.Count
}
}
if pointer > 0 {
return pointer, ">"
} else if pointer < 0 {
return -pointer, "<"
}
return 0, ""
}

func getRemoteCommands(commands []*Command) []*Command {
remote := []*Command{}
pointer := 0
for _, c := range commands {
if c.String == "<" {
pointer -= c.Count
} else if c.String == ">" {
pointer += c.Count
} else {
remote = append(remote, &Command {
String: c.String,
Count: c.Count,
Offset: pointer,
Row: c.Row,
Col: c.Col,
})
}
}
return remote
}

func getMultiplyLoop(commands []*Command) []*Multiply {
m := []*Multiply{}

pointer := 0
Expand All @@ -153,14 +236,14 @@ func newMultiplyLoop(commands []*Command) []*Multiply {
break
case "+":
m = append(m, &Multiply{
CopyTo: pointer,
Offset: pointer,
Factor: c.Count,
})
break
case "-":
if pointer != 0 {
m = append(m, &Multiply{
CopyTo: pointer,
Offset: pointer,
Factor: -c.Count,
})
}
Expand Down
9 changes: 5 additions & 4 deletions src/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import (
type Command struct {
String string
Count int
Offset int
Row int
Col int
MultiplyLoop []*Multiply
}

type Multiply struct {
CopyTo int
Offset int
Factor int
}

Expand All @@ -30,13 +31,13 @@ func Parse(file string) ([]*Command, error) {
for _, char := range content {
str := string(char)
if strings.Contains("><+-.,[]", str) {
command := &Command {
code = append(code, &Command {
String: str,
Count: 1,
Offset: 0,
Row: row,
Col: col,
}
code = append(code, command)
})
}
if char == '\n' {
row++
Expand Down

0 comments on commit 3882f89

Please sign in to comment.