blob: c06693e80450ffc31d00cb2f07b92a1b129d0f2d [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 "compiler_internals.h"
namespace art {
/* Allocate a new basic block */
BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
{
BasicBlock* bb = static_cast<BasicBlock*>(NewMem(cu, sizeof(BasicBlock), true, kAllocBB));
bb->block_type = block_type;
bb->id = block_id;
bb->predecessors = static_cast<GrowableList*>
(NewMem(cu, sizeof(GrowableList), false, kAllocPredecessors));
CompilerInitGrowableList(cu, bb->predecessors,
(block_type == kExitBlock) ? 2048 : 2,
kListPredecessors);
cu->block_id_map.Put(block_id, block_id);
return bb;
}
/* Insert an MIR instruction to the end of a basic block */
void AppendMIR(BasicBlock* bb, MIR* mir)
{
if (bb->first_mir_insn == NULL) {
DCHECK(bb->last_mir_insn == NULL);
bb->last_mir_insn = bb->first_mir_insn = mir;
mir->prev = mir->next = NULL;
} else {
bb->last_mir_insn->next = mir;
mir->prev = bb->last_mir_insn;
mir->next = NULL;
bb->last_mir_insn = mir;
}
}
/* Insert an MIR instruction to the head of a basic block */
void PrependMIR(BasicBlock* bb, MIR* mir)
{
if (bb->first_mir_insn == NULL) {
DCHECK(bb->last_mir_insn == NULL);
bb->last_mir_insn = bb->first_mir_insn = mir;
mir->prev = mir->next = NULL;
} else {
bb->first_mir_insn->prev = mir;
mir->next = bb->first_mir_insn;
mir->prev = NULL;
bb->first_mir_insn = mir;
}
}
/* Insert a MIR instruction after the specified MIR */
void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir)
{
new_mir->prev = current_mir;
new_mir->next = current_mir->next;
current_mir->next = new_mir;
if (new_mir->next) {
/* Is not the last MIR in the block */
new_mir->next->prev = new_mir;
} else {
/* Is the last MIR in the block */
bb->last_mir_insn = new_mir;
}
}
/*
* Append an LIR instruction to the LIR list maintained by a compilation
* unit
*/
void AppendLIR(CompilationUnit *cu, LIR* lir)
{
if (cu->first_lir_insn == NULL) {
DCHECK(cu->last_lir_insn == NULL);
cu->last_lir_insn = cu->first_lir_insn = lir;
lir->prev = lir->next = NULL;
} else {
cu->last_lir_insn->next = lir;
lir->prev = cu->last_lir_insn;
lir->next = NULL;
cu->last_lir_insn = lir;
}
}
/*
* Insert an LIR instruction before the current instruction, which cannot be the
* first instruction.
*
* prev_lir <-> new_lir <-> current_lir
*/
void InsertLIRBefore(LIR* current_lir, LIR* new_lir)
{
DCHECK(current_lir->prev != NULL);
LIR *prev_lir = current_lir->prev;
prev_lir->next = new_lir;
new_lir->prev = prev_lir;
new_lir->next = current_lir;
current_lir->prev = new_lir;
}
/*
* Insert an LIR instruction after the current instruction, which cannot be the
* first instruction.
*
* current_lir -> new_lir -> old_next
*/
void InsertLIRAfter(LIR* current_lir, LIR* new_lir)
{
new_lir->prev = current_lir;
new_lir->next = current_lir->next;
current_lir->next = new_lir;
new_lir->next->prev = new_lir;
}
} // namespace art