blob: d8a59561d0dda94b407bc7e5f954bf7ffb9b9d7e [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] = {
buzbeecbd6d442012-11-17 14:11:25 -080022 "kMirOpPhi",
23 "kMirOpCopy",
24 "kMirFusedCmplFloat",
25 "kMirFusedCmpgFloat",
26 "kMirFusedCmplDouble",
27 "kMirFusedCmpgDouble",
28 "kMirFusedCmpLong",
29 "kMirNop",
30 "kMirOpNullCheck",
31 "kMirOpRangeCheck",
32 "kMirOpDivZeroCheck",
33 "kMirOpCheck",
34};
35
buzbee5abfa3e2012-01-31 17:01:43 -080036#ifdef WITH_MEMSTATS
Elliott Hughes719ace42012-03-09 18:06:03 -080037struct Memstats {
buzbeefa57c472012-11-21 12:06:18 -080038 uint32_t alloc_stats[kNumAllocKinds];
39 int list_sizes[kNumListKinds];
40 int list_wasted[kNumListKinds];
41 int list_grows[kNumListKinds];
42 int list_max_elems[kNumListKinds];
43 int bit_map_sizes[kNumBitMapKinds];
44 int bit_map_wasted[kNumBitMapKinds];
45 int bit_map_grows[kNumBitMapKinds];
Elliott Hughes719ace42012-03-09 18:06:03 -080046};
buzbee5abfa3e2012-01-31 17:01:43 -080047
buzbeefa57c472012-11-21 12:06:18 -080048const char* alloc_names[kNumAllocKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070049 "Misc ",
50 "BasicBlock ",
51 "LIR ",
52 "MIR ",
53 "DataFlow ",
54 "GrowList ",
55 "GrowBitMap ",
56 "Dalvik2SSA ",
57 "DebugInfo ",
58 "Successor ",
59 "RegAlloc ",
60 "Data ",
61 "Preds ",
buzbee5abfa3e2012-01-31 17:01:43 -080062};
63
buzbeefa57c472012-11-21 12:06:18 -080064const char* list_names[kNumListKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070065 "Misc ",
buzbeefa57c472012-11-21 12:06:18 -080066 "block_list ",
Bill Buzbeea114add2012-05-03 15:00:40 -070067 "SSAtoDalvik ",
buzbeefa57c472012-11-21 12:06:18 -080068 "dfs_order ",
69 "dfs_post_order ",
70 "dom_post_order_traversal ",
71 "throw_launch_pads ",
72 "suspend_launch_pads ",
73 "switch_tables ",
74 "fill_array_data ",
Bill Buzbeea114add2012-05-03 15:00:40 -070075 "SuccessorBlocks ",
76 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080077};
78
buzbeefa57c472012-11-21 12:06:18 -080079const char* bit_map_names[kNumBitMapKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070080 "Misc ",
81 "Use ",
82 "Def ",
83 "LiveIn ",
84 "BlockMatrix ",
85 "Dominators ",
86 "IDominated ",
87 "DomFrontier ",
88 "Phi ",
89 "TmpBlocks ",
90 "InputBlocks ",
91 "RegisterV ",
92 "TempSSARegisterV ",
93 "Null Check ",
94 "TmpBlockV ",
95 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080096};
97#endif
98
buzbeeeaf09bc2012-11-15 14:51:41 -080099#define kArenaBitVectorGrowth 4 /* increase by 4 uint32_ts when limit hit */
buzbee67bf8852011-08-17 17:51:35 -0700100
101/* Allocate the initial memory block for arena-based allocation */
buzbeefa57c472012-11-21 12:06:18 -0800102bool HeapInit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700103{
buzbeefa57c472012-11-21 12:06:18 -0800104 DCHECK(cu->arena_head == NULL);
105 cu->arena_head =
buzbeecbd6d442012-11-17 14:11:25 -0800106 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE));
buzbeefa57c472012-11-21 12:06:18 -0800107 if (cu->arena_head == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700108 LOG(FATAL) << "No memory left to create compiler heap memory";
109 }
buzbeefa57c472012-11-21 12:06:18 -0800110 cu->arena_head->block_size = ARENA_DEFAULT_SIZE;
111 cu->current_arena = cu->arena_head;
112 cu->current_arena->bytes_allocated = 0;
113 cu->current_arena->next = NULL;
114 cu->num_arena_blocks = 1;
buzbeeba938cb2012-02-03 14:47:55 -0800115#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800116 cu->mstats = (Memstats*) NewMem(cu, sizeof(Memstats), true,
Bill Buzbeea114add2012-05-03 15:00:40 -0700117 kAllocDebugInfo);
buzbeeba938cb2012-02-03 14:47:55 -0800118#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700119 return true;
buzbee67bf8852011-08-17 17:51:35 -0700120}
121
122/* Arena-based malloc for compilation tasks */
buzbeefa57c472012-11-21 12:06:18 -0800123void* NewMem(CompilationUnit* cu, size_t size, bool zero, oat_alloc_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700124{
Bill Buzbeea114add2012-05-03 15:00:40 -0700125 size = (size + 3) & ~3;
buzbee5abfa3e2012-01-31 17:01:43 -0800126#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800127 if (cu->mstats != NULL) {
128 cu->mstats->alloc_stats[kind] += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700129 }
buzbee5abfa3e2012-01-31 17:01:43 -0800130#endif
buzbee67bf8852011-08-17 17:51:35 -0700131retry:
Bill Buzbeea114add2012-05-03 15:00:40 -0700132 /* Normal case - space is available in the current page */
buzbeefa57c472012-11-21 12:06:18 -0800133 if (size + cu->current_arena->bytes_allocated <=
134 cu->current_arena->block_size) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700135 void *ptr;
buzbeefa57c472012-11-21 12:06:18 -0800136 ptr = &cu->current_arena->ptr[cu->current_arena->bytes_allocated];
137 cu->current_arena->bytes_allocated += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700138 if (zero) {
139 memset(ptr, 0, size);
140 }
141 return ptr;
142 } else {
143 /*
144 * See if there are previously allocated arena blocks before the last
145 * reset
146 */
buzbeefa57c472012-11-21 12:06:18 -0800147 if (cu->current_arena->next) {
148 cu->current_arena = cu->current_arena->next;
149 cu->current_arena->bytes_allocated = 0;
buzbee67bf8852011-08-17 17:51:35 -0700150 goto retry;
151 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700152
buzbeefa57c472012-11-21 12:06:18 -0800153 size_t block_size = (size < ARENA_DEFAULT_SIZE) ? ARENA_DEFAULT_SIZE : size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700154 /* Time to allocate a new arena */
buzbeefa57c472012-11-21 12:06:18 -0800155 ArenaMemBlock *new_arena =
156 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + block_size));
157 if (new_arena == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700158 LOG(FATAL) << "Arena allocation failure";
159 }
buzbeefa57c472012-11-21 12:06:18 -0800160 new_arena->block_size = block_size;
161 new_arena->bytes_allocated = 0;
162 new_arena->next = NULL;
163 cu->current_arena->next = new_arena;
164 cu->current_arena = new_arena;
165 cu->num_arena_blocks++;
166 if (cu->num_arena_blocks > 20000) {
167 LOG(INFO) << "Total arena pages: " << cu->num_arena_blocks;
Bill Buzbeea114add2012-05-03 15:00:40 -0700168 }
169 goto retry;
170 }
buzbee67bf8852011-08-17 17:51:35 -0700171}
172
173/* Reclaim all the arena blocks allocated so far */
buzbeefa57c472012-11-21 12:06:18 -0800174void ArenaReset(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700175{
buzbeefa57c472012-11-21 12:06:18 -0800176 ArenaMemBlock* head = cu->arena_head;
Bill Buzbeea114add2012-05-03 15:00:40 -0700177 while (head != NULL) {
178 ArenaMemBlock* p = head;
179 head = head->next;
180 free(p);
181 }
buzbeefa57c472012-11-21 12:06:18 -0800182 cu->arena_head = NULL;
183 cu->current_arena = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700184}
185
186/* Growable List initialization */
buzbeefa57c472012-11-21 12:06:18 -0800187void CompilerInitGrowableList(CompilationUnit* cu, GrowableList* g_list,
188 size_t init_length, oat_list_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700189{
buzbeefa57c472012-11-21 12:06:18 -0800190 g_list->num_allocated = init_length;
191 g_list->num_used = 0;
192 g_list->elem_list = static_cast<uintptr_t *>(NewMem(cu, sizeof(intptr_t) * init_length,
buzbeecbd6d442012-11-17 14:11:25 -0800193 true, kAllocGrowableList));
buzbee5abfa3e2012-01-31 17:01:43 -0800194#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800195 cu->mstats->list_sizes[kind] += sizeof(uintptr_t) * init_length;
196 g_list->kind = kind;
197 if (static_cast<int>(init_length) > cu->mstats->list_max_elems[kind]) {
198 cu->mstats->list_max_elems[kind] = init_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700199 }
buzbee5abfa3e2012-01-31 17:01:43 -0800200#endif
buzbee67bf8852011-08-17 17:51:35 -0700201}
202
203/* Expand the capacity of a growable list */
buzbeefa57c472012-11-21 12:06:18 -0800204static void ExpandGrowableList(CompilationUnit* cu, GrowableList* g_list)
buzbee67bf8852011-08-17 17:51:35 -0700205{
buzbeefa57c472012-11-21 12:06:18 -0800206 int new_length = g_list->num_allocated;
207 if (new_length < 128) {
208 new_length <<= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 } else {
buzbeefa57c472012-11-21 12:06:18 -0800210 new_length += 128;
Bill Buzbeea114add2012-05-03 15:00:40 -0700211 }
buzbeefa57c472012-11-21 12:06:18 -0800212 uintptr_t *new_array =
213 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
buzbeecbd6d442012-11-17 14:11:25 -0800214 kAllocGrowableList));
buzbeefa57c472012-11-21 12:06:18 -0800215 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800216#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800217 cu->mstats->list_sizes[g_list->kind] += sizeof(uintptr_t) * new_length;
218 cu->mstats->list_wasted[g_list->kind] +=
219 sizeof(uintptr_t) * g_list->num_allocated;
220 cu->mstats->list_grows[g_list->kind]++;
221 if (new_length > cu->mstats->list_max_elems[g_list->kind]) {
222 cu->mstats->list_max_elems[g_list->kind] = new_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700223 }
buzbee5abfa3e2012-01-31 17:01:43 -0800224#endif
buzbeefa57c472012-11-21 12:06:18 -0800225 g_list->num_allocated = new_length;
226 g_list->elem_list = new_array;
buzbee67bf8852011-08-17 17:51:35 -0700227}
228
229/* Insert a new element into the growable list */
buzbeefa57c472012-11-21 12:06:18 -0800230void InsertGrowableList(CompilationUnit* cu, GrowableList* g_list,
buzbeecbd6d442012-11-17 14:11:25 -0800231 uintptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700232{
buzbeefa57c472012-11-21 12:06:18 -0800233 DCHECK_NE(g_list->num_allocated, 0U);
234 if (g_list->num_used == g_list->num_allocated) {
235 ExpandGrowableList(cu, g_list);
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 }
buzbeefa57c472012-11-21 12:06:18 -0800237 g_list->elem_list[g_list->num_used++] = elem;
buzbee67bf8852011-08-17 17:51:35 -0700238}
239
buzbee5abfa3e2012-01-31 17:01:43 -0800240/* Delete an element from a growable list. Element must be present */
buzbeefa57c472012-11-21 12:06:18 -0800241void DeleteGrowableList(GrowableList* g_list, uintptr_t elem)
buzbee5abfa3e2012-01-31 17:01:43 -0800242{
Bill Buzbeea114add2012-05-03 15:00:40 -0700243 bool found = false;
buzbeefa57c472012-11-21 12:06:18 -0800244 for (unsigned int i = 0; i < g_list->num_used; i++) {
245 if (!found && g_list->elem_list[i] == elem) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700246 found = true;
buzbee5abfa3e2012-01-31 17:01:43 -0800247 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700248 if (found) {
buzbeefa57c472012-11-21 12:06:18 -0800249 g_list->elem_list[i] = g_list->elem_list[i+1];
Bill Buzbeea114add2012-05-03 15:00:40 -0700250 }
251 }
252 DCHECK_EQ(found, true);
buzbeefa57c472012-11-21 12:06:18 -0800253 g_list->num_used--;
buzbee5abfa3e2012-01-31 17:01:43 -0800254}
255
buzbeefa57c472012-11-21 12:06:18 -0800256void GrowableListIteratorInit(GrowableList* g_list,
Bill Buzbeea114add2012-05-03 15:00:40 -0700257 GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700258{
buzbeefa57c472012-11-21 12:06:18 -0800259 iterator->list = g_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700260 iterator->idx = 0;
buzbeefa57c472012-11-21 12:06:18 -0800261 iterator->size = g_list->num_used;
buzbee67bf8852011-08-17 17:51:35 -0700262}
263
buzbee52a77fc2012-11-20 19:50:46 -0800264uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700265{
buzbeefa57c472012-11-21 12:06:18 -0800266 DCHECK_EQ(iterator->size, iterator->list->num_used);
Bill Buzbeea114add2012-05-03 15:00:40 -0700267 if (iterator->idx == iterator->size) return 0;
buzbeefa57c472012-11-21 12:06:18 -0800268 return iterator->list->elem_list[iterator->idx++];
buzbee67bf8852011-08-17 17:51:35 -0700269}
270
buzbeefa57c472012-11-21 12:06:18 -0800271uintptr_t GrowableListGetElement(const GrowableList* g_list, size_t idx)
buzbee67bf8852011-08-17 17:51:35 -0700272{
buzbeefa57c472012-11-21 12:06:18 -0800273 DCHECK_LT(idx, g_list->num_used);
274 return g_list->elem_list[idx];
buzbee67bf8852011-08-17 17:51:35 -0700275}
276
buzbee5abfa3e2012-01-31 17:01:43 -0800277#ifdef WITH_MEMSTATS
278/* Dump memory usage stats */
buzbeefa57c472012-11-21 12:06:18 -0800279void DumpMemStats(CompilationUnit* cu)
buzbee5abfa3e2012-01-31 17:01:43 -0800280{
buzbeeeaf09bc2012-11-15 14:51:41 -0800281 uint32_t total = 0;
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800283 total += cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700284 }
285 if (total > (10 * 1024 * 1024)) {
286 LOG(INFO) << "MEMUSAGE: " << total << " : "
buzbeefa57c472012-11-21 12:06:18 -0800287 << PrettyMethod(cu->method_idx, *cu->dex_file);
288 LOG(INFO) << "insns_size: " << cu->insns_size;
289 if (cu->disable_dataflow) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700290 LOG(INFO) << " ** Dataflow disabled ** ";
buzbee5abfa3e2012-01-31 17:01:43 -0800291 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700292 LOG(INFO) << "===== Overall allocations";
293 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800294 LOG(INFO) << alloc_names[i] << std::setw(10) <<
295 cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700296 }
297 LOG(INFO) << "===== GrowableList allocations";
298 for (int i = 0; i < kNumListKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800299 LOG(INFO) << list_names[i]
300 << " S:" << cu->mstats->list_sizes[i]
301 << ", W:" << cu->mstats->list_wasted[i]
302 << ", G:" << cu->mstats->list_grows[i]
303 << ", E:" << cu->mstats->list_max_elems[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700304 }
305 LOG(INFO) << "===== GrowableBitMap allocations";
306 for (int i = 0; i < kNumBitMapKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800307 LOG(INFO) << bit_map_names[i]
308 << " S:" << cu->mstats->bit_map_sizes[i]
309 << ", W:" << cu->mstats->bit_map_wasted[i]
310 << ", G:" << cu->mstats->bit_map_grows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800311 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 }
buzbee5abfa3e2012-01-31 17:01:43 -0800313}
314#endif
315
buzbee67bf8852011-08-17 17:51:35 -0700316/* Debug Utility - dump a compilation unit */
buzbeefa57c472012-11-21 12:06:18 -0800317void DumpCompilationUnit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700318{
Bill Buzbeea114add2012-05-03 15:00:40 -0700319 BasicBlock* bb;
buzbeefa57c472012-11-21 12:06:18 -0800320 const char* block_type_names[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700321 "Entry Block",
322 "Code Block",
323 "Exit Block",
324 "Exception Handling",
325 "Catch Block"
326 };
buzbee67bf8852011-08-17 17:51:35 -0700327
buzbeefa57c472012-11-21 12:06:18 -0800328 LOG(INFO) << "Compiling " << PrettyMethod(cu->method_idx, *cu->dex_file);
329 LOG(INFO) << cu->insns << " insns";
330 LOG(INFO) << cu->num_blocks << " blocks in total";
Bill Buzbeea114add2012-05-03 15:00:40 -0700331 GrowableListIterator iterator;
buzbee67bf8852011-08-17 17:51:35 -0700332
buzbeefa57c472012-11-21 12:06:18 -0800333 GrowableListIteratorInit(&cu->block_list, &iterator);
buzbee67bf8852011-08-17 17:51:35 -0700334
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 while (true) {
buzbee52a77fc2012-11-20 19:50:46 -0800336 bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 if (bb == NULL) break;
338 LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
339 bb->id,
buzbeefa57c472012-11-21 12:06:18 -0800340 block_type_names[bb->block_type],
341 bb->start_offset,
342 bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
343 bb->last_mir_insn ? "" : " empty");
Bill Buzbeea114add2012-05-03 15:00:40 -0700344 if (bb->taken) {
345 LOG(INFO) << " Taken branch: block " << bb->taken->id
buzbeefa57c472012-11-21 12:06:18 -0800346 << "(0x" << std::hex << bb->taken->start_offset << ")";
buzbee67bf8852011-08-17 17:51:35 -0700347 }
buzbeefa57c472012-11-21 12:06:18 -0800348 if (bb->fall_through) {
349 LOG(INFO) << " Fallthrough : block " << bb->fall_through->id
350 << " (0x" << std::hex << bb->fall_through->start_offset << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700351 }
352 }
buzbee67bf8852011-08-17 17:51:35 -0700353}
354
buzbeefa57c472012-11-21 12:06:18 -0800355static uint32_t check_masks[32] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700356 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
357 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
358 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
359 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
360 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
361 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
362 0x40000000, 0x80000000 };
buzbee67bc2362011-10-11 18:08:40 -0700363
buzbee67bf8852011-08-17 17:51:35 -0700364/*
365 * Allocate a bit vector with enough space to hold at least the specified
366 * number of bits.
367 *
368 * NOTE: memory is allocated from the compiler arena.
369 */
buzbeefa57c472012-11-21 12:06:18 -0800370ArenaBitVector* AllocBitVector(CompilationUnit* cu,
371 unsigned int start_bits, bool expandable,
372 oat_bit_map_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700373{
Bill Buzbeea114add2012-05-03 15:00:40 -0700374 ArenaBitVector* bv;
375 unsigned int count;
buzbee67bf8852011-08-17 17:51:35 -0700376
Bill Buzbeea114add2012-05-03 15:00:40 -0700377 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700378
buzbeefa57c472012-11-21 12:06:18 -0800379 bv = static_cast<ArenaBitVector*>(NewMem(cu, sizeof(ArenaBitVector), false,
buzbeecbd6d442012-11-17 14:11:25 -0800380 kAllocGrowableBitMap));
buzbee67bf8852011-08-17 17:51:35 -0700381
buzbeefa57c472012-11-21 12:06:18 -0800382 count = (start_bits + 31) >> 5;
buzbee67bf8852011-08-17 17:51:35 -0700383
buzbeefa57c472012-11-21 12:06:18 -0800384 bv->storage_size = count;
Bill Buzbeea114add2012-05-03 15:00:40 -0700385 bv->expandable = expandable;
buzbeefa57c472012-11-21 12:06:18 -0800386 bv->storage = static_cast<uint32_t*>(NewMem(cu, count * sizeof(uint32_t), true,
buzbeeeaf09bc2012-11-15 14:51:41 -0800387 kAllocGrowableBitMap));
buzbee5abfa3e2012-01-31 17:01:43 -0800388#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700389 bv->kind = kind;
buzbeefa57c472012-11-21 12:06:18 -0800390 cu->mstats->bit_map_sizes[kind] += count * sizeof(uint32_t);
buzbee5abfa3e2012-01-31 17:01:43 -0800391#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 return bv;
buzbee67bf8852011-08-17 17:51:35 -0700393}
394
395/*
396 * Determine whether or not the specified bit is set.
397 */
buzbeefa57c472012-11-21 12:06:18 -0800398bool IsBitSet(const ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700399{
buzbeefa57c472012-11-21 12:06:18 -0800400 DCHECK_LT(num, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700401
buzbeefa57c472012-11-21 12:06:18 -0800402 unsigned int val = p_bits->storage[num >> 5] & check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700403 return (val != 0);
buzbee67bf8852011-08-17 17:51:35 -0700404}
405
406/*
407 * Mark all bits bit as "clear".
408 */
buzbeefa57c472012-11-21 12:06:18 -0800409void ClearAllBits(ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700410{
buzbeefa57c472012-11-21 12:06:18 -0800411 unsigned int count = p_bits->storage_size;
412 memset(p_bits->storage, 0, count * sizeof(uint32_t));
buzbee67bf8852011-08-17 17:51:35 -0700413}
414
415/*
416 * Mark the specified bit as "set".
417 *
418 * Returns "false" if the bit is outside the range of the vector and we're
419 * not allowed to expand.
420 *
421 * NOTE: memory is allocated from the compiler arena.
422 */
buzbeefa57c472012-11-21 12:06:18 -0800423bool SetBit(CompilationUnit* cu, ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700424{
buzbeefa57c472012-11-21 12:06:18 -0800425 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
426 if (!p_bits->expandable) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700427 LOG(FATAL) << "Can't expand";
buzbee67bf8852011-08-17 17:51:35 -0700428 }
429
Bill Buzbeea114add2012-05-03 15:00:40 -0700430 /* Round up to word boundaries for "num+1" bits */
buzbeefa57c472012-11-21 12:06:18 -0800431 unsigned int new_size = (num + 1 + 31) >> 5;
432 DCHECK_GT(new_size, p_bits->storage_size);
433 uint32_t *new_storage = static_cast<uint32_t*>(NewMem(cu, new_size * sizeof(uint32_t), false,
buzbeeeaf09bc2012-11-15 14:51:41 -0800434 kAllocGrowableBitMap));
buzbeefa57c472012-11-21 12:06:18 -0800435 memcpy(new_storage, p_bits->storage, p_bits->storage_size * sizeof(uint32_t));
436 memset(&new_storage[p_bits->storage_size], 0,
437 (new_size - p_bits->storage_size) * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700438#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800439 cu->mstats->bit_map_wasted[p_bits->kind] +=
440 p_bits->storage_size * sizeof(uint32_t);
441 cu->mstats->bit_map_sizes[p_bits->kind] += new_size * sizeof(uint32_t);
442 cu->mstats->bit_map_grows[p_bits->kind]++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700443#endif
buzbeefa57c472012-11-21 12:06:18 -0800444 p_bits->storage = new_storage;
445 p_bits->storage_size = new_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700446 }
447
buzbeefa57c472012-11-21 12:06:18 -0800448 p_bits->storage[num >> 5] |= check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700449 return true;
buzbee67bf8852011-08-17 17:51:35 -0700450}
451
452/*
453 * Mark the specified bit as "unset".
454 *
455 * Returns "false" if the bit is outside the range of the vector and we're
456 * not allowed to expand.
457 *
458 * NOTE: memory is allocated from the compiler arena.
459 */
buzbeefa57c472012-11-21 12:06:18 -0800460bool ClearBit(ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700461{
buzbeefa57c472012-11-21 12:06:18 -0800462 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700463 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
464 }
buzbee67bf8852011-08-17 17:51:35 -0700465
buzbeefa57c472012-11-21 12:06:18 -0800466 p_bits->storage[num >> 5] &= ~check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700467 return true;
buzbee67bf8852011-08-17 17:51:35 -0700468}
469
buzbee67bf8852011-08-17 17:51:35 -0700470/* Initialize the iterator structure */
buzbeefa57c472012-11-21 12:06:18 -0800471void BitVectorIteratorInit(ArenaBitVector* p_bits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700472 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700473{
buzbeefa57c472012-11-21 12:06:18 -0800474 iterator->p_bits = p_bits;
475 iterator->bit_size = p_bits->storage_size * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700477}
478
479/*
480 * If the vector sizes don't match, log an error and abort.
481 */
buzbee52a77fc2012-11-20 19:50:46 -0800482static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700483{
buzbeefa57c472012-11-21 12:06:18 -0800484 if (bv1->storage_size != bv2->storage_size) {
485 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storage_size
486 << ", " << bv2->storage_size << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700487 }
buzbee67bf8852011-08-17 17:51:35 -0700488}
489
490/*
491 * Copy a whole vector to the other. Only do that when the both vectors have
492 * the same size.
493 */
buzbee52a77fc2012-11-20 19:50:46 -0800494void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
buzbee67bf8852011-08-17 17:51:35 -0700495{
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 /* if dest is expandable and < src, we could expand dest to match */
buzbee52a77fc2012-11-20 19:50:46 -0800497 CheckSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700498
buzbeefa57c472012-11-21 12:06:18 -0800499 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storage_size);
buzbee67bf8852011-08-17 17:51:35 -0700500}
501
502/*
503 * Intersect two bit vectors and store the result to the dest vector.
504 */
505
buzbee52a77fc2012-11-20 19:50:46 -0800506bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700507 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700508{
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 DCHECK(src1 != NULL);
510 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800511 if (dest->storage_size != src1->storage_size ||
512 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700513 dest->expandable != src1->expandable ||
514 dest->expandable != src2->expandable)
515 return false;
buzbee67bf8852011-08-17 17:51:35 -0700516
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800518 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700519 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
520 }
521 return true;
buzbee67bf8852011-08-17 17:51:35 -0700522}
523
524/*
525 * Unify two bit vectors and store the result to the dest vector.
526 */
buzbee52a77fc2012-11-20 19:50:46 -0800527bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700528 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700529{
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 DCHECK(src1 != NULL);
531 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800532 if (dest->storage_size != src1->storage_size ||
533 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700534 dest->expandable != src1->expandable ||
535 dest->expandable != src2->expandable)
536 return false;
buzbee67bf8852011-08-17 17:51:35 -0700537
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800539 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
541 }
542 return true;
buzbee67bf8852011-08-17 17:51:35 -0700543}
544
545/*
buzbeee1965672012-03-11 18:39:19 -0700546 * Return true if any bits collide. Vectors must be same size.
547 */
buzbee52a77fc2012-11-20 19:50:46 -0800548bool TestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700549 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700550{
buzbeefa57c472012-11-21 12:06:18 -0800551 DCHECK_EQ(src1->storage_size, src2->storage_size);
552 for (uint32_t idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700553 if (src1->storage[idx] & src2->storage[idx]) return true;
554 }
555 return false;
buzbeee1965672012-03-11 18:39:19 -0700556}
557
558/*
buzbee67bf8852011-08-17 17:51:35 -0700559 * Compare two bit vectors and return true if difference is seen.
560 */
buzbee52a77fc2012-11-20 19:50:46 -0800561bool CompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700562 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700563{
buzbeefa57c472012-11-21 12:06:18 -0800564 if (src1->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700565 src1->expandable != src2->expandable)
566 return true;
buzbee67bf8852011-08-17 17:51:35 -0700567
Bill Buzbeea114add2012-05-03 15:00:40 -0700568 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800569 for (idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700570 if (src1->storage[idx] != src2->storage[idx]) return true;
571 }
572 return false;
buzbee67bf8852011-08-17 17:51:35 -0700573}
574
575/*
576 * Count the number of bits that are set.
577 */
buzbeefa57c472012-11-21 12:06:18 -0800578int CountSetBits(const ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700579{
Bill Buzbeea114add2012-05-03 15:00:40 -0700580 unsigned int word;
581 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700582
buzbeefa57c472012-11-21 12:06:18 -0800583 for (word = 0; word < p_bits->storage_size; word++) {
584 uint32_t val = p_bits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700585
Bill Buzbeea114add2012-05-03 15:00:40 -0700586 if (val != 0) {
587 if (val == 0xffffffff) {
588 count += 32;
589 } else {
590 /* count the number of '1' bits */
591 while (val != 0) {
592 val &= val - 1;
593 count++;
buzbee67bf8852011-08-17 17:51:35 -0700594 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700595 }
buzbee67bf8852011-08-17 17:51:35 -0700596 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700597 }
buzbee67bf8852011-08-17 17:51:35 -0700598
Bill Buzbeea114add2012-05-03 15:00:40 -0700599 return count;
buzbee67bf8852011-08-17 17:51:35 -0700600}
601
602/* Return the next position set to 1. -1 means end-of-element reached */
buzbee52a77fc2012-11-20 19:50:46 -0800603int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700604{
buzbeefa57c472012-11-21 12:06:18 -0800605 ArenaBitVector* p_bits = iterator->p_bits;
606 uint32_t bit_index = iterator->idx;
607 uint32_t bit_size = iterator->bit_size;
buzbee67bf8852011-08-17 17:51:35 -0700608
buzbeefa57c472012-11-21 12:06:18 -0800609 DCHECK_EQ(bit_size, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700610
buzbeefa57c472012-11-21 12:06:18 -0800611 if (bit_index >= bit_size) return -1;
buzbee5b537102012-01-17 17:33:47 -0800612
buzbeefa57c472012-11-21 12:06:18 -0800613 uint32_t word_index = bit_index >> 5;
614 uint32_t end_word_index = bit_size >> 5;
615 uint32_t* storage = p_bits->storage;
616 uint32_t word = storage[word_index++];
buzbee5b537102012-01-17 17:33:47 -0800617
Bill Buzbeea114add2012-05-03 15:00:40 -0700618 // Mask out any bits in the first word we've already considered
buzbeefa57c472012-11-21 12:06:18 -0800619 word &= ~((1 << (bit_index & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800620
buzbeefa57c472012-11-21 12:06:18 -0800621 for (; word_index <= end_word_index;) {
622 uint32_t bit_pos = bit_index & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700623 if (word == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800624 bit_index += (32 - bit_pos);
625 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700626 continue;
buzbee67bf8852011-08-17 17:51:35 -0700627 }
buzbeefa57c472012-11-21 12:06:18 -0800628 for (; bit_pos < 32; bit_pos++) {
629 if (word & (1 << bit_pos)) {
630 iterator->idx = bit_index + 1;
631 return bit_index;
Bill Buzbeea114add2012-05-03 15:00:40 -0700632 }
buzbeefa57c472012-11-21 12:06:18 -0800633 bit_index++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700634 }
buzbeefa57c472012-11-21 12:06:18 -0800635 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700636 }
buzbeefa57c472012-11-21 12:06:18 -0800637 iterator->idx = iterator->bit_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700638 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700639}
640
641/*
642 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
643 * since there might be unused bits - setting those to one will confuse the
644 * iterator.
645 */
buzbeefa57c472012-11-21 12:06:18 -0800646void SetInitialBits(ArenaBitVector* p_bits, unsigned int num_bits)
buzbee67bf8852011-08-17 17:51:35 -0700647{
Bill Buzbeea114add2012-05-03 15:00:40 -0700648 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800649 DCHECK_LE(((num_bits + 31) >> 5), p_bits->storage_size);
650 for (idx = 0; idx < (num_bits >> 5); idx++) {
651 p_bits->storage[idx] = -1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700652 }
buzbeefa57c472012-11-21 12:06:18 -0800653 unsigned int rem_num_bits = num_bits & 0x1f;
654 if (rem_num_bits) {
655 p_bits->storage[idx] = (1 << rem_num_bits) - 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700656 }
buzbee67bf8852011-08-17 17:51:35 -0700657}
658
buzbee52a77fc2012-11-20 19:50:46 -0800659void GetBlockName(BasicBlock* bb, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700660{
buzbeefa57c472012-11-21 12:06:18 -0800661 switch (bb->block_type) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700662 case kEntryBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700663 snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700664 break;
665 case kExitBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700666 snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700667 break;
668 case kDalvikByteCode:
buzbeefa57c472012-11-21 12:06:18 -0800669 snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700670 break;
671 case kExceptionHandling:
buzbeefa57c472012-11-21 12:06:18 -0800672 snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700673 bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700674 break;
675 default:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700676 snprintf(name, BLOCK_NAME_LEN, "??_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 break;
678 }
buzbee67bf8852011-08-17 17:51:35 -0700679}
buzbeeed3e9302011-09-23 17:34:19 -0700680
buzbeefa57c472012-11-21 12:06:18 -0800681const char* GetShortyFromTargetIdx(CompilationUnit *cu, int target_idx)
buzbeeed3e9302011-09-23 17:34:19 -0700682{
buzbeefa57c472012-11-21 12:06:18 -0800683 const DexFile::MethodId& method_id = cu->dex_file->GetMethodId(target_idx);
684 return cu->dex_file->GetShorty(method_id.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700685}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800686
buzbee02031b12012-11-23 09:41:35 -0800687/* Allocate a new basic block */
688BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
689{
690 BasicBlock* bb = static_cast<BasicBlock*>(NewMem(cu, sizeof(BasicBlock), true, kAllocBB));
691 bb->block_type = block_type;
692 bb->id = block_id;
693 bb->predecessors = static_cast<GrowableList*>
694 (NewMem(cu, sizeof(GrowableList), false, kAllocPredecessors));
695 CompilerInitGrowableList(cu, bb->predecessors,
696 (block_type == kExitBlock) ? 2048 : 2,
697 kListPredecessors);
698 cu->block_id_map.Put(block_id, block_id);
699 return bb;
700}
701
702/* Insert an MIR instruction to the end of a basic block */
703void AppendMIR(BasicBlock* bb, MIR* mir)
704{
705 if (bb->first_mir_insn == NULL) {
706 DCHECK(bb->last_mir_insn == NULL);
707 bb->last_mir_insn = bb->first_mir_insn = mir;
708 mir->prev = mir->next = NULL;
709 } else {
710 bb->last_mir_insn->next = mir;
711 mir->prev = bb->last_mir_insn;
712 mir->next = NULL;
713 bb->last_mir_insn = mir;
714 }
715}
716
717/* Insert an MIR instruction to the head of a basic block */
718void PrependMIR(BasicBlock* bb, MIR* mir)
719{
720 if (bb->first_mir_insn == NULL) {
721 DCHECK(bb->last_mir_insn == NULL);
722 bb->last_mir_insn = bb->first_mir_insn = mir;
723 mir->prev = mir->next = NULL;
724 } else {
725 bb->first_mir_insn->prev = mir;
726 mir->next = bb->first_mir_insn;
727 mir->prev = NULL;
728 bb->first_mir_insn = mir;
729 }
730}
731
732/* Insert a MIR instruction after the specified MIR */
733void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir)
734{
735 new_mir->prev = current_mir;
736 new_mir->next = current_mir->next;
737 current_mir->next = new_mir;
738
739 if (new_mir->next) {
740 /* Is not the last MIR in the block */
741 new_mir->next->prev = new_mir;
742 } else {
743 /* Is the last MIR in the block */
744 bb->last_mir_insn = new_mir;
745 }
746}
747
748/*
749 * Append an LIR instruction to the LIR list maintained by a compilation
750 * unit
751 */
752void AppendLIR(CompilationUnit *cu, LIR* lir)
753{
754 if (cu->first_lir_insn == NULL) {
755 DCHECK(cu->last_lir_insn == NULL);
756 cu->last_lir_insn = cu->first_lir_insn = lir;
757 lir->prev = lir->next = NULL;
758 } else {
759 cu->last_lir_insn->next = lir;
760 lir->prev = cu->last_lir_insn;
761 lir->next = NULL;
762 cu->last_lir_insn = lir;
763 }
764}
765
766/*
767 * Insert an LIR instruction before the current instruction, which cannot be the
768 * first instruction.
769 *
770 * prev_lir <-> new_lir <-> current_lir
771 */
772void InsertLIRBefore(LIR* current_lir, LIR* new_lir)
773{
774 DCHECK(current_lir->prev != NULL);
775 LIR *prev_lir = current_lir->prev;
776
777 prev_lir->next = new_lir;
778 new_lir->prev = prev_lir;
779 new_lir->next = current_lir;
780 current_lir->prev = new_lir;
781}
782
783/*
784 * Insert an LIR instruction after the current instruction, which cannot be the
785 * first instruction.
786 *
787 * current_lir -> new_lir -> old_next
788 */
789void InsertLIRAfter(LIR* current_lir, LIR* new_lir)
790{
791 new_lir->prev = current_lir;
792 new_lir->next = current_lir->next;
793 current_lir->next = new_lir;
794 new_lir->next->prev = new_lir;
795}
796
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800797} // namespace art