blob: 2e67902e3407122c6b4684b4284b75454677cb0f [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
buzbeeefc63692012-11-14 16:31:52 -080017#include "compiler_internals.h"
buzbee67bf8852011-08-17 17:51:35 -070018
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080019namespace art {
20
buzbeefa57c472012-11-21 12:06:18 -080021const char* extended_mir_op_names[kMirOpLast - kMirOpFirst] = {
buzbeea169e1d2012-12-05 14:26:44 -080022 "Phi",
23 "Copy",
24 "FusedCmplFloat",
25 "FusedCmpgFloat",
26 "FusedCmplDouble",
27 "FusedCmpgDouble",
28 "FusedCmpLong",
29 "Nop",
30 "OpNullCheck",
31 "OpRangeCheck",
32 "OpDivZeroCheck",
33 "Check1",
34 "Check2",
buzbeecbd6d442012-11-17 14:11:25 -080035};
36
buzbee5abfa3e2012-01-31 17:01:43 -080037#ifdef WITH_MEMSTATS
Elliott Hughes719ace42012-03-09 18:06:03 -080038struct Memstats {
buzbeefa57c472012-11-21 12:06:18 -080039 uint32_t alloc_stats[kNumAllocKinds];
40 int list_sizes[kNumListKinds];
41 int list_wasted[kNumListKinds];
42 int list_grows[kNumListKinds];
43 int list_max_elems[kNumListKinds];
44 int bit_map_sizes[kNumBitMapKinds];
45 int bit_map_wasted[kNumBitMapKinds];
46 int bit_map_grows[kNumBitMapKinds];
Elliott Hughes719ace42012-03-09 18:06:03 -080047};
buzbee5abfa3e2012-01-31 17:01:43 -080048
buzbeefa57c472012-11-21 12:06:18 -080049const char* alloc_names[kNumAllocKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070050 "Misc ",
51 "BasicBlock ",
52 "LIR ",
53 "MIR ",
54 "DataFlow ",
55 "GrowList ",
56 "GrowBitMap ",
57 "Dalvik2SSA ",
58 "DebugInfo ",
59 "Successor ",
60 "RegAlloc ",
61 "Data ",
62 "Preds ",
buzbee5abfa3e2012-01-31 17:01:43 -080063};
64
buzbeefa57c472012-11-21 12:06:18 -080065const char* list_names[kNumListKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070066 "Misc ",
buzbeefa57c472012-11-21 12:06:18 -080067 "block_list ",
Bill Buzbeea114add2012-05-03 15:00:40 -070068 "SSAtoDalvik ",
buzbeefa57c472012-11-21 12:06:18 -080069 "dfs_order ",
70 "dfs_post_order ",
71 "dom_post_order_traversal ",
72 "throw_launch_pads ",
73 "suspend_launch_pads ",
74 "switch_tables ",
75 "fill_array_data ",
Bill Buzbeea114add2012-05-03 15:00:40 -070076 "SuccessorBlocks ",
77 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080078};
79
buzbeefa57c472012-11-21 12:06:18 -080080const char* bit_map_names[kNumBitMapKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070081 "Misc ",
82 "Use ",
83 "Def ",
84 "LiveIn ",
85 "BlockMatrix ",
86 "Dominators ",
87 "IDominated ",
88 "DomFrontier ",
89 "Phi ",
90 "TmpBlocks ",
91 "InputBlocks ",
92 "RegisterV ",
93 "TempSSARegisterV ",
94 "Null Check ",
95 "TmpBlockV ",
96 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080097};
98#endif
99
buzbeeeaf09bc2012-11-15 14:51:41 -0800100#define kArenaBitVectorGrowth 4 /* increase by 4 uint32_ts when limit hit */
buzbee67bf8852011-08-17 17:51:35 -0700101
102/* Allocate the initial memory block for arena-based allocation */
buzbeefa57c472012-11-21 12:06:18 -0800103bool HeapInit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700104{
buzbeefa57c472012-11-21 12:06:18 -0800105 DCHECK(cu->arena_head == NULL);
106 cu->arena_head =
buzbeecbd6d442012-11-17 14:11:25 -0800107 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE));
buzbeefa57c472012-11-21 12:06:18 -0800108 if (cu->arena_head == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700109 LOG(FATAL) << "No memory left to create compiler heap memory";
110 }
buzbeefa57c472012-11-21 12:06:18 -0800111 cu->arena_head->block_size = ARENA_DEFAULT_SIZE;
112 cu->current_arena = cu->arena_head;
113 cu->current_arena->bytes_allocated = 0;
114 cu->current_arena->next = NULL;
115 cu->num_arena_blocks = 1;
buzbeeba938cb2012-02-03 14:47:55 -0800116#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800117 cu->mstats = (Memstats*) NewMem(cu, sizeof(Memstats), true,
Bill Buzbeea114add2012-05-03 15:00:40 -0700118 kAllocDebugInfo);
buzbeeba938cb2012-02-03 14:47:55 -0800119#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700120 return true;
buzbee67bf8852011-08-17 17:51:35 -0700121}
122
123/* Arena-based malloc for compilation tasks */
buzbeefa57c472012-11-21 12:06:18 -0800124void* NewMem(CompilationUnit* cu, size_t size, bool zero, oat_alloc_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700125{
Bill Buzbeea114add2012-05-03 15:00:40 -0700126 size = (size + 3) & ~3;
buzbee5abfa3e2012-01-31 17:01:43 -0800127#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800128 if (cu->mstats != NULL) {
129 cu->mstats->alloc_stats[kind] += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700130 }
buzbee5abfa3e2012-01-31 17:01:43 -0800131#endif
buzbee67bf8852011-08-17 17:51:35 -0700132retry:
Bill Buzbeea114add2012-05-03 15:00:40 -0700133 /* Normal case - space is available in the current page */
buzbeefa57c472012-11-21 12:06:18 -0800134 if (size + cu->current_arena->bytes_allocated <=
135 cu->current_arena->block_size) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 void *ptr;
buzbeefa57c472012-11-21 12:06:18 -0800137 ptr = &cu->current_arena->ptr[cu->current_arena->bytes_allocated];
138 cu->current_arena->bytes_allocated += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700139 if (zero) {
140 memset(ptr, 0, size);
141 }
142 return ptr;
143 } else {
144 /*
145 * See if there are previously allocated arena blocks before the last
146 * reset
147 */
buzbeefa57c472012-11-21 12:06:18 -0800148 if (cu->current_arena->next) {
149 cu->current_arena = cu->current_arena->next;
150 cu->current_arena->bytes_allocated = 0;
buzbee67bf8852011-08-17 17:51:35 -0700151 goto retry;
152 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700153
buzbeefa57c472012-11-21 12:06:18 -0800154 size_t block_size = (size < ARENA_DEFAULT_SIZE) ? ARENA_DEFAULT_SIZE : size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700155 /* Time to allocate a new arena */
buzbeefa57c472012-11-21 12:06:18 -0800156 ArenaMemBlock *new_arena =
157 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + block_size));
158 if (new_arena == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700159 LOG(FATAL) << "Arena allocation failure";
160 }
buzbeefa57c472012-11-21 12:06:18 -0800161 new_arena->block_size = block_size;
162 new_arena->bytes_allocated = 0;
163 new_arena->next = NULL;
164 cu->current_arena->next = new_arena;
165 cu->current_arena = new_arena;
166 cu->num_arena_blocks++;
167 if (cu->num_arena_blocks > 20000) {
168 LOG(INFO) << "Total arena pages: " << cu->num_arena_blocks;
Bill Buzbeea114add2012-05-03 15:00:40 -0700169 }
170 goto retry;
171 }
buzbee67bf8852011-08-17 17:51:35 -0700172}
173
174/* Reclaim all the arena blocks allocated so far */
buzbeefa57c472012-11-21 12:06:18 -0800175void ArenaReset(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700176{
buzbeefa57c472012-11-21 12:06:18 -0800177 ArenaMemBlock* head = cu->arena_head;
Bill Buzbeea114add2012-05-03 15:00:40 -0700178 while (head != NULL) {
179 ArenaMemBlock* p = head;
180 head = head->next;
181 free(p);
182 }
buzbeefa57c472012-11-21 12:06:18 -0800183 cu->arena_head = NULL;
184 cu->current_arena = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700185}
186
187/* Growable List initialization */
buzbeefa57c472012-11-21 12:06:18 -0800188void CompilerInitGrowableList(CompilationUnit* cu, GrowableList* g_list,
189 size_t init_length, oat_list_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700190{
buzbeefa57c472012-11-21 12:06:18 -0800191 g_list->num_allocated = init_length;
192 g_list->num_used = 0;
193 g_list->elem_list = static_cast<uintptr_t *>(NewMem(cu, sizeof(intptr_t) * init_length,
buzbeecbd6d442012-11-17 14:11:25 -0800194 true, kAllocGrowableList));
buzbee5abfa3e2012-01-31 17:01:43 -0800195#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800196 cu->mstats->list_sizes[kind] += sizeof(uintptr_t) * init_length;
197 g_list->kind = kind;
198 if (static_cast<int>(init_length) > cu->mstats->list_max_elems[kind]) {
199 cu->mstats->list_max_elems[kind] = init_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700200 }
buzbee5abfa3e2012-01-31 17:01:43 -0800201#endif
buzbee67bf8852011-08-17 17:51:35 -0700202}
203
204/* Expand the capacity of a growable list */
buzbeefa57c472012-11-21 12:06:18 -0800205static void ExpandGrowableList(CompilationUnit* cu, GrowableList* g_list)
buzbee67bf8852011-08-17 17:51:35 -0700206{
buzbeefa57c472012-11-21 12:06:18 -0800207 int new_length = g_list->num_allocated;
208 if (new_length < 128) {
209 new_length <<= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700210 } else {
buzbeefa57c472012-11-21 12:06:18 -0800211 new_length += 128;
Bill Buzbeea114add2012-05-03 15:00:40 -0700212 }
buzbeefa57c472012-11-21 12:06:18 -0800213 uintptr_t *new_array =
214 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
buzbeecbd6d442012-11-17 14:11:25 -0800215 kAllocGrowableList));
buzbeefa57c472012-11-21 12:06:18 -0800216 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800217#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800218 cu->mstats->list_sizes[g_list->kind] += sizeof(uintptr_t) * new_length;
219 cu->mstats->list_wasted[g_list->kind] +=
220 sizeof(uintptr_t) * g_list->num_allocated;
221 cu->mstats->list_grows[g_list->kind]++;
222 if (new_length > cu->mstats->list_max_elems[g_list->kind]) {
223 cu->mstats->list_max_elems[g_list->kind] = new_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700224 }
buzbee5abfa3e2012-01-31 17:01:43 -0800225#endif
buzbeefa57c472012-11-21 12:06:18 -0800226 g_list->num_allocated = new_length;
227 g_list->elem_list = new_array;
buzbee67bf8852011-08-17 17:51:35 -0700228}
229
230/* Insert a new element into the growable list */
buzbeefa57c472012-11-21 12:06:18 -0800231void InsertGrowableList(CompilationUnit* cu, GrowableList* g_list,
buzbeecbd6d442012-11-17 14:11:25 -0800232 uintptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700233{
buzbeefa57c472012-11-21 12:06:18 -0800234 DCHECK_NE(g_list->num_allocated, 0U);
235 if (g_list->num_used == g_list->num_allocated) {
236 ExpandGrowableList(cu, g_list);
Bill Buzbeea114add2012-05-03 15:00:40 -0700237 }
buzbeefa57c472012-11-21 12:06:18 -0800238 g_list->elem_list[g_list->num_used++] = elem;
buzbee67bf8852011-08-17 17:51:35 -0700239}
240
buzbee5abfa3e2012-01-31 17:01:43 -0800241/* Delete an element from a growable list. Element must be present */
buzbeefa57c472012-11-21 12:06:18 -0800242void DeleteGrowableList(GrowableList* g_list, uintptr_t elem)
buzbee5abfa3e2012-01-31 17:01:43 -0800243{
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 bool found = false;
buzbeefa57c472012-11-21 12:06:18 -0800245 for (unsigned int i = 0; i < g_list->num_used; i++) {
246 if (!found && g_list->elem_list[i] == elem) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700247 found = true;
buzbee5abfa3e2012-01-31 17:01:43 -0800248 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700249 if (found) {
buzbeefa57c472012-11-21 12:06:18 -0800250 g_list->elem_list[i] = g_list->elem_list[i+1];
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 }
252 }
253 DCHECK_EQ(found, true);
buzbeefa57c472012-11-21 12:06:18 -0800254 g_list->num_used--;
buzbee5abfa3e2012-01-31 17:01:43 -0800255}
256
buzbeefa57c472012-11-21 12:06:18 -0800257void GrowableListIteratorInit(GrowableList* g_list,
Bill Buzbeea114add2012-05-03 15:00:40 -0700258 GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700259{
buzbeefa57c472012-11-21 12:06:18 -0800260 iterator->list = g_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 iterator->idx = 0;
buzbeefa57c472012-11-21 12:06:18 -0800262 iterator->size = g_list->num_used;
buzbee67bf8852011-08-17 17:51:35 -0700263}
264
buzbee52a77fc2012-11-20 19:50:46 -0800265uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700266{
buzbeefa57c472012-11-21 12:06:18 -0800267 DCHECK_EQ(iterator->size, iterator->list->num_used);
Bill Buzbeea114add2012-05-03 15:00:40 -0700268 if (iterator->idx == iterator->size) return 0;
buzbeefa57c472012-11-21 12:06:18 -0800269 return iterator->list->elem_list[iterator->idx++];
buzbee67bf8852011-08-17 17:51:35 -0700270}
271
buzbeefa57c472012-11-21 12:06:18 -0800272uintptr_t GrowableListGetElement(const GrowableList* g_list, size_t idx)
buzbee67bf8852011-08-17 17:51:35 -0700273{
buzbeefa57c472012-11-21 12:06:18 -0800274 DCHECK_LT(idx, g_list->num_used);
275 return g_list->elem_list[idx];
buzbee67bf8852011-08-17 17:51:35 -0700276}
277
buzbee5abfa3e2012-01-31 17:01:43 -0800278#ifdef WITH_MEMSTATS
279/* Dump memory usage stats */
buzbeefa57c472012-11-21 12:06:18 -0800280void DumpMemStats(CompilationUnit* cu)
buzbee5abfa3e2012-01-31 17:01:43 -0800281{
buzbeeeaf09bc2012-11-15 14:51:41 -0800282 uint32_t total = 0;
Bill Buzbeea114add2012-05-03 15:00:40 -0700283 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800284 total += cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700285 }
286 if (total > (10 * 1024 * 1024)) {
287 LOG(INFO) << "MEMUSAGE: " << total << " : "
buzbeefa57c472012-11-21 12:06:18 -0800288 << PrettyMethod(cu->method_idx, *cu->dex_file);
289 LOG(INFO) << "insns_size: " << cu->insns_size;
290 if (cu->disable_dataflow) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700291 LOG(INFO) << " ** Dataflow disabled ** ";
buzbee5abfa3e2012-01-31 17:01:43 -0800292 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700293 LOG(INFO) << "===== Overall allocations";
294 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800295 LOG(INFO) << alloc_names[i] << std::setw(10) <<
296 cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700297 }
298 LOG(INFO) << "===== GrowableList allocations";
299 for (int i = 0; i < kNumListKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800300 LOG(INFO) << list_names[i]
301 << " S:" << cu->mstats->list_sizes[i]
302 << ", W:" << cu->mstats->list_wasted[i]
303 << ", G:" << cu->mstats->list_grows[i]
304 << ", E:" << cu->mstats->list_max_elems[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700305 }
306 LOG(INFO) << "===== GrowableBitMap allocations";
307 for (int i = 0; i < kNumBitMapKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800308 LOG(INFO) << bit_map_names[i]
309 << " S:" << cu->mstats->bit_map_sizes[i]
310 << ", W:" << cu->mstats->bit_map_wasted[i]
311 << ", G:" << cu->mstats->bit_map_grows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800312 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700313 }
buzbee5abfa3e2012-01-31 17:01:43 -0800314}
315#endif
316
buzbee67bf8852011-08-17 17:51:35 -0700317/* Debug Utility - dump a compilation unit */
buzbeefa57c472012-11-21 12:06:18 -0800318void DumpCompilationUnit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700319{
Bill Buzbeea114add2012-05-03 15:00:40 -0700320 BasicBlock* bb;
buzbeefa57c472012-11-21 12:06:18 -0800321 const char* block_type_names[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700322 "Entry Block",
323 "Code Block",
324 "Exit Block",
325 "Exception Handling",
326 "Catch Block"
327 };
buzbee67bf8852011-08-17 17:51:35 -0700328
buzbeefa57c472012-11-21 12:06:18 -0800329 LOG(INFO) << "Compiling " << PrettyMethod(cu->method_idx, *cu->dex_file);
330 LOG(INFO) << cu->insns << " insns";
331 LOG(INFO) << cu->num_blocks << " blocks in total";
Bill Buzbeea114add2012-05-03 15:00:40 -0700332 GrowableListIterator iterator;
buzbee67bf8852011-08-17 17:51:35 -0700333
buzbeefa57c472012-11-21 12:06:18 -0800334 GrowableListIteratorInit(&cu->block_list, &iterator);
buzbee67bf8852011-08-17 17:51:35 -0700335
Bill Buzbeea114add2012-05-03 15:00:40 -0700336 while (true) {
buzbee52a77fc2012-11-20 19:50:46 -0800337 bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 if (bb == NULL) break;
339 LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
340 bb->id,
buzbeefa57c472012-11-21 12:06:18 -0800341 block_type_names[bb->block_type],
342 bb->start_offset,
343 bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
344 bb->last_mir_insn ? "" : " empty");
Bill Buzbeea114add2012-05-03 15:00:40 -0700345 if (bb->taken) {
346 LOG(INFO) << " Taken branch: block " << bb->taken->id
buzbeefa57c472012-11-21 12:06:18 -0800347 << "(0x" << std::hex << bb->taken->start_offset << ")";
buzbee67bf8852011-08-17 17:51:35 -0700348 }
buzbeefa57c472012-11-21 12:06:18 -0800349 if (bb->fall_through) {
350 LOG(INFO) << " Fallthrough : block " << bb->fall_through->id
351 << " (0x" << std::hex << bb->fall_through->start_offset << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700352 }
353 }
buzbee67bf8852011-08-17 17:51:35 -0700354}
355
buzbeefa57c472012-11-21 12:06:18 -0800356static uint32_t check_masks[32] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700357 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
358 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
359 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
360 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
361 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
362 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
363 0x40000000, 0x80000000 };
buzbee67bc2362011-10-11 18:08:40 -0700364
buzbee67bf8852011-08-17 17:51:35 -0700365/*
366 * Allocate a bit vector with enough space to hold at least the specified
367 * number of bits.
368 *
369 * NOTE: memory is allocated from the compiler arena.
370 */
buzbeefa57c472012-11-21 12:06:18 -0800371ArenaBitVector* AllocBitVector(CompilationUnit* cu,
372 unsigned int start_bits, bool expandable,
373 oat_bit_map_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700374{
Bill Buzbeea114add2012-05-03 15:00:40 -0700375 ArenaBitVector* bv;
376 unsigned int count;
buzbee67bf8852011-08-17 17:51:35 -0700377
Bill Buzbeea114add2012-05-03 15:00:40 -0700378 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700379
buzbeefa57c472012-11-21 12:06:18 -0800380 bv = static_cast<ArenaBitVector*>(NewMem(cu, sizeof(ArenaBitVector), false,
buzbeecbd6d442012-11-17 14:11:25 -0800381 kAllocGrowableBitMap));
buzbee67bf8852011-08-17 17:51:35 -0700382
buzbeefa57c472012-11-21 12:06:18 -0800383 count = (start_bits + 31) >> 5;
buzbee67bf8852011-08-17 17:51:35 -0700384
buzbeefa57c472012-11-21 12:06:18 -0800385 bv->storage_size = count;
Bill Buzbeea114add2012-05-03 15:00:40 -0700386 bv->expandable = expandable;
buzbeefa57c472012-11-21 12:06:18 -0800387 bv->storage = static_cast<uint32_t*>(NewMem(cu, count * sizeof(uint32_t), true,
buzbeeeaf09bc2012-11-15 14:51:41 -0800388 kAllocGrowableBitMap));
buzbee5abfa3e2012-01-31 17:01:43 -0800389#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 bv->kind = kind;
buzbeefa57c472012-11-21 12:06:18 -0800391 cu->mstats->bit_map_sizes[kind] += count * sizeof(uint32_t);
buzbee5abfa3e2012-01-31 17:01:43 -0800392#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700393 return bv;
buzbee67bf8852011-08-17 17:51:35 -0700394}
395
396/*
397 * Determine whether or not the specified bit is set.
398 */
buzbeefa57c472012-11-21 12:06:18 -0800399bool IsBitSet(const ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700400{
buzbeefa57c472012-11-21 12:06:18 -0800401 DCHECK_LT(num, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700402
buzbeefa57c472012-11-21 12:06:18 -0800403 unsigned int val = p_bits->storage[num >> 5] & check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700404 return (val != 0);
buzbee67bf8852011-08-17 17:51:35 -0700405}
406
407/*
408 * Mark all bits bit as "clear".
409 */
buzbeefa57c472012-11-21 12:06:18 -0800410void ClearAllBits(ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700411{
buzbeefa57c472012-11-21 12:06:18 -0800412 unsigned int count = p_bits->storage_size;
413 memset(p_bits->storage, 0, count * sizeof(uint32_t));
buzbee67bf8852011-08-17 17:51:35 -0700414}
415
416/*
417 * Mark the specified bit as "set".
418 *
419 * Returns "false" if the bit is outside the range of the vector and we're
420 * not allowed to expand.
421 *
422 * NOTE: memory is allocated from the compiler arena.
423 */
buzbeefa57c472012-11-21 12:06:18 -0800424bool SetBit(CompilationUnit* cu, ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700425{
buzbeefa57c472012-11-21 12:06:18 -0800426 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
427 if (!p_bits->expandable) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700428 LOG(FATAL) << "Can't expand";
buzbee67bf8852011-08-17 17:51:35 -0700429 }
430
Bill Buzbeea114add2012-05-03 15:00:40 -0700431 /* Round up to word boundaries for "num+1" bits */
buzbeefa57c472012-11-21 12:06:18 -0800432 unsigned int new_size = (num + 1 + 31) >> 5;
433 DCHECK_GT(new_size, p_bits->storage_size);
434 uint32_t *new_storage = static_cast<uint32_t*>(NewMem(cu, new_size * sizeof(uint32_t), false,
buzbeeeaf09bc2012-11-15 14:51:41 -0800435 kAllocGrowableBitMap));
buzbeefa57c472012-11-21 12:06:18 -0800436 memcpy(new_storage, p_bits->storage, p_bits->storage_size * sizeof(uint32_t));
437 memset(&new_storage[p_bits->storage_size], 0,
438 (new_size - p_bits->storage_size) * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700439#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800440 cu->mstats->bit_map_wasted[p_bits->kind] +=
441 p_bits->storage_size * sizeof(uint32_t);
442 cu->mstats->bit_map_sizes[p_bits->kind] += new_size * sizeof(uint32_t);
443 cu->mstats->bit_map_grows[p_bits->kind]++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700444#endif
buzbeefa57c472012-11-21 12:06:18 -0800445 p_bits->storage = new_storage;
446 p_bits->storage_size = new_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700447 }
448
buzbeefa57c472012-11-21 12:06:18 -0800449 p_bits->storage[num >> 5] |= check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700450 return true;
buzbee67bf8852011-08-17 17:51:35 -0700451}
452
453/*
454 * Mark the specified bit as "unset".
455 *
456 * Returns "false" if the bit is outside the range of the vector and we're
457 * not allowed to expand.
458 *
459 * NOTE: memory is allocated from the compiler arena.
460 */
buzbeefa57c472012-11-21 12:06:18 -0800461bool ClearBit(ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700462{
buzbeefa57c472012-11-21 12:06:18 -0800463 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700464 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
465 }
buzbee67bf8852011-08-17 17:51:35 -0700466
buzbeefa57c472012-11-21 12:06:18 -0800467 p_bits->storage[num >> 5] &= ~check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700468 return true;
buzbee67bf8852011-08-17 17:51:35 -0700469}
470
buzbee67bf8852011-08-17 17:51:35 -0700471/* Initialize the iterator structure */
buzbeefa57c472012-11-21 12:06:18 -0800472void BitVectorIteratorInit(ArenaBitVector* p_bits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700473 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700474{
buzbeefa57c472012-11-21 12:06:18 -0800475 iterator->p_bits = p_bits;
476 iterator->bit_size = p_bits->storage_size * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700477 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700478}
479
480/*
481 * If the vector sizes don't match, log an error and abort.
482 */
buzbee52a77fc2012-11-20 19:50:46 -0800483static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700484{
buzbeefa57c472012-11-21 12:06:18 -0800485 if (bv1->storage_size != bv2->storage_size) {
486 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storage_size
487 << ", " << bv2->storage_size << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 }
buzbee67bf8852011-08-17 17:51:35 -0700489}
490
491/*
492 * Copy a whole vector to the other. Only do that when the both vectors have
493 * the same size.
494 */
buzbee52a77fc2012-11-20 19:50:46 -0800495void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
buzbee67bf8852011-08-17 17:51:35 -0700496{
Bill Buzbeea114add2012-05-03 15:00:40 -0700497 /* if dest is expandable and < src, we could expand dest to match */
buzbee52a77fc2012-11-20 19:50:46 -0800498 CheckSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700499
buzbeefa57c472012-11-21 12:06:18 -0800500 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storage_size);
buzbee67bf8852011-08-17 17:51:35 -0700501}
502
503/*
504 * Intersect two bit vectors and store the result to the dest vector.
505 */
506
buzbee52a77fc2012-11-20 19:50:46 -0800507bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700508 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700509{
Bill Buzbeea114add2012-05-03 15:00:40 -0700510 DCHECK(src1 != NULL);
511 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800512 if (dest->storage_size != src1->storage_size ||
513 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700514 dest->expandable != src1->expandable ||
515 dest->expandable != src2->expandable)
516 return false;
buzbee67bf8852011-08-17 17:51:35 -0700517
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800519 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700520 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
521 }
522 return true;
buzbee67bf8852011-08-17 17:51:35 -0700523}
524
525/*
526 * Unify two bit vectors and store the result to the dest vector.
527 */
buzbee52a77fc2012-11-20 19:50:46 -0800528bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700529 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700530{
Bill Buzbeea114add2012-05-03 15:00:40 -0700531 DCHECK(src1 != NULL);
532 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800533 if (dest->storage_size != src1->storage_size ||
534 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700535 dest->expandable != src1->expandable ||
536 dest->expandable != src2->expandable)
537 return false;
buzbee67bf8852011-08-17 17:51:35 -0700538
Bill Buzbeea114add2012-05-03 15:00:40 -0700539 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800540 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700541 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
542 }
543 return true;
buzbee67bf8852011-08-17 17:51:35 -0700544}
545
546/*
buzbeee1965672012-03-11 18:39:19 -0700547 * Return true if any bits collide. Vectors must be same size.
548 */
buzbee52a77fc2012-11-20 19:50:46 -0800549bool TestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700550 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700551{
buzbeefa57c472012-11-21 12:06:18 -0800552 DCHECK_EQ(src1->storage_size, src2->storage_size);
553 for (uint32_t idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700554 if (src1->storage[idx] & src2->storage[idx]) return true;
555 }
556 return false;
buzbeee1965672012-03-11 18:39:19 -0700557}
558
559/*
buzbee67bf8852011-08-17 17:51:35 -0700560 * Compare two bit vectors and return true if difference is seen.
561 */
buzbee52a77fc2012-11-20 19:50:46 -0800562bool CompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700563 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700564{
buzbeefa57c472012-11-21 12:06:18 -0800565 if (src1->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700566 src1->expandable != src2->expandable)
567 return true;
buzbee67bf8852011-08-17 17:51:35 -0700568
Bill Buzbeea114add2012-05-03 15:00:40 -0700569 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800570 for (idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700571 if (src1->storage[idx] != src2->storage[idx]) return true;
572 }
573 return false;
buzbee67bf8852011-08-17 17:51:35 -0700574}
575
576/*
577 * Count the number of bits that are set.
578 */
buzbeefa57c472012-11-21 12:06:18 -0800579int CountSetBits(const ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700580{
Bill Buzbeea114add2012-05-03 15:00:40 -0700581 unsigned int word;
582 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700583
buzbeefa57c472012-11-21 12:06:18 -0800584 for (word = 0; word < p_bits->storage_size; word++) {
585 uint32_t val = p_bits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700586
Bill Buzbeea114add2012-05-03 15:00:40 -0700587 if (val != 0) {
588 if (val == 0xffffffff) {
589 count += 32;
590 } else {
591 /* count the number of '1' bits */
592 while (val != 0) {
593 val &= val - 1;
594 count++;
buzbee67bf8852011-08-17 17:51:35 -0700595 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700596 }
buzbee67bf8852011-08-17 17:51:35 -0700597 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700598 }
buzbee67bf8852011-08-17 17:51:35 -0700599
Bill Buzbeea114add2012-05-03 15:00:40 -0700600 return count;
buzbee67bf8852011-08-17 17:51:35 -0700601}
602
603/* Return the next position set to 1. -1 means end-of-element reached */
buzbee52a77fc2012-11-20 19:50:46 -0800604int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700605{
buzbeefa57c472012-11-21 12:06:18 -0800606 ArenaBitVector* p_bits = iterator->p_bits;
607 uint32_t bit_index = iterator->idx;
608 uint32_t bit_size = iterator->bit_size;
buzbee67bf8852011-08-17 17:51:35 -0700609
buzbeefa57c472012-11-21 12:06:18 -0800610 DCHECK_EQ(bit_size, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700611
buzbeefa57c472012-11-21 12:06:18 -0800612 if (bit_index >= bit_size) return -1;
buzbee5b537102012-01-17 17:33:47 -0800613
buzbeefa57c472012-11-21 12:06:18 -0800614 uint32_t word_index = bit_index >> 5;
615 uint32_t end_word_index = bit_size >> 5;
616 uint32_t* storage = p_bits->storage;
617 uint32_t word = storage[word_index++];
buzbee5b537102012-01-17 17:33:47 -0800618
Bill Buzbeea114add2012-05-03 15:00:40 -0700619 // Mask out any bits in the first word we've already considered
buzbeefa57c472012-11-21 12:06:18 -0800620 word &= ~((1 << (bit_index & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800621
buzbeefa57c472012-11-21 12:06:18 -0800622 for (; word_index <= end_word_index;) {
623 uint32_t bit_pos = bit_index & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700624 if (word == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800625 bit_index += (32 - bit_pos);
626 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700627 continue;
buzbee67bf8852011-08-17 17:51:35 -0700628 }
buzbeefa57c472012-11-21 12:06:18 -0800629 for (; bit_pos < 32; bit_pos++) {
630 if (word & (1 << bit_pos)) {
631 iterator->idx = bit_index + 1;
632 return bit_index;
Bill Buzbeea114add2012-05-03 15:00:40 -0700633 }
buzbeefa57c472012-11-21 12:06:18 -0800634 bit_index++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700635 }
buzbeefa57c472012-11-21 12:06:18 -0800636 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700637 }
buzbeefa57c472012-11-21 12:06:18 -0800638 iterator->idx = iterator->bit_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700639 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700640}
641
642/*
643 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
644 * since there might be unused bits - setting those to one will confuse the
645 * iterator.
646 */
buzbeefa57c472012-11-21 12:06:18 -0800647void SetInitialBits(ArenaBitVector* p_bits, unsigned int num_bits)
buzbee67bf8852011-08-17 17:51:35 -0700648{
Bill Buzbeea114add2012-05-03 15:00:40 -0700649 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800650 DCHECK_LE(((num_bits + 31) >> 5), p_bits->storage_size);
651 for (idx = 0; idx < (num_bits >> 5); idx++) {
652 p_bits->storage[idx] = -1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700653 }
buzbeefa57c472012-11-21 12:06:18 -0800654 unsigned int rem_num_bits = num_bits & 0x1f;
655 if (rem_num_bits) {
656 p_bits->storage[idx] = (1 << rem_num_bits) - 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700657 }
buzbee67bf8852011-08-17 17:51:35 -0700658}
659
buzbee52a77fc2012-11-20 19:50:46 -0800660void GetBlockName(BasicBlock* bb, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700661{
buzbeefa57c472012-11-21 12:06:18 -0800662 switch (bb->block_type) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700663 case kEntryBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700664 snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700665 break;
666 case kExitBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700667 snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700668 break;
669 case kDalvikByteCode:
buzbeefa57c472012-11-21 12:06:18 -0800670 snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 break;
672 case kExceptionHandling:
buzbeefa57c472012-11-21 12:06:18 -0800673 snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700674 bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700675 break;
676 default:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700677 snprintf(name, BLOCK_NAME_LEN, "??_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700678 break;
679 }
buzbee67bf8852011-08-17 17:51:35 -0700680}
buzbeeed3e9302011-09-23 17:34:19 -0700681
buzbeefa57c472012-11-21 12:06:18 -0800682const char* GetShortyFromTargetIdx(CompilationUnit *cu, int target_idx)
buzbeeed3e9302011-09-23 17:34:19 -0700683{
buzbeefa57c472012-11-21 12:06:18 -0800684 const DexFile::MethodId& method_id = cu->dex_file->GetMethodId(target_idx);
685 return cu->dex_file->GetShorty(method_id.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700686}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800687
buzbee02031b12012-11-23 09:41:35 -0800688/* Allocate a new basic block */
689BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
690{
691 BasicBlock* bb = static_cast<BasicBlock*>(NewMem(cu, sizeof(BasicBlock), true, kAllocBB));
692 bb->block_type = block_type;
693 bb->id = block_id;
694 bb->predecessors = static_cast<GrowableList*>
695 (NewMem(cu, sizeof(GrowableList), false, kAllocPredecessors));
696 CompilerInitGrowableList(cu, bb->predecessors,
697 (block_type == kExitBlock) ? 2048 : 2,
698 kListPredecessors);
699 cu->block_id_map.Put(block_id, block_id);
700 return bb;
701}
702
703/* Insert an MIR instruction to the end of a basic block */
704void AppendMIR(BasicBlock* bb, MIR* mir)
705{
706 if (bb->first_mir_insn == NULL) {
707 DCHECK(bb->last_mir_insn == NULL);
708 bb->last_mir_insn = bb->first_mir_insn = mir;
709 mir->prev = mir->next = NULL;
710 } else {
711 bb->last_mir_insn->next = mir;
712 mir->prev = bb->last_mir_insn;
713 mir->next = NULL;
714 bb->last_mir_insn = mir;
715 }
716}
717
718/* Insert an MIR instruction to the head of a basic block */
719void PrependMIR(BasicBlock* bb, MIR* mir)
720{
721 if (bb->first_mir_insn == NULL) {
722 DCHECK(bb->last_mir_insn == NULL);
723 bb->last_mir_insn = bb->first_mir_insn = mir;
724 mir->prev = mir->next = NULL;
725 } else {
726 bb->first_mir_insn->prev = mir;
727 mir->next = bb->first_mir_insn;
728 mir->prev = NULL;
729 bb->first_mir_insn = mir;
730 }
731}
732
733/* Insert a MIR instruction after the specified MIR */
734void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir)
735{
736 new_mir->prev = current_mir;
737 new_mir->next = current_mir->next;
738 current_mir->next = new_mir;
739
740 if (new_mir->next) {
741 /* Is not the last MIR in the block */
742 new_mir->next->prev = new_mir;
743 } else {
744 /* Is the last MIR in the block */
745 bb->last_mir_insn = new_mir;
746 }
747}
748
749/*
750 * Append an LIR instruction to the LIR list maintained by a compilation
751 * unit
752 */
753void AppendLIR(CompilationUnit *cu, LIR* lir)
754{
755 if (cu->first_lir_insn == NULL) {
756 DCHECK(cu->last_lir_insn == NULL);
757 cu->last_lir_insn = cu->first_lir_insn = lir;
758 lir->prev = lir->next = NULL;
759 } else {
760 cu->last_lir_insn->next = lir;
761 lir->prev = cu->last_lir_insn;
762 lir->next = NULL;
763 cu->last_lir_insn = lir;
764 }
765}
766
767/*
768 * Insert an LIR instruction before the current instruction, which cannot be the
769 * first instruction.
770 *
771 * prev_lir <-> new_lir <-> current_lir
772 */
773void InsertLIRBefore(LIR* current_lir, LIR* new_lir)
774{
775 DCHECK(current_lir->prev != NULL);
776 LIR *prev_lir = current_lir->prev;
777
778 prev_lir->next = new_lir;
779 new_lir->prev = prev_lir;
780 new_lir->next = current_lir;
781 current_lir->prev = new_lir;
782}
783
784/*
785 * Insert an LIR instruction after the current instruction, which cannot be the
786 * first instruction.
787 *
788 * current_lir -> new_lir -> old_next
789 */
790void InsertLIRAfter(LIR* current_lir, LIR* new_lir)
791{
792 new_lir->prev = current_lir;
793 new_lir->next = current_lir->next;
794 current_lir->next = new_lir;
795 new_lir->next->prev = new_lir;
796}
797
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800798} // namespace art