/* * Copyright (C) 2011 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" namespace art { static const char* gOpKindNames[kOpInvalid + 1] = { "OpMov", "OpMvn", "OpCmp", "OpLsl", "OpLsr", "OpAsr", "OpRor", "OpNot", "OpAnd", "OpOr", "OpXor", "OpNeg", "OpAdd", "OpAdc", "OpSub", "OpSbc", "OpRsub", "OpMul", "OpDiv", "OpRem", "OpBic", "OpCmn", "OpTst", "OpBkpt", "OpBlx", "OpPush", "OpPop", "Op2Char", "Op2Short", "Op2Byte", "OpCondBr", "OpUncondBr", "OpBx", "OpInvalid", }; std::ostream& operator<<(std::ostream& os, const OpKind& kind) { if (kind >= kOpMov && kind <= kOpInvalid) { os << gOpKindNames[kind]; } else { os << "Unknown Op " << static_cast(kind); } return os; } /* Allocate a new basic block */ BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId) { BasicBlock* bb = (BasicBlock* )oatNew(cUnit, sizeof(BasicBlock), true, kAllocBB); bb->blockType = blockType; bb->id = blockId; bb->predecessors = (GrowableList*) oatNew(cUnit, sizeof(GrowableList), false, kAllocPredecessors); oatInitGrowableList(cUnit, bb->predecessors, (blockType == kExitBlock) ? 2048 : 2, kListPredecessors); return bb; } /* Insert an MIR instruction to the end of a basic block */ void oatAppendMIR(BasicBlock* bb, MIR* mir) { if (bb->firstMIRInsn == NULL) { DCHECK(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 oatPrependMIR(BasicBlock* bb, MIR* mir) { if (bb->firstMIRInsn == NULL) { DCHECK(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 a MIR instruction after the specified MIR */ void oatInsertMIRAfter(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 oatAppendLIR(CompilationUnit *cUnit, LIR* lir) { if (cUnit->firstLIRInsn == NULL) { DCHECK(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 oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR) { DCHECK(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 oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR) { newLIR->prev = currentLIR; newLIR->next = currentLIR->next; currentLIR->next = newLIR; newLIR->next->prev = newLIR; } } // namespace art