blob: a4ab76f028f561ed23e68dee37112d0afec90390 [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#include "Dataflow.h"
20#include "codegen/Ralloc.h"
21
22/*
23 * Quick & dirty - make FP usage sticky. This is strictly a hint - local
24 * code generation will handle misses. It might be worthwhile to collaborate
25 * with dx/dexopt to avoid reusing the same Dalvik temp for values of
26 * different types.
27 */
28static void inferTypes(CompilationUnit* cUnit, BasicBlock* bb)
29{
30 MIR *mir;
31 if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock)
32 return;
33
34 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
35 SSARepresentation *ssaRep = mir->ssaRep;
36 if (ssaRep) {
37 int i;
38 for (i=0; ssaRep->fpUse && i< ssaRep->numUses; i++) {
39 if (ssaRep->fpUse[i])
40 cUnit->regLocation[ssaRep->uses[i]].fp = true;
41 }
42 for (i=0; ssaRep->fpDef && i< ssaRep->numDefs; i++) {
43 if (ssaRep->fpDef[i])
44 cUnit->regLocation[ssaRep->defs[i]].fp = true;
45 }
46 }
47 }
48}
49
50static const char* storageName[] = {" Frame ", "PhysReg", " Spill "};
51
buzbeedfd3d702011-08-28 12:56:51 -070052void oatDumpRegLocTable(RegLocation* table, int count)
buzbee67bf8852011-08-17 17:51:35 -070053{
54 for (int i = 0; i < count; i++) {
55 char buf[100];
56 snprintf(buf, 100, "Loc[%02d] : %s, %c %c r%d r%d S%d : %s s%d s%d",
57 i, storageName[table[i].location], table[i].wide ? 'W' : 'N',
58 table[i].fp ? 'F' : 'C', table[i].lowReg, table[i].highReg,
59 table[i].sRegLow, storageName[table[i].fpLocation],
60 table[i].fpLowReg & FP_REG_MASK, table[i].fpHighReg &
61 FP_REG_MASK);
62 LOG(INFO) << buf;
63 }
64}
65
66static const RegLocation freshLoc = {kLocDalvikFrame, 0, 0, INVALID_REG,
67 INVALID_REG, INVALID_SREG, 0,
68 kLocDalvikFrame, INVALID_REG, INVALID_REG,
69 INVALID_OFFSET};
70
71/*
72 * Simple register allocation. Some Dalvik virtual registers may
73 * be promoted to physical registers. Most of the work for temp
74 * allocation is done on the fly. We also do some initilization and
75 * type inference here.
76 */
77void oatSimpleRegAlloc(CompilationUnit* cUnit)
78{
79 int i;
80 RegLocation* loc;
81
82 /* Allocate the location map */
83 loc = (RegLocation*)oatNew(cUnit->numSSARegs * sizeof(*loc), true);
84 for (i=0; i< cUnit->numSSARegs; i++) {
85 loc[i] = freshLoc;
86 loc[i].sRegLow = i;
87 }
88 cUnit->regLocation = loc;
89
90 GrowableListIterator iterator;
91
92 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
93 /* Do type inference pass */
94 while (true) {
95 BasicBlock *bb = (BasicBlock *) oatGrowableListIteratorNext(&iterator);
96 if (bb == NULL) break;
97 inferTypes(cUnit, bb);
98 }
99
100 /*
101 * Set the sRegLow field to refer to the pre-SSA name of the
102 * base Dalvik virtual register. Once we add a better register
103 * allocator, remove this remapping.
104 */
105 for (i=0; i < cUnit->numSSARegs; i++) {
106 cUnit->regLocation[i].sRegLow =
107 DECODE_REG(oatConvertSSARegToDalvik(cUnit, loc[i].sRegLow));
108 }
109
110 cUnit->coreSpillMask = 0;
111 cUnit->fpSpillMask = 0;
112 cUnit->numSpills = 0;
113
114 oatDoPromotion(cUnit);
115
116 if (cUnit->printMe && !(cUnit->disableOpt & (1 << kPromoteRegs))) {
117 LOG(INFO) << "After Promotion";
buzbeedfd3d702011-08-28 12:56:51 -0700118 oatDumpRegLocTable(cUnit->regLocation, cUnit->numSSARegs);
buzbee67bf8852011-08-17 17:51:35 -0700119 }
120
121 /* Figure out the frame size */
buzbeec143c552011-08-20 17:38:58 -0700122 cUnit->numIns = cUnit->method->num_ins_;
123 cUnit->numRegs = cUnit->method->num_registers_ - cUnit->numIns;
124 cUnit->numOuts = cUnit->method->num_outs_;
buzbee67bf8852011-08-17 17:51:35 -0700125 cUnit->numPadding = (STACK_ALIGN_WORDS -
126 (cUnit->numSpills + cUnit->numRegs +
127 cUnit->numOuts + 2)) & (STACK_ALIGN_WORDS-1);
128 cUnit->frameSize = (cUnit->numSpills + cUnit->numRegs + cUnit->numOuts +
129 cUnit->numPadding + 2) * 4;
130 cUnit->insOffset = cUnit->frameSize + 4;
131 cUnit->regsOffset = (cUnit->numOuts + cUnit->numPadding + 1) * 4;
132
133 /* Compute sp-relative home location offsets */
134 for (i = 0; i < cUnit->numSSARegs; i++) {
135 int vReg = oatS2VReg(cUnit, cUnit->regLocation[i].sRegLow);
136 cUnit->regLocation[i].spOffset = oatVRegOffset(cUnit, vReg);
137 }
138}