blob: 9dc90ce311981daf7bd4e9c3110e28f86bc339da [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"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070018#include "dex_file-inl.h"
buzbee67bf8852011-08-17 17:51:35 -070019
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080020namespace art {
21
buzbeefa57c472012-11-21 12:06:18 -080022const char* extended_mir_op_names[kMirOpLast - kMirOpFirst] = {
buzbeea169e1d2012-12-05 14:26:44 -080023 "Phi",
24 "Copy",
25 "FusedCmplFloat",
26 "FusedCmpgFloat",
27 "FusedCmplDouble",
28 "FusedCmpgDouble",
29 "FusedCmpLong",
30 "Nop",
31 "OpNullCheck",
32 "OpRangeCheck",
33 "OpDivZeroCheck",
34 "Check1",
35 "Check2",
buzbeef662a7c2013-02-12 16:19:43 -080036 "Select",
buzbeecbd6d442012-11-17 14:11:25 -080037};
38
buzbee5abfa3e2012-01-31 17:01:43 -080039#ifdef WITH_MEMSTATS
Elliott Hughes719ace42012-03-09 18:06:03 -080040struct Memstats {
buzbeefa57c472012-11-21 12:06:18 -080041 uint32_t alloc_stats[kNumAllocKinds];
42 int list_sizes[kNumListKinds];
43 int list_wasted[kNumListKinds];
44 int list_grows[kNumListKinds];
45 int list_max_elems[kNumListKinds];
46 int bit_map_sizes[kNumBitMapKinds];
47 int bit_map_wasted[kNumBitMapKinds];
48 int bit_map_grows[kNumBitMapKinds];
Elliott Hughes719ace42012-03-09 18:06:03 -080049};
buzbee5abfa3e2012-01-31 17:01:43 -080050
buzbeefa57c472012-11-21 12:06:18 -080051const char* alloc_names[kNumAllocKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070052 "Misc ",
53 "BasicBlock ",
54 "LIR ",
55 "MIR ",
56 "DataFlow ",
57 "GrowList ",
58 "GrowBitMap ",
59 "Dalvik2SSA ",
60 "DebugInfo ",
61 "Successor ",
62 "RegAlloc ",
63 "Data ",
64 "Preds ",
buzbee5abfa3e2012-01-31 17:01:43 -080065};
66
buzbeefa57c472012-11-21 12:06:18 -080067const char* list_names[kNumListKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070068 "Misc ",
buzbeefa57c472012-11-21 12:06:18 -080069 "block_list ",
Bill Buzbeea114add2012-05-03 15:00:40 -070070 "SSAtoDalvik ",
buzbeefa57c472012-11-21 12:06:18 -080071 "dfs_order ",
72 "dfs_post_order ",
73 "dom_post_order_traversal ",
74 "throw_launch_pads ",
75 "suspend_launch_pads ",
76 "switch_tables ",
77 "fill_array_data ",
Bill Buzbeea114add2012-05-03 15:00:40 -070078 "SuccessorBlocks ",
79 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080080};
81
buzbeefa57c472012-11-21 12:06:18 -080082const char* bit_map_names[kNumBitMapKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070083 "Misc ",
84 "Use ",
85 "Def ",
86 "LiveIn ",
87 "BlockMatrix ",
88 "Dominators ",
89 "IDominated ",
90 "DomFrontier ",
91 "Phi ",
92 "TmpBlocks ",
93 "InputBlocks ",
94 "RegisterV ",
95 "TempSSARegisterV ",
96 "Null Check ",
97 "TmpBlockV ",
98 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080099};
100#endif
101
buzbeeeaf09bc2012-11-15 14:51:41 -0800102#define kArenaBitVectorGrowth 4 /* increase by 4 uint32_ts when limit hit */
buzbee67bf8852011-08-17 17:51:35 -0700103
104/* Allocate the initial memory block for arena-based allocation */
buzbeefa57c472012-11-21 12:06:18 -0800105bool HeapInit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700106{
buzbeefa57c472012-11-21 12:06:18 -0800107 DCHECK(cu->arena_head == NULL);
108 cu->arena_head =
buzbeecbd6d442012-11-17 14:11:25 -0800109 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE));
buzbeefa57c472012-11-21 12:06:18 -0800110 if (cu->arena_head == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700111 LOG(FATAL) << "No memory left to create compiler heap memory";
112 }
buzbeefa57c472012-11-21 12:06:18 -0800113 cu->arena_head->block_size = ARENA_DEFAULT_SIZE;
114 cu->current_arena = cu->arena_head;
115 cu->current_arena->bytes_allocated = 0;
116 cu->current_arena->next = NULL;
117 cu->num_arena_blocks = 1;
buzbeeba938cb2012-02-03 14:47:55 -0800118#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800119 cu->mstats = (Memstats*) NewMem(cu, sizeof(Memstats), true,
Bill Buzbeea114add2012-05-03 15:00:40 -0700120 kAllocDebugInfo);
buzbeeba938cb2012-02-03 14:47:55 -0800121#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700122 return true;
buzbee67bf8852011-08-17 17:51:35 -0700123}
124
125/* Arena-based malloc for compilation tasks */
buzbeefa57c472012-11-21 12:06:18 -0800126void* NewMem(CompilationUnit* cu, size_t size, bool zero, oat_alloc_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700127{
Bill Buzbeea114add2012-05-03 15:00:40 -0700128 size = (size + 3) & ~3;
buzbee5abfa3e2012-01-31 17:01:43 -0800129#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800130 if (cu->mstats != NULL) {
131 cu->mstats->alloc_stats[kind] += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700132 }
buzbee5abfa3e2012-01-31 17:01:43 -0800133#endif
buzbee67bf8852011-08-17 17:51:35 -0700134retry:
Bill Buzbeea114add2012-05-03 15:00:40 -0700135 /* Normal case - space is available in the current page */
buzbeefa57c472012-11-21 12:06:18 -0800136 if (size + cu->current_arena->bytes_allocated <=
137 cu->current_arena->block_size) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700138 void *ptr;
buzbeefa57c472012-11-21 12:06:18 -0800139 ptr = &cu->current_arena->ptr[cu->current_arena->bytes_allocated];
140 cu->current_arena->bytes_allocated += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700141 if (zero) {
142 memset(ptr, 0, size);
143 }
144 return ptr;
145 } else {
146 /*
147 * See if there are previously allocated arena blocks before the last
148 * reset
149 */
buzbeefa57c472012-11-21 12:06:18 -0800150 if (cu->current_arena->next) {
151 cu->current_arena = cu->current_arena->next;
152 cu->current_arena->bytes_allocated = 0;
buzbee67bf8852011-08-17 17:51:35 -0700153 goto retry;
154 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700155
buzbeefa57c472012-11-21 12:06:18 -0800156 size_t block_size = (size < ARENA_DEFAULT_SIZE) ? ARENA_DEFAULT_SIZE : size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700157 /* Time to allocate a new arena */
buzbeefa57c472012-11-21 12:06:18 -0800158 ArenaMemBlock *new_arena =
159 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + block_size));
160 if (new_arena == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700161 LOG(FATAL) << "Arena allocation failure";
162 }
buzbeefa57c472012-11-21 12:06:18 -0800163 new_arena->block_size = block_size;
164 new_arena->bytes_allocated = 0;
165 new_arena->next = NULL;
166 cu->current_arena->next = new_arena;
167 cu->current_arena = new_arena;
168 cu->num_arena_blocks++;
169 if (cu->num_arena_blocks > 20000) {
170 LOG(INFO) << "Total arena pages: " << cu->num_arena_blocks;
Bill Buzbeea114add2012-05-03 15:00:40 -0700171 }
172 goto retry;
173 }
buzbee67bf8852011-08-17 17:51:35 -0700174}
175
176/* Reclaim all the arena blocks allocated so far */
buzbeefa57c472012-11-21 12:06:18 -0800177void ArenaReset(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700178{
buzbeefa57c472012-11-21 12:06:18 -0800179 ArenaMemBlock* head = cu->arena_head;
Bill Buzbeea114add2012-05-03 15:00:40 -0700180 while (head != NULL) {
181 ArenaMemBlock* p = head;
182 head = head->next;
183 free(p);
184 }
buzbeefa57c472012-11-21 12:06:18 -0800185 cu->arena_head = NULL;
186 cu->current_arena = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700187}
188
189/* Growable List initialization */
buzbeefa57c472012-11-21 12:06:18 -0800190void CompilerInitGrowableList(CompilationUnit* cu, GrowableList* g_list,
191 size_t init_length, oat_list_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700192{
buzbeefa57c472012-11-21 12:06:18 -0800193 g_list->num_allocated = init_length;
194 g_list->num_used = 0;
195 g_list->elem_list = static_cast<uintptr_t *>(NewMem(cu, sizeof(intptr_t) * init_length,
buzbeecbd6d442012-11-17 14:11:25 -0800196 true, kAllocGrowableList));
buzbee5abfa3e2012-01-31 17:01:43 -0800197#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800198 cu->mstats->list_sizes[kind] += sizeof(uintptr_t) * init_length;
199 g_list->kind = kind;
200 if (static_cast<int>(init_length) > cu->mstats->list_max_elems[kind]) {
201 cu->mstats->list_max_elems[kind] = init_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700202 }
buzbee5abfa3e2012-01-31 17:01:43 -0800203#endif
buzbee67bf8852011-08-17 17:51:35 -0700204}
205
206/* Expand the capacity of a growable list */
buzbeefa57c472012-11-21 12:06:18 -0800207static void ExpandGrowableList(CompilationUnit* cu, GrowableList* g_list)
buzbee67bf8852011-08-17 17:51:35 -0700208{
buzbeefa57c472012-11-21 12:06:18 -0800209 int new_length = g_list->num_allocated;
210 if (new_length < 128) {
211 new_length <<= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700212 } else {
buzbeefa57c472012-11-21 12:06:18 -0800213 new_length += 128;
Bill Buzbeea114add2012-05-03 15:00:40 -0700214 }
buzbeefa57c472012-11-21 12:06:18 -0800215 uintptr_t *new_array =
216 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
buzbeecbd6d442012-11-17 14:11:25 -0800217 kAllocGrowableList));
buzbeefa57c472012-11-21 12:06:18 -0800218 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800219#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800220 cu->mstats->list_sizes[g_list->kind] += sizeof(uintptr_t) * new_length;
221 cu->mstats->list_wasted[g_list->kind] +=
222 sizeof(uintptr_t) * g_list->num_allocated;
223 cu->mstats->list_grows[g_list->kind]++;
224 if (new_length > cu->mstats->list_max_elems[g_list->kind]) {
225 cu->mstats->list_max_elems[g_list->kind] = new_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700226 }
buzbee5abfa3e2012-01-31 17:01:43 -0800227#endif
buzbeefa57c472012-11-21 12:06:18 -0800228 g_list->num_allocated = new_length;
229 g_list->elem_list = new_array;
buzbee67bf8852011-08-17 17:51:35 -0700230}
231
232/* Insert a new element into the growable list */
buzbeefa57c472012-11-21 12:06:18 -0800233void InsertGrowableList(CompilationUnit* cu, GrowableList* g_list,
buzbeecbd6d442012-11-17 14:11:25 -0800234 uintptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700235{
buzbeefa57c472012-11-21 12:06:18 -0800236 DCHECK_NE(g_list->num_allocated, 0U);
237 if (g_list->num_used == g_list->num_allocated) {
238 ExpandGrowableList(cu, g_list);
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 }
buzbeefa57c472012-11-21 12:06:18 -0800240 g_list->elem_list[g_list->num_used++] = elem;
buzbee67bf8852011-08-17 17:51:35 -0700241}
242
buzbee5abfa3e2012-01-31 17:01:43 -0800243/* Delete an element from a growable list. Element must be present */
buzbeefa57c472012-11-21 12:06:18 -0800244void DeleteGrowableList(GrowableList* g_list, uintptr_t elem)
buzbee5abfa3e2012-01-31 17:01:43 -0800245{
Bill Buzbeea114add2012-05-03 15:00:40 -0700246 bool found = false;
buzbeefa57c472012-11-21 12:06:18 -0800247 for (unsigned int i = 0; i < g_list->num_used; i++) {
248 if (!found && g_list->elem_list[i] == elem) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700249 found = true;
buzbee5abfa3e2012-01-31 17:01:43 -0800250 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 if (found) {
buzbeefa57c472012-11-21 12:06:18 -0800252 g_list->elem_list[i] = g_list->elem_list[i+1];
Bill Buzbeea114add2012-05-03 15:00:40 -0700253 }
254 }
255 DCHECK_EQ(found, true);
buzbeefa57c472012-11-21 12:06:18 -0800256 g_list->num_used--;
buzbee5abfa3e2012-01-31 17:01:43 -0800257}
258
buzbeefa57c472012-11-21 12:06:18 -0800259void GrowableListIteratorInit(GrowableList* g_list,
Bill Buzbeea114add2012-05-03 15:00:40 -0700260 GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700261{
buzbeefa57c472012-11-21 12:06:18 -0800262 iterator->list = g_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 iterator->idx = 0;
buzbeefa57c472012-11-21 12:06:18 -0800264 iterator->size = g_list->num_used;
buzbee67bf8852011-08-17 17:51:35 -0700265}
266
buzbee52a77fc2012-11-20 19:50:46 -0800267uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700268{
buzbeefa57c472012-11-21 12:06:18 -0800269 DCHECK_EQ(iterator->size, iterator->list->num_used);
Bill Buzbeea114add2012-05-03 15:00:40 -0700270 if (iterator->idx == iterator->size) return 0;
buzbeefa57c472012-11-21 12:06:18 -0800271 return iterator->list->elem_list[iterator->idx++];
buzbee67bf8852011-08-17 17:51:35 -0700272}
273
buzbeefa57c472012-11-21 12:06:18 -0800274uintptr_t GrowableListGetElement(const GrowableList* g_list, size_t idx)
buzbee67bf8852011-08-17 17:51:35 -0700275{
buzbeefa57c472012-11-21 12:06:18 -0800276 DCHECK_LT(idx, g_list->num_used);
277 return g_list->elem_list[idx];
buzbee67bf8852011-08-17 17:51:35 -0700278}
279
buzbee5abfa3e2012-01-31 17:01:43 -0800280#ifdef WITH_MEMSTATS
281/* Dump memory usage stats */
buzbeefa57c472012-11-21 12:06:18 -0800282void DumpMemStats(CompilationUnit* cu)
buzbee5abfa3e2012-01-31 17:01:43 -0800283{
buzbeeeaf09bc2012-11-15 14:51:41 -0800284 uint32_t total = 0;
Bill Buzbeea114add2012-05-03 15:00:40 -0700285 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800286 total += cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700287 }
288 if (total > (10 * 1024 * 1024)) {
289 LOG(INFO) << "MEMUSAGE: " << total << " : "
buzbeefa57c472012-11-21 12:06:18 -0800290 << PrettyMethod(cu->method_idx, *cu->dex_file);
291 LOG(INFO) << "insns_size: " << cu->insns_size;
292 if (cu->disable_dataflow) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700293 LOG(INFO) << " ** Dataflow disabled ** ";
buzbee5abfa3e2012-01-31 17:01:43 -0800294 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700295 LOG(INFO) << "===== Overall allocations";
296 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800297 LOG(INFO) << alloc_names[i] << std::setw(10) <<
298 cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 }
300 LOG(INFO) << "===== GrowableList allocations";
301 for (int i = 0; i < kNumListKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800302 LOG(INFO) << list_names[i]
303 << " S:" << cu->mstats->list_sizes[i]
304 << ", W:" << cu->mstats->list_wasted[i]
305 << ", G:" << cu->mstats->list_grows[i]
306 << ", E:" << cu->mstats->list_max_elems[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700307 }
308 LOG(INFO) << "===== GrowableBitMap allocations";
309 for (int i = 0; i < kNumBitMapKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800310 LOG(INFO) << bit_map_names[i]
311 << " S:" << cu->mstats->bit_map_sizes[i]
312 << ", W:" << cu->mstats->bit_map_wasted[i]
313 << ", G:" << cu->mstats->bit_map_grows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800314 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700315 }
buzbee5abfa3e2012-01-31 17:01:43 -0800316}
317#endif
318
buzbee67bf8852011-08-17 17:51:35 -0700319/* Debug Utility - dump a compilation unit */
buzbeefa57c472012-11-21 12:06:18 -0800320void DumpCompilationUnit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700321{
Bill Buzbeea114add2012-05-03 15:00:40 -0700322 BasicBlock* bb;
buzbeefa57c472012-11-21 12:06:18 -0800323 const char* block_type_names[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700324 "Entry Block",
325 "Code Block",
326 "Exit Block",
327 "Exception Handling",
328 "Catch Block"
329 };
buzbee67bf8852011-08-17 17:51:35 -0700330
buzbeefa57c472012-11-21 12:06:18 -0800331 LOG(INFO) << "Compiling " << PrettyMethod(cu->method_idx, *cu->dex_file);
332 LOG(INFO) << cu->insns << " insns";
333 LOG(INFO) << cu->num_blocks << " blocks in total";
Bill Buzbeea114add2012-05-03 15:00:40 -0700334 GrowableListIterator iterator;
buzbee67bf8852011-08-17 17:51:35 -0700335
buzbeefa57c472012-11-21 12:06:18 -0800336 GrowableListIteratorInit(&cu->block_list, &iterator);
buzbee67bf8852011-08-17 17:51:35 -0700337
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 while (true) {
buzbee52a77fc2012-11-20 19:50:46 -0800339 bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
Bill Buzbeea114add2012-05-03 15:00:40 -0700340 if (bb == NULL) break;
341 LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
342 bb->id,
buzbeefa57c472012-11-21 12:06:18 -0800343 block_type_names[bb->block_type],
344 bb->start_offset,
345 bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
346 bb->last_mir_insn ? "" : " empty");
Bill Buzbeea114add2012-05-03 15:00:40 -0700347 if (bb->taken) {
348 LOG(INFO) << " Taken branch: block " << bb->taken->id
buzbeefa57c472012-11-21 12:06:18 -0800349 << "(0x" << std::hex << bb->taken->start_offset << ")";
buzbee67bf8852011-08-17 17:51:35 -0700350 }
buzbeefa57c472012-11-21 12:06:18 -0800351 if (bb->fall_through) {
352 LOG(INFO) << " Fallthrough : block " << bb->fall_through->id
353 << " (0x" << std::hex << bb->fall_through->start_offset << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700354 }
355 }
buzbee67bf8852011-08-17 17:51:35 -0700356}
357
buzbeefa57c472012-11-21 12:06:18 -0800358static uint32_t check_masks[32] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700359 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
360 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
361 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
362 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
363 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
364 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
365 0x40000000, 0x80000000 };
buzbee67bc2362011-10-11 18:08:40 -0700366
buzbee67bf8852011-08-17 17:51:35 -0700367/*
368 * Allocate a bit vector with enough space to hold at least the specified
369 * number of bits.
370 *
371 * NOTE: memory is allocated from the compiler arena.
372 */
buzbeefa57c472012-11-21 12:06:18 -0800373ArenaBitVector* AllocBitVector(CompilationUnit* cu,
374 unsigned int start_bits, bool expandable,
375 oat_bit_map_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700376{
Bill Buzbeea114add2012-05-03 15:00:40 -0700377 ArenaBitVector* bv;
378 unsigned int count;
buzbee67bf8852011-08-17 17:51:35 -0700379
Bill Buzbeea114add2012-05-03 15:00:40 -0700380 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700381
buzbeefa57c472012-11-21 12:06:18 -0800382 bv = static_cast<ArenaBitVector*>(NewMem(cu, sizeof(ArenaBitVector), false,
buzbeecbd6d442012-11-17 14:11:25 -0800383 kAllocGrowableBitMap));
buzbee67bf8852011-08-17 17:51:35 -0700384
buzbeefa57c472012-11-21 12:06:18 -0800385 count = (start_bits + 31) >> 5;
buzbee67bf8852011-08-17 17:51:35 -0700386
buzbeefa57c472012-11-21 12:06:18 -0800387 bv->storage_size = count;
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 bv->expandable = expandable;
buzbeefa57c472012-11-21 12:06:18 -0800389 bv->storage = static_cast<uint32_t*>(NewMem(cu, count * sizeof(uint32_t), true,
buzbeeeaf09bc2012-11-15 14:51:41 -0800390 kAllocGrowableBitMap));
buzbee5abfa3e2012-01-31 17:01:43 -0800391#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 bv->kind = kind;
buzbeefa57c472012-11-21 12:06:18 -0800393 cu->mstats->bit_map_sizes[kind] += count * sizeof(uint32_t);
buzbee5abfa3e2012-01-31 17:01:43 -0800394#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700395 return bv;
buzbee67bf8852011-08-17 17:51:35 -0700396}
397
398/*
399 * Determine whether or not the specified bit is set.
400 */
buzbeefa57c472012-11-21 12:06:18 -0800401bool IsBitSet(const ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700402{
buzbeefa57c472012-11-21 12:06:18 -0800403 DCHECK_LT(num, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700404
buzbeefa57c472012-11-21 12:06:18 -0800405 unsigned int val = p_bits->storage[num >> 5] & check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700406 return (val != 0);
buzbee67bf8852011-08-17 17:51:35 -0700407}
408
409/*
410 * Mark all bits bit as "clear".
411 */
buzbeefa57c472012-11-21 12:06:18 -0800412void ClearAllBits(ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700413{
buzbeefa57c472012-11-21 12:06:18 -0800414 unsigned int count = p_bits->storage_size;
415 memset(p_bits->storage, 0, count * sizeof(uint32_t));
buzbee67bf8852011-08-17 17:51:35 -0700416}
417
418/*
419 * Mark the specified bit as "set".
420 *
421 * Returns "false" if the bit is outside the range of the vector and we're
422 * not allowed to expand.
423 *
424 * NOTE: memory is allocated from the compiler arena.
425 */
buzbeefa57c472012-11-21 12:06:18 -0800426bool SetBit(CompilationUnit* cu, ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700427{
buzbeefa57c472012-11-21 12:06:18 -0800428 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
429 if (!p_bits->expandable) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700430 LOG(FATAL) << "Can't expand";
buzbee67bf8852011-08-17 17:51:35 -0700431 }
432
Bill Buzbeea114add2012-05-03 15:00:40 -0700433 /* Round up to word boundaries for "num+1" bits */
buzbeefa57c472012-11-21 12:06:18 -0800434 unsigned int new_size = (num + 1 + 31) >> 5;
435 DCHECK_GT(new_size, p_bits->storage_size);
436 uint32_t *new_storage = static_cast<uint32_t*>(NewMem(cu, new_size * sizeof(uint32_t), false,
buzbeeeaf09bc2012-11-15 14:51:41 -0800437 kAllocGrowableBitMap));
buzbeefa57c472012-11-21 12:06:18 -0800438 memcpy(new_storage, p_bits->storage, p_bits->storage_size * sizeof(uint32_t));
439 memset(&new_storage[p_bits->storage_size], 0,
440 (new_size - p_bits->storage_size) * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700441#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800442 cu->mstats->bit_map_wasted[p_bits->kind] +=
443 p_bits->storage_size * sizeof(uint32_t);
444 cu->mstats->bit_map_sizes[p_bits->kind] += new_size * sizeof(uint32_t);
445 cu->mstats->bit_map_grows[p_bits->kind]++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700446#endif
buzbeefa57c472012-11-21 12:06:18 -0800447 p_bits->storage = new_storage;
448 p_bits->storage_size = new_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700449 }
450
buzbeefa57c472012-11-21 12:06:18 -0800451 p_bits->storage[num >> 5] |= check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700452 return true;
buzbee67bf8852011-08-17 17:51:35 -0700453}
454
455/*
456 * Mark the specified bit as "unset".
457 *
458 * Returns "false" if the bit is outside the range of the vector and we're
459 * not allowed to expand.
460 *
461 * NOTE: memory is allocated from the compiler arena.
462 */
buzbeefa57c472012-11-21 12:06:18 -0800463bool ClearBit(ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700464{
buzbeefa57c472012-11-21 12:06:18 -0800465 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700466 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
467 }
buzbee67bf8852011-08-17 17:51:35 -0700468
buzbeefa57c472012-11-21 12:06:18 -0800469 p_bits->storage[num >> 5] &= ~check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700470 return true;
buzbee67bf8852011-08-17 17:51:35 -0700471}
472
buzbee67bf8852011-08-17 17:51:35 -0700473/* Initialize the iterator structure */
buzbeefa57c472012-11-21 12:06:18 -0800474void BitVectorIteratorInit(ArenaBitVector* p_bits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700475 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700476{
buzbeefa57c472012-11-21 12:06:18 -0800477 iterator->p_bits = p_bits;
478 iterator->bit_size = p_bits->storage_size * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700479 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700480}
481
482/*
483 * If the vector sizes don't match, log an error and abort.
484 */
buzbee52a77fc2012-11-20 19:50:46 -0800485static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700486{
buzbeefa57c472012-11-21 12:06:18 -0800487 if (bv1->storage_size != bv2->storage_size) {
488 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storage_size
489 << ", " << bv2->storage_size << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700490 }
buzbee67bf8852011-08-17 17:51:35 -0700491}
492
493/*
494 * Copy a whole vector to the other. Only do that when the both vectors have
495 * the same size.
496 */
buzbee52a77fc2012-11-20 19:50:46 -0800497void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
buzbee67bf8852011-08-17 17:51:35 -0700498{
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 /* if dest is expandable and < src, we could expand dest to match */
buzbee52a77fc2012-11-20 19:50:46 -0800500 CheckSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700501
buzbeefa57c472012-11-21 12:06:18 -0800502 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storage_size);
buzbee67bf8852011-08-17 17:51:35 -0700503}
504
505/*
506 * Intersect two bit vectors and store the result to the dest vector.
507 */
508
buzbee52a77fc2012-11-20 19:50:46 -0800509bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700510 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700511{
Bill Buzbeea114add2012-05-03 15:00:40 -0700512 DCHECK(src1 != NULL);
513 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800514 if (dest->storage_size != src1->storage_size ||
515 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700516 dest->expandable != src1->expandable ||
517 dest->expandable != src2->expandable)
518 return false;
buzbee67bf8852011-08-17 17:51:35 -0700519
Bill Buzbeea114add2012-05-03 15:00:40 -0700520 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800521 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700522 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
523 }
524 return true;
buzbee67bf8852011-08-17 17:51:35 -0700525}
526
527/*
528 * Unify two bit vectors and store the result to the dest vector.
529 */
buzbee52a77fc2012-11-20 19:50:46 -0800530bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700531 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700532{
Bill Buzbeea114add2012-05-03 15:00:40 -0700533 DCHECK(src1 != NULL);
534 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800535 if (dest->storage_size != src1->storage_size ||
536 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700537 dest->expandable != src1->expandable ||
538 dest->expandable != src2->expandable)
539 return false;
buzbee67bf8852011-08-17 17:51:35 -0700540
Bill Buzbeea114add2012-05-03 15:00:40 -0700541 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800542 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700543 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
544 }
545 return true;
buzbee67bf8852011-08-17 17:51:35 -0700546}
547
548/*
buzbeee1965672012-03-11 18:39:19 -0700549 * Return true if any bits collide. Vectors must be same size.
550 */
buzbee52a77fc2012-11-20 19:50:46 -0800551bool TestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700552 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700553{
buzbeefa57c472012-11-21 12:06:18 -0800554 DCHECK_EQ(src1->storage_size, src2->storage_size);
555 for (uint32_t idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700556 if (src1->storage[idx] & src2->storage[idx]) return true;
557 }
558 return false;
buzbeee1965672012-03-11 18:39:19 -0700559}
560
561/*
buzbee67bf8852011-08-17 17:51:35 -0700562 * Compare two bit vectors and return true if difference is seen.
563 */
buzbee52a77fc2012-11-20 19:50:46 -0800564bool CompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700565 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700566{
buzbeefa57c472012-11-21 12:06:18 -0800567 if (src1->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700568 src1->expandable != src2->expandable)
569 return true;
buzbee67bf8852011-08-17 17:51:35 -0700570
Bill Buzbeea114add2012-05-03 15:00:40 -0700571 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800572 for (idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700573 if (src1->storage[idx] != src2->storage[idx]) return true;
574 }
575 return false;
buzbee67bf8852011-08-17 17:51:35 -0700576}
577
578/*
579 * Count the number of bits that are set.
580 */
buzbeefa57c472012-11-21 12:06:18 -0800581int CountSetBits(const ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700582{
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 unsigned int word;
584 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700585
buzbeefa57c472012-11-21 12:06:18 -0800586 for (word = 0; word < p_bits->storage_size; word++) {
587 uint32_t val = p_bits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700588
Bill Buzbeea114add2012-05-03 15:00:40 -0700589 if (val != 0) {
590 if (val == 0xffffffff) {
591 count += 32;
592 } else {
593 /* count the number of '1' bits */
594 while (val != 0) {
595 val &= val - 1;
596 count++;
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 }
buzbee67bf8852011-08-17 17:51:35 -0700601
Bill Buzbeea114add2012-05-03 15:00:40 -0700602 return count;
buzbee67bf8852011-08-17 17:51:35 -0700603}
604
605/* Return the next position set to 1. -1 means end-of-element reached */
buzbee52a77fc2012-11-20 19:50:46 -0800606int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700607{
buzbeefa57c472012-11-21 12:06:18 -0800608 ArenaBitVector* p_bits = iterator->p_bits;
609 uint32_t bit_index = iterator->idx;
610 uint32_t bit_size = iterator->bit_size;
buzbee67bf8852011-08-17 17:51:35 -0700611
buzbeefa57c472012-11-21 12:06:18 -0800612 DCHECK_EQ(bit_size, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700613
buzbeefa57c472012-11-21 12:06:18 -0800614 if (bit_index >= bit_size) return -1;
buzbee5b537102012-01-17 17:33:47 -0800615
buzbeefa57c472012-11-21 12:06:18 -0800616 uint32_t word_index = bit_index >> 5;
617 uint32_t end_word_index = bit_size >> 5;
618 uint32_t* storage = p_bits->storage;
619 uint32_t word = storage[word_index++];
buzbee5b537102012-01-17 17:33:47 -0800620
Bill Buzbeea114add2012-05-03 15:00:40 -0700621 // Mask out any bits in the first word we've already considered
buzbeefa57c472012-11-21 12:06:18 -0800622 word &= ~((1 << (bit_index & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800623
buzbeefa57c472012-11-21 12:06:18 -0800624 for (; word_index <= end_word_index;) {
625 uint32_t bit_pos = bit_index & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700626 if (word == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800627 bit_index += (32 - bit_pos);
628 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700629 continue;
buzbee67bf8852011-08-17 17:51:35 -0700630 }
buzbeefa57c472012-11-21 12:06:18 -0800631 for (; bit_pos < 32; bit_pos++) {
632 if (word & (1 << bit_pos)) {
633 iterator->idx = bit_index + 1;
634 return bit_index;
Bill Buzbeea114add2012-05-03 15:00:40 -0700635 }
buzbeefa57c472012-11-21 12:06:18 -0800636 bit_index++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700637 }
buzbeefa57c472012-11-21 12:06:18 -0800638 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700639 }
buzbeefa57c472012-11-21 12:06:18 -0800640 iterator->idx = iterator->bit_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700641 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700642}
643
644/*
645 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
646 * since there might be unused bits - setting those to one will confuse the
647 * iterator.
648 */
buzbeefa57c472012-11-21 12:06:18 -0800649void SetInitialBits(ArenaBitVector* p_bits, unsigned int num_bits)
buzbee67bf8852011-08-17 17:51:35 -0700650{
Bill Buzbeea114add2012-05-03 15:00:40 -0700651 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800652 DCHECK_LE(((num_bits + 31) >> 5), p_bits->storage_size);
653 for (idx = 0; idx < (num_bits >> 5); idx++) {
654 p_bits->storage[idx] = -1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700655 }
buzbeefa57c472012-11-21 12:06:18 -0800656 unsigned int rem_num_bits = num_bits & 0x1f;
657 if (rem_num_bits) {
658 p_bits->storage[idx] = (1 << rem_num_bits) - 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700659 }
buzbee67bf8852011-08-17 17:51:35 -0700660}
661
buzbee52a77fc2012-11-20 19:50:46 -0800662void GetBlockName(BasicBlock* bb, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700663{
buzbeefa57c472012-11-21 12:06:18 -0800664 switch (bb->block_type) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700665 case kEntryBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700666 snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700667 break;
668 case kExitBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700669 snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700670 break;
671 case kDalvikByteCode:
buzbeefa57c472012-11-21 12:06:18 -0800672 snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700673 break;
674 case kExceptionHandling:
buzbeefa57c472012-11-21 12:06:18 -0800675 snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700676 bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 break;
678 default:
buzbeed8506212012-12-20 14:15:05 -0800679 snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700680 break;
681 }
buzbee67bf8852011-08-17 17:51:35 -0700682}
buzbeeed3e9302011-09-23 17:34:19 -0700683
buzbeefa57c472012-11-21 12:06:18 -0800684const char* GetShortyFromTargetIdx(CompilationUnit *cu, int target_idx)
buzbeeed3e9302011-09-23 17:34:19 -0700685{
buzbeefa57c472012-11-21 12:06:18 -0800686 const DexFile::MethodId& method_id = cu->dex_file->GetMethodId(target_idx);
687 return cu->dex_file->GetShorty(method_id.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700688}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800689
buzbee02031b12012-11-23 09:41:35 -0800690/* Allocate a new basic block */
691BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
692{
693 BasicBlock* bb = static_cast<BasicBlock*>(NewMem(cu, sizeof(BasicBlock), true, kAllocBB));
694 bb->block_type = block_type;
695 bb->id = block_id;
696 bb->predecessors = static_cast<GrowableList*>
697 (NewMem(cu, sizeof(GrowableList), false, kAllocPredecessors));
698 CompilerInitGrowableList(cu, bb->predecessors,
699 (block_type == kExitBlock) ? 2048 : 2,
700 kListPredecessors);
701 cu->block_id_map.Put(block_id, block_id);
702 return bb;
703}
704
705/* Insert an MIR instruction to the end of a basic block */
706void AppendMIR(BasicBlock* bb, MIR* mir)
707{
708 if (bb->first_mir_insn == NULL) {
709 DCHECK(bb->last_mir_insn == NULL);
710 bb->last_mir_insn = bb->first_mir_insn = mir;
711 mir->prev = mir->next = NULL;
712 } else {
713 bb->last_mir_insn->next = mir;
714 mir->prev = bb->last_mir_insn;
715 mir->next = NULL;
716 bb->last_mir_insn = mir;
717 }
718}
719
720/* Insert an MIR instruction to the head of a basic block */
721void PrependMIR(BasicBlock* bb, MIR* mir)
722{
723 if (bb->first_mir_insn == NULL) {
724 DCHECK(bb->last_mir_insn == NULL);
725 bb->last_mir_insn = bb->first_mir_insn = mir;
726 mir->prev = mir->next = NULL;
727 } else {
728 bb->first_mir_insn->prev = mir;
729 mir->next = bb->first_mir_insn;
730 mir->prev = NULL;
731 bb->first_mir_insn = mir;
732 }
733}
734
735/* Insert a MIR instruction after the specified MIR */
736void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir)
737{
738 new_mir->prev = current_mir;
739 new_mir->next = current_mir->next;
740 current_mir->next = new_mir;
741
742 if (new_mir->next) {
743 /* Is not the last MIR in the block */
744 new_mir->next->prev = new_mir;
745 } else {
746 /* Is the last MIR in the block */
747 bb->last_mir_insn = new_mir;
748 }
749}
750
751/*
752 * Append an LIR instruction to the LIR list maintained by a compilation
753 * unit
754 */
755void AppendLIR(CompilationUnit *cu, LIR* lir)
756{
757 if (cu->first_lir_insn == NULL) {
758 DCHECK(cu->last_lir_insn == NULL);
759 cu->last_lir_insn = cu->first_lir_insn = lir;
760 lir->prev = lir->next = NULL;
761 } else {
762 cu->last_lir_insn->next = lir;
763 lir->prev = cu->last_lir_insn;
764 lir->next = NULL;
765 cu->last_lir_insn = lir;
766 }
767}
768
769/*
770 * Insert an LIR instruction before the current instruction, which cannot be the
771 * first instruction.
772 *
773 * prev_lir <-> new_lir <-> current_lir
774 */
775void InsertLIRBefore(LIR* current_lir, LIR* new_lir)
776{
777 DCHECK(current_lir->prev != NULL);
778 LIR *prev_lir = current_lir->prev;
779
780 prev_lir->next = new_lir;
781 new_lir->prev = prev_lir;
782 new_lir->next = current_lir;
783 current_lir->prev = new_lir;
784}
785
786/*
787 * Insert an LIR instruction after the current instruction, which cannot be the
788 * first instruction.
789 *
790 * current_lir -> new_lir -> old_next
791 */
792void InsertLIRAfter(LIR* current_lir, LIR* new_lir)
793{
794 new_lir->prev = current_lir;
795 new_lir->next = current_lir->next;
796 current_lir->next = new_lir;
797 new_lir->next->prev = new_lir;
798}
799
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800800} // namespace art