/*
 * 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 {

const char* extended_mir_op_names[kMirOpLast - kMirOpFirst] = {
  "Phi",
  "Copy",
  "FusedCmplFloat",
  "FusedCmpgFloat",
  "FusedCmplDouble",
  "FusedCmpgDouble",
  "FusedCmpLong",
  "Nop",
  "OpNullCheck",
  "OpRangeCheck",
  "OpDivZeroCheck",
  "Check1",
  "Check2",
};

#ifdef WITH_MEMSTATS
struct Memstats {
  uint32_t alloc_stats[kNumAllocKinds];
  int list_sizes[kNumListKinds];
  int list_wasted[kNumListKinds];
  int list_grows[kNumListKinds];
  int list_max_elems[kNumListKinds];
  int bit_map_sizes[kNumBitMapKinds];
  int bit_map_wasted[kNumBitMapKinds];
  int bit_map_grows[kNumBitMapKinds];
};

const char* alloc_names[kNumAllocKinds] = {
  "Misc       ",
  "BasicBlock ",
  "LIR        ",
  "MIR        ",
  "DataFlow   ",
  "GrowList   ",
  "GrowBitMap ",
  "Dalvik2SSA ",
  "DebugInfo  ",
  "Successor  ",
  "RegAlloc   ",
  "Data       ",
  "Preds      ",
};

const char* list_names[kNumListKinds] = {
  "Misc                  ",
  "block_list             ",
  "SSAtoDalvik           ",
  "dfs_order              ",
  "dfs_post_order          ",
  "dom_post_order_traversal ",
  "throw_launch_pads       ",
  "suspend_launch_pads     ",
  "switch_tables          ",
  "fill_array_data         ",
  "SuccessorBlocks       ",
  "Predecessors          ",
};

const char* bit_map_names[kNumBitMapKinds] = {
  "Misc                  ",
  "Use                   ",
  "Def                   ",
  "LiveIn                ",
  "BlockMatrix           ",
  "Dominators            ",
  "IDominated            ",
  "DomFrontier           ",
  "Phi                   ",
  "TmpBlocks             ",
  "InputBlocks           ",
  "RegisterV             ",
  "TempSSARegisterV      ",
  "Null Check            ",
  "TmpBlockV             ",
  "Predecessors          ",
};
#endif

#define kArenaBitVectorGrowth    4   /* increase by 4 uint32_ts when limit hit */

/* Allocate the initial memory block for arena-based allocation */
bool HeapInit(CompilationUnit* cu)
{
  DCHECK(cu->arena_head == NULL);
  cu->arena_head =
      static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE));
  if (cu->arena_head == NULL) {
    LOG(FATAL) << "No memory left to create compiler heap memory";
  }
  cu->arena_head->block_size = ARENA_DEFAULT_SIZE;
  cu->current_arena = cu->arena_head;
  cu->current_arena->bytes_allocated = 0;
  cu->current_arena->next = NULL;
  cu->num_arena_blocks = 1;
#ifdef WITH_MEMSTATS
  cu->mstats = (Memstats*) NewMem(cu, sizeof(Memstats), true,
                   kAllocDebugInfo);
#endif
  return true;
}

/* Arena-based malloc for compilation tasks */
void* NewMem(CompilationUnit* cu, size_t size, bool zero, oat_alloc_kind kind)
{
  size = (size + 3) & ~3;
#ifdef WITH_MEMSTATS
  if (cu->mstats != NULL) {
    cu->mstats->alloc_stats[kind] += size;
  }
#endif
retry:
  /* Normal case - space is available in the current page */
  if (size + cu->current_arena->bytes_allocated <=
    cu->current_arena->block_size) {
    void *ptr;
    ptr = &cu->current_arena->ptr[cu->current_arena->bytes_allocated];
    cu->current_arena->bytes_allocated += size;
    if (zero) {
      memset(ptr, 0, size);
    }
    return ptr;
  } else {
    /*
     * See if there are previously allocated arena blocks before the last
     * reset
     */
    if (cu->current_arena->next) {
        cu->current_arena = cu->current_arena->next;
        cu->current_arena->bytes_allocated = 0;
        goto retry;
    }

    size_t block_size = (size < ARENA_DEFAULT_SIZE) ?  ARENA_DEFAULT_SIZE : size;
    /* Time to allocate a new arena */
    ArenaMemBlock *new_arena =
        static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + block_size));
    if (new_arena == NULL) {
      LOG(FATAL) << "Arena allocation failure";
    }
    new_arena->block_size = block_size;
    new_arena->bytes_allocated = 0;
    new_arena->next = NULL;
    cu->current_arena->next = new_arena;
    cu->current_arena = new_arena;
    cu->num_arena_blocks++;
    if (cu->num_arena_blocks > 20000) {
      LOG(INFO) << "Total arena pages: " << cu->num_arena_blocks;
    }
    goto retry;
  }
}

