Optimize following Aarch64 assembly language program
.section .data
.prompt1: .asciz "The random array is: "
.prompt2: .asciz "The sorted array is: "
.printint: .asciz "%d "
.printnl: .asciz "\n"

.section .bss
// Allocate space for 10 4-byte integers in the stack
array: .skip 40

.section .text
.global main
.type main, @function

main:
// Create space in the stack frame by adjusting sp
sub sp, sp, #32 
stp x29, x30, [sp, #16]
add x29, sp, #16

// Initialize a temporary register of the array element to zero
str wzr, [x29, #-4] 

// Initialize the loop iterator to zero
str wzr, [sp, #8] 

mov x0, 0

// Generate a seed to be used by srand and set the seed for the random number generator
bl	time
bl  srand

.randloop:
// Load loop iterator and check if i >= 10
ldr w8, [sp, #8] 
subs w8, w8, #10

// If iterator i >= 10, exit randloop
bge .endrandloop 

// Generate random integer
bl rand 

// Load loop iterator
ldrsw x9, [sp, #8]
adrp x8, array 
add x8, x8, :lo12:array

// Following code block is used to do modulus operation to fit the range [10..99]
mov	w3, 90 
udiv w1, w0, w3
mul w1, w1, w3
sub w0, w0, w1

// Add the minimum bound, since the random number starts from 10
add w0, w0, #10 

// Store the generated random integer in the allocated memory spot for the array
str w0, [x8, x9, lsl #2] 
ldr w8, [sp, #8]
add w8, w8, #1

// Update iterator value and continue looping
str w8, [sp, #8]
b .randloop 

.endrandloop:
// Address of the prompt1 into x0
adrp x0, .prompt1 
add x0, x0, :lo12:.prompt1

// Print a formatted string to output stream
bl printf 
str wzr, [sp, #4]

// This loop iterates over the array elements and print them out to console
.printloop:
ldr w8, [sp, #4]
subs w8, w8, #10

// If iterator >= 10, exit loop
bge .endprintloop 

// Load loop iterator
ldrsw x9, [sp, #4] 
adrp x8, array
add x8, x8, :lo12:array 

// Get array element using the iterator and offset by memory size
ldr w1, [x8, x9, lsl #2] 
adrp x0, .printint
add x0, x0, :lo12:.printint

// Print the integer loaded in w1 register
bl printf
ldr w8, [sp, #4]
add w8, w8, #1
str w8, [sp, #4]
b .printloop

// End of print loop. Print empty line
.endprintloop:
adrp x0, .printnl
add x0, x0, :lo12:.printnl
bl printf

// Set outer loop iterator to 1 and store it to register
mov w8, #1
str w8, [sp, #16]

.outerinsertionsort:
ldr w8, [sp, #16]
subs w8, w8, #10

// Iterates from 1 to 9. 
// If iterator >= 10, jump to end of outerinsertionsort
bge .endouterinsertionsort

// Load the value at current position of the arrary, load the value at that location,
// and store it and iterator-1 on the stack (pesudo code: key = array[i]/ j = i - 1)
ldrsw x9, [sp, #16]
adrp x8, array
add x8, x8, :lo12:array
ldr w8, [x8, x9, lsl #2]
str w8, [sp, #12]
ldr w8, [sp, #16]
subs w8, w8, #1
str w8, [sp, #8]

// Compare key with each element on the left of it until an element smaller is found.
.innerinsertionsortcondition:
// Load key
ldr w8, [sp, #8]
mov w9, #0
str w9, [sp]

// Check if bit 31 of w8 is using bitwise tbnz operation (conditional branching)
// If yes, jump to innerinsertionsortbody
tbnz w8, #31, .innerinsertionsortbody

// Load array[j]
ldrsw x9, [sp, #8]
adrp x8, array
add x8, x8, :lo12:array
ldr w8, [x8, x9, lsl #2]
ldr w9, [sp, #12]

// Check if (key < array[j]) and set flag using cset (conditional set)
subs w8, w8, w9
cset w8, gt
str w8, [sp]

.innerinsertionsortbody:
// Load array[j] and store it at array[j+1]
ldr w8, [sp]
tbz w8, #0, .endinnerinsertionsortcondition
ldrsw x8, [sp, #8]
adrp x9, array
add x9, x9, :lo12:array
ldr w8, [x9, x8, lsl #2]
ldr w10, [sp, #8]
add w10, w10, #1
str w8, [x9, w10, sxtw #2]

// Decrement j by 1 (j--)
ldr w8, [sp, #8]
subs w8, w8, #1
str w8, [sp, #8]
b .innerinsertionsortcondition

.endinnerinsertionsortcondition:
// Store key at array[j+1]
ldr w8, [sp, #12]
ldr w9, [sp, #8]
add w10, w9, #1
adrp x9, array
add x9, x9, :lo12:array
str w8, [x9,w10, sxtw #2]

// Increment iterator by 1 and loop again
ldr w8, [sp, #16]
add w8, w8, #1
str w8, [sp, #16]
b .outerinsertionsort

.endouterinsertionsort:
// Address of the prompt2 into x0
adrp x0, .prompt2
add x0, x0, :lo12:.prompt2

// Print a formatted string to output stream
bl printf
str wzr, [sp, #4]

// This loop iterates over the array elements and print them out to console
.printloop2:
ldr w8, [sp, #4]
subs w8, w8, #10

// If iterator >= 10, exit loop
bge .endprintloop2

// Load loop iterator
ldursw x9, [sp, #4]
adrp x8, array
add x8, x8, :lo12:array

// Get array element using the iterator and offset by memory size
ldr w1, [x8, x9, lsl #2]
adrp x0, .printint
add x0, x0, :lo12:.printint

// Print the integer loaded in w1 register
bl printf
ldr w8, [sp, #4]
add w8, w8, #1
str w8, [sp, #4]
b .printloop2

// End of print loop. Print empty line
.endprintloop2:
adrp x0, .printnl
add x0, x0, :lo12:.printnl
bl printf

mov w0, wzr
ldp x29, x30, [sp, #16]
add sp, sp, #32
ret