@@ -110,18 +110,28 @@ int find_in_regs(var_t *var)
110
110
111
111
void load_var (basic_block_t * bb , var_t * var , int idx )
112
112
{
113
- ph2_ir_t * ir = var -> is_global ? bb_add_ph2_ir (bb , OP_global_load )
114
- : bb_add_ph2_ir (bb , OP_load );
115
- ir -> src0 = var -> offset ;
113
+ ph2_ir_t * ir ;
114
+
115
+ /* Load constants directly, others from memory */
116
+ if (var -> is_const ) {
117
+ ir = bb_add_ph2_ir (bb , OP_load_constant );
118
+ ir -> src0 = var -> init_val ;
119
+ } else {
120
+ ir = var -> is_global ? bb_add_ph2_ir (bb , OP_global_load )
121
+ : bb_add_ph2_ir (bb , OP_load );
122
+ ir -> src0 = var -> offset ;
123
+ }
124
+
116
125
ir -> dest = idx ;
117
126
REGS [idx ].var = var ;
118
127
REGS [idx ].polluted = 0 ;
119
128
}
120
129
121
130
int prepare_operand (basic_block_t * bb , var_t * var , int operand_0 )
122
131
{
132
+ /* Force reload for address-taken variables (may be modified via pointer) */
123
133
int i = find_in_regs (var );
124
- if (i > -1 )
134
+ if (i > -1 && ! var -> address_taken )
125
135
return i ;
126
136
127
137
for (i = 0 ; i < REG_CNT ; i ++ ) {
@@ -207,6 +217,16 @@ int prepare_dest(basic_block_t *bb, var_t *var, int operand_0, int operand_1)
207
217
208
218
void spill_alive (basic_block_t * bb , insn_t * insn )
209
219
{
220
+ /* Spill all locals on pointer writes (conservative aliasing handling) */
221
+ if (insn && insn -> opcode == OP_write ) {
222
+ for (int i = 0 ; i < REG_CNT ; i ++ ) {
223
+ if (REGS [i ].var && !REGS [i ].var -> is_global )
224
+ spill_var (bb , REGS [i ].var , i );
225
+ }
226
+ return ;
227
+ }
228
+
229
+ /* Standard spilling for non-pointer operations */
210
230
for (int i = 0 ; i < REG_CNT ; i ++ ) {
211
231
if (!REGS [i ].var )
212
232
continue ;
@@ -471,9 +491,6 @@ void reg_alloc(void)
471
491
break ;
472
492
case OP_load_constant :
473
493
case OP_load_data_address :
474
- if (insn -> rd -> consumed == -1 )
475
- break ;
476
-
477
494
dest = prepare_dest (bb , insn -> rd , -1 , -1 );
478
495
ir = bb_add_ph2_ir (bb , insn -> opcode );
479
496
ir -> src0 = insn -> rd -> init_val ;
@@ -490,6 +507,12 @@ void reg_alloc(void)
490
507
break ;
491
508
case OP_address_of :
492
509
case OP_global_address_of :
510
+ /* Mark variable as address-taken, disable constant
511
+ * optimization
512
+ */
513
+ insn -> rs1 -> address_taken = true;
514
+ insn -> rs1 -> is_const = false;
515
+
493
516
/* make sure variable is on stack */
494
517
if (!insn -> rs1 -> offset ) {
495
518
insn -> rs1 -> offset = bb -> belong_to -> stack_size ;
@@ -500,6 +523,8 @@ void reg_alloc(void)
500
523
ir = bb_add_ph2_ir (bb , OP_store );
501
524
ir -> src0 = i ;
502
525
ir -> src1 = insn -> rs1 -> offset ;
526
+ /* Clear stale register tracking */
527
+ REGS [i ].var = NULL ;
503
528
}
504
529
}
505
530
@@ -792,7 +817,7 @@ void dump_ph2_ir(void)
792
817
printf ("\t%%x%c = (%%x%c)" , rd , rs1 );
793
818
break ;
794
819
case OP_write :
795
- printf ("\t(%%x%c) = %%x%c" , rs2 , rs1 );
820
+ printf ("\t(%%x%c) = %%x%c" , rs1 , rs2 );
796
821
break ;
797
822
case OP_address_of_func :
798
823
printf ("\t(%%x%c) = @%s" , rs1 , ph2_ir -> func_name );
0 commit comments