1ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
2ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Copyright (C) 2009 The Android Open Source Project
3ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
4ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Licensed under the Apache License, Version 2.0 (the "License");
5ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * you may not use this file except in compliance with the License.
6ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * You may obtain a copy of the License at
7ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
8ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *      http://www.apache.org/licenses/LICENSE-2.0
9ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
10ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Unless required by applicable law or agreed to in writing, software
11ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * distributed under the License is distributed on an "AS IS" BASIS,
12ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * See the License for the specific language governing permissions and
14ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * limitations under the License.
15ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
16ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
17ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "Dalvik.h"
18ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "CompilerInternals.h"
19ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
20ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Allocate a new basic block */
2100603079b8723b32c955513eae63a8f97898074dBen ChengBasicBlock *dvmCompilerNewBB(BBType blockType, int blockId)
22ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
23fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    BasicBlock *bb = (BasicBlock *)dvmCompilerNew(sizeof(BasicBlock), true);
24ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bb->blockType = blockType;
2500603079b8723b32c955513eae63a8f97898074dBen Cheng    bb->id = blockId;
2600603079b8723b32c955513eae63a8f97898074dBen Cheng    bb->predecessors = dvmCompilerAllocBitVector(blockId > 32 ? blockId : 32,
2700603079b8723b32c955513eae63a8f97898074dBen Cheng                                                 true /* expandable */);
28ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    return bb;
29ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
30ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
31ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Insert an MIR instruction to the end of a basic block */
32ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerAppendMIR(BasicBlock *bb, MIR *mir)
33ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
34ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (bb->firstMIRInsn == NULL) {
354238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        assert(bb->lastMIRInsn == NULL);
36ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        bb->lastMIRInsn = bb->firstMIRInsn = mir;
37ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        mir->prev = mir->next = NULL;
38ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    } else {
39ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        bb->lastMIRInsn->next = mir;
40ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        mir->prev = bb->lastMIRInsn;
41ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        mir->next = NULL;
42ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        bb->lastMIRInsn = mir;
43ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
44ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
45ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
464238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng/* Insert an MIR instruction to the head of a basic block */
474238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Chengvoid dvmCompilerPrependMIR(BasicBlock *bb, MIR *mir)
484238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng{
494238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    if (bb->firstMIRInsn == NULL) {
504238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        assert(bb->lastMIRInsn == NULL);
514238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        bb->lastMIRInsn = bb->firstMIRInsn = mir;
524238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        mir->prev = mir->next = NULL;
534238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    } else {
544238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        bb->firstMIRInsn->prev = mir;
554238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        mir->next = bb->firstMIRInsn;
564238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        mir->prev = NULL;
574238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng        bb->firstMIRInsn = mir;
584238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng    }
594238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng}
604238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng
617a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng/* Insert an MIR instruction after the specified MIR */
627a2697d327936e20ef5484f7819e2e4bf91c891fBen Chengvoid dvmCompilerInsertMIRAfter(BasicBlock *bb, MIR *currentMIR, MIR *newMIR)
637a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng{
647a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newMIR->prev = currentMIR;
657a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    newMIR->next = currentMIR->next;
667a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    currentMIR->next = newMIR;
677a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
687a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    if (newMIR->next) {
697a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        /* Is not the last MIR in the block */
707a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        newMIR->next->prev = newMIR;
717a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    } else {
727a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        /* Is the last MIR in the block */
737a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng        bb->lastMIRInsn = newMIR;
747a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng    }
757a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng}
767a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
77ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
78ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Append an LIR instruction to the LIR list maintained by a compilation
79ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * unit
80ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
81ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir)
82ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
83ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (cUnit->firstLIRInsn == NULL) {
84ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        assert(cUnit->lastLIRInsn == NULL);
85ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        cUnit->lastLIRInsn = cUnit->firstLIRInsn = lir;
86ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        lir->prev = lir->next = NULL;
87ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    } else {
88ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        cUnit->lastLIRInsn->next = lir;
89ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        lir->prev = cUnit->lastLIRInsn;
90ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        lir->next = NULL;
91ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        cUnit->lastLIRInsn = lir;
92ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
93ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
94e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng
95e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng/*
96e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * Insert an LIR instruction before the current instruction, which cannot be the
97e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * first instruction.
98e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng *
99e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * prevLIR <-> newLIR <-> currentLIR
100e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng */
101e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Chengvoid dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR)
102e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng{
103fc519dc8f4444f6d93806ec15ce7445b322070fdBill Buzbee    assert(currentLIR->prev != NULL);
104e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng    LIR *prevLIR = currentLIR->prev;
105e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng
106e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng    prevLIR->next = newLIR;
107e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng    newLIR->prev = prevLIR;
108e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng    newLIR->next = currentLIR;
109e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng    currentLIR->prev = newLIR;
110e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng}
111dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng
112dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng/*
113dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng * Insert an LIR instruction after the current instruction, which cannot be the
114dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng * first instruction.
115dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng *
116dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng * currentLIR -> newLIR -> oldNext
117dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng */
118dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Chengvoid dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR)
119dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng{
120dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng    newLIR->prev = currentLIR;
121dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng    newLIR->next = currentLIR->next;
122dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng    currentLIR->next = newLIR;
123dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng    newLIR->next->prev = newLIR;
124dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng}
125