blob: 729486cdc39ff179cf48df352f5ef35a033ddaa0 [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 Chenge9695e52009-06-16 16:11:47 -070081 int nativeRegId = thisLIR->operands[0];
Bill Buzbee89efc3d2009-07-28 11:22:22 -070082 ArmLIR *checkLIR;
Ben Chenge9695e52009-06-16 16:11:47 -070083 int sinkDistance = 0;
Ben Chengdcf3e5d2009-09-11 13:42:05 -070084 /*
85 * Add r15 (pc) to the mask to prevent this instruction
Ben Chengd7d426a2009-09-22 11:23:36 -070086 * from sinking past branch instructions. Unset the Dalvik register
87 * bit when checking with native resource constraints.
Ben Chengdcf3e5d2009-09-11 13:42:05 -070088 */
Ben Chengd7d426a2009-09-22 11:23:36 -070089 u8 stopMask = (ENCODE_REG_PC | thisLIR->useMask) &
90 ~ENCODE_DALVIK_REG;
Ben Chenge9695e52009-06-16 16:11:47 -070091
92 for (checkLIR = NEXT_LIR(thisLIR);
93 checkLIR != tailLIR;
94 checkLIR = NEXT_LIR(checkLIR)) {
95
96 /* Check if a Dalvik register load is redundant */
Bill Buzbee7ea0f642009-08-10 17:06:51 -070097 if (isDalvikLoad(checkLIR) &&
Ben Chengd7d426a2009-09-22 11:23:36 -070098 (checkLIR->aliasInfo == thisLIR->aliasInfo) &&
99 (REGTYPE(checkLIR->operands[0]) == REGTYPE(nativeRegId))) {
Ben Chenge9695e52009-06-16 16:11:47 -0700100 /* Insert a move to replace the load */
101 if (checkLIR->operands[0] != nativeRegId) {
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700102 ArmLIR *moveLIR;
Ben Cheng5d90c202009-11-22 23:31:11 -0800103 moveLIR = dvmCompilerRegCopyNoInsert(
104 cUnit, checkLIR->operands[0], nativeRegId);
Ben Chenge9695e52009-06-16 16:11:47 -0700105 /*
Ben Cheng58ece732010-03-17 23:32:26 -0700106 * Insert the converted checkLIR instruction after the
107 * the original checkLIR since the optimization is
108 * scannng in the top-down order and the new instruction
109 * will need to be checked.
Ben Chenge9695e52009-06-16 16:11:47 -0700110 */
Ben Cheng58ece732010-03-17 23:32:26 -0700111 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
112 (LIR *) moveLIR);
Ben Chenge9695e52009-06-16 16:11:47 -0700113 }
114 checkLIR->isNop = true;
115 continue;
116
Ben Chengd7d426a2009-09-22 11:23:36 -0700117 /*
118 * Found a true output dependency - nuke the previous store.
119 * The register type doesn't matter here.
120 */
Bill Buzbee7ea0f642009-08-10 17:06:51 -0700121 } else if (isDalvikStore(checkLIR) &&
Ben Chengd7d426a2009-09-22 11:23:36 -0700122 (checkLIR->aliasInfo == thisLIR->aliasInfo)) {
Ben Chenge9695e52009-06-16 16:11:47 -0700123 thisLIR->isNop = true;
124 break;
125 /* Find out the latest slot that the store can be sunk into */
126 } else {
Ben Chenge9695e52009-06-16 16:11:47 -0700127 /* Last instruction reached */
Ben Chengd7d426a2009-09-22 11:23:36 -0700128 bool stopHere = (NEXT_LIR(checkLIR) == tailLIR);
Bill Buzbeea4a7f072009-08-27 13:58:09 -0700129
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700130 /* Store data is clobbered */
Ben Chengd7d426a2009-09-22 11:23:36 -0700131 stopHere |= ((stopMask & checkLIR->defMask) != 0);
132
133 /* Store data partially clobbers the Dalvik register */
134 if (stopHere == false &&
135 ((checkLIR->useMask | checkLIR->defMask) &
136 ENCODE_DALVIK_REG)) {
Ben Chenga4aaf682009-09-30 22:53:44 -0700137 stopHere = isDalvikRegisterClobbered(thisLIR, checkLIR);
Ben Chengd7d426a2009-09-22 11:23:36 -0700138 }
Ben Chenge9695e52009-06-16 16:11:47 -0700139
140 /* Found a new place to put the store - move it here */
141 if (stopHere == true) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700142 DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR,
143 "SINK STORE"));
Ben Chenge9695e52009-06-16 16:11:47 -0700144 /* The store can be sunk for at least one cycle */
145 if (sinkDistance != 0) {
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700146 ArmLIR *newStoreLIR =
147 dvmCompilerNew(sizeof(ArmLIR), true);
Ben Chenge9695e52009-06-16 16:11:47 -0700148 *newStoreLIR = *thisLIR;
149 newStoreLIR->age = cUnit->optRound;
150 /*
Ben Cheng63868fe2010-03-25 16:16:02 -0700151 * Stop point found - insert *before* the checkLIR
152 * since the instruction list is scanned in the
153 * top-down order.
Ben Chenge9695e52009-06-16 16:11:47 -0700154 */
155 dvmCompilerInsertLIRBefore((LIR *) checkLIR,
156 (LIR *) newStoreLIR);
157 thisLIR->isNop = true;
158 }
159 break;
160 }
161
162 /*
163 * Saw a real instruction that the store can be sunk after
164 */
165 if (!isPseudoOpCode(checkLIR->opCode)) {
166 sinkDistance++;
167 }
168 }
169 }
170 }
171 }
172}
173
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700174static void applyLoadHoisting(CompilationUnit *cUnit,
175 ArmLIR *headLIR,
176 ArmLIR *tailLIR)
177{
178 ArmLIR *thisLIR;
Bill Buzbee1f748632010-03-02 16:14:41 -0800179 /*
180 * Don't want to hoist in front of first load following a barrier (or
181 * first instruction of the block.
182 */
183 bool firstLoad = true;
184 int maxHoist = dvmCompilerTargetOptHint(kMaxHoistDistance);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700185
186 cUnit->optRound++;
187 for (thisLIR = headLIR;
188 thisLIR != tailLIR;
189 thisLIR = NEXT_LIR(thisLIR)) {
190 /* Skip newly added instructions */
191 if (thisLIR->age >= cUnit->optRound ||
192 thisLIR->isNop == true) {
193 continue;
194 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800195
196 if (firstLoad && (EncodingMap[thisLIR->opCode].flags & IS_LOAD)) {
197 /*
198 * Ensure nothing will be hoisted in front of this load because
199 * it's result will likely be needed soon.
200 */
201 thisLIR->defMask |= ENCODE_MEM_USE;
202 firstLoad = false;
203 }
204
205 firstLoad |= (thisLIR->defMask == ENCODE_ALL);
206
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700207 if (isDalvikLoad(thisLIR)) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700208 int dRegId = DECODE_ALIAS_INFO_REG(thisLIR->aliasInfo);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700209 int nativeRegId = thisLIR->operands[0];
210 ArmLIR *checkLIR;
211 int hoistDistance = 0;
Ben Cheng63868fe2010-03-25 16:16:02 -0700212 u8 stopUseMask = (ENCODE_REG_PC | thisLIR->useMask);
213 u8 stopDefMask = thisLIR->defMask;
214 u8 checkResult;
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700215
Ben Chengd7d426a2009-09-22 11:23:36 -0700216 /* First check if the load can be completely elinimated */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700217 for (checkLIR = PREV_LIR(thisLIR);
218 checkLIR != headLIR;
219 checkLIR = PREV_LIR(checkLIR)) {
220
221 if (checkLIR->isNop) continue;
222
Ben Chengd7d426a2009-09-22 11:23:36 -0700223 /*
224 * Check if the Dalvik register is previously accessed
225 * with exactly the same type.
226 */
227 if ((isDalvikLoad(checkLIR) || isDalvikStore(checkLIR)) &&
228 (checkLIR->aliasInfo == thisLIR->aliasInfo) &&
229 (checkLIR->operands[0] == nativeRegId)) {
230 /*
231 * If it is previously accessed but with a different type,
232 * the search will terminate later at the point checking
233 * for partially overlapping stores.
234 */
235 thisLIR->isNop = true;
236 break;
237 }
238
239 /*
240 * No earlier use/def can reach this load if:
241 * 1) Head instruction is reached
Ben Cheng63868fe2010-03-25 16:16:02 -0700242 */
243 if (checkLIR == headLIR) {
244 break;
245 }
246
247 checkResult = (stopUseMask | stopDefMask) & checkLIR->defMask;
248
249 /*
250 * If both instructions are verified Dalvik accesses, clear the
251 * may- and must-alias bits to detect true resource
252 * dependencies.
253 */
254 if (checkResult & ENCODE_DALVIK_REG) {
255 checkResult &= ~(ENCODE_DALVIK_REG | ENCODE_FRAME_REF);
256 }
257
258 /*
Ben Chengd7d426a2009-09-22 11:23:36 -0700259 * 2) load target register is clobbered
260 * 3) A branch is seen (stopUseMask has the PC bit set).
261 */
Ben Cheng63868fe2010-03-25 16:16:02 -0700262 if (checkResult) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700263 break;
264 }
265
266 /* Store data partially clobbers the Dalvik register */
267 if (isDalvikStore(checkLIR) &&
Ben Chenga4aaf682009-09-30 22:53:44 -0700268 isDalvikRegisterClobbered(thisLIR, checkLIR)) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700269 break;
270 }
271 }
272
273 /* The load has been eliminated */
274 if (thisLIR->isNop) continue;
275
276 /*
277 * The load cannot be eliminated. See if it can be hoisted to an
278 * earlier spot.
279 */
280 for (checkLIR = PREV_LIR(thisLIR);
281 /* empty by intention */;
282 checkLIR = PREV_LIR(checkLIR)) {
283
284 if (checkLIR->isNop) continue;
285
Bill Buzbee1f748632010-03-02 16:14:41 -0800286 /*
287 * Check if the "thisLIR" load is redundant
288 * NOTE: At one point, we also triggered if the checkLIR
289 * instruction was a load. However, that tended to insert
290 * a load/use dependency because the full scheduler is
291 * not yet complete. When it is, we chould also trigger
292 * on loads.
293 */
294 if (isDalvikStore(checkLIR) &&
Ben Chengd7d426a2009-09-22 11:23:36 -0700295 (checkLIR->aliasInfo == thisLIR->aliasInfo) &&
296 (REGTYPE(checkLIR->operands[0]) == REGTYPE(nativeRegId))) {
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700297 /* Insert a move to replace the load */
298 if (checkLIR->operands[0] != nativeRegId) {
299 ArmLIR *moveLIR;
Ben Cheng5d90c202009-11-22 23:31:11 -0800300 moveLIR = dvmCompilerRegCopyNoInsert(
301 cUnit, nativeRegId, checkLIR->operands[0]);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700302 /*
303 * Convert *thisLIR* load into a move
304 */
305 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
306 (LIR *) moveLIR);
307 }
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700308 thisLIR->isNop = true;
309 break;
310
311 /* Find out if the load can be yanked past the checkLIR */
312 } else {
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700313 /* Last instruction reached */
Ben Chengd7d426a2009-09-22 11:23:36 -0700314 bool stopHere = (checkLIR == headLIR);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700315
316 /* Base address is clobbered by checkLIR */
Ben Cheng63868fe2010-03-25 16:16:02 -0700317 checkResult = stopUseMask & checkLIR->defMask;
318 if (checkResult & ENCODE_DALVIK_REG) {
319 checkResult &= ~(ENCODE_DALVIK_REG | ENCODE_FRAME_REF);
320 }
321 stopHere |= (checkResult != 0);
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700322
323 /* Load target clobbers use/def in checkLIR */
Ben Cheng63868fe2010-03-25 16:16:02 -0700324 checkResult = stopDefMask &
325 (checkLIR->useMask | checkLIR->defMask);
326 if (checkResult & ENCODE_DALVIK_REG) {
327 checkResult &= ~(ENCODE_DALVIK_REG | ENCODE_FRAME_REF);
328 }
329 stopHere |= (checkResult != 0);
Ben Chengd7d426a2009-09-22 11:23:36 -0700330
331 /* Store data partially clobbers the Dalvik register */
332 if (stopHere == false &&
333 (checkLIR->defMask & ENCODE_DALVIK_REG)) {
Ben Chenga4aaf682009-09-30 22:53:44 -0700334 stopHere = isDalvikRegisterClobbered(thisLIR, checkLIR);
Ben Chengd7d426a2009-09-22 11:23:36 -0700335 }
336
337 /*
338 * Stop at an earlier Dalvik load if the offset of checkLIR
339 * is not less than thisLIR
340 *
341 * Experiments show that doing
342 *
343 * ldr r1, [r5, #16]
344 * ldr r0, [r5, #20]
345 *
346 * is much faster than
347 *
348 * ldr r0, [r5, #20]
349 * ldr r1, [r5, #16]
350 */
351 if (isDalvikLoad(checkLIR)) {
352 int dRegId2 =
353 DECODE_ALIAS_INFO_REG(checkLIR->aliasInfo);
354 if (dRegId2 <= dRegId) {
355 stopHere = true;
356 }
357 }
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700358
Bill Buzbee1f748632010-03-02 16:14:41 -0800359 /* Don't go too far */
360 stopHere |= (hoistDistance >= maxHoist);
361
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700362 /* Found a new place to put the load - move it here */
363 if (stopHere == true) {
Ben Chengd7d426a2009-09-22 11:23:36 -0700364 DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR,
365 "HOIST LOAD"));
Ben Cheng63868fe2010-03-25 16:16:02 -0700366 /* The load can be hoisted for at least one cycle */
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700367 if (hoistDistance != 0) {
368 ArmLIR *newLoadLIR =
369 dvmCompilerNew(sizeof(ArmLIR), true);
370 *newLoadLIR = *thisLIR;
371 newLoadLIR->age = cUnit->optRound;
372 /*
Ben Cheng63868fe2010-03-25 16:16:02 -0700373 * Stop point found - insert *after* the checkLIR
374 * since the instruction list is scanned in the
375 * bottom-up order.
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700376 */
377 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
378 (LIR *) newLoadLIR);
379 thisLIR->isNop = true;
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700380 }
381 break;
382 }
383
384 /*
Ben Chengd7d426a2009-09-22 11:23:36 -0700385 * Saw a real instruction that hosting the load is
386 * beneficial
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700387 */
388 if (!isPseudoOpCode(checkLIR->opCode)) {
389 hoistDistance++;
390 }
391 }
392 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800393 } else if (isLiteralLoad(thisLIR)) {
394 int litVal = thisLIR->aliasInfo;
395 int nativeRegId = thisLIR->operands[0];
396 ArmLIR *checkLIR;
397 int hoistDistance = 0;
398 u8 stopUseMask = (ENCODE_REG_PC | thisLIR->useMask) &
399 ~ENCODE_LITPOOL_REF;
400 u8 stopDefMask = thisLIR->defMask & ~ENCODE_LITPOOL_REF;
401
402 /* First check if the load can be completely elinimated */
403 for (checkLIR = PREV_LIR(thisLIR);
404 checkLIR != headLIR;
405 checkLIR = PREV_LIR(checkLIR)) {
406
407 if (checkLIR->isNop) continue;
408
409 /* Reloading same literal into same tgt reg? Eliminate if so */
410 if (isLiteralLoad(checkLIR) &&
411 (checkLIR->aliasInfo == litVal) &&
412 (checkLIR->operands[0] == nativeRegId)) {
413 thisLIR->isNop = true;
414 break;
415 }
416
417 /*
418 * No earlier use/def can reach this load if:
419 * 1) Head instruction is reached
420 * 2) load target register is clobbered
421 * 3) A branch is seen (stopUseMask has the PC bit set).
422 */
423 if ((checkLIR == headLIR) ||
424 (stopUseMask | stopDefMask) & checkLIR->defMask) {
425 break;
426 }
427 }
428
429 /* The load has been eliminated */
430 if (thisLIR->isNop) continue;
431
432 /*
433 * The load cannot be eliminated. See if it can be hoisted to an
434 * earlier spot.
435 */
436 for (checkLIR = PREV_LIR(thisLIR);
437 /* empty by intention */;
438 checkLIR = PREV_LIR(checkLIR)) {
439
440 if (checkLIR->isNop) continue;
441
442 /*
443 * TUNING: once a full scheduler exists, check here
444 * for conversion of a redundant load into a copy similar
445 * to the way redundant loads are handled above.
446 */
447
448 /* Find out if the load can be yanked past the checkLIR */
449
450 /* Last instruction reached */
451 bool stopHere = (checkLIR == headLIR);
452
453 /* Base address is clobbered by checkLIR */
454 stopHere |= ((stopUseMask & checkLIR->defMask) != 0);
455
456 /* Load target clobbers use/def in checkLIR */
457 stopHere |= ((stopDefMask &
458 (checkLIR->useMask | checkLIR->defMask)) != 0);
459
460 /* Avoid re-ordering literal pool loads */
461 stopHere |= isLiteralLoad(checkLIR);
462
463 /* Don't go too far */
464 stopHere |= (hoistDistance >= maxHoist);
465
466 /* Found a new place to put the load - move it here */
467 if (stopHere == true) {
468 DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR,
469 "HOIST LOAD"));
470 /* The store can be hoisted for at least one cycle */
471 if (hoistDistance != 0) {
472 ArmLIR *newLoadLIR =
473 dvmCompilerNew(sizeof(ArmLIR), true);
474 *newLoadLIR = *thisLIR;
475 newLoadLIR->age = cUnit->optRound;
476 /*
477 * Insertion is guaranteed to succeed since checkLIR
478 * is never the first LIR on the list
479 */
480 dvmCompilerInsertLIRAfter((LIR *) checkLIR,
481 (LIR *) newLoadLIR);
482 thisLIR->isNop = true;
483 }
484 break;
485 }
486
487 /*
488 * Saw a real instruction that hosting the load is
489 * beneficial
490 */
491 if (!isPseudoOpCode(checkLIR->opCode)) {
492 hoistDistance++;
493 }
494 }
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700495 }
496 }
497}
498
Ben Chenge9695e52009-06-16 16:11:47 -0700499void dvmCompilerApplyLocalOptimizations(CompilationUnit *cUnit, LIR *headLIR,
500 LIR *tailLIR)
501{
Ben Chengdcf3e5d2009-09-11 13:42:05 -0700502 if (!(gDvmJit.disableOpt & (1 << kLoadStoreElimination))) {
503 applyLoadStoreElimination(cUnit, (ArmLIR *) headLIR,
504 (ArmLIR *) tailLIR);
505 }
506 if (!(gDvmJit.disableOpt & (1 << kLoadHoisting))) {
507 applyLoadHoisting(cUnit, (ArmLIR *) headLIR, (ArmLIR *) tailLIR);
508 }
Ben Chenge9695e52009-06-16 16:11:47 -0700509}