Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "Dalvik.h"
     18 #include "CompilerInternals.h"
     19 
     20 /* Allocate a new basic block */
     21 BasicBlock *dvmCompilerNewBB(BBType blockType, int blockId)
     22 {
     23     BasicBlock *bb = (BasicBlock *)dvmCompilerNew(sizeof(BasicBlock), true);
     24     bb->blockType = blockType;
     25     bb->id = blockId;
     26     bb->predecessors = dvmCompilerAllocBitVector(blockId > 32 ? blockId : 32,
     27                                                  true /* expandable */);
     28     return bb;
     29 }
     30 
     31 /* Insert an MIR instruction to the end of a basic block */
     32 void dvmCompilerAppendMIR(BasicBlock *bb, MIR *mir)
     33 {
     34     if (bb->firstMIRInsn == NULL) {
     35         assert(bb->lastMIRInsn == NULL);
     36         bb->lastMIRInsn = bb->firstMIRInsn = mir;
     37         mir->prev = mir->next = NULL;
     38     } else {
     39         bb->lastMIRInsn->next = mir;
     40         mir->prev = bb->lastMIRInsn;
     41         mir->next = NULL;
     42         bb->lastMIRInsn = mir;
     43     }
     44 }
     45 
     46 /* Insert an MIR instruction to the head of a basic block */
     47 void dvmCompilerPrependMIR(BasicBlock *bb, MIR *mir)
     48 {
     49     if (bb->firstMIRInsn == NULL) {
     50         assert(bb->lastMIRInsn == NULL);
     51         bb->lastMIRInsn = bb->firstMIRInsn = mir;
     52         mir->prev = mir->next = NULL;
     53     } else {
     54         bb->firstMIRInsn->prev = mir;
     55         mir->next = bb->firstMIRInsn;
     56         mir->prev = NULL;
     57         bb->firstMIRInsn = mir;
     58     }
     59 }
     60 
     61 /* Insert an MIR instruction after the specified MIR */
     62 void dvmCompilerInsertMIRAfter(BasicBlock *bb, MIR *currentMIR, MIR *newMIR)
     63 {
     64     newMIR->prev = currentMIR;
     65     newMIR->next = currentMIR->next;
     66     currentMIR->next = newMIR;
     67 
     68     if (newMIR->next) {
     69         /* Is not the last MIR in the block */
     70         newMIR->next->prev = newMIR;
     71     } else {
     72         /* Is the last MIR in the block */
     73         bb->lastMIRInsn = newMIR;
     74     }
     75 }
     76 
     77 /*
     78  * Append an LIR instruction to the LIR list maintained by a compilation
     79  * unit
     80  */
     81 void dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir)
     82 {
     83     if (cUnit->firstLIRInsn == NULL) {
     84         assert(cUnit->lastLIRInsn == NULL);
     85         cUnit->lastLIRInsn = cUnit->firstLIRInsn = lir;
     86         lir->prev = lir->next = NULL;
     87     } else {
     88         cUnit->lastLIRInsn->next = lir;
     89         lir->prev = cUnit->lastLIRInsn;
     90         lir->next = NULL;
     91         cUnit->lastLIRInsn = lir;
     92     }
     93 }
     94 
     95 /*
     96  * Insert an LIR instruction before the current instruction, which cannot be the
     97  * first instruction.
     98  *
     99  * prevLIR <-> newLIR <-> currentLIR
    100  */
    101 void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR)
    102 {
    103     assert(currentLIR->prev != NULL);
    104     LIR *prevLIR = currentLIR->prev;
    105 
    106     prevLIR->next = newLIR;
    107     newLIR->prev = prevLIR;
    108     newLIR->next = currentLIR;
    109     currentLIR->prev = newLIR;
    110 }
    111 
    112 /*
    113  * Insert an LIR instruction after the current instruction, which cannot be the
    114  * first instruction.
    115  *
    116  * currentLIR -> newLIR -> oldNext
    117  */
    118 void dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR)
    119 {
    120     newLIR->prev = currentLIR;
    121     newLIR->next = currentLIR->next;
    122     currentLIR->next = newLIR;
    123     newLIR->next->prev = newLIR;
    124 }
    125