blob: 85dfa8ef199ada0d4e8154be4f8318ac27b952a5 [file] [log] [blame]
Ben Chenge9695e52009-06-16 16:11:47 -07001/*
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 "vm/compiler/CompilerInternals.h"
Bill Buzbee89efc3d2009-07-28 11:22:22 -070019#include "ArmLIR.h"
Ben Cheng5d90c202009-11-22 23:31:11 -080020#include "Codegen.h"
Ben Chenge9695e52009-06-16 16:11:47 -070021
Ben Chengd7d426a2009-09-22 11:23:36 -070022#define DEBUG_OPT(X)
23
Bill Buzbee7ea0f642009-08-10 17:06:51 -070024ArmLIR* dvmCompilerGenCopy(CompilationUnit *cUnit, int rDest, int rSrc);
25
26/* Is this a Dalvik register access? */
27static inline bool isDalvikLoad(ArmLIR *lir)
28{
Bill Buzbee1f748632010-03-02 16:14:41 -080029 return (lir->useMask != ENCODE_ALL) && (lir->useMask & ENCODE_DALVIK_REG);
30}
31
32/* Is this a load from the literal pool? */
33static inline bool isLiteralLoad(ArmLIR *lir)
34{
35 return (lir->useMask != ENCODE_ALL) && (lir->useMask & ENCODE_LITERAL);
Bill Buzbee7ea0f642009-08-10 17:06:51 -070036}
37
38static inline bool isDalvikStore(ArmLIR *lir)
39{
Bill Buzbee1f748632010-03-02 16:14:41 -080040 return (lir->defMask != ENCODE_ALL) && (lir->defMask & ENCODE_DALVIK_REG);
Bill Buzbee7ea0f642009-08-10 17:06:51 -070041}
42
Ben Chenga4aaf682009-09-30 22:53:44 -070043static inline bool isDalvikRegisterClobbered(ArmLIR *lir1, ArmLIR *lir2)
Bill Buzbee270c1d62009-08-13 16:58:07 -070044{
Ben Chengd7d426a2009-09-22 11:23:36 -070045 int reg1Lo = DECODE_ALIAS_INFO_REG(lir1->aliasInfo);
46 int reg1Hi = reg1Lo + DECODE_ALIAS_INFO_WIDE(lir1->aliasInfo);
47 int reg2Lo = DECODE_ALIAS_INFO_REG(lir2->aliasInfo);
48 int reg2Hi = reg2Lo + DECODE_ALIAS_INFO_WIDE(lir2->aliasInfo);
49
Ben Chenga4aaf682009-09-30 22:53:44 -070050 return (reg1Lo == reg2Lo) || (reg1Lo == reg2Hi) || (reg1Hi == reg2Lo);
Bill Buzbee270c1d62009-08-13 16:58:07 -070051}
Ben Chengd7d426a2009-09-22 11:23:36 -070052
53static void dumpDependentInsnPair(ArmLIR *thisLIR, ArmLIR *checkLIR,
54 const char *optimization)
55{
56 LOGD("************ %s ************", optimization);
57 dvmDumpLIRInsn((LIR *) thisLIR, 0);
58 dvmDumpLIRInsn((LIR *) checkLIR, 0);
59}
60
Ben Chenge9695e52009-06-16 16:11:47 -070061/*
62 * Perform a pass of top-down walk to
63 * 1) Eliminate redundant loads and stores
64 * 2) Sink stores to latest possible slot
65 */
66static void applyLoadStoreElimination(CompilationUnit *cUnit,
Bill Buzbee89efc3d2009-07-28 11:22:22 -070067 ArmLIR *headLIR,
68 ArmLIR *tailLIR)
Ben Chenge9695e52009-06-16 16:11:47 -070069{
Bill Buzbee89efc3d2009-07-28 11:22:22 -070070 ArmLIR *thisLIR;
Ben Chenge9695e52009-06-16 16:11:47 -070071
72 cUnit->optRound++;
73 for (thisLIR = headLIR;
74 thisLIR != tailLIR;
75 thisLIR = NEXT_LIR(thisLIR)) {
76 /* Skip newly added instructions */
77 if (thisLIR->age >= cUnit->optRound) {
78 continue;
79 }
Bill Buzbee7ea0f642009-08-10 17:06:51 -070080 if (isDalvikStore(thisLIR)) {
Ben Chengd7d426a2009-09-22 11:23:36 -070081 int dRegId = DECODE_ALIAS_INFO_REG(thisLIR->aliasInfo);
82 int dRegIdHi = dRegId + DECODE_ALIAS_INFO_WIDE(thisLIR->aliasInfo);
Ben Chenge9695e52009-06-16 16:11:47 -070083 int nativeRegId = thisLIR->operands[0];
Bill Buzbee89efc3d2009-07-28 11:22:22 -070084 ArmLIR *checkLIR;
Ben Chenge9695e52009-06-16 16:11:47 -070085 int sinkDistance = 0;
Ben Chengdcf3e5d2009-09-11 13:42:05 -070086 /*
87 * Add r15 (pc) to the mask to prevent this instruction
Ben Chengd7d426a2009-09-22 11:23:36 -070088 * from sinking past branch instructions. Unset the Dalvik register
89 * bit when checking with native resource constraints.
Ben Chengdcf3e5d2009-09-11 13:42:05 -070090 */
Ben Chengd7d426a2009-09-22 11:23:36 -070091 u8 stopMask = (ENCODE_REG_PC | thisLIR->useMask) &
92 ~ENCODE_DALVIK_REG;
Ben Chenge9695e52009-06-16 16:11:47 -070093
94 for (checkLIR = NEXT_LIR(thisLIR);
95 checkLIR != tailLIR;
96 checkLIR = NEXT_LIR(checkLIR)) {
97
98 /* Check if a Dalvik register load is redundant */
Bill Buzbee7ea0f642009-08-10 17:06:51 -070099 if (isDalvikLoad(checkLIR) &&
Ben Chengd7d426a2009-09-22 11:23:36 -0700100 (checkLIR->aliasInfo == thisLIR->aliasInfo) &&
101 (REGTYPE(checkLIR->operands[0]) == REGTYPE(nativeRegId))) {
Ben Chenge9695e52009-06-16 16:11:47 -0700102 /* Insert a move to replace the load */
103 if (checkLIR->operands[0] != nativeRegId) {
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700104 ArmLIR *moveLIR;
Ben Cheng5d90c202009-11-22 23:31:11 -0800105 moveLIR = dvmCompilerRegCopyNoInsert(
106 cUnit, checkLIR->operands[0], nativeRegId);
Ben Chenge9695e52009-06-16 16:11:47 -0700107 /*
Ben Cheng58ece732010-03-17 23:32:26 -0700108 * Insert the converted checkLIR instruction after the
109 * the original checkLIR since the optimization is
110 * scannng in the top-down order and the new instruction
111 * will need to be checked.
Ben Chenge9695e52009-06-16 16:11:47 -0700112 */
Ben Cheng58ece732010-03-17 23:32:26 -0700113 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
114 (LIR *) moveLIR);
Ben Chenge9695e52009-06-16 16:11:47 -0700115 }
116 checkLIR->isNop = true;
117 continue;
118
Ben Chengd7d426a2009-09-22 11:23:36 -0700119 /*
120 * Found a true output dependency - nuke the previous store.
121 * The register type doesn't matter here.
122 */
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700123 } else if (isDalvikStore(checkLIR) &&
Ben Chengd7d426a2009-09-22 11:23:36 -0700124 (checkLIR->aliasInfo == thisLIR->aliasInfo)) {
Ben Chenge9695e52009-06-16 16:11:47 -0700125 thisLIR->isNop = true;
126 break;
127 /* Find out the latest slot that the store can be sunk into */
128 } else {
Ben Chenge9695e52009-06-16 16:11:47 -0700129 /* Last instruction reached */
Ben Chengd7d426a2009-09-22 11:23:36 -0700130 bool stopHere = (NEXT_LIR(checkLIR) == tailLIR);
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700131
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700132 /* Store data is clobbered */
Ben Chengd7d426a2009-09-22 11:23:36 -0700133 stopHere |= ((stopMask & checkLIR->defMask) != 0);
134
135 /* Store data partially clobbers the Dalvik register */
136 if (stopHere == false &&
137 ((checkLIR->useMask | checkLIR->defMask) &
138 ENCODE_DALVIK_REG)) {
Ben Chenga4aaf682009-09-30 22:53:44 -0700139 stopHere = isDalvikRegisterClobbered(thisLIR, checkLIR);
Ben Chengd7d426a2009-09-22 11:23:36 -0700140 }
Ben Chenge9695e52009-06-16 16:11:47 -0700141
142 /* Found a new place to put the store - move it here */
143 if (stopHere == true) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700144 DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR,
145 "SINK STORE"));
Ben Chenge9695e52009-06-16 16:11:47 -0700146 /* The store can be sunk for at least one cycle */
147 if (sinkDistance != 0) {
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700148 ArmLIR *newStoreLIR =
149 dvmCompilerNew(sizeof(ArmLIR), true);
Ben Chenge9695e52009-06-16 16:11:47 -0700150 *newStoreLIR = *thisLIR;
151 newStoreLIR->age = cUnit->optRound;
152 /*
Ben Cheng63868fe2010-03-25 16:16:02 -0700153 * Stop point found - insert *before* the checkLIR
154 * since the instruction list is scanned in the
155 * top-down order.
Ben Chenge9695e52009-06-16 16:11:47 -0700156 */
157 dvmCompilerInsertLIRBefore((LIR *) checkLIR,
158 (LIR *) newStoreLIR);
159 thisLIR->isNop = true;
160 }
161 break;
162 }
163
164 /*
165 * Saw a real instruction that the store can be sunk after
166 */
167 if (!isPseudoOpCode(checkLIR->opCode)) {
168 sinkDistance++;
169 }
170 }
171 }
172 }
173 }
174}
175
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700176static void applyLoadHoisting(CompilationUnit *cUnit,
177 ArmLIR *headLIR,
178 ArmLIR *tailLIR)
179{
180 ArmLIR *thisLIR;
Bill Buzbee1f748632010-03-02 16:14:41 -0800181 /*
182 * Don't want to hoist in front of first load following a barrier (or
183 * first instruction of the block.
184 */
185 bool firstLoad = true;
186 int maxHoist = dvmCompilerTargetOptHint(kMaxHoistDistance);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700187
188 cUnit->optRound++;
189 for (thisLIR = headLIR;
190 thisLIR != tailLIR;
191 thisLIR = NEXT_LIR(thisLIR)) {
192 /* Skip newly added instructions */
193 if (thisLIR->age >= cUnit->optRound ||
194 thisLIR->isNop == true) {
195 continue;
196 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800197
198 if (firstLoad && (EncodingMap[thisLIR->opCode].flags & IS_LOAD)) {
199 /*
200 * Ensure nothing will be hoisted in front of this load because
201 * it's result will likely be needed soon.
202 */
203 thisLIR->defMask |= ENCODE_MEM_USE;
204 firstLoad = false;
205 }
206
207 firstLoad |= (thisLIR->defMask == ENCODE_ALL);
208
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700209 if (isDalvikLoad(thisLIR)) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700210 int dRegId = DECODE_ALIAS_INFO_REG(thisLIR->aliasInfo);
211 int dRegIdHi = dRegId + DECODE_ALIAS_INFO_WIDE(thisLIR->aliasInfo);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700212 int nativeRegId = thisLIR->operands[0];
213 ArmLIR *checkLIR;
214 int hoistDistance = 0;
Ben Cheng63868fe2010-03-25 16:16:02 -0700215 u8 stopUseMask = (ENCODE_REG_PC | thisLIR->useMask);
216 u8 stopDefMask = thisLIR->defMask;
217 u8 checkResult;
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700218
Ben Chengd7d426a2009-09-22 11:23:36 -0700219 /* First check if the load can be completely elinimated */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700220 for (checkLIR = PREV_LIR(thisLIR);
221 checkLIR != headLIR;
222 checkLIR = PREV_LIR(checkLIR)) {
223
224 if (checkLIR->isNop) continue;
225
Ben Chengd7d426a2009-09-22 11:23:36 -0700226 /*
227 * Check if the Dalvik register is previously accessed
228 * with exactly the same type.
229 */
230 if ((isDalvikLoad(checkLIR) || isDalvikStore(checkLIR)) &&
231 (checkLIR->aliasInfo == thisLIR->aliasInfo) &&
232 (checkLIR->operands[0] == nativeRegId)) {
233 /*
234 * If it is previously accessed but with a different type,
235 * the search will terminate later at the point checking
236 * for partially overlapping stores.
237 */
238 thisLIR->isNop = true;
239 break;
240 }
241
242 /*
243 * No earlier use/def can reach this load if:
244 * 1) Head instruction is reached
Ben Cheng63868fe2010-03-25 16:16:02 -0700245 */
246 if (checkLIR == headLIR) {
247 break;
248 }
249
250 checkResult = (stopUseMask | stopDefMask) & checkLIR->defMask;
251
252 /*
253 * If both instructions are verified Dalvik accesses, clear the
254 * may- and must-alias bits to detect true resource
255 * dependencies.
256 */
257 if (checkResult & ENCODE_DALVIK_REG) {
258 checkResult &= ~(ENCODE_DALVIK_REG | ENCODE_FRAME_REF);
259 }
260
261 /*
Ben Chengd7d426a2009-09-22 11:23:36 -0700262 * 2) load target register is clobbered
263 * 3) A branch is seen (stopUseMask has the PC bit set).
264 */
Ben Cheng63868fe2010-03-25 16:16:02 -0700265 if (checkResult) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700266 break;
267 }
268
269 /* Store data partially clobbers the Dalvik register */
270 if (isDalvikStore(checkLIR) &&
Ben Chenga4aaf682009-09-30 22:53:44 -0700271 isDalvikRegisterClobbered(thisLIR, checkLIR)) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700272 break;
273 }
274 }
275
276 /* The load has been eliminated */
277 if (thisLIR->isNop) continue;
278
279 /*
280 * The load cannot be eliminated. See if it can be hoisted to an
281 * earlier spot.
282 */
283 for (checkLIR = PREV_LIR(thisLIR);
284 /* empty by intention */;
285 checkLIR = PREV_LIR(checkLIR)) {
286
287 if (checkLIR->isNop) continue;
288
Bill Buzbee1f748632010-03-02 16:14:41 -0800289 /*
290 * Check if the "thisLIR" load is redundant
291 * NOTE: At one point, we also triggered if the checkLIR
292 * instruction was a load. However, that tended to insert
293 * a load/use dependency because the full scheduler is
294 * not yet complete. When it is, we chould also trigger
295 * on loads.
296 */
297 if (isDalvikStore(checkLIR) &&
Ben Chengd7d426a2009-09-22 11:23:36 -0700298 (checkLIR->aliasInfo == thisLIR->aliasInfo) &&
299 (REGTYPE(checkLIR->operands[0]) == REGTYPE(nativeRegId))) {
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700300 /* Insert a move to replace the load */
301 if (checkLIR->operands[0] != nativeRegId) {
302 ArmLIR *moveLIR;
Ben Cheng5d90c202009-11-22 23:31:11 -0800303 moveLIR = dvmCompilerRegCopyNoInsert(
304 cUnit, nativeRegId, checkLIR->operands[0]);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700305 /*
306 * Convert *thisLIR* load into a move
307 */
308 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
309 (LIR *) moveLIR);
310 }
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700311 thisLIR->isNop = true;
312 break;
313
314 /* Find out if the load can be yanked past the checkLIR */
315 } else {
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700316 /* Last instruction reached */
Ben Chengd7d426a2009-09-22 11:23:36 -0700317 bool stopHere = (checkLIR == headLIR);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700318
319 /* Base address is clobbered by checkLIR */
Ben Cheng63868fe2010-03-25 16:16:02 -0700320 checkResult = stopUseMask & checkLIR->defMask;
321 if (checkResult & ENCODE_DALVIK_REG) {
322 checkResult &= ~(ENCODE_DALVIK_REG | ENCODE_FRAME_REF);
323 }
324 stopHere |= (checkResult != 0);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700325
326 /* Load target clobbers use/def in checkLIR */
Ben Cheng63868fe2010-03-25 16:16:02 -0700327 checkResult = stopDefMask &
328 (checkLIR->useMask | checkLIR->defMask);
329 if (checkResult & ENCODE_DALVIK_REG) {
330 checkResult &= ~(ENCODE_DALVIK_REG | ENCODE_FRAME_REF);
331 }
332 stopHere |= (checkResult != 0);
Ben Chengd7d426a2009-09-22 11:23:36 -0700333
334 /* Store data partially clobbers the Dalvik register */
335 if (stopHere == false &&
336 (checkLIR->defMask & ENCODE_DALVIK_REG)) {
Ben Chenga4aaf682009-09-30 22:53:44 -0700337 stopHere = isDalvikRegisterClobbered(thisLIR, checkLIR);
Ben Chengd7d426a2009-09-22 11:23:36 -0700338 }
339
340 /*
341 * Stop at an earlier Dalvik load if the offset of checkLIR
342 * is not less than thisLIR
343 *
344 * Experiments show that doing
345 *
346 * ldr r1, [r5, #16]
347 * ldr r0, [r5, #20]
348 *
349 * is much faster than
350 *
351 * ldr r0, [r5, #20]
352 * ldr r1, [r5, #16]
353 */
354 if (isDalvikLoad(checkLIR)) {
355 int dRegId2 =
356 DECODE_ALIAS_INFO_REG(checkLIR->aliasInfo);
357 if (dRegId2 <= dRegId) {
358 stopHere = true;
359 }
360 }
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700361
Bill Buzbee1f748632010-03-02 16:14:41 -0800362 /* Don't go too far */
363 stopHere |= (hoistDistance >= maxHoist);
364
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700365 /* Found a new place to put the load - move it here */
366 if (stopHere == true) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700367 DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR,
368 "HOIST LOAD"));
Ben Cheng63868fe2010-03-25 16:16:02 -0700369 /* The load can be hoisted for at least one cycle */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700370 if (hoistDistance != 0) {
371 ArmLIR *newLoadLIR =
372 dvmCompilerNew(sizeof(ArmLIR), true);
373 *newLoadLIR = *thisLIR;
374 newLoadLIR->age = cUnit->optRound;
375 /*
Ben Cheng63868fe2010-03-25 16:16:02 -0700376 * Stop point found - insert *after* the checkLIR
377 * since the instruction list is scanned in the
378 * bottom-up order.
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700379 */
380 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
381 (LIR *) newLoadLIR);
382 thisLIR->isNop = true;
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700383 }
384 break;
385 }
386
387 /*
Ben Chengd7d426a2009-09-22 11:23:36 -0700388 * Saw a real instruction that hosting the load is
389 * beneficial
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700390 */
391 if (!isPseudoOpCode(checkLIR->opCode)) {
392 hoistDistance++;
393 }
394 }
395 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800396 } else if (isLiteralLoad(thisLIR)) {
397 int litVal = thisLIR->aliasInfo;
398 int nativeRegId = thisLIR->operands[0];
399 ArmLIR *checkLIR;
400 int hoistDistance = 0;
401 u8 stopUseMask = (ENCODE_REG_PC | thisLIR->useMask) &
402 ~ENCODE_LITPOOL_REF;
403 u8 stopDefMask = thisLIR->defMask & ~ENCODE_LITPOOL_REF;
404
405 /* First check if the load can be completely elinimated */
406 for (checkLIR = PREV_LIR(thisLIR);
407 checkLIR != headLIR;
408 checkLIR = PREV_LIR(checkLIR)) {
409
410 if (checkLIR->isNop) continue;
411
412 /* Reloading same literal into same tgt reg? Eliminate if so */
413 if (isLiteralLoad(checkLIR) &&
414 (checkLIR->aliasInfo == litVal) &&
415 (checkLIR->operands[0] == nativeRegId)) {
416 thisLIR->isNop = true;
417 break;
418 }
419
420 /*
421 * No earlier use/def can reach this load if:
422 * 1) Head instruction is reached
423 * 2) load target register is clobbered
424 * 3) A branch is seen (stopUseMask has the PC bit set).
425 */
426 if ((checkLIR == headLIR) ||
427 (stopUseMask | stopDefMask) & checkLIR->defMask) {
428 break;
429 }
430 }
431
432 /* The load has been eliminated */
433 if (thisLIR->isNop) continue;
434
435 /*
436 * The load cannot be eliminated. See if it can be hoisted to an
437 * earlier spot.
438 */
439 for (checkLIR = PREV_LIR(thisLIR);
440 /* empty by intention */;
441 checkLIR = PREV_LIR(checkLIR)) {
442
443 if (checkLIR->isNop) continue;
444
445 /*
446 * TUNING: once a full scheduler exists, check here
447 * for conversion of a redundant load into a copy similar
448 * to the way redundant loads are handled above.
449 */
450
451 /* Find out if the load can be yanked past the checkLIR */
452
453 /* Last instruction reached */
454 bool stopHere = (checkLIR == headLIR);
455
456 /* Base address is clobbered by checkLIR */
457 stopHere |= ((stopUseMask & checkLIR->defMask) != 0);
458
459 /* Load target clobbers use/def in checkLIR */
460 stopHere |= ((stopDefMask &
461 (checkLIR->useMask | checkLIR->defMask)) != 0);
462
463 /* Avoid re-ordering literal pool loads */
464 stopHere |= isLiteralLoad(checkLIR);
465
466 /* Don't go too far */
467 stopHere |= (hoistDistance >= maxHoist);
468
469 /* Found a new place to put the load - move it here */
470 if (stopHere == true) {
471 DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR,
472 "HOIST LOAD"));
473 /* The store can be hoisted for at least one cycle */
474 if (hoistDistance != 0) {
475 ArmLIR *newLoadLIR =
476 dvmCompilerNew(sizeof(ArmLIR), true);
477 *newLoadLIR = *thisLIR;
478 newLoadLIR->age = cUnit->optRound;
479 /*
480 * Insertion is guaranteed to succeed since checkLIR
481 * is never the first LIR on the list
482 */
483 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
484 (LIR *) newLoadLIR);
485 thisLIR->isNop = true;
486 }
487 break;
488 }
489
490 /*
491 * Saw a real instruction that hosting the load is
492 * beneficial
493 */
494 if (!isPseudoOpCode(checkLIR->opCode)) {
495 hoistDistance++;
496 }
497 }
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700498 }
499 }
500}
501
Ben Chenge9695e52009-06-16 16:11:47 -0700502void dvmCompilerApplyLocalOptimizations(CompilationUnit *cUnit, LIR *headLIR,
503 LIR *tailLIR)
504{
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700505 if (!(gDvmJit.disableOpt & (1 << kLoadStoreElimination))) {
506 applyLoadStoreElimination(cUnit, (ArmLIR *) headLIR,
507 (ArmLIR *) tailLIR);
508 }
509 if (!(gDvmJit.disableOpt & (1 << kLoadHoisting))) {
510 applyLoadHoisting(cUnit, (ArmLIR *) headLIR, (ArmLIR *) tailLIR);
511 }
Ben Chenge9695e52009-06-16 16:11:47 -0700512}