blob: d1ba45c18c01d350c67dde0fc893d3c846627324 [file] [log] [blame]
/*
* 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<int>(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