1 /* 2 * Copyright (C) 2009 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 17 #include "Dalvik.h" 18 #include "CompilerInternals.h" 19 20 /* Allocate a new basic block */ 21 BasicBlock *dvmCompilerNewBB(BBType blockType, int blockId) 22 { 23 BasicBlock *bb = (BasicBlock *)dvmCompilerNew(sizeof(BasicBlock), true); 24 bb->blockType = blockType; 25 bb->id = blockId; 26 bb->predecessors = dvmCompilerAllocBitVector(blockId > 32 ? blockId : 32, 27 true /* expandable */); 28 return bb; 29 } 30 31 /* Insert an MIR instruction to the end of a basic block */ 32 void dvmCompilerAppendMIR(BasicBlock *bb, MIR *mir) 33 { 34 if (bb->firstMIRInsn == NULL) { 35 assert(bb->lastMIRInsn == NULL); 36 bb->lastMIRInsn = bb->firstMIRInsn = mir; 37 mir->prev = mir->next = NULL; 38 } else { 39 bb->lastMIRInsn->next = mir; 40 mir->prev = bb->lastMIRInsn; 41 mir->next = NULL; 42 bb->lastMIRInsn = mir; 43 } 44 } 45 46 /* Insert an MIR instruction to the head of a basic block */ 47 void dvmCompilerPrependMIR(BasicBlock *bb, MIR *mir) 48 { 49 if (bb->firstMIRInsn == NULL) { 50 assert(bb->lastMIRInsn == NULL); 51 bb->lastMIRInsn = bb->firstMIRInsn = mir; 52 mir->prev = mir->next = NULL; 53 } else { 54 bb->firstMIRInsn->prev = mir; 55 mir->next = bb->firstMIRInsn; 56 mir->prev = NULL; 57 bb->firstMIRInsn = mir; 58 } 59 } 60 61 /* Insert an MIR instruction after the specified MIR */ 62 void dvmCompilerInsertMIRAfter(BasicBlock *bb, MIR *currentMIR, MIR *newMIR) 63 { 64 newMIR->prev = currentMIR; 65 newMIR->next = currentMIR->next; 66 currentMIR->next = newMIR; 67 68 if (newMIR->next) { 69 /* Is not the last MIR in the block */ 70 newMIR->next->prev = newMIR; 71 } else { 72 /* Is the last MIR in the block */ 73 bb->lastMIRInsn = newMIR; 74 } 75 } 76 77 /* 78 * Append an LIR instruction to the LIR list maintained by a compilation 79 * unit 80 */ 81 void dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir) 82 { 83 if (cUnit->firstLIRInsn == NULL) { 84 assert(cUnit->lastLIRInsn == NULL); 85 cUnit->lastLIRInsn = cUnit->firstLIRInsn = lir; 86 lir->prev = lir->next = NULL; 87 } else { 88 cUnit->lastLIRInsn->next = lir; 89 lir->prev = cUnit->lastLIRInsn; 90 lir->next = NULL; 91 cUnit->lastLIRInsn = lir; 92 } 93 } 94 95 /* 96 * Insert an LIR instruction before the current instruction, which cannot be the 97 * first instruction. 98 * 99 * prevLIR <-> newLIR <-> currentLIR 100 */ 101 void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR) 102 { 103 assert(currentLIR->prev != NULL); 104 LIR *prevLIR = currentLIR->prev; 105 106 prevLIR->next = newLIR; 107 newLIR->prev = prevLIR; 108 newLIR->next = currentLIR; 109 currentLIR->prev = newLIR; 110 } 111 112 /* 113 * Insert an LIR instruction after the current instruction, which cannot be the 114 * first instruction. 115 * 116 * currentLIR -> newLIR -> oldNext 117 */ 118 void dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR) 119 { 120 newLIR->prev = currentLIR; 121 newLIR->next = currentLIR->next; 122 currentLIR->next = newLIR; 123 newLIR->next->prev = newLIR; 124 } 125