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 */ 21BasicBlock *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 */ 32void 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 */ 47void 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 */ 62void 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 */ 81void 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 */ 101void 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 */ 118void 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