/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Dalvik.h" #include "CompilerInternals.h" /* Allocate a new basic block */ BasicBlock *dvmCompilerNewBB(BBType blockType, int blockId) { BasicBlock *bb = (BasicBlock *)dvmCompilerNew(sizeof(BasicBlock), true); bb->blockType = blockType; bb->id = blockId; bb->predecessors = dvmCompilerAllocBitVector(blockId > 32 ? blockId : 32, true /* expandable */); return bb; } /* Insert an MIR instruction to the end of a basic block */ void dvmCompilerAppendMIR(BasicBlock *bb, MIR *mir) { if (bb->firstMIRInsn == NULL) { assert(bb->lastMIRInsn == NULL); bb->lastMIRInsn = bb->firstMIRInsn = mir; mir->prev = mir->next = NULL; } else { bb->lastMIRInsn->next = mir; mir->prev = bb->lastMIRInsn; mir->next = NULL; bb->lastMIRInsn = mir; } } /* Insert an MIR instruction to the head of a basic block */ void dvmCompilerPrependMIR(BasicBlock *bb, MIR *mir) { if (bb->firstMIRInsn == NULL) { assert(bb->lastMIRInsn == NULL); bb->lastMIRInsn = bb->firstMIRInsn = mir; mir->prev = mir->next = NULL; } else { bb->firstMIRInsn->prev = mir; mir->next = bb->firstMIRInsn; mir->prev = NULL; bb->firstMIRInsn = mir; } } /* Insert an MIR instruction after the specified MIR */ void dvmCompilerInsertMIRAfter(BasicBlock *bb, MIR *currentMIR, MIR *newMIR) { newMIR->prev = currentMIR; newMIR->next = currentMIR->next; currentMIR->next = newMIR; if (newMIR->next) { /* Is not the last MIR in the block */ newMIR->next->prev = newMIR; } else { /* Is the last MIR in the block */ bb->lastMIRInsn = newMIR; } } /* * Append an LIR instruction to the LIR list maintained by a compilation * unit */ void dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir) { if (cUnit->firstLIRInsn == NULL) { assert(cUnit->lastLIRInsn == NULL); cUnit->lastLIRInsn = cUnit->firstLIRInsn = lir; lir->prev = lir->next = NULL; } else { cUnit->lastLIRInsn->next = lir; lir->prev = cUnit->lastLIRInsn; lir->next = NULL; cUnit->lastLIRInsn = lir; } } /* * Insert an LIR instruction before the current instruction, which cannot be the * first instruction. * * prevLIR <-> newLIR <-> currentLIR */ void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR) { assert(currentLIR->prev != NULL); LIR *prevLIR = currentLIR->prev; prevLIR->next = newLIR; newLIR->prev = prevLIR; newLIR->next = currentLIR; currentLIR->prev = newLIR; } /* * Insert an LIR instruction after the current instruction, which cannot be the * first instruction. * * currentLIR -> newLIR -> oldNext */ void dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR) { newLIR->prev = currentLIR; newLIR->next = currentLIR->next; currentLIR->next = newLIR; newLIR->next->prev = newLIR; }