Setting struct to load/store in variable affected by address-of (struct Point*) main::q ← &(struct Point) main::p
Adding value bulk copy *(&(struct Point) main::p) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference *((struct Point*) main::q).x with member unwinding reference *((byte*~) main::$1)
Replacing struct member reference *((struct Point*) main::q).y with member unwinding reference *((byte*~) main::$2)
Replacing struct member reference *((struct Point*) set::ptr).x with member unwinding reference *((byte*~) set::$0)
Replacing struct member reference *((struct Point*) set::ptr).y with member unwinding reference *((byte*~) set::$1)
Identified constant variable (struct Point*) main::q
Culled Empty Block (label) @1

CONTROL FLOW GRAPH SSA
@begin: scope:[]  from
  to:@2

(void()) main()
main: scope:[main]  from @2
  *(&(struct Point) main::p) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
  (struct Point) main::p ← struct-unwound {*(&(struct Point) main::p)}
  (struct Point*) set::ptr#0 ← (const struct Point*) main::q
  call set 
  to:main::@1
main::@1: scope:[main]  from main
  (byte*~) main::$1 ← (byte*)(const struct Point*) main::q + (const byte) OFFSET_STRUCT_POINT_X
  *((const byte*) main::SCREEN + (number) 0) ← *((byte*~) main::$1)
  (byte*~) main::$2 ← (byte*)(const struct Point*) main::q + (const byte) OFFSET_STRUCT_POINT_Y
  *((const byte*) main::SCREEN + (number) 1) ← *((byte*~) main::$2)
  to:main::@return
main::@return: scope:[main]  from main::@1
  return 
  to:@return

(void()) set((struct Point*) set::ptr)
set: scope:[set]  from main
  (struct Point*) set::ptr#1 ← phi( main/(struct Point*) set::ptr#0 )
  (byte*~) set::$0 ← (byte*)(struct Point*) set::ptr#1 + (const byte) OFFSET_STRUCT_POINT_X
  *((byte*~) set::$0) ← (number) 4
  (byte*~) set::$1 ← (byte*)(struct Point*) set::ptr#1 + (const byte) OFFSET_STRUCT_POINT_Y
  *((byte*~) set::$1) ← (number) 5
  to:set::@return
set::@return: scope:[set]  from set
  return 
  to:@return
@2: scope:[]  from @begin
  call main 
  to:@3
@3: scope:[]  from @2
  to:@end
@end: scope:[]  from @3

