blob: 031d3d379cd29ad019e44559b092ebc2a8b76d0f [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 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
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080020namespace art {
21
Ian Rogers680b1bd2012-03-07 20:18:49 -080022static const char* gOpKindNames[kOpInvalid + 1] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070023 "OpMov",
24 "OpMvn",
25 "OpCmp",
26 "OpLsl",
27 "OpLsr",
28 "OpAsr",
29 "OpRor",
30 "OpNot",
31 "OpAnd",
32 "OpOr",
33 "OpXor",
34 "OpNeg",
35 "OpAdd",
36 "OpAdc",
37 "OpSub",
38 "OpSbc",
39 "OpRsub",
40 "OpMul",
41 "OpDiv",
42 "OpRem",
43 "OpBic",
44 "OpCmn",
45 "OpTst",
46 "OpBkpt",
47 "OpBlx",
48 "OpPush",
49 "OpPop",
50 "Op2Char",
51 "Op2Short",
52 "Op2Byte",
53 "OpCondBr",
54 "OpUncondBr",
55 "OpBx",
56 "OpInvalid",
Ian Rogers680b1bd2012-03-07 20:18:49 -080057};
58
59std::ostream& operator<<(std::ostream& os, const OpKind& kind) {
60 if (kind >= kOpMov && kind <= kOpInvalid) {
61 os << gOpKindNames[kind];
62 } else {
63 os << "Unknown Op " << static_cast<int>(kind);
64 }
65 return os;
66}
67
buzbee67bf8852011-08-17 17:51:35 -070068/* Allocate a new basic block */
buzbee5abfa3e2012-01-31 17:01:43 -080069BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId)
buzbee67bf8852011-08-17 17:51:35 -070070{
Bill Buzbeea114add2012-05-03 15:00:40 -070071 BasicBlock* bb = (BasicBlock* )oatNew(cUnit, sizeof(BasicBlock), true,
72 kAllocBB);
73 bb->blockType = blockType;
74 bb->id = blockId;
75 bb->predecessors = (GrowableList*) oatNew(cUnit, sizeof(GrowableList),
76 false, kAllocPredecessors);
77 oatInitGrowableList(cUnit, bb->predecessors,
78 (blockType == kExitBlock) ? 2048 : 2,
79 kListPredecessors);
buzbeed1643e42012-09-05 14:06:51 -070080 cUnit->blockIdMap.Put(blockId, blockId);
Bill Buzbeea114add2012-05-03 15:00:40 -070081 return bb;
buzbee67bf8852011-08-17 17:51:35 -070082}
83
84/* Insert an MIR instruction to the end of a basic block */
85void oatAppendMIR(BasicBlock* bb, MIR* mir)
86{
Bill Buzbeea114add2012-05-03 15:00:40 -070087 if (bb->firstMIRInsn == NULL) {
88 DCHECK(bb->lastMIRInsn == NULL);
89 bb->lastMIRInsn = bb->firstMIRInsn = mir;
90 mir->prev = mir->next = NULL;
91 } else {
92 bb->lastMIRInsn->next = mir;
93 mir->prev = bb->lastMIRInsn;
94 mir->next = NULL;
95 bb->lastMIRInsn = mir;
96 }
buzbee67bf8852011-08-17 17:51:35 -070097}
98
99/* Insert an MIR instruction to the head of a basic block */
100void oatPrependMIR(BasicBlock* bb, MIR* mir)
101{
Bill Buzbeea114add2012-05-03 15:00:40 -0700102 if (bb->firstMIRInsn == NULL) {
103 DCHECK(bb->lastMIRInsn == NULL);
104 bb->lastMIRInsn = bb->firstMIRInsn = mir;
105 mir->prev = mir->next = NULL;
106 } else {
107 bb->firstMIRInsn->prev = mir;
108 mir->next = bb->firstMIRInsn;
109 mir->prev = NULL;
110 bb->firstMIRInsn = mir;
111 }
buzbee67bf8852011-08-17 17:51:35 -0700112}
113
buzbeee1965672012-03-11 18:39:19 -0700114/* Insert a MIR instruction after the specified MIR */
buzbee67bf8852011-08-17 17:51:35 -0700115void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR)
116{
Bill Buzbeea114add2012-05-03 15:00:40 -0700117 newMIR->prev = currentMIR;
118 newMIR->next = currentMIR->next;
119 currentMIR->next = newMIR;
buzbee67bf8852011-08-17 17:51:35 -0700120
Bill Buzbeea114add2012-05-03 15:00:40 -0700121 if (newMIR->next) {
122 /* Is not the last MIR in the block */
123 newMIR->next->prev = newMIR;
124 } else {
125 /* Is the last MIR in the block */
126 bb->lastMIRInsn = newMIR;
127 }
buzbee67bf8852011-08-17 17:51:35 -0700128}
129
130/*
131 * Append an LIR instruction to the LIR list maintained by a compilation
132 * unit
133 */
134void oatAppendLIR(CompilationUnit *cUnit, LIR* lir)
135{
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 if (cUnit->firstLIRInsn == NULL) {
137 DCHECK(cUnit->lastLIRInsn == NULL);
138 cUnit->lastLIRInsn = cUnit->firstLIRInsn = lir;
139 lir->prev = lir->next = NULL;
140 } else {
141 cUnit->lastLIRInsn->next = lir;
142 lir->prev = cUnit->lastLIRInsn;
143 lir->next = NULL;
144 cUnit->lastLIRInsn = lir;
145 }
buzbee67bf8852011-08-17 17:51:35 -0700146}
147
148/*
149 * Insert an LIR instruction before the current instruction, which cannot be the
150 * first instruction.
151 *
152 * prevLIR <-> newLIR <-> currentLIR
153 */
154void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR)
155{
Bill Buzbeea114add2012-05-03 15:00:40 -0700156 DCHECK(currentLIR->prev != NULL);
157 LIR *prevLIR = currentLIR->prev;
buzbee67bf8852011-08-17 17:51:35 -0700158
Bill Buzbeea114add2012-05-03 15:00:40 -0700159 prevLIR->next = newLIR;
160 newLIR->prev = prevLIR;
161 newLIR->next = currentLIR;
162 currentLIR->prev = newLIR;
buzbee67bf8852011-08-17 17:51:35 -0700163}
164
165/*
166 * Insert an LIR instruction after the current instruction, which cannot be the
167 * first instruction.
168 *
169 * currentLIR -> newLIR -> oldNext
170 */
171void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR)
172{
Bill Buzbeea114add2012-05-03 15:00:40 -0700173 newLIR->prev = currentLIR;
174 newLIR->next = currentLIR->next;
175 currentLIR->next = newLIR;
176 newLIR->next->prev = newLIR;
buzbee67bf8852011-08-17 17:51:35 -0700177}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800178
179} // namespace art