/* Reclaim all the arena blocks allocated so far */
void ArenaReset(CompilationUnit* cu)
{
  ArenaMemBlock* head = cu->arena_head;
  while (head != NULL) {
    ArenaMemBlock* p = head;
    head = head->next;
    free(p);
  }
  cu->arena_head = NULL;
  cu->current_arena = NULL;
}

/* Growable List initialization */
void CompilerInitGrowableList(CompilationUnit* cu, GrowableList* g_list,
                       size_t init_length, oat_list_kind kind)
{
  g_list->num_allocated = init_length;
  g_list->num_used = 0;
  g_list->elem_list = static_cast<uintptr_t *>(NewMem(cu, sizeof(intptr_t) * init_length,
                                             true, kAllocGrowableList));
#ifdef WITH_MEMSTATS
  cu->mstats->list_sizes[kind] += sizeof(uintptr_t) * init_length;
  g_list->kind = kind;
  if (static_cast<int>(init_length) > cu->mstats->list_max_elems[kind]) {
    cu->mstats->list_max_elems[kind] = init_length;
  }
#endif
}

/* Expand the capacity of a growable list */
static void ExpandGrowableList(CompilationUnit* cu, GrowableList* g_list)
{
  int new_length = g_list->num_allocated;
  if (new_length < 128) {
    new_length <<= 1;
  } else {
    new_length += 128;
  }
  uintptr_t *new_array =
      static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
                                     kAllocGrowableList));
  memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
#ifdef WITH_MEMSTATS
  cu->mstats->list_sizes[g_list->kind] += sizeof(uintptr_t) * new_length;
  cu->mstats->list_wasted[g_list->kind] +=
      sizeof(uintptr_t) * g_list->num_allocated;
  cu->mstats->list_grows[g_list->kind]++;
  if (new_length > cu->mstats->list_max_elems[g_list->kind]) {
    cu->mstats->list_max_elems[g_list->kind] = new_length;
  }
#endif
  g_list->num_allocated = new_length;
  g_list->elem_list = new_array;
}

/* Insert a new element into the growable list */
void InsertGrowableList(CompilationUnit* cu, GrowableList* g_list,
                           uintptr_t elem)
{
  DCHECK_NE(g_list->num_allocated, 0U);
  if (g_list->num_used == g_list->num_allocated) {
    ExpandGrowableList(cu, g_list);
  }
  g_list->elem_list[g_list->num_used++] = elem;
}

/* Delete an element from a growable list. Element must be present */
void DeleteGrowableList(GrowableList* g_list, uintptr_t elem)
{
  bool found = false;
  for (unsigned int i = 0; i < g_list->num_used; i++) {
    if (!found && g_list->elem_list[i] == elem) {
      found = true;
    }
    if (found) {
      g_list->elem_list[i] = g_list->elem_list[i+1];
    }
  }
  DCHECK_EQ(found, true);
  g_list->num_used--;
}

void GrowableListIteratorInit(GrowableList* g_list,
                               GrowableListIterator* iterator)
{
  iterator->list = g_list;
  iterator->idx = 0;
  iterator->size = g_list->num_used;
}

uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
{
  DCHECK_EQ(iterator->size, iterator->list->num_used);
  if (iterator->idx == iterator->size) return 0;
  return iterator->list->elem_list[iterator->idx++];
}

uintptr_t GrowableListGetElement(const GrowableList* g_list, size_t idx)
{
  DCHECK_LT(idx, g_list->num_used);
  return g_list->elem_list[idx];
}