SYMBOL TABLE SSA
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @2
(label) @3
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_POINT_X = (byte) 0
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x
(byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(byte*~) main::$1
(byte*~) main::$2
(label) main::@1
(label) main::@return
(const byte*) main::SCREEN = (byte*)(number) $400
(struct Point) main::p loadstore
(const struct Point*) main::q = &(struct Point) main::p
(void()) set((struct Point*) set::ptr)
(byte*~) set::$0
(byte*~) set::$1
(label) set::@return
(struct Point*) set::ptr
(struct Point*) set::ptr#0
(struct Point*) set::ptr#1

Adding number conversion cast (unumber) 0 in *((const byte*) main::SCREEN + (number) 0) ← *((byte*~) main::$1)
Adding number conversion cast (unumber) 1 in *((const byte*) main::SCREEN + (number) 1) ← *((byte*~) main::$2)
Adding number conversion cast (unumber) 4 in *((byte*~) set::$0) ← (number) 4
Adding number conversion cast (unumber) 5 in *((byte*~) set::$1) ← (number) 5
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((byte*~) set::$0) ← (unumber)(number) 4
Inlining cast *((byte*~) set::$1) ← (unumber)(number) 5
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Simplifying constant integer cast 4
Simplifying constant integer cast 5
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 4
Finalized unsigned number type (byte) 5
Successful SSA optimization PassNFinalizeNumberTypeConversions
Identical Phi Values (struct Point*) set::ptr#1 (struct Point*) set::ptr#0
Successful SSA optimization Pass2IdenticalPhiElimination
Removing C-classic struct-unwound assignment [1] (struct Point) main::p ← struct-unwound {*(&(struct Point) main::p)}
Constant right-side identified [4] (byte*~) main::$1 ← (byte*)(const struct Point*) main::q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [6] (byte*~) main::$2 ← (byte*)(const struct Point*) main::q + (const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const struct Point*) set::ptr#0 = main::q
Constant (const byte*) main::$1 = (byte*)main::q+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$2 = (byte*)main::q+OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantIdentification
Constant value identified (byte*)set::ptr#0 in [10] (byte*~) set::$0 ← (byte*)(const struct Point*) set::ptr#0 + (const byte) OFFSET_STRUCT_POINT_X
Constant value identified (byte*)set::ptr#0 in [12] (byte*~) set::$1 ← (byte*)(const struct Point*) set::ptr#0 + (const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantValues
Converting *(pointer+n) to pointer[n] [11] *((byte*~) set::$0) ← (byte) 4  -- *((byte*)set::ptr#0 + OFFSET_STRUCT_POINT_X)
Converting *(pointer+n) to pointer[n] [13] *((byte*~) set::$1) ← (byte) 5  -- *((byte*)set::ptr#0 + OFFSET_STRUCT_POINT_Y)
Successful SSA optimization Pass2InlineDerefIdx
Simplifying expression containing zero (byte*)main::q in 
Simplifying expression containing zero main::SCREEN in [5] *((const byte*) main::SCREEN + (byte) 0) ← *((const byte*) main::$1)
Simplifying expression containing zero (byte*)set::ptr#0 in [10] (byte*~) set::$0 ← (byte*)(const struct Point*) set::ptr#0 + (const byte) OFFSET_STRUCT_POINT_X
Simplifying expression containing zero (byte*)set::ptr#0 in [11] *((byte*)(const struct Point*) set::ptr#0 + (const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (byte*~) set::$0 and assignment [5] (byte*~) set::$0 ← (byte*)(const struct Point*) set::ptr#0
Eliminating unused variable (byte*~) set::$1 and assignment [7] (byte*~) set::$1 ← (byte*)(const struct Point*) set::ptr#0 + (const byte) OFFSET_STRUCT_POINT_Y
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined set::ptr#0 = (const struct Point*) main::q
Constant inlined main::$1 = (byte*)(const struct Point*) main::q
Constant inlined main::$2 = (byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(main::SCREEN+1)
Consolidated array index constant in *((byte*)main::q+OFFSET_STRUCT_POINT_Y)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @3
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2 
Calls in [main] to set:6 

Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @3
Renumbering block @2 to @1
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end

FINAL CONTROL FLOW GRAPH
@begin: scope:[]  from
  [0] phi()
  to:@1
@1: scope:[]  from @begin
  [1] phi()
  [2] call main 
  to:@end
@end: scope:[]  from @1
  [3] phi()

(void()) main()
main: scope:[main]  from @1
  [4] *(&(struct Point) main::p) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
  [5] call set 
  to:main::@1
main::@1: scope:[main]  from main
  [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct Point*) main::q)
  [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y)
  to:main::@return
main::@return: scope:[main]  from main::@1
  [8] return 
  to:@return

(void()) set((struct Point*) set::ptr)
set: scope:[set]  from main
  [9] *((byte*)(const struct Point*) main::q) ← (byte) 4
  [10] *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
  to:set::@return
set::@return: scope:[set]  from set
  [11] return 
  to:@return


VARIABLE REGISTER WEIGHTS
(byte) Point::x
(byte) Point::y
(void()) main()
(struct Point) main::p loadstore
(void()) set((struct Point*) set::ptr)
(struct Point*) set::ptr

Initial phi equivalence classes
Added variable main::p to live range equivalence class [ main::p ]
Complete equivalence classes
[ main::p ]
Allocated zp[2]:2 [ main::p ]

INITIAL ASM
Target platform is c64basic / MOS6502X
  // File Comments
// Minimal struct -  using address-of and passing it to a function
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .const SIZEOF_STRUCT_POINT = 2
  .const OFFSET_STRUCT_POINT_Y = 1
  // @begin
__bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
  jmp __b1
  // @1
__b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
  jmp __bend
  // @end
__bend:
  // main
main: {
    .label SCREEN = $400
    .label q = p
    .label p = 2
    // [4] *(&(struct Point) main::p) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 
    ldy #SIZEOF_STRUCT_POINT
  !:
    lda __0-1,y
    sta p-1,y
    dey
    bne !-
    // [5] call set 
    jsr set
    jmp __b1
    // main::@1
  __b1:
    // [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct Point*) main::q) -- _deref_pbuc1=_deref_pbuc2 
    lda.z q
    sta SCREEN
    // [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2 
    lda q+OFFSET_STRUCT_POINT_Y
    sta SCREEN+1
    jmp __breturn
    // main::@return
  __breturn:
    // [8] return 
    rts
}
  // set
set: {
    // [9] *((byte*)(const struct Point*) main::q) ← (byte) 4 -- _deref_pbuc1=vbuc2 
    lda #4
    sta.z main.q
    // [10] *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2 
    lda #5
    sta main.q+OFFSET_STRUCT_POINT_Y
    jmp __breturn
    // set::@return
  __breturn:
    // [11] return 
    rts
}
  // File Data
  __0: .byte 2, 3

REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *(&(struct Point) main::p) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y 
Statement [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct Point*) main::q) [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [9] *((byte*)(const struct Point*) main::q) ← (byte) 4 [ ] ( main:2::set:5 [ ] ) always clobbers reg byte a 
Statement [10] *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 [ ] ( main:2::set:5 [ ] ) always clobbers reg byte a 
Potential registers zp[2]:2 [ main::p ] : zp[2]:2 , 

REGISTER UPLIFT SCOPES
Uplift Scope [Point] 
Uplift Scope [main] 0: zp[2]:2 [ main::p ] 
Uplift Scope [set] 
Uplift Scope [] 

Uplifting [Point] best 81 combination 
Uplifting [main] best 81 combination zp[2]:2 [ main::p ] 
Uplifting [set] best 81 combination 
Uplifting [] best 81 combination 

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Minimal struct -  using address-of and passing it to a function
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .const SIZEOF_STRUCT_POINT = 2
  .const OFFSET_STRUCT_POINT_Y = 1
  // @begin
__bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
  jmp __b1
  // @1
__b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
  jmp __bend
  // @end
__bend:
  // main
main: {
    .label SCREEN = $400
    .label q = p
    .label p = 2
    // [4] *(&(struct Point) main::p) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 
    ldy #SIZEOF_STRUCT_POINT
  !:
    lda __0-1,y
    sta p-1,y
    dey
    bne !-
    // [5] call set 
    jsr set
    jmp __b1
    // main::@1
  __b1:
    // [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct Point*) main::q) -- _deref_pbuc1=_deref_pbuc2 
    lda.z q
    sta SCREEN
    // [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2 
    lda q+OFFSET_STRUCT_POINT_Y
    sta SCREEN+1
    jmp __breturn
    // main::@return
  __breturn:
    // [8] return 
    rts
}
  // set
set: {
    // [9] *((byte*)(const struct Point*) main::q) ← (byte) 4 -- _deref_pbuc1=vbuc2 
    lda #4
    sta.z main.q
    // [10] *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2 
    lda #5
    sta main.q+OFFSET_STRUCT_POINT_Y
    jmp __breturn
    // set::@return
  __breturn:
    // [11] return 
    rts
}
  // File Data
  __0: .byte 2, 3

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x
(byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@1
(label) main::@return
(const byte*) main::SCREEN = (byte*) 1024
(struct Point) main::p loadstore zp[2]:2
(const struct Point*) main::q = &(struct Point) main::p
(void()) set((struct Point*) set::ptr)
(label) set::@return
(struct Point*) set::ptr

zp[2]:2 [ main::p ]


FINAL ASSEMBLER
Score: 60

  // File Comments
// Minimal struct -  using address-of and passing it to a function
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
  // Global Constants & labels
  .const SIZEOF_STRUCT_POINT = 2
  .const OFFSET_STRUCT_POINT_Y = 1
  // @begin
  // [1] phi from @begin to @1 [phi:@begin->@1]
  // @1
  // [2] call main 
  // [3] phi from @1 to @end [phi:@1->@end]
  // @end
  // main
main: {
    .label SCREEN = $400
    .label q = p
    .label p = 2
    // p = { 2, 3 }
    // [4] *(&(struct Point) main::p) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 
    ldy #SIZEOF_STRUCT_POINT
  !:
    lda __0-1,y
    sta p-1,y
    dey
    bne !-
    // set(q)
    // [5] call set 
    jsr set
    // main::@1
    // SCREEN[0] = q->x
    // [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct Point*) main::q) -- _deref_pbuc1=_deref_pbuc2 
    lda.z q
    sta SCREEN
    // SCREEN[1] = q->y
    // [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2 
    lda q+OFFSET_STRUCT_POINT_Y
    sta SCREEN+1
    // main::@return
    // }
    // [8] return 
    rts
}
  // set
set: {
    // ptr->x = 4
    // [9] *((byte*)(const struct Point*) main::q) ← (byte) 4 -- _deref_pbuc1=vbuc2 
    lda #4
    sta.z main.q
    // ptr->y = 5
    // [10] *((byte*)(const struct Point*) main::q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2 
    lda #5
    sta main.q+OFFSET_STRUCT_POINT_Y
    // set::@return
    // }
    // [11] return 
    rts
}
  // File Data
  __0: .byte 2, 3

