blob: b5185b00e64263eb0ee0f2a17ebce17fae0d5a94 [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",
buzbeef662a7c2013-02-12 16:19:43 -080035 "Select",
buzbeecbd6d442012-11-17 14:11:25 -080036};
37
buzbee5abfa3e2012-01-31 17:01:43 -080038#ifdef WITH_MEMSTATS
Elliott Hughes719ace42012-03-09 18:06:03 -080039struct Memstats {
buzbeefa57c472012-11-21 12:06:18 -080040 uint32_t alloc_stats[kNumAllocKinds];
41 int list_sizes[kNumListKinds];
42 int list_wasted[kNumListKinds];
43 int list_grows[kNumListKinds];
44 int list_max_elems[kNumListKinds];
45 int bit_map_sizes[kNumBitMapKinds];
46 int bit_map_wasted[kNumBitMapKinds];
47 int bit_map_grows[kNumBitMapKinds];
Elliott Hughes719ace42012-03-09 18:06:03 -080048};
buzbee5abfa3e2012-01-31 17:01:43 -080049
buzbeefa57c472012-11-21 12:06:18 -080050const char* alloc_names[kNumAllocKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070051 "Misc ",
52 "BasicBlock ",
53 "LIR ",
54 "MIR ",
55 "DataFlow ",
56 "GrowList ",
57 "GrowBitMap ",
58 "Dalvik2SSA ",
59 "DebugInfo ",
60 "Successor ",
61 "RegAlloc ",
62 "Data ",
63 "Preds ",
buzbee5abfa3e2012-01-31 17:01:43 -080064};
65
buzbeefa57c472012-11-21 12:06:18 -080066const char* list_names[kNumListKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070067 "Misc ",
buzbeefa57c472012-11-21 12:06:18 -080068 "block_list ",
Bill Buzbeea114add2012-05-03 15:00:40 -070069 "SSAtoDalvik ",
buzbeefa57c472012-11-21 12:06:18 -080070 "dfs_order ",
71 "dfs_post_order ",
72 "dom_post_order_traversal ",
73 "throw_launch_pads ",
74 "suspend_launch_pads ",
75 "switch_tables ",
76 "fill_array_data ",
Bill Buzbeea114add2012-05-03 15:00:40 -070077 "SuccessorBlocks ",
78 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080079};
80
buzbeefa57c472012-11-21 12:06:18 -080081const char* bit_map_names[kNumBitMapKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070082 "Misc ",
83 "Use ",
84 "Def ",
85 "LiveIn ",
86 "BlockMatrix ",
87 "Dominators ",
88 "IDominated ",
89 "DomFrontier ",
90 "Phi ",
91 "TmpBlocks ",
92 "InputBlocks ",
93 "RegisterV ",
94 "TempSSARegisterV ",
95 "Null Check ",
96 "TmpBlockV ",
97 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080098};
99#endif
100
buzbeeeaf09bc2012-11-15 14:51:41 -0800101#define kArenaBitVectorGrowth 4 /* increase by 4 uint32_ts when limit hit */
buzbee67bf8852011-08-17 17:51:35 -0700102
103/* Allocate the initial memory block for arena-based allocation */
buzbeefa57c472012-11-21 12:06:18 -0800104bool HeapInit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700105{
buzbeefa57c472012-11-21 12:06:18 -0800106 DCHECK(cu->arena_head == NULL);
107 cu->arena_head =
buzbeecbd6d442012-11-17 14:11:25 -0800108 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE));
buzbeefa57c472012-11-21 12:06:18 -0800109 if (cu->arena_head == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700110 LOG(FATAL) << "No memory left to create compiler heap memory";
111 }
buzbeefa57c472012-11-21 12:06:18 -0800112 cu->arena_head->block_size = ARENA_DEFAULT_SIZE;
113 cu->current_arena = cu->arena_head;
114 cu->current_arena->bytes_allocated = 0;
115 cu->current_arena->next = NULL;
116 cu->num_arena_blocks = 1;
buzbeeba938cb2012-02-03 14:47:55 -0800117#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800118 cu->mstats = (Memstats*) NewMem(cu, sizeof(Memstats), true,
Bill Buzbeea114add2012-05-03 15:00:40 -0700119 kAllocDebugInfo);
buzbeeba938cb2012-02-03 14:47:55 -0800120#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700121 return true;
buzbee67bf8852011-08-17 17:51:35 -0700122}
123
124/* Arena-based malloc for compilation tasks */
buzbeefa57c472012-11-21 12:06:18 -0800125void* NewMem(CompilationUnit* cu, size_t size, bool zero, oat_alloc_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700126{
Bill Buzbeea114add2012-05-03 15:00:40 -0700127 size = (size + 3) & ~3;
buzbee5abfa3e2012-01-31 17:01:43 -0800128#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800129 if (cu->mstats != NULL) {
130 cu->mstats->alloc_stats[kind] += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700131 }
buzbee5abfa3e2012-01-31 17:01:43 -0800132#endif
buzbee67bf8852011-08-17 17:51:35 -0700133retry:
Bill Buzbeea114add2012-05-03 15:00:40 -0700134 /* Normal case - space is available in the current page */
buzbeefa57c472012-11-21 12:06:18 -0800135 if (size + cu->current_arena->bytes_allocated <=
136 cu->current_arena->block_size) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700137 void *ptr;
buzbeefa57c472012-11-21 12:06:18 -0800138 ptr = &cu->current_arena->ptr[cu->current_arena->bytes_allocated];
139 cu->current_arena->bytes_allocated += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700140 if (zero) {
141 memset(ptr, 0, size);
142 }
143 return ptr;
144 } else {
145 /*
146 * See if there are previously allocated arena blocks before the last
147 * reset
148 */
buzbeefa57c472012-11-21 12:06:18 -0800149 if (cu->current_arena->next) {
150 cu->current_arena = cu->current_arena->next;
151 cu->current_arena->bytes_allocated = 0;
buzbee67bf8852011-08-17 17:51:35 -0700152 goto retry;
153 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700154
buzbeefa57c472012-11-21 12:06:18 -0800155 size_t block_size = (size < ARENA_DEFAULT_SIZE) ? ARENA_DEFAULT_SIZE : size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700156 /* Time to allocate a new arena */
buzbeefa57c472012-11-21 12:06:18 -0800157 ArenaMemBlock *new_arena =
158 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + block_size));
159 if (new_arena == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700160 LOG(FATAL) << "Arena allocation failure";
161 }
buzbeefa57c472012-11-21 12:06:18 -0800162 new_arena->block_size = block_size;
163 new_arena->bytes_allocated = 0;
164 new_arena->next = NULL;
165 cu->current_arena->next = new_arena;
166 cu->current_arena = new_arena;
167 cu->num_arena_blocks++;
168 if (cu->num_arena_blocks > 20000) {
169 LOG(INFO) << "Total arena pages: " << cu->num_arena_blocks;
Bill Buzbeea114add2012-05-03 15:00:40 -0700170 }
171 goto retry;
172 }
buzbee67bf8852011-08-17 17:51:35 -0700173}
174
175/* Reclaim all the arena blocks allocated so far */
buzbeefa57c472012-11-21 12:06:18 -0800176void ArenaReset(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700177{
buzbeefa57c472012-11-21 12:06:18 -0800178 ArenaMemBlock* head = cu->arena_head;
Bill Buzbeea114add2012-05-03 15:00:40 -0700179 while (head != NULL) {
180 ArenaMemBlock* p = head;
181 head = head->next;
182 free(p);
183 }
buzbeefa57c472012-11-21 12:06:18 -0800184 cu->arena_head = NULL;
185 cu->current_arena = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700186}
187
188/* Growable List initialization */
buzbeefa57c472012-11-21 12:06:18 -0800189void CompilerInitGrowableList(CompilationUnit* cu, GrowableList* g_list,
190 size_t init_length, oat_list_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700191{
buzbeefa57c472012-11-21 12:06:18 -0800192 g_list->num_allocated = init_length;
193 g_list->num_used = 0;
194 g_list->elem_list = static_cast<uintptr_t *>(NewMem(cu, sizeof(intptr_t) * init_length,
buzbeecbd6d442012-11-17 14:11:25 -0800195 true, kAllocGrowableList));
buzbee5abfa3e2012-01-31 17:01:43 -0800196#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800197 cu->mstats->list_sizes[kind] += sizeof(uintptr_t) * init_length;
198 g_list->kind = kind;
199 if (static_cast<int>(init_length) > cu->mstats->list_max_elems[kind]) {
200 cu->mstats->list_max_elems[kind] = init_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700201 }
buzbee5abfa3e2012-01-31 17:01:43 -0800202#endif
buzbee67bf8852011-08-17 17:51:35 -0700203}
204
205/* Expand the capacity of a growable list */
buzbeefa57c472012-11-21 12:06:18 -0800206static void ExpandGrowableList(CompilationUnit* cu, GrowableList* g_list)
buzbee67bf8852011-08-17 17:51:35 -0700207{
buzbeefa57c472012-11-21 12:06:18 -0800208 int new_length = g_list->num_allocated;
209 if (new_length < 128) {
210 new_length <<= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700211 } else {
buzbeefa57c472012-11-21 12:06:18 -0800212 new_length += 128;
Bill Buzbeea114add2012-05-03 15:00:40 -0700213 }
buzbeefa57c472012-11-21 12:06:18 -0800214 uintptr_t *new_array =
215 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
buzbeecbd6d442012-11-17 14:11:25 -0800216 kAllocGrowableList));
buzbeefa57c472012-11-21 12:06:18 -0800217 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800218#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800219 cu->mstats->list_sizes[g_list->kind] += sizeof(uintptr_t) * new_length;
220 cu->mstats->list_wasted[g_list->kind] +=
221 sizeof(uintptr_t) * g_list->num_allocated;
222 cu->mstats->list_grows[g_list->kind]++;
223 if (new_length > cu->mstats->list_max_elems[g_list->kind]) {
224 cu->mstats->list_max_elems[g_list->kind] = new_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700225 }
buzbee5abfa3e2012-01-31 17:01:43 -0800226#endif
buzbeefa57c472012-11-21 12:06:18 -0800227 g_list->num_allocated = new_length;
228 g_list->elem_list = new_array;
buzbee67bf8852011-08-17 17:51:35 -0700229}
230
231/* Insert a new element into the growable list */
buzbeefa57c472012-11-21 12:06:18 -0800232void InsertGrowableList(CompilationUnit* cu, GrowableList* g_list,
buzbeecbd6d442012-11-17 14:11:25 -0800233 uintptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700234{
buzbeefa57c472012-11-21 12:06:18 -0800235 DCHECK_NE(g_list->num_allocated, 0U);
236 if (g_list->num_used == g_list->num_allocated) {
237 ExpandGrowableList(cu, g_list);
Bill Buzbeea114add2012-05-03 15:00:40 -0700238 }
buzbeefa57c472012-11-21 12:06:18 -0800239 g_list->elem_list[g_list->num_used++] = elem;
buzbee67bf8852011-08-17 17:51:35 -0700240}
241
buzbee5abfa3e2012-01-31 17:01:43 -0800242/* Delete an element from a growable list. Element must be present */
buzbeefa57c472012-11-21 12:06:18 -0800243void DeleteGrowableList(GrowableList* g_list, uintptr_t elem)
buzbee5abfa3e2012-01-31 17:01:43 -0800244{
Bill Buzbeea114add2012-05-03 15:00:40 -0700245 bool found = false;
buzbeefa57c472012-11-21 12:06:18 -0800246 for (unsigned int i = 0; i < g_list->num_used; i++) {
247 if (!found && g_list->elem_list[i] == elem) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700248 found = true;
buzbee5abfa3e2012-01-31 17:01:43 -0800249 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700250 if (found) {
buzbeefa57c472012-11-21 12:06:18 -0800251 g_list->elem_list[i] = g_list->elem_list[i+1];
Bill Buzbeea114add2012-05-03 15:00:40 -0700252 }
253 }
254 DCHECK_EQ(found, true);
buzbeefa57c472012-11-21 12:06:18 -0800255 g_list->num_used--;
buzbee5abfa3e2012-01-31 17:01:43 -0800256}
257
buzbeefa57c472012-11-21 12:06:18 -0800258void GrowableListIteratorInit(GrowableList* g_list,
Bill Buzbeea114add2012-05-03 15:00:40 -0700259 GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700260{
buzbeefa57c472012-11-21 12:06:18 -0800261 iterator->list = g_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700262 iterator->idx = 0;
buzbeefa57c472012-11-21 12:06:18 -0800263 iterator->size = g_list->num_used;
buzbee67bf8852011-08-17 17:51:35 -0700264}
265
buzbee52a77fc2012-11-20 19:50:46 -0800266uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700267{
buzbeefa57c472012-11-21 12:06:18 -0800268 DCHECK_EQ(iterator->size, iterator->list->num_used);
Bill Buzbeea114add2012-05-03 15:00:40 -0700269 if (iterator->idx == iterator->size) return 0;
buzbeefa57c472012-11-21 12:06:18 -0800270 return iterator->list->elem_list[iterator->idx++];
buzbee67bf8852011-08-17 17:51:35 -0700271}
272
buzbeefa57c472012-11-21 12:06:18 -0800273uintptr_t GrowableListGetElement(const GrowableList* g_list, size_t idx)
buzbee67bf8852011-08-17 17:51:35 -0700274{
buzbeefa57c472012-11-21 12:06:18 -0800275 DCHECK_LT(idx, g_list->num_used);
276 return g_list->elem_list[idx];
buzbee67bf8852011-08-17 17:51:35 -0700277}
278
buzbee5abfa3e2012-01-31 17:01:43 -0800279#ifdef WITH_MEMSTATS
280/* Dump memory usage stats */
buzbeefa57c472012-11-21 12:06:18 -0800281void DumpMemStats(CompilationUnit* cu)
buzbee5abfa3e2012-01-31 17:01:43 -0800282{
buzbeeeaf09bc2012-11-15 14:51:41 -0800283 uint32_t total = 0;
Bill Buzbeea114add2012-05-03 15:00:40 -0700284 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800285 total += cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700286 }
287 if (total > (10 * 1024 * 1024)) {
288 LOG(INFO) << "MEMUSAGE: " << total << " : "
buzbeefa57c472012-11-21 12:06:18 -0800289 << PrettyMethod(cu->method_idx, *cu->dex_file);
290 LOG(INFO) << "insns_size: " << cu->insns_size;
291 if (cu->disable_dataflow) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700292 LOG(INFO) << " ** Dataflow disabled ** ";
buzbee5abfa3e2012-01-31 17:01:43 -0800293 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700294 LOG(INFO) << "===== Overall allocations";
295 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800296 LOG(INFO) << alloc_names[i] << std::setw(10) <<
297 cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700298 }
299 LOG(INFO) << "===== GrowableList allocations";
300 for (int i = 0; i < kNumListKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800301 LOG(INFO) << list_names[i]
302 << " S:" << cu->mstats->list_sizes[i]
303 << ", W:" << cu->mstats->list_wasted[i]
304 << ", G:" << cu->mstats->list_grows[i]
305 << ", E:" << cu->mstats->list_max_elems[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700306 }
307 LOG(INFO) << "===== GrowableBitMap allocations";
308 for (int i = 0; i < kNumBitMapKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800309 LOG(INFO) << bit_map_names[i]
310 << " S:" << cu->mstats->bit_map_sizes[i]
311 << ", W:" << cu->mstats->bit_map_wasted[i]
312 << ", G:" << cu->mstats->bit_map_grows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800313 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 }
buzbee5abfa3e2012-01-31 17:01:43 -0800315}
316#endif
317
buzbee67bf8852011-08-17 17:51:35 -0700318/* Debug Utility - dump a compilation unit */
buzbeefa57c472012-11-21 12:06:18 -0800319void DumpCompilationUnit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700320{
Bill Buzbeea114add2012-05-03 15:00:40 -0700321 BasicBlock* bb;
buzbeefa57c472012-11-21 12:06:18 -0800322 const char* block_type_names[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 "Entry Block",
324 "Code Block",
325 "Exit Block",
326 "Exception Handling",
327 "Catch Block"
328 };
buzbee67bf8852011-08-17 17:51:35 -0700329
buzbeefa57c472012-11-21 12:06:18 -0800330 LOG(INFO) << "Compiling " << PrettyMethod(cu->method_idx, *cu->dex_file);
331 LOG(INFO) << cu->insns << " insns";
332 LOG(INFO) << cu->num_blocks << " blocks in total";
Bill Buzbeea114add2012-05-03 15:00:40 -0700333 GrowableListIterator iterator;
buzbee67bf8852011-08-17 17:51:35 -0700334
buzbeefa57c472012-11-21 12:06:18 -0800335 GrowableListIteratorInit(&cu->block_list, &iterator);
buzbee67bf8852011-08-17 17:51:35 -0700336
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 while (true) {
buzbee52a77fc2012-11-20 19:50:46 -0800338 bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
Bill Buzbeea114add2012-05-03 15:00:40 -0700339 if (bb == NULL) break;
340 LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
341 bb->id,
buzbeefa57c472012-11-21 12:06:18 -0800342 block_type_names[bb->block_type],
343 bb->start_offset,
344 bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
345 bb->last_mir_insn ? "" : " empty");
Bill Buzbeea114add2012-05-03 15:00:40 -0700346 if (bb->taken) {
347 LOG(INFO) << " Taken branch: block " << bb->taken->id
buzbeefa57c472012-11-21 12:06:18 -0800348 << "(0x" << std::hex << bb->taken->start_offset << ")";
buzbee67bf8852011-08-17 17:51:35 -0700349 }
buzbeefa57c472012-11-21 12:06:18 -0800350 if (bb->fall_through) {
351 LOG(INFO) << " Fallthrough : block " << bb->fall_through->id
352 << " (0x" << std::hex << bb->fall_through->start_offset << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700353 }
354 }
buzbee67bf8852011-08-17 17:51:35 -0700355}
356
buzbeefa57c472012-11-21 12:06:18 -0800357static uint32_t check_masks[32] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700358 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
359 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
360 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
361 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
362 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
363 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
364 0x40000000, 0x80000000 };
buzbee67bc2362011-10-11 18:08:40 -0700365
buzbee67bf8852011-08-17 17:51:35 -0700366/*
367 * Allocate a bit vector with enough space to hold at least the specified
368 * number of bits.
369 *
370 * NOTE: memory is allocated from the compiler arena.
371 */
buzbeefa57c472012-11-21 12:06:18 -0800372ArenaBitVector* AllocBitVector(CompilationUnit* cu,
373 unsigned int start_bits, bool expandable,
374 oat_bit_map_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700375{
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 ArenaBitVector* bv;
377 unsigned int count;
buzbee67bf8852011-08-17 17:51:35 -0700378
Bill Buzbeea114add2012-05-03 15:00:40 -0700379 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700380
buzbeefa57c472012-11-21 12:06:18 -0800381 bv = static_cast<ArenaBitVector*>(NewMem(cu, sizeof(ArenaBitVector), false,
buzbeecbd6d442012-11-17 14:11:25 -0800382 kAllocGrowableBitMap));
buzbee67bf8852011-08-17 17:51:35 -0700383
buzbeefa57c472012-11-21 12:06:18 -0800384 count = (start_bits + 31) >> 5;
buzbee67bf8852011-08-17 17:51:35 -0700385
buzbeefa57c472012-11-21 12:06:18 -0800386 bv->storage_size = count;
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 bv->expandable = expandable;
buzbeefa57c472012-11-21 12:06:18 -0800388 bv->storage = static_cast<uint32_t*>(NewMem(cu, count * sizeof(uint32_t), true,
buzbeeeaf09bc2012-11-15 14:51:41 -0800389 kAllocGrowableBitMap));
buzbee5abfa3e2012-01-31 17:01:43 -0800390#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700391 bv->kind = kind;
buzbeefa57c472012-11-21 12:06:18 -0800392 cu->mstats->bit_map_sizes[kind] += count * sizeof(uint32_t);
buzbee5abfa3e2012-01-31 17:01:43 -0800393#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700394 return bv;
buzbee67bf8852011-08-17 17:51:35 -0700395}
396
397/*
398 * Determine whether or not the specified bit is set.
399 */
buzbeefa57c472012-11-21 12:06:18 -0800400bool IsBitSet(const ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700401{
buzbeefa57c472012-11-21 12:06:18 -0800402 DCHECK_LT(num, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700403
buzbeefa57c472012-11-21 12:06:18 -0800404 unsigned int val = p_bits->storage[num >> 5] & check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 return (val != 0);
buzbee67bf8852011-08-17 17:51:35 -0700406}
407
408/*
409 * Mark all bits bit as "clear".
410 */
buzbeefa57c472012-11-21 12:06:18 -0800411void ClearAllBits(ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700412{
buzbeefa57c472012-11-21 12:06:18 -0800413 unsigned int count = p_bits->storage_size;
414 memset(p_bits->storage, 0, count * sizeof(uint32_t));
buzbee67bf8852011-08-17 17:51:35 -0700415}
416
417/*
418 * Mark the specified bit as "set".
419 *
420 * Returns "false" if the bit is outside the range of the vector and we're
421 * not allowed to expand.
422 *
423 * NOTE: memory is allocated from the compiler arena.
424 */
buzbeefa57c472012-11-21 12:06:18 -0800425bool SetBit(CompilationUnit* cu, ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700426{
buzbeefa57c472012-11-21 12:06:18 -0800427 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
428 if (!p_bits->expandable) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700429 LOG(FATAL) << "Can't expand";
buzbee67bf8852011-08-17 17:51:35 -0700430 }
431
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 /* Round up to word boundaries for "num+1" bits */
buzbeefa57c472012-11-21 12:06:18 -0800433 unsigned int new_size = (num + 1 + 31) >> 5;
434 DCHECK_GT(new_size, p_bits->storage_size);
435 uint32_t *new_storage = static_cast<uint32_t*>(NewMem(cu, new_size * sizeof(uint32_t), false,
buzbeeeaf09bc2012-11-15 14:51:41 -0800436 kAllocGrowableBitMap));
buzbeefa57c472012-11-21 12:06:18 -0800437 memcpy(new_storage, p_bits->storage, p_bits->storage_size * sizeof(uint32_t));
438 memset(&new_storage[p_bits->storage_size], 0,
439 (new_size - p_bits->storage_size) * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700440#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800441 cu->mstats->bit_map_wasted[p_bits->kind] +=
442 p_bits->storage_size * sizeof(uint32_t);
443 cu->mstats->bit_map_sizes[p_bits->kind] += new_size * sizeof(uint32_t);
444 cu->mstats->bit_map_grows[p_bits->kind]++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700445#endif
buzbeefa57c472012-11-21 12:06:18 -0800446 p_bits->storage = new_storage;
447 p_bits->storage_size = new_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700448 }
449
buzbeefa57c472012-11-21 12:06:18 -0800450 p_bits->storage[num >> 5] |= check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 return true;
buzbee67bf8852011-08-17 17:51:35 -0700452}
453
454/*
455 * Mark the specified bit as "unset".
456 *
457 * Returns "false" if the bit is outside the range of the vector and we're
458 * not allowed to expand.
459 *
460 * NOTE: memory is allocated from the compiler arena.
461 */
buzbeefa57c472012-11-21 12:06:18 -0800462bool ClearBit(ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700463{
buzbeefa57c472012-11-21 12:06:18 -0800464 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700465 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
466 }
buzbee67bf8852011-08-17 17:51:35 -0700467
buzbeefa57c472012-11-21 12:06:18 -0800468 p_bits->storage[num >> 5] &= ~check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700469 return true;
buzbee67bf8852011-08-17 17:51:35 -0700470}
471
buzbee67bf8852011-08-17 17:51:35 -0700472/* Initialize the iterator structure */
buzbeefa57c472012-11-21 12:06:18 -0800473void BitVectorIteratorInit(ArenaBitVector* p_bits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700474 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700475{
buzbeefa57c472012-11-21 12:06:18 -0800476 iterator->p_bits = p_bits;
477 iterator->bit_size = p_bits->storage_size * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700478 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700479}
480
481/*
482 * If the vector sizes don't match, log an error and abort.
483 */
buzbee52a77fc2012-11-20 19:50:46 -0800484static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700485{
buzbeefa57c472012-11-21 12:06:18 -0800486 if (bv1->storage_size != bv2->storage_size) {
487 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storage_size
488 << ", " << bv2->storage_size << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700489 }
buzbee67bf8852011-08-17 17:51:35 -0700490}
491
492/*
493 * Copy a whole vector to the other. Only do that when the both vectors have
494 * the same size.
495 */
buzbee52a77fc2012-11-20 19:50:46 -0800496void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
buzbee67bf8852011-08-17 17:51:35 -0700497{
Bill Buzbeea114add2012-05-03 15:00:40 -0700498 /* if dest is expandable and < src, we could expand dest to match */
buzbee52a77fc2012-11-20 19:50:46 -0800499 CheckSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700500
buzbeefa57c472012-11-21 12:06:18 -0800501 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storage_size);
buzbee67bf8852011-08-17 17:51:35 -0700502}
503
504/*
505 * Intersect two bit vectors and store the result to the dest vector.
506 */
507
buzbee52a77fc2012-11-20 19:50:46 -0800508bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700510{
Bill Buzbeea114add2012-05-03 15:00:40 -0700511 DCHECK(src1 != NULL);
512 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800513 if (dest->storage_size != src1->storage_size ||
514 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700515 dest->expandable != src1->expandable ||
516 dest->expandable != src2->expandable)
517 return false;
buzbee67bf8852011-08-17 17:51:35 -0700518
Bill Buzbeea114add2012-05-03 15:00:40 -0700519 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800520 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700521 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
522 }
523 return true;
buzbee67bf8852011-08-17 17:51:35 -0700524}
525
526/*
527 * Unify two bit vectors and store the result to the dest vector.
528 */
buzbee52a77fc2012-11-20 19:50:46 -0800529bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700531{
Bill Buzbeea114add2012-05-03 15:00:40 -0700532 DCHECK(src1 != NULL);
533 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800534 if (dest->storage_size != src1->storage_size ||
535 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700536 dest->expandable != src1->expandable ||
537 dest->expandable != src2->expandable)
538 return false;
buzbee67bf8852011-08-17 17:51:35 -0700539
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800541 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700542 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
543 }
544 return true;
buzbee67bf8852011-08-17 17:51:35 -0700545}
546
547/*
buzbeee1965672012-03-11 18:39:19 -0700548 * Return true if any bits collide. Vectors must be same size.
549 */
buzbee52a77fc2012-11-20 19:50:46 -0800550bool TestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700551 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700552{
buzbeefa57c472012-11-21 12:06:18 -0800553 DCHECK_EQ(src1->storage_size, src2->storage_size);
554 for (uint32_t idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 if (src1->storage[idx] & src2->storage[idx]) return true;
556 }
557 return false;
buzbeee1965672012-03-11 18:39:19 -0700558}
559
560/*
buzbee67bf8852011-08-17 17:51:35 -0700561 * Compare two bit vectors and return true if difference is seen.
562 */
buzbee52a77fc2012-11-20 19:50:46 -0800563bool CompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700564 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700565{
buzbeefa57c472012-11-21 12:06:18 -0800566 if (src1->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700567 src1->expandable != src2->expandable)
568 return true;
buzbee67bf8852011-08-17 17:51:35 -0700569
Bill Buzbeea114add2012-05-03 15:00:40 -0700570 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800571 for (idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700572 if (src1->storage[idx] != src2->storage[idx]) return true;
573 }
574 return false;
buzbee67bf8852011-08-17 17:51:35 -0700575}
576
577/*
578 * Count the number of bits that are set.
579 */
buzbeefa57c472012-11-21 12:06:18 -0800580int CountSetBits(const ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700581{
Bill Buzbeea114add2012-05-03 15:00:40 -0700582 unsigned int word;
583 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700584
buzbeefa57c472012-11-21 12:06:18 -0800585 for (word = 0; word < p_bits->storage_size; word++) {
586 uint32_t val = p_bits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700587
Bill Buzbeea114add2012-05-03 15:00:40 -0700588 if (val != 0) {
589 if (val == 0xffffffff) {
590 count += 32;
591 } else {
592 /* count the number of '1' bits */
593 while (val != 0) {
594 val &= val - 1;
595 count++;
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 }
buzbee67bf8852011-08-17 17:51:35 -0700600
Bill Buzbeea114add2012-05-03 15:00:40 -0700601 return count;
buzbee67bf8852011-08-17 17:51:35 -0700602}
603
604/* Return the next position set to 1. -1 means end-of-element reached */
buzbee52a77fc2012-11-20 19:50:46 -0800605int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700606{
buzbeefa57c472012-11-21 12:06:18 -0800607 ArenaBitVector* p_bits = iterator->p_bits;
608 uint32_t bit_index = iterator->idx;
609 uint32_t bit_size = iterator->bit_size;
buzbee67bf8852011-08-17 17:51:35 -0700610
buzbeefa57c472012-11-21 12:06:18 -0800611 DCHECK_EQ(bit_size, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700612
buzbeefa57c472012-11-21 12:06:18 -0800613 if (bit_index >= bit_size) return -1;
buzbee5b537102012-01-17 17:33:47 -0800614
buzbeefa57c472012-11-21 12:06:18 -0800615 uint32_t word_index = bit_index >> 5;
616 uint32_t end_word_index = bit_size >> 5;
617 uint32_t* storage = p_bits->storage;
618 uint32_t word = storage[word_index++];
buzbee5b537102012-01-17 17:33:47 -0800619
Bill Buzbeea114add2012-05-03 15:00:40 -0700620 // Mask out any bits in the first word we've already considered
buzbeefa57c472012-11-21 12:06:18 -0800621 word &= ~((1 << (bit_index & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800622
buzbeefa57c472012-11-21 12:06:18 -0800623 for (; word_index <= end_word_index;) {
624 uint32_t bit_pos = bit_index & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700625 if (word == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800626 bit_index += (32 - bit_pos);
627 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700628 continue;
buzbee67bf8852011-08-17 17:51:35 -0700629 }
buzbeefa57c472012-11-21 12:06:18 -0800630 for (; bit_pos < 32; bit_pos++) {
631 if (word & (1 << bit_pos)) {
632 iterator->idx = bit_index + 1;
633 return bit_index;
Bill Buzbeea114add2012-05-03 15:00:40 -0700634 }
buzbeefa57c472012-11-21 12:06:18 -0800635 bit_index++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700636 }
buzbeefa57c472012-11-21 12:06:18 -0800637 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700638 }
buzbeefa57c472012-11-21 12:06:18 -0800639 iterator->idx = iterator->bit_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700640 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700641}
642
643/*
644 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
645 * since there might be unused bits - setting those to one will confuse the
646 * iterator.
647 */
buzbeefa57c472012-11-21 12:06:18 -0800648void SetInitialBits(ArenaBitVector* p_bits, unsigned int num_bits)
buzbee67bf8852011-08-17 17:51:35 -0700649{
Bill Buzbeea114add2012-05-03 15:00:40 -0700650 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800651 DCHECK_LE(((num_bits + 31) >> 5), p_bits->storage_size);
652 for (idx = 0; idx < (num_bits >> 5); idx++) {
653 p_bits->storage[idx] = -1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700654 }
buzbeefa57c472012-11-21 12:06:18 -0800655 unsigned int rem_num_bits = num_bits & 0x1f;
656 if (rem_num_bits) {
657 p_bits->storage[idx] = (1 << rem_num_bits) - 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700658 }
buzbee67bf8852011-08-17 17:51:35 -0700659}
660
buzbee52a77fc2012-11-20 19:50:46 -0800661void GetBlockName(BasicBlock* bb, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700662{
buzbeefa57c472012-11-21 12:06:18 -0800663 switch (bb->block_type) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700664 case kEntryBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700665 snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700666 break;
667 case kExitBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700668 snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700669 break;
670 case kDalvikByteCode:
buzbeefa57c472012-11-21 12:06:18 -0800671 snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700672 break;
673 case kExceptionHandling:
buzbeefa57c472012-11-21 12:06:18 -0800674 snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700675 bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700676 break;
677 default:
buzbeed8506212012-12-20 14:15:05 -0800678 snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700679 break;
680 }
buzbee67bf8852011-08-17 17:51:35 -0700681}
buzbeeed3e9302011-09-23 17:34:19 -0700682
buzbeefa57c472012-11-21 12:06:18 -0800683const char* GetShortyFromTargetIdx(CompilationUnit *cu, int target_idx)
buzbeeed3e9302011-09-23 17:34:19 -0700684{
buzbeefa57c472012-11-21 12:06:18 -0800685 const DexFile::MethodId& method_id = cu->dex_file->GetMethodId(target_idx);
686 return cu->dex_file->GetShorty(method_id.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700687}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800688
buzbee02031b12012-11-23 09:41:35 -0800689/* Allocate a new basic block */
690BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
691{
692 BasicBlock* bb = static_cast<BasicBlock*>(NewMem(cu, sizeof(BasicBlock), true, kAllocBB));
693 bb->block_type = block_type;
694 bb->id = block_id;
695 bb->predecessors = static_cast<GrowableList*>
696 (NewMem(cu, sizeof(GrowableList), false, kAllocPredecessors));
697 CompilerInitGrowableList(cu, bb->predecessors,
698 (block_type == kExitBlock) ? 2048 : 2,
699 kListPredecessors);
700 cu->block_id_map.Put(block_id, block_id);
701 return bb;
702}
703
704/* Insert an MIR instruction to the end of a basic block */
705void AppendMIR(BasicBlock* bb, MIR* mir)
706{
707 if (bb->first_mir_insn == NULL) {
708 DCHECK(bb->last_mir_insn == NULL);
709 bb->last_mir_insn = bb->first_mir_insn = mir;
710 mir->prev = mir->next = NULL;
711 } else {
712 bb->last_mir_insn->next = mir;
713 mir->prev = bb->last_mir_insn;
714 mir->next = NULL;
715 bb->last_mir_insn = mir;
716 }
717}
718
719/* Insert an MIR instruction to the head of a basic block */
720void PrependMIR(BasicBlock* bb, MIR* mir)
721{
722 if (bb->first_mir_insn == NULL) {
723 DCHECK(bb->last_mir_insn == NULL);
724 bb->last_mir_insn = bb->first_mir_insn = mir;
725 mir->prev = mir->next = NULL;
726 } else {
727 bb->first_mir_insn->prev = mir;
728 mir->next = bb->first_mir_insn;
729 mir->prev = NULL;
730 bb->first_mir_insn = mir;
731 }
732}
733
734/* Insert a MIR instruction after the specified MIR */
735void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir)
736{
737 new_mir->prev = current_mir;
738 new_mir->next = current_mir->next;
739 current_mir->next = new_mir;
740
741 if (new_mir->next) {
742 /* Is not the last MIR in the block */
743 new_mir->next->prev = new_mir;
744 } else {
745 /* Is the last MIR in the block */
746 bb->last_mir_insn = new_mir;
747 }
748}
749
750/*
751 * Append an LIR instruction to the LIR list maintained by a compilation
752 * unit
753 */
754void AppendLIR(CompilationUnit *cu, LIR* lir)
755{
756 if (cu->first_lir_insn == NULL) {
757 DCHECK(cu->last_lir_insn == NULL);
758 cu->last_lir_insn = cu->first_lir_insn = lir;
759 lir->prev = lir->next = NULL;
760 } else {
761 cu->last_lir_insn->next = lir;
762 lir->prev = cu->last_lir_insn;
763 lir->next = NULL;
764 cu->last_lir_insn = lir;
765 }
766}
767
768/*
769 * Insert an LIR instruction before the current instruction, which cannot be the
770 * first instruction.
771 *
772 * prev_lir <-> new_lir <-> current_lir
773 */
774void InsertLIRBefore(LIR* current_lir, LIR* new_lir)
775{
776 DCHECK(current_lir->prev != NULL);
777 LIR *prev_lir = current_lir->prev;
778
779 prev_lir->next = new_lir;
780 new_lir->prev = prev_lir;
781 new_lir->next = current_lir;
782 current_lir->prev = new_lir;
783}
784
785/*
786 * Insert an LIR instruction after the current instruction, which cannot be the
787 * first instruction.
788 *
789 * current_lir -> new_lir -> old_next
790 */
791void InsertLIRAfter(LIR* current_lir, LIR* new_lir)
792{
793 new_lir->prev = current_lir;
794 new_lir->next = current_lir->next;
795 current_lir->next = new_lir;
796 new_lir->next->prev = new_lir;
797}
798
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800799} // namespace art