#ifdef WITH_MEMSTATS
/* Dump memory usage stats */
void DumpMemStats(CompilationUnit* cu)
{
  uint32_t total = 0;
  for (int i = 0; i < kNumAllocKinds; i++) {
    total += cu->mstats->alloc_stats[i];
  }
  if (total > (10 * 1024 * 1024)) {
    LOG(INFO) << "MEMUSAGE: " << total << " : "
        << PrettyMethod(cu->method_idx, *cu->dex_file);
    LOG(INFO) << "insns_size: " << cu->insns_size;
    if (cu->disable_dataflow) {
        LOG(INFO) << " ** Dataflow disabled ** ";
    }
    LOG(INFO) << "===== Overall allocations";
    for (int i = 0; i < kNumAllocKinds; i++) {
        LOG(INFO) << alloc_names[i] << std::setw(10) <<
        cu->mstats->alloc_stats[i];
    }
    LOG(INFO) << "===== GrowableList allocations";
    for (int i = 0; i < kNumListKinds; i++) {
      LOG(INFO) << list_names[i]
                << " S:" << cu->mstats->list_sizes[i]
                << ", W:" << cu->mstats->list_wasted[i]
                << ", G:" << cu->mstats->list_grows[i]
                << ", E:" << cu->mstats->list_max_elems[i];
    }
    LOG(INFO) << "===== GrowableBitMap allocations";
    for (int i = 0; i < kNumBitMapKinds; i++) {
      LOG(INFO) << bit_map_names[i]
                << " S:" << cu->mstats->bit_map_sizes[i]
                << ", W:" << cu->mstats->bit_map_wasted[i]
                << ", G:" << cu->mstats->bit_map_grows[i];
    }
  }
}
#endif

/* Debug Utility - dump a compilation unit */
void DumpCompilationUnit(CompilationUnit* cu)
{
  BasicBlock* bb;
  const char* block_type_names[] = {
    "Entry Block",
    "Code Block",
    "Exit Block",
    "Exception Handling",
    "Catch Block"
  };

  LOG(INFO) << "Compiling " << PrettyMethod(cu->method_idx, *cu->dex_file);
  LOG(INFO) << cu->insns << " insns";
  LOG(INFO) << cu->num_blocks << " blocks in total";
  GrowableListIterator iterator;

  GrowableListIteratorInit(&cu->block_list, &iterator);

  while (true) {
    bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
    if (bb == NULL) break;
    LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
        bb->id,
        block_type_names[bb->block_type],
        bb->start_offset,
        bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
        bb->last_mir_insn ? "" : " empty");
    if (bb->taken) {
      LOG(INFO) << "  Taken branch: block " << bb->taken->id
                << "(0x" << std::hex << bb->taken->start_offset << ")";
    }
    if (bb->fall_through) {
      LOG(INFO) << "  Fallthrough : block " << bb->fall_through->id
                << " (0x" << std::hex << bb->fall_through->start_offset << ")";
    }
  }
}

static uint32_t check_masks[32] = {
  0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
  0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
  0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
  0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
  0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
  0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
  0x40000000, 0x80000000 };

/*
 * Allocate a bit vector with enough space to hold at least the specified
 * number of bits.
 *
 * NOTE: memory is allocated from the compiler arena.
 */
ArenaBitVector* AllocBitVector(CompilationUnit* cu,
                                unsigned int start_bits, bool expandable,
                                oat_bit_map_kind kind)
{
  ArenaBitVector* bv;
  unsigned int count;

  DCHECK_EQ(sizeof(bv->storage[0]), 4U);        /* assuming 32-bit units */

  bv = static_cast<ArenaBitVector*>(NewMem(cu, sizeof(ArenaBitVector), false,
                                                kAllocGrowableBitMap));

  count = (start_bits + 31) >> 5;

  bv->storage_size = count;
  bv->expandable = expandable;
  bv->storage = static_cast<uint32_t*>(NewMem(cu, count * sizeof(uint32_t), true,
                                              kAllocGrowableBitMap));
#ifdef WITH_MEMSTATS
  bv->kind = kind;
  cu->mstats->bit_map_sizes[kind] += count * sizeof(uint32_t);
#endif
  return bv;
}

