blob: 82a156d1c2597a542684fb06ce4affabd6596e6e [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
buzbee311ca162013-02-28 15:56:43 -0800206void ReallocGrowableList(CompilationUnit* cu, GrowableList* g_list, size_t new_length)
207{
208 if (new_length > g_list->num_allocated) {
209 uintptr_t *new_array =
210 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
211 kAllocGrowableList));
212 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
213 g_list->num_allocated = new_length;
214 g_list->elem_list = new_array;
215 }
216}
217
buzbee67bf8852011-08-17 17:51:35 -0700218/* Expand the capacity of a growable list */
buzbeefa57c472012-11-21 12:06:18 -0800219static void ExpandGrowableList(CompilationUnit* cu, GrowableList* g_list)
buzbee67bf8852011-08-17 17:51:35 -0700220{
buzbeefa57c472012-11-21 12:06:18 -0800221 int new_length = g_list->num_allocated;
222 if (new_length < 128) {
223 new_length <<= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700224 } else {
buzbeefa57c472012-11-21 12:06:18 -0800225 new_length += 128;
Bill Buzbeea114add2012-05-03 15:00:40 -0700226 }
buzbeefa57c472012-11-21 12:06:18 -0800227 uintptr_t *new_array =
228 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
buzbeecbd6d442012-11-17 14:11:25 -0800229 kAllocGrowableList));
buzbeefa57c472012-11-21 12:06:18 -0800230 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800231#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800232 cu->mstats->list_sizes[g_list->kind] += sizeof(uintptr_t) * new_length;
233 cu->mstats->list_wasted[g_list->kind] +=
234 sizeof(uintptr_t) * g_list->num_allocated;
235 cu->mstats->list_grows[g_list->kind]++;
236 if (new_length > cu->mstats->list_max_elems[g_list->kind]) {
237 cu->mstats->list_max_elems[g_list->kind] = new_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700238 }
buzbee5abfa3e2012-01-31 17:01:43 -0800239#endif
buzbeefa57c472012-11-21 12:06:18 -0800240 g_list->num_allocated = new_length;
241 g_list->elem_list = new_array;
buzbee67bf8852011-08-17 17:51:35 -0700242}
243
244/* Insert a new element into the growable list */
buzbeefa57c472012-11-21 12:06:18 -0800245void InsertGrowableList(CompilationUnit* cu, GrowableList* g_list,
buzbeecbd6d442012-11-17 14:11:25 -0800246 uintptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700247{
buzbeefa57c472012-11-21 12:06:18 -0800248 DCHECK_NE(g_list->num_allocated, 0U);
249 if (g_list->num_used == g_list->num_allocated) {
250 ExpandGrowableList(cu, g_list);
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 }
buzbeefa57c472012-11-21 12:06:18 -0800252 g_list->elem_list[g_list->num_used++] = elem;
buzbee67bf8852011-08-17 17:51:35 -0700253}
254
buzbee5abfa3e2012-01-31 17:01:43 -0800255/* Delete an element from a growable list. Element must be present */
buzbeefa57c472012-11-21 12:06:18 -0800256void DeleteGrowableList(GrowableList* g_list, uintptr_t elem)
buzbee5abfa3e2012-01-31 17:01:43 -0800257{
Bill Buzbeea114add2012-05-03 15:00:40 -0700258 bool found = false;
buzbeefa57c472012-11-21 12:06:18 -0800259 for (unsigned int i = 0; i < g_list->num_used; i++) {
260 if (!found && g_list->elem_list[i] == elem) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 found = true;
buzbee5abfa3e2012-01-31 17:01:43 -0800262 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 if (found) {
buzbeefa57c472012-11-21 12:06:18 -0800264 g_list->elem_list[i] = g_list->elem_list[i+1];
Bill Buzbeea114add2012-05-03 15:00:40 -0700265 }
266 }
267 DCHECK_EQ(found, true);
buzbeefa57c472012-11-21 12:06:18 -0800268 g_list->num_used--;
buzbee5abfa3e2012-01-31 17:01:43 -0800269}
270
buzbeefa57c472012-11-21 12:06:18 -0800271void GrowableListIteratorInit(GrowableList* g_list,
Bill Buzbeea114add2012-05-03 15:00:40 -0700272 GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700273{
buzbeefa57c472012-11-21 12:06:18 -0800274 iterator->list = g_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700275 iterator->idx = 0;
buzbeefa57c472012-11-21 12:06:18 -0800276 iterator->size = g_list->num_used;
buzbee67bf8852011-08-17 17:51:35 -0700277}
278
buzbee52a77fc2012-11-20 19:50:46 -0800279uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700280{
buzbeefa57c472012-11-21 12:06:18 -0800281 DCHECK_EQ(iterator->size, iterator->list->num_used);
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 if (iterator->idx == iterator->size) return 0;
buzbeefa57c472012-11-21 12:06:18 -0800283 return iterator->list->elem_list[iterator->idx++];
buzbee67bf8852011-08-17 17:51:35 -0700284}
285
buzbeefa57c472012-11-21 12:06:18 -0800286uintptr_t GrowableListGetElement(const GrowableList* g_list, size_t idx)
buzbee67bf8852011-08-17 17:51:35 -0700287{
buzbeefa57c472012-11-21 12:06:18 -0800288 DCHECK_LT(idx, g_list->num_used);
289 return g_list->elem_list[idx];
buzbee67bf8852011-08-17 17:51:35 -0700290}
291
buzbee5abfa3e2012-01-31 17:01:43 -0800292#ifdef WITH_MEMSTATS
293/* Dump memory usage stats */
buzbeefa57c472012-11-21 12:06:18 -0800294void DumpMemStats(CompilationUnit* cu)
buzbee5abfa3e2012-01-31 17:01:43 -0800295{
buzbeeeaf09bc2012-11-15 14:51:41 -0800296 uint32_t total = 0;
Bill Buzbeea114add2012-05-03 15:00:40 -0700297 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800298 total += cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 }
300 if (total > (10 * 1024 * 1024)) {
301 LOG(INFO) << "MEMUSAGE: " << total << " : "
buzbeefa57c472012-11-21 12:06:18 -0800302 << PrettyMethod(cu->method_idx, *cu->dex_file);
buzbee311ca162013-02-28 15:56:43 -0800303 LOG(INFO) << "insns_size: " << cu->code_item->insns_size_in_code_units_;
buzbeefa57c472012-11-21 12:06:18 -0800304 if (cu->disable_dataflow) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700305 LOG(INFO) << " ** Dataflow disabled ** ";
buzbee5abfa3e2012-01-31 17:01:43 -0800306 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700307 LOG(INFO) << "===== Overall allocations";
308 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800309 LOG(INFO) << alloc_names[i] << std::setw(10) <<
310 cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700311 }
312 LOG(INFO) << "===== GrowableList allocations";
313 for (int i = 0; i < kNumListKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800314 LOG(INFO) << list_names[i]
315 << " S:" << cu->mstats->list_sizes[i]
316 << ", W:" << cu->mstats->list_wasted[i]
317 << ", G:" << cu->mstats->list_grows[i]
318 << ", E:" << cu->mstats->list_max_elems[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700319 }
320 LOG(INFO) << "===== GrowableBitMap allocations";
321 for (int i = 0; i < kNumBitMapKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800322 LOG(INFO) << bit_map_names[i]
323 << " S:" << cu->mstats->bit_map_sizes[i]
324 << ", W:" << cu->mstats->bit_map_wasted[i]
325 << ", G:" << cu->mstats->bit_map_grows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800326 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700327 }
buzbee5abfa3e2012-01-31 17:01:43 -0800328}
329#endif
330
buzbee67bf8852011-08-17 17:51:35 -0700331/* Debug Utility - dump a compilation unit */
buzbeefa57c472012-11-21 12:06:18 -0800332void DumpCompilationUnit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700333{
Bill Buzbeea114add2012-05-03 15:00:40 -0700334 BasicBlock* bb;
buzbeefa57c472012-11-21 12:06:18 -0800335 const char* block_type_names[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700336 "Entry Block",
337 "Code Block",
338 "Exit Block",
339 "Exception Handling",
340 "Catch Block"
341 };
buzbee67bf8852011-08-17 17:51:35 -0700342
buzbeefa57c472012-11-21 12:06:18 -0800343 LOG(INFO) << "Compiling " << PrettyMethod(cu->method_idx, *cu->dex_file);
344 LOG(INFO) << cu->insns << " insns";
buzbee311ca162013-02-28 15:56:43 -0800345 LOG(INFO) << cu->mir_graph->GetNumBlocks() << " blocks in total";
346 GrowableListIterator iterator = cu->mir_graph->GetBasicBlockIterator();
buzbee67bf8852011-08-17 17:51:35 -0700347
Bill Buzbeea114add2012-05-03 15:00:40 -0700348 while (true) {
buzbee52a77fc2012-11-20 19:50:46 -0800349 bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 if (bb == NULL) break;
351 LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
352 bb->id,
buzbeefa57c472012-11-21 12:06:18 -0800353 block_type_names[bb->block_type],
354 bb->start_offset,
355 bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
356 bb->last_mir_insn ? "" : " empty");
Bill Buzbeea114add2012-05-03 15:00:40 -0700357 if (bb->taken) {
358 LOG(INFO) << " Taken branch: block " << bb->taken->id
buzbeefa57c472012-11-21 12:06:18 -0800359 << "(0x" << std::hex << bb->taken->start_offset << ")";
buzbee67bf8852011-08-17 17:51:35 -0700360 }
buzbeefa57c472012-11-21 12:06:18 -0800361 if (bb->fall_through) {
362 LOG(INFO) << " Fallthrough : block " << bb->fall_through->id
363 << " (0x" << std::hex << bb->fall_through->start_offset << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700364 }
365 }
buzbee67bf8852011-08-17 17:51:35 -0700366}
367
buzbeefa57c472012-11-21 12:06:18 -0800368static uint32_t check_masks[32] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700369 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
370 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
371 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
372 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
373 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
374 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
375 0x40000000, 0x80000000 };
buzbee67bc2362011-10-11 18:08:40 -0700376
buzbee67bf8852011-08-17 17:51:35 -0700377/*
378 * Allocate a bit vector with enough space to hold at least the specified
379 * number of bits.
380 *
381 * NOTE: memory is allocated from the compiler arena.
382 */
buzbeefa57c472012-11-21 12:06:18 -0800383ArenaBitVector* AllocBitVector(CompilationUnit* cu,
384 unsigned int start_bits, bool expandable,
385 oat_bit_map_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700386{
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 ArenaBitVector* bv;
388 unsigned int count;
buzbee67bf8852011-08-17 17:51:35 -0700389
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700391
buzbeefa57c472012-11-21 12:06:18 -0800392 bv = static_cast<ArenaBitVector*>(NewMem(cu, sizeof(ArenaBitVector), false,
buzbeecbd6d442012-11-17 14:11:25 -0800393 kAllocGrowableBitMap));
buzbee67bf8852011-08-17 17:51:35 -0700394
buzbeefa57c472012-11-21 12:06:18 -0800395 count = (start_bits + 31) >> 5;
buzbee67bf8852011-08-17 17:51:35 -0700396
buzbeefa57c472012-11-21 12:06:18 -0800397 bv->storage_size = count;
Bill Buzbeea114add2012-05-03 15:00:40 -0700398 bv->expandable = expandable;
buzbeefa57c472012-11-21 12:06:18 -0800399 bv->storage = static_cast<uint32_t*>(NewMem(cu, count * sizeof(uint32_t), true,
buzbeeeaf09bc2012-11-15 14:51:41 -0800400 kAllocGrowableBitMap));
buzbee5abfa3e2012-01-31 17:01:43 -0800401#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 bv->kind = kind;
buzbeefa57c472012-11-21 12:06:18 -0800403 cu->mstats->bit_map_sizes[kind] += count * sizeof(uint32_t);
buzbee5abfa3e2012-01-31 17:01:43 -0800404#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 return bv;
buzbee67bf8852011-08-17 17:51:35 -0700406}
407
408/*
409 * Determine whether or not the specified bit is set.
410 */
buzbeefa57c472012-11-21 12:06:18 -0800411bool IsBitSet(const ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700412{
buzbeefa57c472012-11-21 12:06:18 -0800413 DCHECK_LT(num, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700414
buzbeefa57c472012-11-21 12:06:18 -0800415 unsigned int val = p_bits->storage[num >> 5] & check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 return (val != 0);
buzbee67bf8852011-08-17 17:51:35 -0700417}
418
419/*
420 * Mark all bits bit as "clear".
421 */
buzbeefa57c472012-11-21 12:06:18 -0800422void ClearAllBits(ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700423{
buzbeefa57c472012-11-21 12:06:18 -0800424 unsigned int count = p_bits->storage_size;
425 memset(p_bits->storage, 0, count * sizeof(uint32_t));
buzbee67bf8852011-08-17 17:51:35 -0700426}
427
428/*
429 * Mark the specified bit as "set".
430 *
431 * Returns "false" if the bit is outside the range of the vector and we're
432 * not allowed to expand.
433 *
434 * NOTE: memory is allocated from the compiler arena.
435 */
buzbeefa57c472012-11-21 12:06:18 -0800436bool SetBit(CompilationUnit* cu, ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700437{
buzbeefa57c472012-11-21 12:06:18 -0800438 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
439 if (!p_bits->expandable) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 LOG(FATAL) << "Can't expand";
buzbee67bf8852011-08-17 17:51:35 -0700441 }
442
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 /* Round up to word boundaries for "num+1" bits */
buzbeefa57c472012-11-21 12:06:18 -0800444 unsigned int new_size = (num + 1 + 31) >> 5;
445 DCHECK_GT(new_size, p_bits->storage_size);
446 uint32_t *new_storage = static_cast<uint32_t*>(NewMem(cu, new_size * sizeof(uint32_t), false,
buzbeeeaf09bc2012-11-15 14:51:41 -0800447 kAllocGrowableBitMap));
buzbeefa57c472012-11-21 12:06:18 -0800448 memcpy(new_storage, p_bits->storage, p_bits->storage_size * sizeof(uint32_t));
449 memset(&new_storage[p_bits->storage_size], 0,
450 (new_size - p_bits->storage_size) * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700451#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800452 cu->mstats->bit_map_wasted[p_bits->kind] +=
453 p_bits->storage_size * sizeof(uint32_t);
454 cu->mstats->bit_map_sizes[p_bits->kind] += new_size * sizeof(uint32_t);
455 cu->mstats->bit_map_grows[p_bits->kind]++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700456#endif
buzbeefa57c472012-11-21 12:06:18 -0800457 p_bits->storage = new_storage;
458 p_bits->storage_size = new_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700459 }
460
buzbeefa57c472012-11-21 12:06:18 -0800461 p_bits->storage[num >> 5] |= check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700462 return true;
buzbee67bf8852011-08-17 17:51:35 -0700463}
464
465/*
466 * Mark the specified bit as "unset".
467 *
468 * Returns "false" if the bit is outside the range of the vector and we're
469 * not allowed to expand.
470 *
471 * NOTE: memory is allocated from the compiler arena.
472 */
buzbeefa57c472012-11-21 12:06:18 -0800473bool ClearBit(ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700474{
buzbeefa57c472012-11-21 12:06:18 -0800475 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
477 }
buzbee67bf8852011-08-17 17:51:35 -0700478
buzbeefa57c472012-11-21 12:06:18 -0800479 p_bits->storage[num >> 5] &= ~check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700480 return true;
buzbee67bf8852011-08-17 17:51:35 -0700481}
482
buzbee67bf8852011-08-17 17:51:35 -0700483/* Initialize the iterator structure */
buzbeefa57c472012-11-21 12:06:18 -0800484void BitVectorIteratorInit(ArenaBitVector* p_bits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700485 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700486{
buzbeefa57c472012-11-21 12:06:18 -0800487 iterator->p_bits = p_bits;
488 iterator->bit_size = p_bits->storage_size * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700489 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700490}
491
492/*
493 * If the vector sizes don't match, log an error and abort.
494 */
buzbee52a77fc2012-11-20 19:50:46 -0800495static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700496{
buzbeefa57c472012-11-21 12:06:18 -0800497 if (bv1->storage_size != bv2->storage_size) {
498 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storage_size
499 << ", " << bv2->storage_size << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 }
buzbee67bf8852011-08-17 17:51:35 -0700501}
502
503/*
504 * Copy a whole vector to the other. Only do that when the both vectors have
505 * the same size.
506 */
buzbee52a77fc2012-11-20 19:50:46 -0800507void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
buzbee67bf8852011-08-17 17:51:35 -0700508{
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 /* if dest is expandable and < src, we could expand dest to match */
buzbee52a77fc2012-11-20 19:50:46 -0800510 CheckSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700511
buzbeefa57c472012-11-21 12:06:18 -0800512 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storage_size);
buzbee67bf8852011-08-17 17:51:35 -0700513}
514
515/*
516 * Intersect two bit vectors and store the result to the dest vector.
517 */
518
buzbee52a77fc2012-11-20 19:50:46 -0800519bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700520 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700521{
Bill Buzbeea114add2012-05-03 15:00:40 -0700522 DCHECK(src1 != NULL);
523 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800524 if (dest->storage_size != src1->storage_size ||
525 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700526 dest->expandable != src1->expandable ||
527 dest->expandable != src2->expandable)
528 return false;
buzbee67bf8852011-08-17 17:51:35 -0700529
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800531 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700532 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
533 }
534 return true;
buzbee67bf8852011-08-17 17:51:35 -0700535}
536
537/*
538 * Unify two bit vectors and store the result to the dest vector.
539 */
buzbee52a77fc2012-11-20 19:50:46 -0800540bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700541 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700542{
Bill Buzbeea114add2012-05-03 15:00:40 -0700543 DCHECK(src1 != NULL);
544 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800545 if (dest->storage_size != src1->storage_size ||
546 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700547 dest->expandable != src1->expandable ||
548 dest->expandable != src2->expandable)
549 return false;
buzbee67bf8852011-08-17 17:51:35 -0700550
Bill Buzbeea114add2012-05-03 15:00:40 -0700551 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800552 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700553 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
554 }
555 return true;
buzbee67bf8852011-08-17 17:51:35 -0700556}
557
558/*
buzbeee1965672012-03-11 18:39:19 -0700559 * Return true if any bits collide. Vectors must be same size.
560 */
buzbee52a77fc2012-11-20 19:50:46 -0800561bool TestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700562 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700563{
buzbeefa57c472012-11-21 12:06:18 -0800564 DCHECK_EQ(src1->storage_size, src2->storage_size);
565 for (uint32_t idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700566 if (src1->storage[idx] & src2->storage[idx]) return true;
567 }
568 return false;
buzbeee1965672012-03-11 18:39:19 -0700569}
570
571/*
buzbee67bf8852011-08-17 17:51:35 -0700572 * Compare two bit vectors and return true if difference is seen.
573 */
buzbee52a77fc2012-11-20 19:50:46 -0800574bool CompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700575 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700576{
buzbeefa57c472012-11-21 12:06:18 -0800577 if (src1->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700578 src1->expandable != src2->expandable)
579 return true;
buzbee67bf8852011-08-17 17:51:35 -0700580
Bill Buzbeea114add2012-05-03 15:00:40 -0700581 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800582 for (idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 if (src1->storage[idx] != src2->storage[idx]) return true;
584 }
585 return false;
buzbee67bf8852011-08-17 17:51:35 -0700586}
587
588/*
589 * Count the number of bits that are set.
590 */
buzbeefa57c472012-11-21 12:06:18 -0800591int CountSetBits(const ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700592{
Bill Buzbeea114add2012-05-03 15:00:40 -0700593 unsigned int word;
594 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700595
buzbeefa57c472012-11-21 12:06:18 -0800596 for (word = 0; word < p_bits->storage_size; word++) {
597 uint32_t val = p_bits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700598
Bill Buzbeea114add2012-05-03 15:00:40 -0700599 if (val != 0) {
600 if (val == 0xffffffff) {
601 count += 32;
602 } else {
603 /* count the number of '1' bits */
604 while (val != 0) {
605 val &= val - 1;
606 count++;
buzbee67bf8852011-08-17 17:51:35 -0700607 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700608 }
buzbee67bf8852011-08-17 17:51:35 -0700609 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700610 }
buzbee67bf8852011-08-17 17:51:35 -0700611
Bill Buzbeea114add2012-05-03 15:00:40 -0700612 return count;
buzbee67bf8852011-08-17 17:51:35 -0700613}
614
615/* Return the next position set to 1. -1 means end-of-element reached */
buzbee52a77fc2012-11-20 19:50:46 -0800616int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700617{
buzbeefa57c472012-11-21 12:06:18 -0800618 ArenaBitVector* p_bits = iterator->p_bits;
619 uint32_t bit_index = iterator->idx;
620 uint32_t bit_size = iterator->bit_size;
buzbee67bf8852011-08-17 17:51:35 -0700621
buzbeefa57c472012-11-21 12:06:18 -0800622 DCHECK_EQ(bit_size, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700623
buzbeefa57c472012-11-21 12:06:18 -0800624 if (bit_index >= bit_size) return -1;
buzbee5b537102012-01-17 17:33:47 -0800625
buzbeefa57c472012-11-21 12:06:18 -0800626 uint32_t word_index = bit_index >> 5;
627 uint32_t end_word_index = bit_size >> 5;
628 uint32_t* storage = p_bits->storage;
629 uint32_t word = storage[word_index++];
buzbee5b537102012-01-17 17:33:47 -0800630
Bill Buzbeea114add2012-05-03 15:00:40 -0700631 // Mask out any bits in the first word we've already considered
buzbeefa57c472012-11-21 12:06:18 -0800632 word &= ~((1 << (bit_index & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800633
buzbeefa57c472012-11-21 12:06:18 -0800634 for (; word_index <= end_word_index;) {
635 uint32_t bit_pos = bit_index & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700636 if (word == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800637 bit_index += (32 - bit_pos);
638 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700639 continue;
buzbee67bf8852011-08-17 17:51:35 -0700640 }
buzbeefa57c472012-11-21 12:06:18 -0800641 for (; bit_pos < 32; bit_pos++) {
642 if (word & (1 << bit_pos)) {
643 iterator->idx = bit_index + 1;
644 return bit_index;
Bill Buzbeea114add2012-05-03 15:00:40 -0700645 }
buzbeefa57c472012-11-21 12:06:18 -0800646 bit_index++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700647 }
buzbeefa57c472012-11-21 12:06:18 -0800648 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700649 }
buzbeefa57c472012-11-21 12:06:18 -0800650 iterator->idx = iterator->bit_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700651 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700652}
653
654/*
655 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
656 * since there might be unused bits - setting those to one will confuse the
657 * iterator.
658 */
buzbeefa57c472012-11-21 12:06:18 -0800659void SetInitialBits(ArenaBitVector* p_bits, unsigned int num_bits)
buzbee67bf8852011-08-17 17:51:35 -0700660{
Bill Buzbeea114add2012-05-03 15:00:40 -0700661 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800662 DCHECK_LE(((num_bits + 31) >> 5), p_bits->storage_size);
663 for (idx = 0; idx < (num_bits >> 5); idx++) {
664 p_bits->storage[idx] = -1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700665 }
buzbeefa57c472012-11-21 12:06:18 -0800666 unsigned int rem_num_bits = num_bits & 0x1f;
667 if (rem_num_bits) {
668 p_bits->storage[idx] = (1 << rem_num_bits) - 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700669 }
buzbee67bf8852011-08-17 17:51:35 -0700670}
671
buzbee52a77fc2012-11-20 19:50:46 -0800672void GetBlockName(BasicBlock* bb, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700673{
buzbeefa57c472012-11-21 12:06:18 -0800674 switch (bb->block_type) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700675 case kEntryBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700676 snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 break;
678 case kExitBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700679 snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700680 break;
681 case kDalvikByteCode:
buzbeefa57c472012-11-21 12:06:18 -0800682 snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700683 break;
684 case kExceptionHandling:
buzbeefa57c472012-11-21 12:06:18 -0800685 snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700686 bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700687 break;
688 default:
buzbeed8506212012-12-20 14:15:05 -0800689 snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700690 break;
691 }
buzbee67bf8852011-08-17 17:51:35 -0700692}
buzbeeed3e9302011-09-23 17:34:19 -0700693
buzbeefa57c472012-11-21 12:06:18 -0800694const char* GetShortyFromTargetIdx(CompilationUnit *cu, int target_idx)
buzbeeed3e9302011-09-23 17:34:19 -0700695{
buzbeefa57c472012-11-21 12:06:18 -0800696 const DexFile::MethodId& method_id = cu->dex_file->GetMethodId(target_idx);
697 return cu->dex_file->GetShorty(method_id.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700698}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800699
buzbee02031b12012-11-23 09:41:35 -0800700/* Allocate a new basic block */
701BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
702{
703 BasicBlock* bb = static_cast<BasicBlock*>(NewMem(cu, sizeof(BasicBlock), true, kAllocBB));
704 bb->block_type = block_type;
705 bb->id = block_id;
706 bb->predecessors = static_cast<GrowableList*>
707 (NewMem(cu, sizeof(GrowableList), false, kAllocPredecessors));
708 CompilerInitGrowableList(cu, bb->predecessors,
709 (block_type == kExitBlock) ? 2048 : 2,
710 kListPredecessors);
711 cu->block_id_map.Put(block_id, block_id);
712 return bb;
713}
714
715/* Insert an MIR instruction to the end of a basic block */
716void AppendMIR(BasicBlock* bb, MIR* mir)
717{
718 if (bb->first_mir_insn == NULL) {
719 DCHECK(bb->last_mir_insn == NULL);
720 bb->last_mir_insn = bb->first_mir_insn = mir;
721 mir->prev = mir->next = NULL;
722 } else {
723 bb->last_mir_insn->next = mir;
724 mir->prev = bb->last_mir_insn;
725 mir->next = NULL;
726 bb->last_mir_insn = mir;
727 }
728}
729
730/* Insert an MIR instruction to the head of a basic block */
731void PrependMIR(BasicBlock* bb, MIR* mir)
732{
733 if (bb->first_mir_insn == NULL) {
734 DCHECK(bb->last_mir_insn == NULL);
735 bb->last_mir_insn = bb->first_mir_insn = mir;
736 mir->prev = mir->next = NULL;
737 } else {
738 bb->first_mir_insn->prev = mir;
739 mir->next = bb->first_mir_insn;
740 mir->prev = NULL;
741 bb->first_mir_insn = mir;
742 }
743}
744
745/* Insert a MIR instruction after the specified MIR */
746void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir)
747{
748 new_mir->prev = current_mir;
749 new_mir->next = current_mir->next;
750 current_mir->next = new_mir;
751
752 if (new_mir->next) {
753 /* Is not the last MIR in the block */
754 new_mir->next->prev = new_mir;
755 } else {
756 /* Is the last MIR in the block */
757 bb->last_mir_insn = new_mir;
758 }
759}
760
761/*
762 * Append an LIR instruction to the LIR list maintained by a compilation
763 * unit
764 */
765void AppendLIR(CompilationUnit *cu, LIR* lir)
766{
767 if (cu->first_lir_insn == NULL) {
768 DCHECK(cu->last_lir_insn == NULL);
769 cu->last_lir_insn = cu->first_lir_insn = lir;
770 lir->prev = lir->next = NULL;
771 } else {
772 cu->last_lir_insn->next = lir;
773 lir->prev = cu->last_lir_insn;
774 lir->next = NULL;
775 cu->last_lir_insn = lir;
776 }
777}
778
779/*
780 * Insert an LIR instruction before the current instruction, which cannot be the
781 * first instruction.
782 *
783 * prev_lir <-> new_lir <-> current_lir
784 */
785void InsertLIRBefore(LIR* current_lir, LIR* new_lir)
786{
787 DCHECK(current_lir->prev != NULL);
788 LIR *prev_lir = current_lir->prev;
789
790 prev_lir->next = new_lir;
791 new_lir->prev = prev_lir;
792 new_lir->next = current_lir;
793 current_lir->prev = new_lir;
794}
795
796/*
797 * Insert an LIR instruction after the current instruction, which cannot be the
798 * first instruction.
799 *
800 * current_lir -> new_lir -> old_next
801 */
802void InsertLIRAfter(LIR* current_lir, LIR* new_lir)
803{
804 new_lir->prev = current_lir;
805 new_lir->next = current_lir->next;
806 current_lir->next = new_lir;
807 new_lir->next->prev = new_lir;
808}
809
buzbee311ca162013-02-28 15:56:43 -0800810/* Turn method name into a legal Linux file name */
811void ReplaceSpecialChars(std::string& str)
812{
813 static const struct { const char before; const char after; } match[] =
814 {{'/','-'}, {';','#'}, {' ','#'}, {'$','+'},
815 {'(','@'}, {')','@'}, {'<','='}, {'>','='}};
816 for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
817 std::replace(str.begin(), str.end(), match[i].before, match[i].after);
818 }
819}
820
821std::string GetSSAName(const CompilationUnit* cu, int ssa_reg)
822{
823 return StringPrintf("v%d_%d", cu->mir_graph->SRegToVReg(ssa_reg), cu->mir_graph->GetSSASubscript(ssa_reg));
824}
825
826// Similar to GetSSAName, but if ssa name represents an immediate show that as well.
827std::string GetSSANameWithConst(const CompilationUnit* cu, int ssa_reg, bool singles_only)
828{
829 if (cu->reg_location == NULL) {
830 // Pre-SSA - just use the standard name
831 return GetSSAName(cu, ssa_reg);
832 }
833 if (cu->mir_graph->IsConst(cu->reg_location[ssa_reg])) {
834 if (!singles_only && cu->reg_location[ssa_reg].wide) {
835 return StringPrintf("v%d_%d#0x%llx", cu->mir_graph->SRegToVReg(ssa_reg),
836 cu->mir_graph->GetSSASubscript(ssa_reg),
837 cu->mir_graph->ConstantValueWide(cu->reg_location[ssa_reg]));
838 } else {
839 return StringPrintf("v%d_%d#0x%x", cu->mir_graph->SRegToVReg(ssa_reg),
840 cu->mir_graph->GetSSASubscript(ssa_reg),
841 cu->mir_graph->ConstantValue(cu->reg_location[ssa_reg]));
842 }
843 } else {
844 return StringPrintf("v%d_%d", cu->mir_graph->SRegToVReg(ssa_reg),
845 cu->mir_graph->GetSSASubscript(ssa_reg));
846 }
847}
848
849char* GetDalvikDisassembly(CompilationUnit* cu, const MIR* mir)
850{
851 DecodedInstruction insn = mir->dalvikInsn;
852 std::string str;
853 int flags = 0;
854 int opcode = insn.opcode;
855 char* ret;
856 bool nop = false;
857 SSARepresentation* ssa_rep = mir->ssa_rep;
858 Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format
859 int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0;
860 int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0;
861
862 // Handle special cases.
863 if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) {
864 str.append(extended_mir_op_names[opcode - kMirOpFirst]);
865 str.append(": ");
866 // Recover the original Dex instruction
867 insn = mir->meta.throw_insn->dalvikInsn;
868 ssa_rep = mir->meta.throw_insn->ssa_rep;
869 defs = ssa_rep->num_defs;
870 uses = ssa_rep->num_uses;
871 opcode = insn.opcode;
872 } else if (opcode == kMirOpNop) {
873 str.append("[");
874 insn.opcode = mir->meta.original_opcode;
875 opcode = mir->meta.original_opcode;
876 nop = true;
877 }
878
879 if (opcode >= kMirOpFirst) {
880 str.append(extended_mir_op_names[opcode - kMirOpFirst]);
881 } else {
882 dalvik_format = Instruction::FormatOf(insn.opcode);
883 flags = Instruction::FlagsOf(insn.opcode);
884 str.append(Instruction::Name(insn.opcode));
885 }
886
887 if (opcode == kMirOpPhi) {
888 int* incoming = reinterpret_cast<int*>(insn.vB);
889 str.append(StringPrintf(" %s = (%s",
890 GetSSANameWithConst(cu, ssa_rep->defs[0], true).c_str(),
891 GetSSANameWithConst(cu, ssa_rep->uses[0], true).c_str()));
892 str.append(StringPrintf(":%d",incoming[0]));
893 int i;
894 for (i = 1; i < uses; i++) {
895 str.append(StringPrintf(", %s:%d",
896 GetSSANameWithConst(cu, ssa_rep->uses[i], true).c_str(),
897 incoming[i]));
898 }
899 str.append(")");
900 } else if ((flags & Instruction::kBranch) != 0) {
901 // For branches, decode the instructions to print out the branch targets.
902 int offset = 0;
903 switch (dalvik_format) {
904 case Instruction::k21t:
905 str.append(StringPrintf(" %s,", GetSSANameWithConst(cu, ssa_rep->uses[0], false).c_str()));
906 offset = insn.vB;
907 break;
908 case Instruction::k22t:
909 str.append(StringPrintf(" %s, %s,", GetSSANameWithConst(cu, ssa_rep->uses[0], false).c_str(),
910 GetSSANameWithConst(cu, ssa_rep->uses[1], false).c_str()));
911 offset = insn.vC;
912 break;
913 case Instruction::k10t:
914 case Instruction::k20t:
915 case Instruction::k30t:
916 offset = insn.vA;
917 break;
918 default:
919 LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode;
920 }
921 str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset,
922 offset > 0 ? '+' : '-', offset > 0 ? offset : -offset));
923 } else {
924 // For invokes-style formats, treat wide regs as a pair of singles
925 bool show_singles = ((dalvik_format == Instruction::k35c) ||
926 (dalvik_format == Instruction::k3rc));
927 if (defs != 0) {
928 str.append(StringPrintf(" %s", GetSSANameWithConst(cu, ssa_rep->defs[0], false).c_str()));
929 if (uses != 0) {
930 str.append(", ");
931 }
932 }
933 for (int i = 0; i < uses; i++) {
934 str.append(
935 StringPrintf(" %s", GetSSANameWithConst(cu, ssa_rep->uses[i], show_singles).c_str()));
936 if (!show_singles && (cu->reg_location != NULL) && cu->reg_location[i].wide) {
937 // For the listing, skip the high sreg.
938 i++;
939 }
940 if (i != (uses -1)) {
941 str.append(",");
942 }
943 }
944 switch (dalvik_format) {
945 case Instruction::k11n: // Add one immediate from vB
946 case Instruction::k21s:
947 case Instruction::k31i:
948 case Instruction::k21h:
949 str.append(StringPrintf(", #%d", insn.vB));
950 break;
951 case Instruction::k51l: // Add one wide immediate
952 str.append(StringPrintf(", #%lld", insn.vB_wide));
953 break;
954 case Instruction::k21c: // One register, one string/type/method index
955 case Instruction::k31c:
956 str.append(StringPrintf(", index #%d", insn.vB));
957 break;
958 case Instruction::k22c: // Two registers, one string/type/method index
959 str.append(StringPrintf(", index #%d", insn.vC));
960 break;
961 case Instruction::k22s: // Add one immediate from vC
962 case Instruction::k22b:
963 str.append(StringPrintf(", #%d", insn.vC));
964 break;
965 default:
966 ; // Nothing left to print
967 }
968 }
969 if (nop) {
970 str.append("]--optimized away");
971 }
972 int length = str.length() + 1;
973 ret = static_cast<char*>(NewMem(cu, length, false, kAllocDFInfo));
974 strncpy(ret, str.c_str(), length);
975 return ret;
976}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800977} // namespace art