@@ -32,7 +32,12 @@ int global_ir_idx = 0;
3232ph1_ir_t * PH1_IR ;
3333int ph1_ir_idx = 0 ;
3434
35- ph2_ir_t * PH2_IR ;
35+ arena_t * INSN_ARENA ;
36+
37+ /* BB_ARENA is responsible for basic_block_t / ph2_ir_t allocation */
38+ arena_t * BB_ARENA ;
39+
40+ ph2_ir_t * * PH2_IR_FLATTEN ;
3641int ph2_ir_idx = 0 ;
3742
3843label_lut_t * LABEL_LUT ;
@@ -69,6 +74,87 @@ char *elf_symtab;
6974char * elf_strtab ;
7075char * elf_section ;
7176
77+ arena_block_t * arena_block_create (int capacity )
78+ {
79+ arena_block_t * block = malloc (sizeof (arena_block_t ));
80+
81+ if (!block ) {
82+ printf ("Failed to allocate memory for arena block\n" );
83+ exit (1 );
84+ }
85+
86+ block -> memory = calloc (capacity , sizeof (char ));
87+
88+ if (!block -> memory ) {
89+ printf ("Failed to allocate memory for arena block\n" );
90+ free (block );
91+ exit (1 );
92+ }
93+
94+ block -> capacity = capacity ;
95+ block -> offset = 0 ;
96+ block -> next = NULL ;
97+ return block ;
98+ }
99+
100+ arena_t * arena_init (int initial_capacity )
101+ {
102+ arena_t * arena = malloc (sizeof (arena_t ));
103+ arena -> head = arena_block_create (initial_capacity );
104+ return arena ;
105+ }
106+
107+ void * arena_alloc (arena_t * arena , int size )
108+ {
109+ char * ptr ;
110+ arena_block_t * block = arena -> head ;
111+
112+ while (block ) {
113+ if (block -> offset + size <= block -> capacity ) {
114+ ptr = block -> memory + block -> offset ;
115+ block -> offset += size ;
116+ return ptr ;
117+ }
118+ if (!block -> next )
119+ break ;
120+ block = block -> next ;
121+ }
122+
123+ /* If no space is available, create a new block
124+ * Allocate at least 1 KB or the requested size
125+ */
126+ int new_capacity = size > DEFAULT_ARENA_SIZE ? size : DEFAULT_ARENA_SIZE ;
127+ arena_block_t * new_block = arena_block_create (new_capacity );
128+ block -> next = new_block ;
129+ ptr = new_block -> memory + new_block -> offset ;
130+ new_block -> offset += size ;
131+ return ptr ;
132+ }
133+
134+ void arena_reset (arena_t * arena )
135+ {
136+ arena_block_t * block = arena -> head ;
137+
138+ while (block ) {
139+ block -> offset = 0 ;
140+ block = block -> next ;
141+ }
142+ }
143+
144+ void arena_free (arena_t * arena )
145+ {
146+ arena_block_t * block = arena -> head , * next ;
147+
148+ while (block ) {
149+ next = block -> next ;
150+ free (block -> memory );
151+ free (block );
152+ block = next ;
153+ }
154+
155+ free (arena );
156+ }
157+
72158/**
73159 * hashmap_hash_index() - hashses a string with FNV-1a hash function
74160 * and converts into usable hashmap index. The range of returned
@@ -312,11 +398,17 @@ ph1_ir_t *add_ph1_ir(opcode_t op)
312398 return ph1_ir ;
313399}
314400
401+ ph2_ir_t * add_existed_ph2_ir (ph2_ir_t * ph2_ir )
402+ {
403+ PH2_IR_FLATTEN [ph2_ir_idx ++ ] = ph2_ir ;
404+ return ph2_ir ;
405+ }
406+
315407ph2_ir_t * add_ph2_ir (opcode_t op )
316408{
317- ph2_ir_t * ph2_ir = & PH2_IR [ ph2_ir_idx ++ ] ;
409+ ph2_ir_t * ph2_ir = arena_alloc ( BB_ARENA , sizeof ( ph2_ir_t )) ;
318410 ph2_ir -> op = op ;
319- return ph2_ir ;
411+ return add_existed_ph2_ir ( ph2_ir ) ;
320412}
321413
322414void set_var_liveout (var_t * var , int end )
@@ -579,7 +671,7 @@ fn_t *add_fn()
579671/* Create a basic block and set the scope of variables to 'parent' block */
580672basic_block_t * bb_create (block_t * parent )
581673{
582- basic_block_t * bb = calloc ( 1 , sizeof (basic_block_t ));
674+ basic_block_t * bb = arena_alloc ( BB_ARENA , sizeof (basic_block_t ));
583675
584676 for (int i = 0 ; i < MAX_BB_PRED ; i ++ ) {
585677 bb -> prev [i ].bb = NULL ;
@@ -691,7 +783,7 @@ void add_insn(block_t *block,
691783
692784 bb -> scope = block ;
693785
694- insn_t * n = calloc ( 1 , sizeof (insn_t ));
786+ insn_t * n = arena_alloc ( INSN_ARENA , sizeof (insn_t ));
695787 n -> opcode = op ;
696788 n -> rd = rd ;
697789 n -> rs1 = rs1 ;
@@ -725,7 +817,9 @@ void global_init()
725817 TYPES = malloc (MAX_TYPES * sizeof (type_t ));
726818 GLOBAL_IR = malloc (MAX_GLOBAL_IR * sizeof (ph1_ir_t ));
727819 PH1_IR = malloc (MAX_IR_INSTR * sizeof (ph1_ir_t ));
728- PH2_IR = malloc (MAX_IR_INSTR * sizeof (ph2_ir_t ));
820+ INSN_ARENA = arena_init (DEFAULT_ARENA_SIZE );
821+ BB_ARENA = arena_init (DEFAULT_ARENA_SIZE );
822+ PH2_IR_FLATTEN = malloc (MAX_IR_INSTR * sizeof (ph2_ir_t ));
729823 LABEL_LUT = malloc (MAX_LABEL * sizeof (label_lut_t ));
730824 SOURCE = malloc (MAX_SOURCE );
731825 ALIASES = malloc (MAX_ALIASES * sizeof (alias_t ));
@@ -755,7 +849,9 @@ void global_release()
755849 free (TYPES );
756850 free (GLOBAL_IR );
757851 free (PH1_IR );
758- free (PH2_IR );
852+ arena_free (INSN_ARENA );
853+ arena_free (BB_ARENA );
854+ free (PH2_IR_FLATTEN );
759855 free (LABEL_LUT );
760856 free (SOURCE );
761857 free (ALIASES );
0 commit comments