/*
 * Determine whether or not the specified bit is set.
 */
bool IsBitSet(const ArenaBitVector* p_bits, unsigned int num)
{
  DCHECK_LT(num, p_bits->storage_size * sizeof(uint32_t) * 8);

  unsigned int val = p_bits->storage[num >> 5] & check_masks[num & 0x1f];
  return (val != 0);
}

/*
 * Mark all bits bit as "clear".
 */
void ClearAllBits(ArenaBitVector* p_bits)
{
  unsigned int count = p_bits->storage_size;
  memset(p_bits->storage, 0, count * sizeof(uint32_t));
}

/*
 * Mark the specified bit as "set".
 *
 * Returns "false" if the bit is outside the range of the vector and we're
 * not allowed to expand.
 *
 * NOTE: memory is allocated from the compiler arena.
 */
bool SetBit(CompilationUnit* cu, ArenaBitVector* p_bits, unsigned int num)
{
  if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
    if (!p_bits->expandable) {
      LOG(FATAL) << "Can't expand";
    }

    /* Round up to word boundaries for "num+1" bits */
    unsigned int new_size = (num + 1 + 31) >> 5;
    DCHECK_GT(new_size, p_bits->storage_size);
    uint32_t *new_storage = static_cast<uint32_t*>(NewMem(cu, new_size * sizeof(uint32_t), false,
                                                         kAllocGrowableBitMap));
    memcpy(new_storage, p_bits->storage, p_bits->storage_size * sizeof(uint32_t));
    memset(&new_storage[p_bits->storage_size], 0,
           (new_size - p_bits->storage_size) * sizeof(uint32_t));
#ifdef WITH_MEMSTATS
    cu->mstats->bit_map_wasted[p_bits->kind] +=
        p_bits->storage_size * sizeof(uint32_t);
    cu->mstats->bit_map_sizes[p_bits->kind] += new_size * sizeof(uint32_t);
    cu->mstats->bit_map_grows[p_bits->kind]++;
#endif
    p_bits->storage = new_storage;
    p_bits->storage_size = new_size;
  }

  p_bits->storage[num >> 5] |= check_masks[num & 0x1f];
  return true;
}

/*
 * Mark the specified bit as "unset".
 *
 * Returns "false" if the bit is outside the range of the vector and we're
 * not allowed to expand.
 *
 * NOTE: memory is allocated from the compiler arena.
 */
bool ClearBit(ArenaBitVector* p_bits, unsigned int num)
{
  if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
    LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
  }

  p_bits->storage[num >> 5] &= ~check_masks[num & 0x1f];
  return true;
}

/* Initialize the iterator structure */
void BitVectorIteratorInit(ArenaBitVector* p_bits,
                            ArenaBitVectorIterator* iterator)
{
  iterator->p_bits = p_bits;
  iterator->bit_size = p_bits->storage_size * sizeof(uint32_t) * 8;
  iterator->idx = 0;
}

/*
 * If the vector sizes don't match, log an error and abort.
 */
static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
{
  if (bv1->storage_size != bv2->storage_size) {
    LOG(FATAL) << "Mismatched vector sizes (" << bv1->storage_size
               << ", " << bv2->storage_size << ")";
  }
}

/*
 * Copy a whole vector to the other. Only do that when the both vectors have
 * the same size.
 */
void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
{
  /* if dest is expandable and < src, we could expand dest to match */
  CheckSizes(dest, src);

  memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storage_size);
}

/*
 * Intersect two bit vectors and store the result to the dest vector.
 */

bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
                          const ArenaBitVector* src2)
{
  DCHECK(src1 != NULL);
  DCHECK(src2 != NULL);
  if (dest->storage_size != src1->storage_size ||
      dest->storage_size != src2->storage_size ||
      dest->expandable != src1->expandable ||
      dest->expandable != src2->expandable)
    return false;

  unsigned int idx;
  for (idx = 0; idx < dest->storage_size; idx++) {
    dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
  }
  return true;
}

/*
 * Unify two bit vectors and store the result to the dest vector.
 */
bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
                      const ArenaBitVector* src2)
{
  DCHECK(src1 != NULL);
  DCHECK(src2 != NULL);
  if (dest->storage_size != src1->storage_size ||
      dest->storage_size != src2->storage_size ||
      dest->expandable != src1->expandable ||
      dest->expandable != src2->expandable)
    return false;

  unsigned int idx;
  for (idx = 0; idx < dest->storage_size; idx++) {
    dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
  }
  return true;
}

/*
 * Return true if any bits collide.  Vectors must be same size.
 */
bool TestBitVectors(const ArenaBitVector* src1,
                     const ArenaBitVector* src2)
{
  DCHECK_EQ(src1->storage_size, src2->storage_size);
  for (uint32_t idx = 0; idx < src1->storage_size; idx++) {
    if (src1->storage[idx] & src2->storage[idx]) return true;
  }
  return false;
}

/*
 * Compare two bit vectors and return true if difference is seen.
 */
bool CompareBitVectors(const ArenaBitVector* src1,
                        const ArenaBitVector* src2)
{
  if (src1->storage_size != src2->storage_size ||
      src1->expandable != src2->expandable)
    return true;

  unsigned int idx;
  for (idx = 0; idx < src1->storage_size; idx++) {
    if (src1->storage[idx] != src2->storage[idx]) return true;
  }
  return false;
}

/*
 * Count the number of bits that are set.
 */
int CountSetBits(const ArenaBitVector* p_bits)
{
  unsigned int word;
  unsigned int count = 0;

  for (word = 0; word < p_bits->storage_size; word++) {
    uint32_t val = p_bits->storage[word];

    if (val != 0) {
      if (val == 0xffffffff) {
        count += 32;
      } else {
        /* count the number of '1' bits */
        while (val != 0) {
          val &= val - 1;
          count++;
        }
      }
    }
  }

  return count;
}

/* Return the next position set to 1. -1 means end-of-element reached */
int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
{
  ArenaBitVector* p_bits = iterator->p_bits;
  uint32_t bit_index = iterator->idx;
  uint32_t bit_size = iterator->bit_size;

  DCHECK_EQ(bit_size, p_bits->storage_size * sizeof(uint32_t) * 8);

  if (bit_index >= bit_size) return -1;

  uint32_t word_index = bit_index >> 5;
  uint32_t end_word_index = bit_size >> 5;
  uint32_t* storage = p_bits->storage;
  uint32_t word = storage[word_index++];

  // Mask out any bits in the first word we've already considered
  word &= ~((1 << (bit_index & 0x1f))-1);

  for (; word_index <= end_word_index;) {
    uint32_t bit_pos = bit_index & 0x1f;
    if (word == 0) {
      bit_index += (32 - bit_pos);
      word = storage[word_index++];
      continue;
    }
    for (; bit_pos < 32; bit_pos++) {
      if (word & (1 << bit_pos)) {
        iterator->idx = bit_index + 1;
        return bit_index;
      }
      bit_index++;
    }
    word = storage[word_index++];
  }
  iterator->idx = iterator->bit_size;
  return -1;
}

/*
 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
 * since there might be unused bits - setting those to one will confuse the
 * iterator.
 */
void SetInitialBits(ArenaBitVector* p_bits, unsigned int num_bits)
{
  unsigned int idx;
  DCHECK_LE(((num_bits + 31) >> 5), p_bits->storage_size);
  for (idx = 0; idx < (num_bits >> 5); idx++) {
    p_bits->storage[idx] = -1;
  }
  unsigned int rem_num_bits = num_bits & 0x1f;
  if (rem_num_bits) {
    p_bits->storage[idx] = (1 << rem_num_bits) - 1;
  }
}

void GetBlockName(BasicBlock* bb, char* name)
{
  switch (bb->block_type) {
    case kEntryBlock:
      snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
      break;
    case kExitBlock:
      snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
      break;
    case kDalvikByteCode:
      snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
      break;
    case kExceptionHandling:
      snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
               bb->id);
      break;
    default:
      snprintf(name, BLOCK_NAME_LEN, "??_%d", bb->id);
      break;
  }
}

const char* GetShortyFromTargetIdx(CompilationUnit *cu, int target_idx)
{
  const DexFile::MethodId& method_id = cu->dex_file->GetMethodId(target_idx);
  return cu->dex_file->GetShorty(method_id.proto_idx_);
}

/* 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
