1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-03 01:29:04 +00:00

Improved static value analysis to identify #<0, #>0 as identical to #0

This commit is contained in:
jespergravgaard 2017-11-27 18:11:28 +01:00
parent 7d08159fb2
commit 015de8da3d
8 changed files with 131 additions and 64 deletions

View File

@ -72,43 +72,37 @@ public class AsmProgramStaticRegisterValues {
current.setA(instruction.getParameter());
current.setaMem(null);
try {
int immValue = getImmValue(instruction);
Integer immValue = getImmValue(instruction.getParameter());
if (immValue != null) {
current.setZ(immValue == 0);
current.setN(immValue > 127);
} catch (NumberFormatException e) {
// ignore
}
}
if (instructionType.getMnemnonic().equals("sta") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP)||instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) {
if (instructionType.getMnemnonic().equals("sta") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP) || instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) {
current.setaMem(instruction.getParameter());
}
if (instructionType.getMnemnonic().equals("ldx") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) {
current.setX(instruction.getParameter());
current.setxMem(null);
try {
int immValue = getImmValue(instruction);
Integer immValue = getImmValue(instruction.getParameter());
if (immValue != null) {
current.setZ(immValue == 0);
current.setN(immValue > 127);
} catch (NumberFormatException e) {
// ignore
}
}
if (instructionType.getMnemnonic().equals("stx") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP)||instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) {
if (instructionType.getMnemnonic().equals("stx") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP) || instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) {
current.setxMem(instruction.getParameter());
}
if (instructionType.getMnemnonic().equals("ldy") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) {
current.setY(instruction.getParameter());
current.setyMem(null);
try {
int immValue = getImmValue(instruction);
Integer immValue = getImmValue(instruction.getParameter());
if (immValue != null) {
current.setZ(immValue == 0);
current.setN(immValue > 127);
} catch (NumberFormatException e) {
// ignore
}
}
if (instructionType.getMnemnonic().equals("sty") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP)||instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) {
if (instructionType.getMnemnonic().equals("sty") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP) || instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) {
current.setyMem(instruction.getParameter());
}
if (instructionType.getMnemnonic().equals("txa")) {
@ -137,18 +131,47 @@ public class AsmProgramStaticRegisterValues {
return current;
}
private int getImmValue(AsmInstruction instruction) {
int immValue;
if(instruction.getParameter().equals("<0")) {
immValue = 0;
} else if(instruction.getParameter().equals(">0")) {
immValue = 0;
} else{
immValue = Integer.parseInt(instruction.getParameter());
public static Integer getImmValue(String parameter) {
Integer immValue = null;
if (parameter != null) {
if(parameter.startsWith("<")) {
try {
int parValue = Integer.parseInt(parameter.substring(1));
return 0xff & parValue;
} catch (NumberFormatException e) {
// ignore
}
} else if(parameter.startsWith(">")) {
try {
int parValue = Integer.parseInt(parameter.substring(1));
return 0xff & (parValue / 0x100);
} catch (NumberFormatException e) {
// ignore
}
} else {
try {
immValue = Integer.parseInt(parameter);
return immValue;
} catch (NumberFormatException e) {
// ignore
}
}
}
return immValue;
}
public static boolean matchImm(String immVal1, String immVal2) {
if (immVal1 != null && immVal2 != null && immVal1.equals(immVal2)) {
return true;
}
Integer immInt1 = getImmValue(immVal1);
Integer immInt2 = getImmValue(immVal2);
if (immInt1 != null && immInt2 != null && immInt1.equals(immInt2)) {
return true;
}
return false;
}
/**
* Known values of registers/flags at an instruction. null where value is unknown.
*/
@ -260,6 +283,7 @@ public class AsmProgramStaticRegisterValues {
this.z = z;
}
}
}

View File

@ -34,13 +34,13 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
if (instructionType.getMnemnonic().equals("lda") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) {
String immValue = instruction.getParameter();
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
if (instructionValues.getA() != null && instructionValues.getA().equals(immValue)) {
if (AsmProgramStaticRegisterValues.matchImm(instructionValues.getA(), immValue)) {
modified = remove(lineIt);
} else if (instructionValues.getX() != null && instructionValues.getX().equals(immValue)) {
} else if (AsmProgramStaticRegisterValues.matchImm(instructionValues.getX(), immValue)) {
getLog().append("Replacing instruction "+instruction+" with TXA");
instruction.setType(AsmInstructionSet.getInstructionType("txa", AsmAddressingMode.NON, null, false));
instruction.setParameter(null);
} else if (instructionValues.getY() != null && instructionValues.getY().equals(immValue)) {
} else if (AsmProgramStaticRegisterValues.matchImm(instructionValues.getY(), immValue)) {
getLog().append("Replacing instruction "+instruction+" with TYA");
instruction.setType(AsmInstructionSet.getInstructionType("tya", AsmAddressingMode.NON, null, false));
instruction.setParameter(null);
@ -64,9 +64,9 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
if (instructionType.getMnemnonic().equals("ldx") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) {
String immValue = instruction.getParameter();
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
if (instructionValues.getX() != null && instructionValues.getX().equals(immValue)) {
if (AsmProgramStaticRegisterValues.matchImm(instructionValues.getX(), immValue)) {
modified = remove(lineIt);
} else if (instructionValues.getA() != null && instructionValues.getA().equals(immValue)) {
} else if (AsmProgramStaticRegisterValues.matchImm(instructionValues.getA(), immValue)) {
getLog().append("Replacing instruction "+instruction+" with TAX");
instruction.setType(AsmInstructionSet.getInstructionType("tax", AsmAddressingMode.NON, null, false));
instruction.setParameter(null);
@ -86,9 +86,9 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
if (instructionType.getMnemnonic().equals("ldy") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) {
String immValue = instruction.getParameter();
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
if (instructionValues.getY() != null && instructionValues.getY().equals(immValue)) {
if (AsmProgramStaticRegisterValues.matchImm(instructionValues.getY(), immValue)) {
modified = remove(lineIt);
} else if (instructionValues.getA() != null && instructionValues.getA().equals(immValue)) {
} else if (AsmProgramStaticRegisterValues.matchImm(instructionValues.getA(), immValue)) {
getLog().append("Replacing instruction "+instruction+" with TAY");
instruction.setType(AsmInstructionSet.getInstructionType("tay", AsmAddressingMode.NON, null, false));
instruction.setParameter(null);

View File

@ -394,9 +394,8 @@ init_plot_tables: {
bne b1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
ldx #0
tax
b3:
txa
and #7

View File

@ -18292,6 +18292,8 @@ Removing instruction lda yd
Removing instruction lda yd
Removing instruction lda yd
Removing instruction ldy #0
Removing instruction lda #>0
Replacing instruction ldx #0 with TAX
Replacing instruction lda #0 with TYA
Succesful ASM optimization Pass5UnnecesaryLoadElimination
ASSEMBLER
@ -19082,10 +19084,9 @@ init_plot_tables: {
//SEG316 [171] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG317 [171] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
jmp b3
//SEG318 [171] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
b3_from_b4:
@ -20024,10 +20025,9 @@ init_plot_tables: {
//SEG316 [171] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG317 [171] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
jmp b3
//SEG318 [171] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG319 [171] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
@ -20922,10 +20922,9 @@ init_plot_tables: {
//SEG316 [171] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG317 [171] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
jmp b3
//SEG318 [171] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG319 [171] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
@ -21769,10 +21768,9 @@ init_plot_tables: {
//SEG316 [171] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG317 [171] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
//SEG318 [171] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG319 [171] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
//SEG320 [171] phi (byte) init_plot_tables::y#2 = (byte) init_plot_tables::y#1 [phi:init_plot_tables::@4->init_plot_tables::@3#1] -- register_copy
@ -22961,10 +22959,9 @@ init_plot_tables: {
//SEG316 [171] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG317 [171] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
//SEG318 [171] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG319 [171] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
//SEG320 [171] phi (byte) init_plot_tables::y#2 = (byte) init_plot_tables::y#1 [phi:init_plot_tables::@4->init_plot_tables::@3#1] -- register_copy

View File

@ -118,9 +118,8 @@ init_plot_tables: {
bne b1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
ldx #0
tax
b3:
txa
and #7

View File

@ -6849,6 +6849,8 @@ init_screen: {
Removing instruction lda #0
Removing instruction ldy #0
Removing instruction lda #>0
Replacing instruction ldx #0 with TAX
Replacing instruction lda #0 with TYA
Succesful ASM optimization Pass5UnnecesaryLoadElimination
ASSEMBLER
@ -7073,10 +7075,9 @@ init_plot_tables: {
//SEG78 [47] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG79 [47] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
jmp b3
//SEG80 [47] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
b3_from_b4:
@ -7441,10 +7442,9 @@ init_plot_tables: {
//SEG78 [47] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG79 [47] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
jmp b3
//SEG80 [47] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG81 [47] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
@ -7790,10 +7790,9 @@ init_plot_tables: {
//SEG78 [47] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG79 [47] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
jmp b3
//SEG80 [47] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG81 [47] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
@ -8117,10 +8116,9 @@ init_plot_tables: {
//SEG78 [47] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG79 [47] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
//SEG80 [47] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG81 [47] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
//SEG82 [47] phi (byte) init_plot_tables::y#2 = (byte) init_plot_tables::y#1 [phi:init_plot_tables::@4->init_plot_tables::@3#1] -- register_copy
@ -8583,10 +8581,9 @@ init_plot_tables: {
//SEG78 [47] phi (byte*) init_plot_tables::yoffs#2 = ((byte*))(byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#0] -- zpptrby1=cowo1
lda #<0
sta yoffs
lda #>0
sta yoffs+1
//SEG79 [47] phi (byte) init_plot_tables::y#2 = (byte/signed byte/word/signed word) 0 [phi:init_plot_tables::@2->init_plot_tables::@3#1] -- xby=coby1
ldx #0
tax
//SEG80 [47] phi from init_plot_tables::@4 to init_plot_tables::@3 [phi:init_plot_tables::@4->init_plot_tables::@3]
//SEG81 [47] phi (byte*) init_plot_tables::yoffs#2 = (byte*) init_plot_tables::yoffs#4 [phi:init_plot_tables::@4->init_plot_tables::@3#0] -- register_copy
//SEG82 [47] phi (byte) init_plot_tables::y#2 = (byte) init_plot_tables::y#1 [phi:init_plot_tables::@4->init_plot_tables::@3#1] -- register_copy

View File

@ -6,9 +6,8 @@ main: {
.label w = 2
lda #<0
sta w
lda #>0
sta w+1
ldx #0
tax
b1:
txa
clc

View File

@ -635,6 +635,62 @@ main: {
rts
}
Removing instruction lda #>0
Replacing instruction ldx #0 with TAX
Succesful ASM optimization Pass5UnnecesaryLoadElimination
ASSEMBLER
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
//SEG2 @begin
bbegin:
//SEG3 @1
b1:
//SEG4 [0] call main param-assignment [ ] ( )
//SEG5 [1] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
//SEG6 @end
bend:
//SEG7 main
main: {
.label w = 2
//SEG8 [2] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
//SEG9 [2] phi (word) main::w#2 = ((word))(byte/signed byte/word/signed word) 0 [phi:main->main::@1#0] -- zpwo1=cowo1
lda #<0
sta w
sta w+1
//SEG10 [2] phi (byte) main::i#1 = (byte/signed byte/word/signed word) 0 [phi:main->main::@1#1] -- xby=coby1
tax
jmp b1
//SEG11 [2] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG12 [2] phi (word) main::w#2 = (word) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG13 [2] phi (byte) main::i#1 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
//SEG14 main::@1
b1:
//SEG15 [3] (word) main::w#1 ← (word) main::w#2 + (byte) main::i#1 [ main::i#1 main::w#1 ] ( main:0 [ main::i#1 main::w#1 ] ) -- zpwo1=zpwo1_plus_xby
txa
clc
adc w
sta w
bcc !+
inc w+1
!:
//SEG16 [4] (byte) main::j#1 ← ++ (byte) main::i#1 [ main::j#1 main::w#1 ] ( main:0 [ main::j#1 main::w#1 ] ) -- xby=_inc_xby
inx
//SEG17 [5] if((byte) main::j#1!=(byte/signed byte/word/signed word) 11) goto main::@1 [ main::j#1 main::w#1 ] ( main:0 [ main::j#1 main::w#1 ] ) -- xby_neq_coby1_then_la1
cpx #$b
bne b1_from_b1
//SEG18 main::@return
breturn:
//SEG19 [6] return [ ] ( main:0 [ ] )
rts
}
Replacing label b1_from_b1 with b1
Removing instruction bbegin:
Removing instruction main_from_b1:
@ -662,10 +718,9 @@ main: {
//SEG9 [2] phi (word) main::w#2 = ((word))(byte/signed byte/word/signed word) 0 [phi:main->main::@1#0] -- zpwo1=cowo1
lda #<0
sta w
lda #>0
sta w+1
//SEG10 [2] phi (byte) main::i#1 = (byte/signed byte/word/signed word) 0 [phi:main->main::@1#1] -- xby=coby1
ldx #0
tax
jmp b1
//SEG11 [2] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG12 [2] phi (word) main::w#2 = (word) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
@ -715,10 +770,9 @@ main: {
//SEG9 [2] phi (word) main::w#2 = ((word))(byte/signed byte/word/signed word) 0 [phi:main->main::@1#0] -- zpwo1=cowo1
lda #<0
sta w
lda #>0
sta w+1
//SEG10 [2] phi (byte) main::i#1 = (byte/signed byte/word/signed word) 0 [phi:main->main::@1#1] -- xby=coby1
ldx #0
tax
jmp b1
//SEG11 [2] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG12 [2] phi (word) main::w#2 = (word) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
@ -764,10 +818,9 @@ main: {
//SEG9 [2] phi (word) main::w#2 = ((word))(byte/signed byte/word/signed word) 0 [phi:main->main::@1#0] -- zpwo1=cowo1
lda #<0
sta w
lda #>0
sta w+1
//SEG10 [2] phi (byte) main::i#1 = (byte/signed byte/word/signed word) 0 [phi:main->main::@1#1] -- xby=coby1
ldx #0
tax
//SEG11 [2] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG12 [2] phi (word) main::w#2 = (word) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG13 [2] phi (byte) main::i#1 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
@ -828,10 +881,9 @@ main: {
//SEG9 [2] phi (word) main::w#2 = ((word))(byte/signed byte/word/signed word) 0 [phi:main->main::@1#0] -- zpwo1=cowo1
lda #<0
sta w
lda #>0
sta w+1
//SEG10 [2] phi (byte) main::i#1 = (byte/signed byte/word/signed word) 0 [phi:main->main::@1#1] -- xby=coby1
ldx #0
tax
//SEG11 [2] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG12 [2] phi (word) main::w#2 = (word) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG13 [2] phi (byte) main::i#1 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy