@@ -110,18 +110,28 @@ int find_in_regs(var_t *var)
110110
111111void load_var (basic_block_t * bb , var_t * var , int idx )
112112{
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+
116125 ir -> dest = idx ;
117126 REGS [idx ].var = var ;
118127 REGS [idx ].polluted = 0 ;
119128}
120129
121130int prepare_operand (basic_block_t * bb , var_t * var , int operand_0 )
122131{
132+ /* Force reload for address-taken variables (may be modified via pointer) */
123133 int i = find_in_regs (var );
124- if (i > -1 )
134+ if (i > -1 && ! var -> address_taken )
125135 return i ;
126136
127137 for (i = 0 ; i < REG_CNT ; i ++ ) {
@@ -207,6 +217,17 @@ int prepare_dest(basic_block_t *bb, var_t *var, int operand_0, int operand_1)
207217
208218void spill_alive (basic_block_t * bb , insn_t * insn )
209219{
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+ }
227+ return ;
228+ }
229+
230+ /* Standard spilling for non-pointer operations */
210231 for (int i = 0 ; i < REG_CNT ; i ++ ) {
211232 if (!REGS [i ].var )
212233 continue ;
@@ -471,9 +492,6 @@ void reg_alloc(void)
471492 break ;
472493 case OP_load_constant :
473494 case OP_load_data_address :
474- if (insn -> rd -> consumed == -1 )
475- break ;
476-
477495 dest = prepare_dest (bb , insn -> rd , -1 , -1 );
478496 ir = bb_add_ph2_ir (bb , insn -> opcode );
479497 ir -> src0 = insn -> rd -> init_val ;
@@ -490,6 +508,12 @@ void reg_alloc(void)
490508 break ;
491509 case OP_address_of :
492510 case OP_global_address_of :
511+ /* Mark variable as address-taken, disable constant
512+ * optimization
513+ */
514+ insn -> rs1 -> address_taken = true;
515+ insn -> rs1 -> is_const = false;
516+
493517 /* make sure variable is on stack */
494518 if (!insn -> rs1 -> offset ) {
495519 insn -> rs1 -> offset = bb -> belong_to -> stack_size ;
@@ -500,6 +524,8 @@ void reg_alloc(void)
500524 ir = bb_add_ph2_ir (bb , OP_store );
501525 ir -> src0 = i ;
502526 ir -> src1 = insn -> rs1 -> offset ;
527+ /* Clear stale register tracking */
528+ REGS [i ].var = NULL ;
503529 }
504530 }
505531
@@ -792,7 +818,7 @@ void dump_ph2_ir(void)
792818 printf ("\t%%x%c = (%%x%c)" , rd , rs1 );
793819 break ;
794820 case OP_write :
795- printf ("\t(%%x%c) = %%x%c" , rs2 , rs1 );
821+ printf ("\t(%%x%c) = %%x%c" , rs1 , rs2 );
796822 break ;
797823 case OP_address_of_func :
798824 printf ("\t(%%x%c) = @%s" , rs1 , ph2_ir -> func_name );
0 commit comments